diff options
Diffstat (limited to 'arch')
892 files changed, 60872 insertions, 10254 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 99193b160232..beea3ccebb5e 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
| @@ -30,6 +30,18 @@ config OPROFILE_IBS | |||
| 30 | 30 | ||
| 31 | If unsure, say N. | 31 | If unsure, say N. |
| 32 | 32 | ||
| 33 | config OPROFILE_EVENT_MULTIPLEX | ||
| 34 | bool "OProfile multiplexing support (EXPERIMENTAL)" | ||
| 35 | default n | ||
| 36 | depends on OPROFILE && X86 | ||
| 37 | help | ||
| 38 | The number of hardware counters is limited. The multiplexing | ||
| 39 | feature enables OProfile to gather more events than counters | ||
| 40 | are provided by the hardware. This is realized by switching | ||
| 41 | between events at an user specified time interval. | ||
| 42 | |||
| 43 | If unsure, say N. | ||
| 44 | |||
| 33 | config HAVE_OPROFILE | 45 | config HAVE_OPROFILE |
| 34 | bool | 46 | bool |
| 35 | 47 | ||
diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h index 3641ec1452f4..26773e3246e2 100644 --- a/arch/alpha/include/asm/socket.h +++ b/arch/alpha/include/asm/socket.h | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | #define SO_RCVTIMEO 0x1012 | 32 | #define SO_RCVTIMEO 0x1012 |
| 33 | #define SO_SNDTIMEO 0x1013 | 33 | #define SO_SNDTIMEO 0x1013 |
| 34 | #define SO_ACCEPTCONN 0x1014 | 34 | #define SO_ACCEPTCONN 0x1014 |
| 35 | #define SO_PROTOCOL 0x1028 | ||
| 36 | #define SO_DOMAIN 0x1029 | ||
| 35 | 37 | ||
| 36 | /* linux-specific, might as well be the same as on i386 */ | 38 | /* linux-specific, might as well be the same as on i386 */ |
| 37 | #define SO_NO_CHECK 11 | 39 | #define SO_NO_CHECK 11 |
diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h index 60c83abfde70..5076a8860b18 100644 --- a/arch/alpha/include/asm/thread_info.h +++ b/arch/alpha/include/asm/thread_info.h | |||
| @@ -75,6 +75,7 @@ register struct thread_info *__current_thread_info __asm__("$8"); | |||
| 75 | #define TIF_UAC_SIGBUS 7 | 75 | #define TIF_UAC_SIGBUS 7 |
| 76 | #define TIF_MEMDIE 8 | 76 | #define TIF_MEMDIE 8 |
| 77 | #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */ | 77 | #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */ |
| 78 | #define TIF_NOTIFY_RESUME 10 /* callback before returning to user */ | ||
| 78 | #define TIF_FREEZE 16 /* is freezing for suspend */ | 79 | #define TIF_FREEZE 16 /* is freezing for suspend */ |
| 79 | 80 | ||
| 80 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 81 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
| @@ -82,10 +83,12 @@ register struct thread_info *__current_thread_info __asm__("$8"); | |||
| 82 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | 83 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
| 83 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 84 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
| 84 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) | 85 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) |
| 86 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) | ||
| 85 | #define _TIF_FREEZE (1<<TIF_FREEZE) | 87 | #define _TIF_FREEZE (1<<TIF_FREEZE) |
| 86 | 88 | ||
| 87 | /* Work to do on interrupt/exception return. */ | 89 | /* Work to do on interrupt/exception return. */ |
| 88 | #define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED) | 90 | #define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ |
| 91 | _TIF_NOTIFY_RESUME) | ||
| 89 | 92 | ||
| 90 | /* Work to do on any return to userspace. */ | 93 | /* Work to do on any return to userspace. */ |
| 91 | #define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \ | 94 | #define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \ |
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index df65eaa84c4c..0932dbb1ef8e 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/binfmts.h> | 20 | #include <linux/binfmts.h> |
| 21 | #include <linux/bitops.h> | 21 | #include <linux/bitops.h> |
| 22 | #include <linux/syscalls.h> | 22 | #include <linux/syscalls.h> |
| 23 | #include <linux/tracehook.h> | ||
| 23 | 24 | ||
| 24 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
| 25 | #include <asm/sigcontext.h> | 26 | #include <asm/sigcontext.h> |
| @@ -683,4 +684,11 @@ do_notify_resume(struct pt_regs *regs, struct switch_stack *sw, | |||
| 683 | { | 684 | { |
| 684 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 685 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) |
| 685 | do_signal(regs, sw, r0, r19); | 686 | do_signal(regs, sw, r0, r19); |
| 687 | |||
| 688 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | ||
| 689 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
| 690 | tracehook_notify_resume(regs); | ||
| 691 | if (current->replacement_session_keyring) | ||
| 692 | key_replace_session_keyring(); | ||
| 693 | } | ||
| 686 | } | 694 | } |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index aef63c8e3d2d..d778a699f577 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -46,10 +46,6 @@ config GENERIC_CLOCKEVENTS_BROADCAST | |||
| 46 | depends on GENERIC_CLOCKEVENTS | 46 | depends on GENERIC_CLOCKEVENTS |
| 47 | default y if SMP && !LOCAL_TIMERS | 47 | default y if SMP && !LOCAL_TIMERS |
| 48 | 48 | ||
| 49 | config MMU | ||
| 50 | bool | ||
| 51 | default y | ||
| 52 | |||
| 53 | config NO_IOPORT | 49 | config NO_IOPORT |
| 54 | bool | 50 | bool |
| 55 | 51 | ||
| @@ -126,6 +122,13 @@ config ARCH_HAS_ILOG2_U32 | |||
| 126 | config ARCH_HAS_ILOG2_U64 | 122 | config ARCH_HAS_ILOG2_U64 |
| 127 | bool | 123 | bool |
| 128 | 124 | ||
| 125 | config ARCH_HAS_CPUFREQ | ||
| 126 | bool | ||
| 127 | help | ||
| 128 | Internal node to signify that the ARCH has CPUFREQ support | ||
| 129 | and that the relevant menu configurations are displayed for | ||
| 130 | it. | ||
| 131 | |||
| 129 | config GENERIC_HWEIGHT | 132 | config GENERIC_HWEIGHT |
| 130 | bool | 133 | bool |
| 131 | default y | 134 | default y |
| @@ -188,6 +191,13 @@ source "kernel/Kconfig.freezer" | |||
| 188 | 191 | ||
| 189 | menu "System Type" | 192 | menu "System Type" |
| 190 | 193 | ||
| 194 | config MMU | ||
| 195 | bool "MMU-based Paged Memory Management Support" | ||
| 196 | default y | ||
| 197 | help | ||
| 198 | Select if you want MMU-based virtualised addressing space | ||
| 199 | support by paged memory management. If unsure, say 'Y'. | ||
| 200 | |||
| 191 | choice | 201 | choice |
| 192 | prompt "ARM system type" | 202 | prompt "ARM system type" |
| 193 | default ARCH_VERSATILE | 203 | default ARCH_VERSATILE |
| @@ -203,6 +213,7 @@ config ARCH_AAEC2000 | |||
| 203 | config ARCH_INTEGRATOR | 213 | config ARCH_INTEGRATOR |
| 204 | bool "ARM Ltd. Integrator family" | 214 | bool "ARM Ltd. Integrator family" |
| 205 | select ARM_AMBA | 215 | select ARM_AMBA |
| 216 | select ARCH_HAS_CPUFREQ | ||
| 206 | select HAVE_CLK | 217 | select HAVE_CLK |
| 207 | select COMMON_CLKDEV | 218 | select COMMON_CLKDEV |
| 208 | select ICST525 | 219 | select ICST525 |
| @@ -217,6 +228,7 @@ config ARCH_REALVIEW | |||
| 217 | select ICST307 | 228 | select ICST307 |
| 218 | select GENERIC_TIME | 229 | select GENERIC_TIME |
| 219 | select GENERIC_CLOCKEVENTS | 230 | select GENERIC_CLOCKEVENTS |
| 231 | select ARCH_WANT_OPTIONAL_GPIOLIB | ||
| 220 | help | 232 | help |
| 221 | This enables support for ARM Ltd RealView boards. | 233 | This enables support for ARM Ltd RealView boards. |
| 222 | 234 | ||
| @@ -229,6 +241,7 @@ config ARCH_VERSATILE | |||
| 229 | select ICST307 | 241 | select ICST307 |
| 230 | select GENERIC_TIME | 242 | select GENERIC_TIME |
| 231 | select GENERIC_CLOCKEVENTS | 243 | select GENERIC_CLOCKEVENTS |
| 244 | select ARCH_WANT_OPTIONAL_GPIOLIB | ||
| 232 | help | 245 | help |
| 233 | This enables support for ARM Ltd Versatile board. | 246 | This enables support for ARM Ltd Versatile board. |
| 234 | 247 | ||
| @@ -327,6 +340,20 @@ config ARCH_H720X | |||
| 327 | help | 340 | help |
| 328 | This enables support for systems based on the Hynix HMS720x | 341 | This enables support for systems based on the Hynix HMS720x |
| 329 | 342 | ||
| 343 | config ARCH_NOMADIK | ||
| 344 | bool "STMicroelectronics Nomadik" | ||
| 345 | select ARM_AMBA | ||
| 346 | select ARM_VIC | ||
| 347 | select CPU_ARM926T | ||
| 348 | select HAVE_CLK | ||
| 349 | select COMMON_CLKDEV | ||
| 350 | select GENERIC_TIME | ||
| 351 | select GENERIC_CLOCKEVENTS | ||
| 352 | select GENERIC_GPIO | ||
| 353 | select ARCH_REQUIRE_GPIOLIB | ||
| 354 | help | ||
| 355 | Support for the Nomadik platform by ST-Ericsson | ||
| 356 | |||
| 330 | config ARCH_IOP13XX | 357 | config ARCH_IOP13XX |
| 331 | bool "IOP13xx-based" | 358 | bool "IOP13xx-based" |
| 332 | depends on MMU | 359 | depends on MMU |
| @@ -493,10 +520,18 @@ config ARCH_W90X900 | |||
| 493 | select CPU_ARM926T | 520 | select CPU_ARM926T |
| 494 | select ARCH_REQUIRE_GPIOLIB | 521 | select ARCH_REQUIRE_GPIOLIB |
| 495 | select GENERIC_GPIO | 522 | select GENERIC_GPIO |
| 523 | select HAVE_CLK | ||
| 496 | select COMMON_CLKDEV | 524 | select COMMON_CLKDEV |
| 525 | select GENERIC_TIME | ||
| 526 | select GENERIC_CLOCKEVENTS | ||
| 497 | help | 527 | help |
| 498 | Support for Nuvoton (Winbond logic dept.) ARM9 processor,You | 528 | Support for Nuvoton (Winbond logic dept.) ARM9 processor, |
| 499 | can login www.mcuos.com or www.nuvoton.com to know more. | 529 | At present, the w90x900 has been renamed nuc900, regarding |
| 530 | the ARM series product line, you can login the following | ||
| 531 | link address to know more. | ||
| 532 | |||
| 533 | <http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/ | ||
| 534 | ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller> | ||
| 500 | 535 | ||
| 501 | config ARCH_PNX4008 | 536 | config ARCH_PNX4008 |
| 502 | bool "Philips Nexperia PNX4008 Mobile" | 537 | bool "Philips Nexperia PNX4008 Mobile" |
| @@ -509,6 +544,7 @@ config ARCH_PXA | |||
| 509 | bool "PXA2xx/PXA3xx-based" | 544 | bool "PXA2xx/PXA3xx-based" |
| 510 | depends on MMU | 545 | depends on MMU |
| 511 | select ARCH_MTD_XIP | 546 | select ARCH_MTD_XIP |
| 547 | select ARCH_HAS_CPUFREQ | ||
| 512 | select GENERIC_GPIO | 548 | select GENERIC_GPIO |
| 513 | select HAVE_CLK | 549 | select HAVE_CLK |
| 514 | select COMMON_CLKDEV | 550 | select COMMON_CLKDEV |
| @@ -551,6 +587,7 @@ config ARCH_SA1100 | |||
| 551 | select ISA | 587 | select ISA |
| 552 | select ARCH_SPARSEMEM_ENABLE | 588 | select ARCH_SPARSEMEM_ENABLE |
| 553 | select ARCH_MTD_XIP | 589 | select ARCH_MTD_XIP |
| 590 | select ARCH_HAS_CPUFREQ | ||
| 554 | select GENERIC_GPIO | 591 | select GENERIC_GPIO |
| 555 | select GENERIC_TIME | 592 | select GENERIC_TIME |
| 556 | select GENERIC_CLOCKEVENTS | 593 | select GENERIC_CLOCKEVENTS |
| @@ -563,6 +600,7 @@ config ARCH_SA1100 | |||
| 563 | config ARCH_S3C2410 | 600 | config ARCH_S3C2410 |
| 564 | bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443" | 601 | bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443" |
| 565 | select GENERIC_GPIO | 602 | select GENERIC_GPIO |
| 603 | select ARCH_HAS_CPUFREQ | ||
| 566 | select HAVE_CLK | 604 | select HAVE_CLK |
| 567 | help | 605 | help |
| 568 | Samsung S3C2410X CPU based systems, such as the Simtec Electronics | 606 | Samsung S3C2410X CPU based systems, such as the Simtec Electronics |
| @@ -573,9 +611,18 @@ config ARCH_S3C64XX | |||
| 573 | bool "Samsung S3C64XX" | 611 | bool "Samsung S3C64XX" |
| 574 | select GENERIC_GPIO | 612 | select GENERIC_GPIO |
| 575 | select HAVE_CLK | 613 | select HAVE_CLK |
| 614 | select ARCH_HAS_CPUFREQ | ||
| 576 | help | 615 | help |
| 577 | Samsung S3C64XX series based systems | 616 | Samsung S3C64XX series based systems |
| 578 | 617 | ||
| 618 | config ARCH_S5PC1XX | ||
| 619 | bool "Samsung S5PC1XX" | ||
| 620 | select GENERIC_GPIO | ||
| 621 | select HAVE_CLK | ||
| 622 | select CPU_V7 | ||
| 623 | help | ||
| 624 | Samsung S5PC1XX series based systems | ||
| 625 | |||
| 579 | config ARCH_SHARK | 626 | config ARCH_SHARK |
| 580 | bool "Shark" | 627 | bool "Shark" |
| 581 | select CPU_SA110 | 628 | select CPU_SA110 |
| @@ -632,11 +679,24 @@ config ARCH_OMAP | |||
| 632 | select GENERIC_GPIO | 679 | select GENERIC_GPIO |
| 633 | select HAVE_CLK | 680 | select HAVE_CLK |
| 634 | select ARCH_REQUIRE_GPIOLIB | 681 | select ARCH_REQUIRE_GPIOLIB |
| 682 | select ARCH_HAS_CPUFREQ | ||
| 635 | select GENERIC_TIME | 683 | select GENERIC_TIME |
| 636 | select GENERIC_CLOCKEVENTS | 684 | select GENERIC_CLOCKEVENTS |
| 637 | help | 685 | help |
| 638 | Support for TI's OMAP platform (OMAP1 and OMAP2). | 686 | Support for TI's OMAP platform (OMAP1 and OMAP2). |
| 639 | 687 | ||
| 688 | config ARCH_BCMRING | ||
| 689 | bool "Broadcom BCMRING" | ||
| 690 | depends on MMU | ||
| 691 | select CPU_V6 | ||
| 692 | select ARM_AMBA | ||
| 693 | select COMMON_CLKDEV | ||
| 694 | select GENERIC_TIME | ||
| 695 | select GENERIC_CLOCKEVENTS | ||
| 696 | select ARCH_WANT_OPTIONAL_GPIOLIB | ||
| 697 | help | ||
| 698 | Support for Broadcom's BCMRing platform. | ||
| 699 | |||
| 640 | endchoice | 700 | endchoice |
| 641 | 701 | ||
| 642 | source "arch/arm/mach-clps711x/Kconfig" | 702 | source "arch/arm/mach-clps711x/Kconfig" |
| @@ -685,6 +745,7 @@ source "arch/arm/mach-kirkwood/Kconfig" | |||
| 685 | source "arch/arm/plat-s3c24xx/Kconfig" | 745 | source "arch/arm/plat-s3c24xx/Kconfig" |
| 686 | source "arch/arm/plat-s3c64xx/Kconfig" | 746 | source "arch/arm/plat-s3c64xx/Kconfig" |
| 687 | source "arch/arm/plat-s3c/Kconfig" | 747 | source "arch/arm/plat-s3c/Kconfig" |
| 748 | source "arch/arm/plat-s5pc1xx/Kconfig" | ||
| 688 | 749 | ||
| 689 | if ARCH_S3C2410 | 750 | if ARCH_S3C2410 |
| 690 | source "arch/arm/mach-s3c2400/Kconfig" | 751 | source "arch/arm/mach-s3c2400/Kconfig" |
| @@ -702,6 +763,10 @@ endif | |||
| 702 | 763 | ||
| 703 | source "arch/arm/plat-stmp3xxx/Kconfig" | 764 | source "arch/arm/plat-stmp3xxx/Kconfig" |
| 704 | 765 | ||
| 766 | if ARCH_S5PC1XX | ||
| 767 | source "arch/arm/mach-s5pc100/Kconfig" | ||
| 768 | endif | ||
| 769 | |||
| 705 | source "arch/arm/mach-lh7a40x/Kconfig" | 770 | source "arch/arm/mach-lh7a40x/Kconfig" |
| 706 | 771 | ||
| 707 | source "arch/arm/mach-h720x/Kconfig" | 772 | source "arch/arm/mach-h720x/Kconfig" |
| @@ -716,6 +781,8 @@ source "arch/arm/mach-at91/Kconfig" | |||
| 716 | 781 | ||
| 717 | source "arch/arm/plat-mxc/Kconfig" | 782 | source "arch/arm/plat-mxc/Kconfig" |
| 718 | 783 | ||
| 784 | source "arch/arm/mach-nomadik/Kconfig" | ||
| 785 | |||
| 719 | source "arch/arm/mach-netx/Kconfig" | 786 | source "arch/arm/mach-netx/Kconfig" |
| 720 | 787 | ||
| 721 | source "arch/arm/mach-ns9xxx/Kconfig" | 788 | source "arch/arm/mach-ns9xxx/Kconfig" |
| @@ -730,6 +797,8 @@ source "arch/arm/mach-u300/Kconfig" | |||
| 730 | 797 | ||
| 731 | source "arch/arm/mach-w90x900/Kconfig" | 798 | source "arch/arm/mach-w90x900/Kconfig" |
| 732 | 799 | ||
| 800 | source "arch/arm/mach-bcmring/Kconfig" | ||
| 801 | |||
| 733 | # Definitions to make life easier | 802 | # Definitions to make life easier |
| 734 | config ARCH_ACORN | 803 | config ARCH_ACORN |
| 735 | bool | 804 | bool |
| @@ -962,18 +1031,7 @@ config LOCAL_TIMERS | |||
| 962 | accounting to be spread across the timer interval, preventing a | 1031 | accounting to be spread across the timer interval, preventing a |
| 963 | "thundering herd" at every timer tick. | 1032 | "thundering herd" at every timer tick. |
| 964 | 1033 | ||
| 965 | config PREEMPT | 1034 | source kernel/Kconfig.preempt |
| 966 | bool "Preemptible Kernel (EXPERIMENTAL)" | ||
| 967 | depends on EXPERIMENTAL | ||
| 968 | help | ||
| 969 | This option reduces the latency of the kernel when reacting to | ||
| 970 | real-time or interactive events by allowing a low priority process to | ||
| 971 | be preempted even if it is in kernel mode executing a system call. | ||
| 972 | This allows applications to run more reliably even when the system is | ||
| 973 | under load. | ||
| 974 | |||
| 975 | Say Y here if you are building a kernel for a desktop, embedded | ||
| 976 | or real-time system. Say N if you are unsure. | ||
| 977 | 1035 | ||
| 978 | config HZ | 1036 | config HZ |
| 979 | int | 1037 | int |
| @@ -983,6 +1041,21 @@ config HZ | |||
| 983 | default AT91_TIMER_HZ if ARCH_AT91 | 1041 | default AT91_TIMER_HZ if ARCH_AT91 |
| 984 | default 100 | 1042 | default 100 |
| 985 | 1043 | ||
| 1044 | config THUMB2_KERNEL | ||
| 1045 | bool "Compile the kernel in Thumb-2 mode" | ||
| 1046 | depends on CPU_V7 && EXPERIMENTAL | ||
| 1047 | select AEABI | ||
| 1048 | select ARM_ASM_UNIFIED | ||
| 1049 | help | ||
| 1050 | By enabling this option, the kernel will be compiled in | ||
| 1051 | Thumb-2 mode. A compiler/assembler that understand the unified | ||
| 1052 | ARM-Thumb syntax is needed. | ||
| 1053 | |||
| 1054 | If unsure, say N. | ||
| 1055 | |||
| 1056 | config ARM_ASM_UNIFIED | ||
| 1057 | bool | ||
| 1058 | |||
| 986 | config AEABI | 1059 | config AEABI |
| 987 | bool "Use the ARM EABI to compile the kernel" | 1060 | bool "Use the ARM EABI to compile the kernel" |
| 988 | help | 1061 | help |
| @@ -1054,6 +1127,11 @@ config HIGHMEM | |||
| 1054 | 1127 | ||
| 1055 | If unsure, say n. | 1128 | If unsure, say n. |
| 1056 | 1129 | ||
| 1130 | config HIGHPTE | ||
| 1131 | bool "Allocate 2nd-level pagetables from highmem" | ||
| 1132 | depends on HIGHMEM | ||
| 1133 | depends on !OUTER_CACHE | ||
| 1134 | |||
| 1057 | source "mm/Kconfig" | 1135 | source "mm/Kconfig" |
| 1058 | 1136 | ||
| 1059 | config LEDS | 1137 | config LEDS |
| @@ -1241,7 +1319,7 @@ endmenu | |||
| 1241 | 1319 | ||
| 1242 | menu "CPU Power Management" | 1320 | menu "CPU Power Management" |
| 1243 | 1321 | ||
| 1244 | if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_PXA || ARCH_S3C64XX) | 1322 | if ARCH_HAS_CPUFREQ |
| 1245 | 1323 | ||
| 1246 | source "drivers/cpufreq/Kconfig" | 1324 | source "drivers/cpufreq/Kconfig" |
| 1247 | 1325 | ||
| @@ -1276,6 +1354,52 @@ config CPU_FREQ_S3C64XX | |||
| 1276 | bool "CPUfreq support for Samsung S3C64XX CPUs" | 1354 | bool "CPUfreq support for Samsung S3C64XX CPUs" |
| 1277 | depends on CPU_FREQ && CPU_S3C6410 | 1355 | depends on CPU_FREQ && CPU_S3C6410 |
| 1278 | 1356 | ||
| 1357 | config CPU_FREQ_S3C | ||
| 1358 | bool | ||
| 1359 | help | ||
| 1360 | Internal configuration node for common cpufreq on Samsung SoC | ||
| 1361 | |||
| 1362 | config CPU_FREQ_S3C24XX | ||
| 1363 | bool "CPUfreq driver for Samsung S3C24XX series CPUs" | ||
| 1364 | depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL | ||
| 1365 | select CPU_FREQ_S3C | ||
| 1366 | help | ||
| 1367 | This enables the CPUfreq driver for the Samsung S3C24XX family | ||
| 1368 | of CPUs. | ||
| 1369 | |||
| 1370 | For details, take a look at <file:Documentation/cpu-freq>. | ||
| 1371 | |||
| 1372 | If in doubt, say N. | ||
| 1373 | |||
| 1374 | config CPU_FREQ_S3C24XX_PLL | ||
| 1375 | bool "Support CPUfreq changing of PLL frequency" | ||
| 1376 | depends on CPU_FREQ_S3C24XX && EXPERIMENTAL | ||
| 1377 | help | ||
| 1378 | Compile in support for changing the PLL frequency from the | ||
| 1379 | S3C24XX series CPUfreq driver. The PLL takes time to settle | ||
| 1380 | after a frequency change, so by default it is not enabled. | ||
| 1381 | |||
| 1382 | This also means that the PLL tables for the selected CPU(s) will | ||
| 1383 | be built which may increase the size of the kernel image. | ||
| 1384 | |||
| 1385 | config CPU_FREQ_S3C24XX_DEBUG | ||
| 1386 | bool "Debug CPUfreq Samsung driver core" | ||
| 1387 | depends on CPU_FREQ_S3C24XX | ||
| 1388 | help | ||
| 1389 | Enable s3c_freq_dbg for the Samsung S3C CPUfreq core | ||
| 1390 | |||
| 1391 | config CPU_FREQ_S3C24XX_IODEBUG | ||
| 1392 | bool "Debug CPUfreq Samsung driver IO timing" | ||
| 1393 | depends on CPU_FREQ_S3C24XX | ||
| 1394 | help | ||
| 1395 | Enable s3c_freq_iodbg for the Samsung S3C CPUfreq core | ||
| 1396 | |||
| 1397 | config CPU_FREQ_S3C24XX_DEBUGFS | ||
| 1398 | bool "Export debugfs for CPUFreq" | ||
| 1399 | depends on CPU_FREQ_S3C24XX && DEBUG_FS | ||
| 1400 | help | ||
| 1401 | Export status information via debugfs. | ||
| 1402 | |||
| 1279 | endif | 1403 | endif |
| 1280 | 1404 | ||
| 1281 | source "drivers/cpuidle/Kconfig" | 1405 | source "drivers/cpuidle/Kconfig" |
| @@ -1377,107 +1501,7 @@ endmenu | |||
| 1377 | 1501 | ||
| 1378 | source "net/Kconfig" | 1502 | source "net/Kconfig" |
| 1379 | 1503 | ||
| 1380 | menu "Device Drivers" | 1504 | source "drivers/Kconfig" |
| 1381 | |||
| 1382 | source "drivers/base/Kconfig" | ||
| 1383 | |||
| 1384 | source "drivers/connector/Kconfig" | ||
| 1385 | |||
| 1386 | if ALIGNMENT_TRAP || !CPU_CP15_MMU | ||
| 1387 | source "drivers/mtd/Kconfig" | ||
| 1388 | endif | ||
| 1389 | |||
| 1390 | source "drivers/parport/Kconfig" | ||
| 1391 | |||
| 1392 | source "drivers/pnp/Kconfig" | ||
| 1393 | |||
| 1394 | source "drivers/block/Kconfig" | ||
| 1395 | |||
| 1396 | # misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4 | ||
| 1397 | |||
| 1398 | source "drivers/misc/Kconfig" | ||
| 1399 | |||
| 1400 | source "drivers/ide/Kconfig" | ||
| 1401 | |||
| 1402 | source "drivers/scsi/Kconfig" | ||
| 1403 | |||
| 1404 | source "drivers/ata/Kconfig" | ||
| 1405 | |||
| 1406 | source "drivers/md/Kconfig" | ||
| 1407 | |||
| 1408 | source "drivers/message/fusion/Kconfig" | ||
| 1409 | |||
| 1410 | source "drivers/ieee1394/Kconfig" | ||
| 1411 | |||
| 1412 | source "drivers/message/i2o/Kconfig" | ||
| 1413 | |||
| 1414 | source "drivers/net/Kconfig" | ||
| 1415 | |||
| 1416 | source "drivers/isdn/Kconfig" | ||
| 1417 | |||
| 1418 | # input before char - char/joystick depends on it. As does USB. | ||
| 1419 | |||
| 1420 | source "drivers/input/Kconfig" | ||
| 1421 | |||
| 1422 | source "drivers/char/Kconfig" | ||
| 1423 | |||
| 1424 | source "drivers/i2c/Kconfig" | ||
| 1425 | |||
| 1426 | source "drivers/spi/Kconfig" | ||
| 1427 | |||
| 1428 | source "drivers/gpio/Kconfig" | ||
| 1429 | |||
| 1430 | source "drivers/w1/Kconfig" | ||
| 1431 | |||
| 1432 | source "drivers/power/Kconfig" | ||
| 1433 | |||
| 1434 | source "drivers/hwmon/Kconfig" | ||
| 1435 | |||
| 1436 | source "drivers/thermal/Kconfig" | ||
| 1437 | |||
| 1438 | source "drivers/watchdog/Kconfig" | ||
| 1439 | |||
| 1440 | source "drivers/ssb/Kconfig" | ||
| 1441 | |||
| 1442 | #source "drivers/l3/Kconfig" | ||
| 1443 | |||
| 1444 | source "drivers/mfd/Kconfig" | ||
| 1445 | |||
| 1446 | source "drivers/media/Kconfig" | ||
| 1447 | |||
| 1448 | source "drivers/video/Kconfig" | ||
| 1449 | |||
| 1450 | source "sound/Kconfig" | ||
| 1451 | |||
| 1452 | source "drivers/hid/Kconfig" | ||
| 1453 | |||
| 1454 | source "drivers/usb/Kconfig" | ||
| 1455 | |||
| 1456 | source "drivers/uwb/Kconfig" | ||
| 1457 | |||
| 1458 | source "drivers/mmc/Kconfig" | ||
| 1459 | |||
| 1460 | source "drivers/memstick/Kconfig" | ||
| 1461 | |||
| 1462 | source "drivers/accessibility/Kconfig" | ||
| 1463 | |||
| 1464 | source "drivers/leds/Kconfig" | ||
| 1465 | |||
| 1466 | source "drivers/rtc/Kconfig" | ||
| 1467 | |||
| 1468 | source "drivers/dma/Kconfig" | ||
| 1469 | |||
| 1470 | source "drivers/dca/Kconfig" | ||
| 1471 | |||
| 1472 | source "drivers/auxdisplay/Kconfig" | ||
| 1473 | |||
| 1474 | source "drivers/regulator/Kconfig" | ||
| 1475 | |||
| 1476 | source "drivers/uio/Kconfig" | ||
| 1477 | |||
| 1478 | source "drivers/staging/Kconfig" | ||
| 1479 | |||
| 1480 | endmenu | ||
| 1481 | 1505 | ||
| 1482 | source "fs/Kconfig" | 1506 | source "fs/Kconfig" |
| 1483 | 1507 | ||
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index a89e4734b8f0..1a6f70e52921 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
| @@ -8,6 +8,7 @@ source "lib/Kconfig.debug" | |||
| 8 | # n, but then RMK will have to kill you ;). | 8 | # n, but then RMK will have to kill you ;). |
| 9 | config FRAME_POINTER | 9 | config FRAME_POINTER |
| 10 | bool | 10 | bool |
| 11 | depends on !THUMB2_KERNEL | ||
| 11 | default y if !ARM_UNWIND | 12 | default y if !ARM_UNWIND |
| 12 | help | 13 | help |
| 13 | If you say N here, the resulting kernel will be slightly smaller and | 14 | If you say N here, the resulting kernel will be slightly smaller and |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index c877d6df23d1..7350557a81e0 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
| @@ -93,9 +93,16 @@ ifeq ($(CONFIG_ARM_UNWIND),y) | |||
| 93 | CFLAGS_ABI +=-funwind-tables | 93 | CFLAGS_ABI +=-funwind-tables |
| 94 | endif | 94 | endif |
| 95 | 95 | ||
| 96 | ifeq ($(CONFIG_THUMB2_KERNEL),y) | ||
| 97 | AFLAGS_AUTOIT :=$(call as-option,-Wa$(comma)-mimplicit-it=thumb,-Wa$(comma)-mauto-it) | ||
| 98 | AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W) | ||
| 99 | CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN) | ||
| 100 | AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb | ||
| 101 | endif | ||
| 102 | |||
| 96 | # Need -Uarm for gcc < 3.x | 103 | # Need -Uarm for gcc < 3.x |
| 97 | KBUILD_CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm | 104 | KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_THUMB2) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm |
| 98 | KBUILD_AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float | 105 | KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_THUMB2) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float |
| 99 | 106 | ||
| 100 | CHECKFLAGS += -D__arm__ | 107 | CHECKFLAGS += -D__arm__ |
| 101 | 108 | ||
| @@ -112,6 +119,7 @@ endif | |||
| 112 | # by CONFIG_* macro name. | 119 | # by CONFIG_* macro name. |
| 113 | machine-$(CONFIG_ARCH_AAEC2000) := aaec2000 | 120 | machine-$(CONFIG_ARCH_AAEC2000) := aaec2000 |
| 114 | machine-$(CONFIG_ARCH_AT91) := at91 | 121 | machine-$(CONFIG_ARCH_AT91) := at91 |
| 122 | machine-$(CONFIG_ARCH_BCMRING) := bcmring | ||
| 115 | machine-$(CONFIG_ARCH_CLPS711X) := clps711x | 123 | machine-$(CONFIG_ARCH_CLPS711X) := clps711x |
| 116 | machine-$(CONFIG_ARCH_DAVINCI) := davinci | 124 | machine-$(CONFIG_ARCH_DAVINCI) := davinci |
| 117 | machine-$(CONFIG_ARCH_EBSA110) := ebsa110 | 125 | machine-$(CONFIG_ARCH_EBSA110) := ebsa110 |
| @@ -135,8 +143,10 @@ machine-$(CONFIG_ARCH_MSM) := msm | |||
| 135 | machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0 | 143 | machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0 |
| 136 | machine-$(CONFIG_ARCH_MX1) := mx1 | 144 | machine-$(CONFIG_ARCH_MX1) := mx1 |
| 137 | machine-$(CONFIG_ARCH_MX2) := mx2 | 145 | machine-$(CONFIG_ARCH_MX2) := mx2 |
| 146 | machine-$(CONFIG_ARCH_MX25) := mx25 | ||
| 138 | machine-$(CONFIG_ARCH_MX3) := mx3 | 147 | machine-$(CONFIG_ARCH_MX3) := mx3 |
| 139 | machine-$(CONFIG_ARCH_NETX) := netx | 148 | machine-$(CONFIG_ARCH_NETX) := netx |
| 149 | machine-$(CONFIG_ARCH_NOMADIK) := nomadik | ||
| 140 | machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx | 150 | machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx |
| 141 | machine-$(CONFIG_ARCH_OMAP1) := omap1 | 151 | machine-$(CONFIG_ARCH_OMAP1) := omap1 |
| 142 | machine-$(CONFIG_ARCH_OMAP2) := omap2 | 152 | machine-$(CONFIG_ARCH_OMAP2) := omap2 |
| @@ -150,6 +160,7 @@ machine-$(CONFIG_ARCH_RPC) := rpc | |||
| 150 | machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443 | 160 | machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443 |
| 151 | machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 | 161 | machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 |
| 152 | machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410 | 162 | machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410 |
| 163 | machine-$(CONFIG_ARCH_S5PC1XX) := s5pc100 | ||
| 153 | machine-$(CONFIG_ARCH_SA1100) := sa1100 | 164 | machine-$(CONFIG_ARCH_SA1100) := sa1100 |
| 154 | machine-$(CONFIG_ARCH_SHARK) := shark | 165 | machine-$(CONFIG_ARCH_SHARK) := shark |
| 155 | machine-$(CONFIG_ARCH_STMP378X) := stmp378x | 166 | machine-$(CONFIG_ARCH_STMP378X) := stmp378x |
| @@ -158,6 +169,7 @@ machine-$(CONFIG_ARCH_U300) := u300 | |||
| 158 | machine-$(CONFIG_ARCH_VERSATILE) := versatile | 169 | machine-$(CONFIG_ARCH_VERSATILE) := versatile |
| 159 | machine-$(CONFIG_ARCH_W90X900) := w90x900 | 170 | machine-$(CONFIG_ARCH_W90X900) := w90x900 |
| 160 | machine-$(CONFIG_FOOTBRIDGE) := footbridge | 171 | machine-$(CONFIG_FOOTBRIDGE) := footbridge |
| 172 | machine-$(CONFIG_ARCH_MXC91231) := mxc91231 | ||
| 161 | 173 | ||
| 162 | # Platform directory name. This list is sorted alphanumerically | 174 | # Platform directory name. This list is sorted alphanumerically |
| 163 | # by CONFIG_* macro name. | 175 | # by CONFIG_* macro name. |
| @@ -168,6 +180,7 @@ plat-$(CONFIG_PLAT_ORION) := orion | |||
| 168 | plat-$(CONFIG_PLAT_PXA) := pxa | 180 | plat-$(CONFIG_PLAT_PXA) := pxa |
| 169 | plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c | 181 | plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c |
| 170 | plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c | 182 | plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c |
| 183 | plat-$(CONFIG_PLAT_S5PC1XX) := s5pc1xx s3c | ||
| 171 | plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx | 184 | plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx |
| 172 | 185 | ||
| 173 | ifeq ($(CONFIG_ARCH_EBSA110),y) | 186 | ifeq ($(CONFIG_ARCH_EBSA110),y) |
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index da226abce2d0..4a590f4113e2 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile | |||
| @@ -61,7 +61,7 @@ endif | |||
| 61 | 61 | ||
| 62 | quiet_cmd_uimage = UIMAGE $@ | 62 | quiet_cmd_uimage = UIMAGE $@ |
| 63 | cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \ | 63 | cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \ |
| 64 | -C none -a $(LOADADDR) -e $(LOADADDR) \ | 64 | -C none -a $(LOADADDR) -e $(STARTADDR) \ |
| 65 | -n 'Linux-$(KERNELRELEASE)' -d $< $@ | 65 | -n 'Linux-$(KERNELRELEASE)' -d $< $@ |
| 66 | 66 | ||
| 67 | ifeq ($(CONFIG_ZBOOT_ROM),y) | 67 | ifeq ($(CONFIG_ZBOOT_ROM),y) |
| @@ -70,6 +70,13 @@ else | |||
| 70 | $(obj)/uImage: LOADADDR=$(ZRELADDR) | 70 | $(obj)/uImage: LOADADDR=$(ZRELADDR) |
| 71 | endif | 71 | endif |
| 72 | 72 | ||
| 73 | ifeq ($(CONFIG_THUMB2_KERNEL),y) | ||
| 74 | # Set bit 0 to 1 so that "mov pc, rx" switches to Thumb-2 mode | ||
| 75 | $(obj)/uImage: STARTADDR=$(shell echo $(LOADADDR) | sed -e "s/.$$/1/") | ||
| 76 | else | ||
| 77 | $(obj)/uImage: STARTADDR=$(LOADADDR) | ||
| 78 | endif | ||
| 79 | |||
| 73 | $(obj)/uImage: $(obj)/zImage FORCE | 80 | $(obj)/uImage: $(obj)/zImage FORCE |
| 74 | $(call if_changed,uimage) | 81 | $(call if_changed,uimage) |
| 75 | @echo ' Image $@ is ready' | 82 | @echo ' Image $@ is ready' |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 4515728c5345..fa6fbf45cf3b 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
| @@ -140,7 +140,8 @@ start: | |||
| 140 | tst r2, #3 @ not user? | 140 | tst r2, #3 @ not user? |
| 141 | bne not_angel | 141 | bne not_angel |
| 142 | mov r0, #0x17 @ angel_SWIreason_EnterSVC | 142 | mov r0, #0x17 @ angel_SWIreason_EnterSVC |
| 143 | swi 0x123456 @ angel_SWI_ARM | 143 | ARM( swi 0x123456 ) @ angel_SWI_ARM |
| 144 | THUMB( svc 0xab ) @ angel_SWI_THUMB | ||
| 144 | not_angel: | 145 | not_angel: |
| 145 | mrs r2, cpsr @ turn off interrupts to | 146 | mrs r2, cpsr @ turn off interrupts to |
| 146 | orr r2, r2, #0xc0 @ prevent angel from running | 147 | orr r2, r2, #0xc0 @ prevent angel from running |
| @@ -161,7 +162,9 @@ not_angel: | |||
| 161 | 162 | ||
| 162 | .text | 163 | .text |
| 163 | adr r0, LC0 | 164 | adr r0, LC0 |
| 164 | ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp} | 165 | ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp} ) |
| 166 | THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, ip} ) | ||
| 167 | THUMB( ldr sp, [r0, #28] ) | ||
| 165 | subs r0, r0, r1 @ calculate the delta offset | 168 | subs r0, r0, r1 @ calculate the delta offset |
| 166 | 169 | ||
| 167 | @ if delta is zero, we are | 170 | @ if delta is zero, we are |
| @@ -263,22 +266,25 @@ not_relocated: mov r0, #0 | |||
| 263 | * r6 = processor ID | 266 | * r6 = processor ID |
| 264 | * r7 = architecture ID | 267 | * r7 = architecture ID |
| 265 | * r8 = atags pointer | 268 | * r8 = atags pointer |
| 266 | * r9-r14 = corrupted | 269 | * r9-r12,r14 = corrupted |
| 267 | */ | 270 | */ |
| 268 | add r1, r5, r0 @ end of decompressed kernel | 271 | add r1, r5, r0 @ end of decompressed kernel |
| 269 | adr r2, reloc_start | 272 | adr r2, reloc_start |
| 270 | ldr r3, LC1 | 273 | ldr r3, LC1 |
| 271 | add r3, r2, r3 | 274 | add r3, r2, r3 |
| 272 | 1: ldmia r2!, {r9 - r14} @ copy relocation code | 275 | 1: ldmia r2!, {r9 - r12, r14} @ copy relocation code |
| 273 | stmia r1!, {r9 - r14} | 276 | stmia r1!, {r9 - r12, r14} |
| 274 | ldmia r2!, {r9 - r14} | 277 | ldmia r2!, {r9 - r12, r14} |
| 275 | stmia r1!, {r9 - r14} | 278 | stmia r1!, {r9 - r12, r14} |
| 276 | cmp r2, r3 | 279 | cmp r2, r3 |
| 277 | blo 1b | 280 | blo 1b |
| 278 | add sp, r1, #128 @ relocate the stack | 281 | mov sp, r1 |
| 282 | add sp, sp, #128 @ relocate the stack | ||
| 279 | 283 | ||
| 280 | bl cache_clean_flush | 284 | bl cache_clean_flush |
| 281 | add pc, r5, r0 @ call relocation code | 285 | ARM( add pc, r5, r0 ) @ call relocation code |
| 286 | THUMB( add r12, r5, r0 ) | ||
| 287 | THUMB( mov pc, r12 ) @ call relocation code | ||
| 282 | 288 | ||
| 283 | /* | 289 | /* |
| 284 | * We're not in danger of overwriting ourselves. Do this the simple way. | 290 | * We're not in danger of overwriting ourselves. Do this the simple way. |
| @@ -291,6 +297,7 @@ wont_overwrite: mov r0, r4 | |||
| 291 | bl decompress_kernel | 297 | bl decompress_kernel |
| 292 | b call_kernel | 298 | b call_kernel |
| 293 | 299 | ||
| 300 | .align 2 | ||
| 294 | .type LC0, #object | 301 | .type LC0, #object |
| 295 | LC0: .word LC0 @ r1 | 302 | LC0: .word LC0 @ r1 |
| 296 | .word __bss_start @ r2 | 303 | .word __bss_start @ r2 |
| @@ -431,6 +438,7 @@ ENDPROC(__setup_mmu) | |||
| 431 | 438 | ||
| 432 | __armv4_mmu_cache_on: | 439 | __armv4_mmu_cache_on: |
| 433 | mov r12, lr | 440 | mov r12, lr |
| 441 | #ifdef CONFIG_MMU | ||
| 434 | bl __setup_mmu | 442 | bl __setup_mmu |
| 435 | mov r0, #0 | 443 | mov r0, #0 |
| 436 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | 444 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer |
| @@ -444,10 +452,12 @@ __armv4_mmu_cache_on: | |||
| 444 | bl __common_mmu_cache_on | 452 | bl __common_mmu_cache_on |
| 445 | mov r0, #0 | 453 | mov r0, #0 |
| 446 | mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs | 454 | mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs |
| 455 | #endif | ||
| 447 | mov pc, r12 | 456 | mov pc, r12 |
| 448 | 457 | ||
| 449 | __armv7_mmu_cache_on: | 458 | __armv7_mmu_cache_on: |
| 450 | mov r12, lr | 459 | mov r12, lr |
| 460 | #ifdef CONFIG_MMU | ||
| 451 | mrc p15, 0, r11, c0, c1, 4 @ read ID_MMFR0 | 461 | mrc p15, 0, r11, c0, c1, 4 @ read ID_MMFR0 |
| 452 | tst r11, #0xf @ VMSA | 462 | tst r11, #0xf @ VMSA |
| 453 | blne __setup_mmu | 463 | blne __setup_mmu |
| @@ -455,9 +465,11 @@ __armv7_mmu_cache_on: | |||
| 455 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | 465 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer |
| 456 | tst r11, #0xf @ VMSA | 466 | tst r11, #0xf @ VMSA |
| 457 | mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs | 467 | mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs |
| 468 | #endif | ||
| 458 | mrc p15, 0, r0, c1, c0, 0 @ read control reg | 469 | mrc p15, 0, r0, c1, c0, 0 @ read control reg |
| 459 | orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement | 470 | orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement |
| 460 | orr r0, r0, #0x003c @ write buffer | 471 | orr r0, r0, #0x003c @ write buffer |
| 472 | #ifdef CONFIG_MMU | ||
| 461 | #ifdef CONFIG_CPU_ENDIAN_BE8 | 473 | #ifdef CONFIG_CPU_ENDIAN_BE8 |
| 462 | orr r0, r0, #1 << 25 @ big-endian page tables | 474 | orr r0, r0, #1 << 25 @ big-endian page tables |
| 463 | #endif | 475 | #endif |
| @@ -465,6 +477,7 @@ __armv7_mmu_cache_on: | |||
| 465 | movne r1, #-1 | 477 | movne r1, #-1 |
| 466 | mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer | 478 | mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer |
| 467 | mcrne p15, 0, r1, c3, c0, 0 @ load domain access control | 479 | mcrne p15, 0, r1, c3, c0, 0 @ load domain access control |
| 480 | #endif | ||
| 468 | mcr p15, 0, r0, c1, c0, 0 @ load control register | 481 | mcr p15, 0, r0, c1, c0, 0 @ load control register |
| 469 | mrc p15, 0, r0, c1, c0, 0 @ and read it back | 482 | mrc p15, 0, r0, c1, c0, 0 @ and read it back |
| 470 | mov r0, #0 | 483 | mov r0, #0 |
| @@ -498,6 +511,7 @@ __arm6_mmu_cache_on: | |||
| 498 | mov pc, r12 | 511 | mov pc, r12 |
| 499 | 512 | ||
| 500 | __common_mmu_cache_on: | 513 | __common_mmu_cache_on: |
| 514 | #ifndef CONFIG_THUMB2_KERNEL | ||
| 501 | #ifndef DEBUG | 515 | #ifndef DEBUG |
| 502 | orr r0, r0, #0x000d @ Write buffer, mmu | 516 | orr r0, r0, #0x000d @ Write buffer, mmu |
| 503 | #endif | 517 | #endif |
| @@ -509,6 +523,7 @@ __common_mmu_cache_on: | |||
| 509 | 1: mcr p15, 0, r0, c1, c0, 0 @ load control register | 523 | 1: mcr p15, 0, r0, c1, c0, 0 @ load control register |
| 510 | mrc p15, 0, r0, c1, c0, 0 @ and read it back to | 524 | mrc p15, 0, r0, c1, c0, 0 @ and read it back to |
| 511 | sub pc, lr, r0, lsr #32 @ properly flush pipeline | 525 | sub pc, lr, r0, lsr #32 @ properly flush pipeline |
| 526 | #endif | ||
| 512 | 527 | ||
| 513 | /* | 528 | /* |
| 514 | * All code following this line is relocatable. It is relocated by | 529 | * All code following this line is relocatable. It is relocated by |
| @@ -522,7 +537,7 @@ __common_mmu_cache_on: | |||
| 522 | * r6 = processor ID | 537 | * r6 = processor ID |
| 523 | * r7 = architecture ID | 538 | * r7 = architecture ID |
| 524 | * r8 = atags pointer | 539 | * r8 = atags pointer |
| 525 | * r9-r14 = corrupted | 540 | * r9-r12,r14 = corrupted |
| 526 | */ | 541 | */ |
| 527 | .align 5 | 542 | .align 5 |
| 528 | reloc_start: add r9, r5, r0 | 543 | reloc_start: add r9, r5, r0 |
| @@ -531,13 +546,14 @@ reloc_start: add r9, r5, r0 | |||
| 531 | mov r1, r4 | 546 | mov r1, r4 |
| 532 | 1: | 547 | 1: |
| 533 | .rept 4 | 548 | .rept 4 |
| 534 | ldmia r5!, {r0, r2, r3, r10 - r14} @ relocate kernel | 549 | ldmia r5!, {r0, r2, r3, r10 - r12, r14} @ relocate kernel |
| 535 | stmia r1!, {r0, r2, r3, r10 - r14} | 550 | stmia r1!, {r0, r2, r3, r10 - r12, r14} |
| 536 | .endr | 551 | .endr |
| 537 | 552 | ||
| 538 | cmp r5, r9 | 553 | cmp r5, r9 |
| 539 | blo 1b | 554 | blo 1b |
| 540 | add sp, r1, #128 @ relocate the stack | 555 | mov sp, r1 |
| 556 | add sp, sp, #128 @ relocate the stack | ||
| 541 | debug_reloc_end | 557 | debug_reloc_end |
| 542 | 558 | ||
| 543 | call_kernel: bl cache_clean_flush | 559 | call_kernel: bl cache_clean_flush |
| @@ -571,7 +587,9 @@ call_cache_fn: adr r12, proc_types | |||
| 571 | ldr r2, [r12, #4] @ get mask | 587 | ldr r2, [r12, #4] @ get mask |
| 572 | eor r1, r1, r6 @ (real ^ match) | 588 | eor r1, r1, r6 @ (real ^ match) |
| 573 | tst r1, r2 @ & mask | 589 | tst r1, r2 @ & mask |
| 574 | addeq pc, r12, r3 @ call cache function | 590 | ARM( addeq pc, r12, r3 ) @ call cache function |
| 591 | THUMB( addeq r12, r3 ) | ||
| 592 | THUMB( moveq pc, r12 ) @ call cache function | ||
| 575 | add r12, r12, #4*5 | 593 | add r12, r12, #4*5 |
| 576 | b 1b | 594 | b 1b |
| 577 | 595 | ||
| @@ -589,13 +607,15 @@ call_cache_fn: adr r12, proc_types | |||
| 589 | * methods. Writeback caches _must_ have the flush method | 607 | * methods. Writeback caches _must_ have the flush method |
| 590 | * defined. | 608 | * defined. |
| 591 | */ | 609 | */ |
| 610 | .align 2 | ||
| 592 | .type proc_types,#object | 611 | .type proc_types,#object |
| 593 | proc_types: | 612 | proc_types: |
| 594 | .word 0x41560600 @ ARM6/610 | 613 | .word 0x41560600 @ ARM6/610 |
| 595 | .word 0xffffffe0 | 614 | .word 0xffffffe0 |
| 596 | b __arm6_mmu_cache_off @ works, but slow | 615 | W(b) __arm6_mmu_cache_off @ works, but slow |
| 597 | b __arm6_mmu_cache_off | 616 | W(b) __arm6_mmu_cache_off |
| 598 | mov pc, lr | 617 | mov pc, lr |
| 618 | THUMB( nop ) | ||
| 599 | @ b __arm6_mmu_cache_on @ untested | 619 | @ b __arm6_mmu_cache_on @ untested |
| 600 | @ b __arm6_mmu_cache_off | 620 | @ b __arm6_mmu_cache_off |
| 601 | @ b __armv3_mmu_cache_flush | 621 | @ b __armv3_mmu_cache_flush |
| @@ -603,76 +623,84 @@ proc_types: | |||
| 603 | .word 0x00000000 @ old ARM ID | 623 | .word 0x00000000 @ old ARM ID |
| 604 | .word 0x0000f000 | 624 | .word 0x0000f000 |
| 605 | mov pc, lr | 625 | mov pc, lr |
| 626 | THUMB( nop ) | ||
| 606 | mov pc, lr | 627 | mov pc, lr |
| 628 | THUMB( nop ) | ||
| 607 | mov pc, lr | 629 | mov pc, lr |
| 630 | THUMB( nop ) | ||
| 608 | 631 | ||
| 609 | .word 0x41007000 @ ARM7/710 | 632 | .word 0x41007000 @ ARM7/710 |
| 610 | .word 0xfff8fe00 | 633 | .word 0xfff8fe00 |
| 611 | b __arm7_mmu_cache_off | 634 | W(b) __arm7_mmu_cache_off |
| 612 | b __arm7_mmu_cache_off | 635 | W(b) __arm7_mmu_cache_off |
| 613 | mov pc, lr | 636 | mov pc, lr |
| 637 | THUMB( nop ) | ||
| 614 | 638 | ||
| 615 | .word 0x41807200 @ ARM720T (writethrough) | 639 | .word 0x41807200 @ ARM720T (writethrough) |
| 616 | .word 0xffffff00 | 640 | .word 0xffffff00 |
| 617 | b __armv4_mmu_cache_on | 641 | W(b) __armv4_mmu_cache_on |
| 618 | b __armv4_mmu_cache_off | 642 | W(b) __armv4_mmu_cache_off |
| 619 | mov pc, lr | 643 | mov pc, lr |
| 644 | THUMB( nop ) | ||
| 620 | 645 | ||
| 621 | .word 0x41007400 @ ARM74x | 646 | .word 0x41007400 @ ARM74x |
| 622 | .word 0xff00ff00 | 647 | .word 0xff00ff00 |
| 623 | b __armv3_mpu_cache_on | 648 | W(b) __armv3_mpu_cache_on |
| 624 | b __armv3_mpu_cache_off | 649 | W(b) __armv3_mpu_cache_off |
| 625 | b __armv3_mpu_cache_flush | 650 | W(b) __armv3_mpu_cache_flush |
| 626 | 651 | ||
| 627 | .word 0x41009400 @ ARM94x | 652 | .word 0x41009400 @ ARM94x |
| 628 | .word 0xff00ff00 | 653 | .word 0xff00ff00 |
| 629 | b __armv4_mpu_cache_on | 654 | W(b) __armv4_mpu_cache_on |
| 630 | b __armv4_mpu_cache_off | 655 | W(b) __armv4_mpu_cache_off |
| 631 | b __armv4_mpu_cache_flush | 656 | W(b) __armv4_mpu_cache_flush |
| 632 | 657 | ||
| 633 | .word 0x00007000 @ ARM7 IDs | 658 | .word 0x00007000 @ ARM7 IDs |
| 634 | .word 0x0000f000 | 659 | .word 0x0000f000 |
| 635 | mov pc, lr | 660 | mov pc, lr |
| 661 | THUMB( nop ) | ||
| 636 | mov pc, lr | 662 | mov pc, lr |
| 663 | THUMB( nop ) | ||
| 637 | mov pc, lr | 664 | mov pc, lr |
| 665 | THUMB( nop ) | ||
| 638 | 666 | ||
| 639 | @ Everything from here on will be the new ID system. | 667 | @ Everything from here on will be the new ID system. |
| 640 | 668 | ||
| 641 | .word 0x4401a100 @ sa110 / sa1100 | 669 | .word 0x4401a100 @ sa110 / sa1100 |
| 642 | .word 0xffffffe0 | 670 | .word 0xffffffe0 |
| 643 | b __armv4_mmu_cache_on | 671 | W(b) __armv4_mmu_cache_on |
| 644 | b __armv4_mmu_cache_off | 672 | W(b) __armv4_mmu_cache_off |
| 645 | b __armv4_mmu_cache_flush | 673 | W(b) __armv4_mmu_cache_flush |
| 646 | 674 | ||
| 647 | .word 0x6901b110 @ sa1110 | 675 | .word 0x6901b110 @ sa1110 |
| 648 | .word 0xfffffff0 | 676 | .word 0xfffffff0 |
| 649 | b __armv4_mmu_cache_on | 677 | W(b) __armv4_mmu_cache_on |
| 650 | b __armv4_mmu_cache_off | 678 | W(b) __armv4_mmu_cache_off |
| 651 | b __armv4_mmu_cache_flush | 679 | W(b) __armv4_mmu_cache_flush |
| 652 | 680 | ||
| 653 | .word 0x56056930 | 681 | .word 0x56056930 |
| 654 | .word 0xff0ffff0 @ PXA935 | 682 | .word 0xff0ffff0 @ PXA935 |
| 655 | b __armv4_mmu_cache_on | 683 | W(b) __armv4_mmu_cache_on |
| 656 | b __armv4_mmu_cache_off | 684 | W(b) __armv4_mmu_cache_off |
| 657 | b __armv4_mmu_cache_flush | 685 | W(b) __armv4_mmu_cache_flush |
| 658 | 686 | ||
| 659 | .word 0x56158000 @ PXA168 | 687 | .word 0x56158000 @ PXA168 |
| 660 | .word 0xfffff000 | 688 | .word 0xfffff000 |
| 661 | b __armv4_mmu_cache_on | 689 | W(b) __armv4_mmu_cache_on |
| 662 | b __armv4_mmu_cache_off | 690 | W(b) __armv4_mmu_cache_off |
| 663 | b __armv5tej_mmu_cache_flush | 691 | W(b) __armv5tej_mmu_cache_flush |
| 664 | 692 | ||
| 665 | .word 0x56056930 | 693 | .word 0x56056930 |
| 666 | .word 0xff0ffff0 @ PXA935 | 694 | .word 0xff0ffff0 @ PXA935 |
| 667 | b __armv4_mmu_cache_on | 695 | W(b) __armv4_mmu_cache_on |
| 668 | b __armv4_mmu_cache_off | 696 | W(b) __armv4_mmu_cache_off |
| 669 | b __armv4_mmu_cache_flush | 697 | W(b) __armv4_mmu_cache_flush |
| 670 | 698 | ||
| 671 | .word 0x56050000 @ Feroceon | 699 | .word 0x56050000 @ Feroceon |
| 672 | .word 0xff0f0000 | 700 | .word 0xff0f0000 |
| 673 | b __armv4_mmu_cache_on | 701 | W(b) __armv4_mmu_cache_on |
| 674 | b __armv4_mmu_cache_off | 702 | W(b) __armv4_mmu_cache_off |
| 675 | b __armv5tej_mmu_cache_flush | 703 | W(b) __armv5tej_mmu_cache_flush |
| 676 | 704 | ||
| 677 | #ifdef CONFIG_CPU_FEROCEON_OLD_ID | 705 | #ifdef CONFIG_CPU_FEROCEON_OLD_ID |
| 678 | /* this conflicts with the standard ARMv5TE entry */ | 706 | /* this conflicts with the standard ARMv5TE entry */ |
| @@ -685,47 +713,50 @@ proc_types: | |||
| 685 | 713 | ||
| 686 | .word 0x66015261 @ FA526 | 714 | .word 0x66015261 @ FA526 |
| 687 | .word 0xff01fff1 | 715 | .word 0xff01fff1 |
| 688 | b __fa526_cache_on | 716 | W(b) __fa526_cache_on |
| 689 | b __armv4_mmu_cache_off | 717 | W(b) __armv4_mmu_cache_off |
| 690 | b __fa526_cache_flush | 718 | W(b) __fa526_cache_flush |
| 691 | 719 | ||
| 692 | @ These match on the architecture ID | 720 | @ These match on the architecture ID |
| 693 | 721 | ||
| 694 | .word 0x00020000 @ ARMv4T | 722 | .word 0x00020000 @ ARMv4T |
| 695 | .word 0x000f0000 | 723 | .word 0x000f0000 |
| 696 | b __armv4_mmu_cache_on | 724 | W(b) __armv4_mmu_cache_on |
| 697 | b __armv4_mmu_cache_off | 725 | W(b) __armv4_mmu_cache_off |
| 698 | b __armv4_mmu_cache_flush | 726 | W(b) __armv4_mmu_cache_flush |
| 699 | 727 | ||
| 700 | .word 0x00050000 @ ARMv5TE | 728 | .word 0x00050000 @ ARMv5TE |
| 701 | .word 0x000f0000 | 729 | .word 0x000f0000 |
| 702 | b __armv4_mmu_cache_on | 730 | W(b) __armv4_mmu_cache_on |
| 703 | b __armv4_mmu_cache_off | 731 | W(b) __armv4_mmu_cache_off |
| 704 | b __armv4_mmu_cache_flush | 732 | W(b) __armv4_mmu_cache_flush |
| 705 | 733 | ||
| 706 | .word 0x00060000 @ ARMv5TEJ | 734 | .word 0x00060000 @ ARMv5TEJ |
| 707 | .word 0x000f0000 | 735 | .word 0x000f0000 |
| 708 | b __armv4_mmu_cache_on | 736 | W(b) __armv4_mmu_cache_on |
| 709 | b __armv4_mmu_cache_off | 737 | W(b) __armv4_mmu_cache_off |
| 710 | b __armv5tej_mmu_cache_flush | 738 | W(b) __armv4_mmu_cache_flush |
| 711 | 739 | ||
| 712 | .word 0x0007b000 @ ARMv6 | 740 | .word 0x0007b000 @ ARMv6 |
| 713 | .word 0x000ff000 | 741 | .word 0x000ff000 |
| 714 | b __armv4_mmu_cache_on | 742 | W(b) __armv4_mmu_cache_on |
| 715 | b __armv4_mmu_cache_off | 743 | W(b) __armv4_mmu_cache_off |
| 716 | b __armv6_mmu_cache_flush | 744 | W(b) __armv6_mmu_cache_flush |
| 717 | 745 | ||
| 718 | .word 0x000f0000 @ new CPU Id | 746 | .word 0x000f0000 @ new CPU Id |
| 719 | .word 0x000f0000 | 747 | .word 0x000f0000 |
| 720 | b __armv7_mmu_cache_on | 748 | W(b) __armv7_mmu_cache_on |
| 721 | b __armv7_mmu_cache_off | 749 | W(b) __armv7_mmu_cache_off |
| 722 | b __armv7_mmu_cache_flush | 750 | W(b) __armv7_mmu_cache_flush |
| 723 | 751 | ||
| 724 | .word 0 @ unrecognised type | 752 | .word 0 @ unrecognised type |
| 725 | .word 0 | 753 | .word 0 |
| 726 | mov pc, lr | 754 | mov pc, lr |
| 755 | THUMB( nop ) | ||
| 727 | mov pc, lr | 756 | mov pc, lr |
| 757 | THUMB( nop ) | ||
| 728 | mov pc, lr | 758 | mov pc, lr |
| 759 | THUMB( nop ) | ||
| 729 | 760 | ||
| 730 | .size proc_types, . - proc_types | 761 | .size proc_types, . - proc_types |
| 731 | 762 | ||
| @@ -760,22 +791,30 @@ __armv3_mpu_cache_off: | |||
| 760 | mov pc, lr | 791 | mov pc, lr |
| 761 | 792 | ||
| 762 | __armv4_mmu_cache_off: | 793 | __armv4_mmu_cache_off: |
| 794 | #ifdef CONFIG_MMU | ||
| 763 | mrc p15, 0, r0, c1, c0 | 795 | mrc p15, 0, r0, c1, c0 |
| 764 | bic r0, r0, #0x000d | 796 | bic r0, r0, #0x000d |
| 765 | mcr p15, 0, r0, c1, c0 @ turn MMU and cache off | 797 | mcr p15, 0, r0, c1, c0 @ turn MMU and cache off |
| 766 | mov r0, #0 | 798 | mov r0, #0 |
| 767 | mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4 | 799 | mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4 |
| 768 | mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4 | 800 | mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4 |
| 801 | #endif | ||
| 769 | mov pc, lr | 802 | mov pc, lr |
| 770 | 803 | ||
| 771 | __armv7_mmu_cache_off: | 804 | __armv7_mmu_cache_off: |
| 772 | mrc p15, 0, r0, c1, c0 | 805 | mrc p15, 0, r0, c1, c0 |
| 806 | #ifdef CONFIG_MMU | ||
| 773 | bic r0, r0, #0x000d | 807 | bic r0, r0, #0x000d |
| 808 | #else | ||
| 809 | bic r0, r0, #0x000c | ||
| 810 | #endif | ||
| 774 | mcr p15, 0, r0, c1, c0 @ turn MMU and cache off | 811 | mcr p15, 0, r0, c1, c0 @ turn MMU and cache off |
| 775 | mov r12, lr | 812 | mov r12, lr |
| 776 | bl __armv7_mmu_cache_flush | 813 | bl __armv7_mmu_cache_flush |
| 777 | mov r0, #0 | 814 | mov r0, #0 |
| 815 | #ifdef CONFIG_MMU | ||
| 778 | mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB | 816 | mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB |
| 817 | #endif | ||
| 779 | mcr p15, 0, r0, c7, c5, 6 @ invalidate BTC | 818 | mcr p15, 0, r0, c7, c5, 6 @ invalidate BTC |
| 780 | mcr p15, 0, r0, c7, c10, 4 @ DSB | 819 | mcr p15, 0, r0, c7, c10, 4 @ DSB |
| 781 | mcr p15, 0, r0, c7, c5, 4 @ ISB | 820 | mcr p15, 0, r0, c7, c5, 4 @ ISB |
| @@ -852,7 +891,7 @@ __armv7_mmu_cache_flush: | |||
| 852 | b iflush | 891 | b iflush |
| 853 | hierarchical: | 892 | hierarchical: |
| 854 | mcr p15, 0, r10, c7, c10, 5 @ DMB | 893 | mcr p15, 0, r10, c7, c10, 5 @ DMB |
| 855 | stmfd sp!, {r0-r5, r7, r9, r11} | 894 | stmfd sp!, {r0-r7, r9-r11} |
| 856 | mrc p15, 1, r0, c0, c0, 1 @ read clidr | 895 | mrc p15, 1, r0, c0, c0, 1 @ read clidr |
| 857 | ands r3, r0, #0x7000000 @ extract loc from clidr | 896 | ands r3, r0, #0x7000000 @ extract loc from clidr |
| 858 | mov r3, r3, lsr #23 @ left align loc bit field | 897 | mov r3, r3, lsr #23 @ left align loc bit field |
| @@ -877,8 +916,12 @@ loop1: | |||
| 877 | loop2: | 916 | loop2: |
| 878 | mov r9, r4 @ create working copy of max way size | 917 | mov r9, r4 @ create working copy of max way size |
| 879 | loop3: | 918 | loop3: |
| 880 | orr r11, r10, r9, lsl r5 @ factor way and cache number into r11 | 919 | ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11 |
| 881 | orr r11, r11, r7, lsl r2 @ factor index number into r11 | 920 | ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11 |
| 921 | THUMB( lsl r6, r9, r5 ) | ||
| 922 | THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11 | ||
| 923 | THUMB( lsl r6, r7, r2 ) | ||
| 924 | THUMB( orr r11, r11, r6 ) @ factor index number into r11 | ||
| 882 | mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way | 925 | mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way |
| 883 | subs r9, r9, #1 @ decrement the way | 926 | subs r9, r9, #1 @ decrement the way |
| 884 | bge loop3 | 927 | bge loop3 |
| @@ -889,7 +932,7 @@ skip: | |||
| 889 | cmp r3, r10 | 932 | cmp r3, r10 |
| 890 | bgt loop1 | 933 | bgt loop1 |
| 891 | finished: | 934 | finished: |
| 892 | ldmfd sp!, {r0-r5, r7, r9, r11} | 935 | ldmfd sp!, {r0-r7, r9-r11} |
| 893 | mov r10, #0 @ swith back to cache level 0 | 936 | mov r10, #0 @ swith back to cache level 0 |
| 894 | mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr | 937 | mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr |
| 895 | iflush: | 938 | iflush: |
| @@ -923,9 +966,13 @@ __armv4_mmu_cache_flush: | |||
| 923 | mov r11, #8 | 966 | mov r11, #8 |
| 924 | mov r11, r11, lsl r3 @ cache line size in bytes | 967 | mov r11, r11, lsl r3 @ cache line size in bytes |
| 925 | no_cache_id: | 968 | no_cache_id: |
| 926 | bic r1, pc, #63 @ align to longest cache line | 969 | mov r1, pc |
| 970 | bic r1, r1, #63 @ align to longest cache line | ||
| 927 | add r2, r1, r2 | 971 | add r2, r1, r2 |
| 928 | 1: ldr r3, [r1], r11 @ s/w flush D cache | 972 | 1: |
| 973 | ARM( ldr r3, [r1], r11 ) @ s/w flush D cache | ||
| 974 | THUMB( ldr r3, [r1] ) @ s/w flush D cache | ||
| 975 | THUMB( add r1, r1, r11 ) | ||
| 929 | teq r1, r2 | 976 | teq r1, r2 |
| 930 | bne 1b | 977 | bne 1b |
| 931 | 978 | ||
| @@ -945,6 +992,7 @@ __armv3_mpu_cache_flush: | |||
| 945 | * memory, which again must be relocatable. | 992 | * memory, which again must be relocatable. |
| 946 | */ | 993 | */ |
| 947 | #ifdef DEBUG | 994 | #ifdef DEBUG |
| 995 | .align 2 | ||
| 948 | .type phexbuf,#object | 996 | .type phexbuf,#object |
| 949 | phexbuf: .space 12 | 997 | phexbuf: .space 12 |
| 950 | .size phexbuf, . - phexbuf | 998 | .size phexbuf, . - phexbuf |
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c index 6ed89836e908..920ced0b73c5 100644 --- a/arch/arm/common/vic.c +++ b/arch/arm/common/vic.c | |||
| @@ -22,10 +22,20 @@ | |||
| 22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
| 23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
| 24 | #include <linux/sysdev.h> | 24 | #include <linux/sysdev.h> |
| 25 | #include <linux/amba/bus.h> | ||
| 25 | 26 | ||
| 26 | #include <asm/mach/irq.h> | 27 | #include <asm/mach/irq.h> |
| 27 | #include <asm/hardware/vic.h> | 28 | #include <asm/hardware/vic.h> |
| 28 | 29 | ||
| 30 | static void vic_ack_irq(unsigned int irq) | ||
| 31 | { | ||
| 32 | void __iomem *base = get_irq_chip_data(irq); | ||
| 33 | irq &= 31; | ||
| 34 | writel(1 << irq, base + VIC_INT_ENABLE_CLEAR); | ||
| 35 | /* moreover, clear the soft-triggered, in case it was the reason */ | ||
| 36 | writel(1 << irq, base + VIC_INT_SOFT_CLEAR); | ||
| 37 | } | ||
| 38 | |||
| 29 | static void vic_mask_irq(unsigned int irq) | 39 | static void vic_mask_irq(unsigned int irq) |
| 30 | { | 40 | { |
| 31 | void __iomem *base = get_irq_chip_data(irq); | 41 | void __iomem *base = get_irq_chip_data(irq); |
| @@ -253,12 +263,16 @@ static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg | |||
| 253 | 263 | ||
| 254 | static struct irq_chip vic_chip = { | 264 | static struct irq_chip vic_chip = { |
| 255 | .name = "VIC", | 265 | .name = "VIC", |
| 256 | .ack = vic_mask_irq, | 266 | .ack = vic_ack_irq, |
| 257 | .mask = vic_mask_irq, | 267 | .mask = vic_mask_irq, |
| 258 | .unmask = vic_unmask_irq, | 268 | .unmask = vic_unmask_irq, |
| 259 | .set_wake = vic_set_wake, | 269 | .set_wake = vic_set_wake, |
| 260 | }; | 270 | }; |
| 261 | 271 | ||
| 272 | /* The PL190 cell from ARM has been modified by ST, so handle both here */ | ||
| 273 | static void vik_init_st(void __iomem *base, unsigned int irq_start, | ||
| 274 | u32 vic_sources); | ||
| 275 | |||
| 262 | /** | 276 | /** |
| 263 | * vic_init - initialise a vectored interrupt controller | 277 | * vic_init - initialise a vectored interrupt controller |
| 264 | * @base: iomem base address | 278 | * @base: iomem base address |
| @@ -270,6 +284,28 @@ void __init vic_init(void __iomem *base, unsigned int irq_start, | |||
| 270 | u32 vic_sources, u32 resume_sources) | 284 | u32 vic_sources, u32 resume_sources) |
| 271 | { | 285 | { |
| 272 | unsigned int i; | 286 | unsigned int i; |
| 287 | u32 cellid = 0; | ||
| 288 | enum amba_vendor vendor; | ||
| 289 | |||
| 290 | /* Identify which VIC cell this one is, by reading the ID */ | ||
| 291 | for (i = 0; i < 4; i++) { | ||
| 292 | u32 addr = ((u32)base & PAGE_MASK) + 0xfe0 + (i * 4); | ||
| 293 | cellid |= (readl(addr) & 0xff) << (8 * i); | ||
| 294 | } | ||
| 295 | vendor = (cellid >> 12) & 0xff; | ||
| 296 | printk(KERN_INFO "VIC @%p: id 0x%08x, vendor 0x%02x\n", | ||
| 297 | base, cellid, vendor); | ||
| 298 | |||
| 299 | switch(vendor) { | ||
| 300 | case AMBA_VENDOR_ST: | ||
| 301 | vik_init_st(base, irq_start, vic_sources); | ||
| 302 | return; | ||
| 303 | default: | ||
| 304 | printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n"); | ||
| 305 | /* fall through */ | ||
| 306 | case AMBA_VENDOR_ARM: | ||
| 307 | break; | ||
| 308 | } | ||
| 273 | 309 | ||
| 274 | /* Disable all interrupts initially. */ | 310 | /* Disable all interrupts initially. */ |
| 275 | 311 | ||
| @@ -306,3 +342,60 @@ void __init vic_init(void __iomem *base, unsigned int irq_start, | |||
| 306 | 342 | ||
| 307 | vic_pm_register(base, irq_start, resume_sources); | 343 | vic_pm_register(base, irq_start, resume_sources); |
| 308 | } | 344 | } |
| 345 | |||
| 346 | /* | ||
| 347 | * The PL190 cell from ARM has been modified by ST to handle 64 interrupts. | ||
| 348 | * The original cell has 32 interrupts, while the modified one has 64, | ||
| 349 | * replocating two blocks 0x00..0x1f in 0x20..0x3f. In that case | ||
| 350 | * the probe function is called twice, with base set to offset 000 | ||
| 351 | * and 020 within the page. We call this "second block". | ||
| 352 | */ | ||
| 353 | static void __init vik_init_st(void __iomem *base, unsigned int irq_start, | ||
| 354 | u32 vic_sources) | ||
| 355 | { | ||
| 356 | unsigned int i; | ||
| 357 | int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0; | ||
| 358 | |||
| 359 | /* Disable all interrupts initially. */ | ||
| 360 | |||
| 361 | writel(0, base + VIC_INT_SELECT); | ||
| 362 | writel(0, base + VIC_INT_ENABLE); | ||
| 363 | writel(~0, base + VIC_INT_ENABLE_CLEAR); | ||
| 364 | writel(0, base + VIC_IRQ_STATUS); | ||
| 365 | writel(0, base + VIC_ITCR); | ||
| 366 | writel(~0, base + VIC_INT_SOFT_CLEAR); | ||
| 367 | |||
| 368 | /* | ||
| 369 | * Make sure we clear all existing interrupts. The vector registers | ||
| 370 | * in this cell are after the second block of general registers, | ||
| 371 | * so we can address them using standard offsets, but only from | ||
| 372 | * the second base address, which is 0x20 in the page | ||
| 373 | */ | ||
| 374 | if (vic_2nd_block) { | ||
| 375 | writel(0, base + VIC_PL190_VECT_ADDR); | ||
| 376 | for (i = 0; i < 19; i++) { | ||
| 377 | unsigned int value; | ||
| 378 | |||
| 379 | value = readl(base + VIC_PL190_VECT_ADDR); | ||
| 380 | writel(value, base + VIC_PL190_VECT_ADDR); | ||
| 381 | } | ||
| 382 | /* ST has 16 vectors as well, but we don't enable them by now */ | ||
| 383 | for (i = 0; i < 16; i++) { | ||
| 384 | void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4); | ||
| 385 | writel(0, reg); | ||
| 386 | } | ||
| 387 | |||
| 388 | writel(32, base + VIC_PL190_DEF_VECT_ADDR); | ||
| 389 | } | ||
| 390 | |||
| 391 | for (i = 0; i < 32; i++) { | ||
| 392 | if (vic_sources & (1 << i)) { | ||
| 393 | unsigned int irq = irq_start + i; | ||
| 394 | |||
| 395 | set_irq_chip(irq, &vic_chip); | ||
| 396 | set_irq_chip_data(irq, base); | ||
| 397 | set_irq_handler(irq, handle_level_irq); | ||
| 398 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
| 399 | } | ||
| 400 | } | ||
| 401 | } | ||
diff --git a/arch/arm/configs/bcmring_defconfig b/arch/arm/configs/bcmring_defconfig new file mode 100644 index 000000000000..bcc0bac551a5 --- /dev/null +++ b/arch/arm/configs/bcmring_defconfig | |||
| @@ -0,0 +1,725 @@ | |||
| 1 | # | ||
| 2 | # Automatically generated make config: don't edit | ||
| 3 | # Linux kernel version: 2.6.31-rc3 | ||
| 4 | # Fri Jul 17 12:07:28 2009 | ||
| 5 | # | ||
| 6 | CONFIG_ARM=y | ||
| 7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||
| 8 | CONFIG_GENERIC_TIME=y | ||
| 9 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
| 10 | CONFIG_MMU=y | ||
| 11 | CONFIG_GENERIC_HARDIRQS=y | ||
| 12 | CONFIG_STACKTRACE_SUPPORT=y | ||
| 13 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | ||
| 14 | CONFIG_LOCKDEP_SUPPORT=y | ||
| 15 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
| 16 | CONFIG_HARDIRQS_SW_RESEND=y | ||
| 17 | CONFIG_GENERIC_IRQ_PROBE=y | ||
| 18 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
| 19 | CONFIG_GENERIC_HWEIGHT=y | ||
| 20 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
| 21 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | ||
| 22 | CONFIG_VECTORS_BASE=0xffff0000 | ||
| 23 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
| 24 | CONFIG_CONSTRUCTORS=y | ||
| 25 | |||
| 26 | # | ||
| 27 | # General setup | ||
| 28 | # | ||
| 29 | CONFIG_EXPERIMENTAL=y | ||
| 30 | CONFIG_BROKEN_ON_SMP=y | ||
| 31 | CONFIG_LOCK_KERNEL=y | ||
| 32 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
| 33 | CONFIG_LOCALVERSION="" | ||
| 34 | # CONFIG_LOCALVERSION_AUTO is not set | ||
| 35 | # CONFIG_SWAP is not set | ||
| 36 | CONFIG_SYSVIPC=y | ||
| 37 | CONFIG_SYSVIPC_SYSCTL=y | ||
| 38 | # CONFIG_POSIX_MQUEUE is not set | ||
| 39 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
| 40 | # CONFIG_TASKSTATS is not set | ||
| 41 | # CONFIG_AUDIT is not set | ||
| 42 | |||
| 43 | # | ||
| 44 | # RCU Subsystem | ||
| 45 | # | ||
| 46 | CONFIG_CLASSIC_RCU=y | ||
| 47 | # CONFIG_TREE_RCU is not set | ||
| 48 | # CONFIG_PREEMPT_RCU is not set | ||
| 49 | # CONFIG_TREE_RCU_TRACE is not set | ||
| 50 | # CONFIG_PREEMPT_RCU_TRACE is not set | ||
| 51 | # CONFIG_IKCONFIG is not set | ||
| 52 | CONFIG_LOG_BUF_SHIFT=17 | ||
| 53 | # CONFIG_GROUP_SCHED is not set | ||
| 54 | # CONFIG_CGROUPS is not set | ||
| 55 | # CONFIG_SYSFS_DEPRECATED_V2 is not set | ||
| 56 | # CONFIG_RELAY is not set | ||
| 57 | # CONFIG_NAMESPACES is not set | ||
| 58 | # CONFIG_BLK_DEV_INITRD is not set | ||
| 59 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
| 60 | CONFIG_SYSCTL=y | ||
| 61 | CONFIG_EMBEDDED=y | ||
| 62 | CONFIG_UID16=y | ||
| 63 | CONFIG_SYSCTL_SYSCALL=y | ||
| 64 | CONFIG_KALLSYMS=y | ||
| 65 | CONFIG_KALLSYMS_EXTRA_PASS=y | ||
| 66 | # CONFIG_HOTPLUG is not set | ||
| 67 | CONFIG_PRINTK=y | ||
| 68 | CONFIG_BUG=y | ||
| 69 | # CONFIG_ELF_CORE is not set | ||
| 70 | CONFIG_BASE_FULL=y | ||
| 71 | CONFIG_FUTEX=y | ||
| 72 | # CONFIG_EPOLL is not set | ||
| 73 | # CONFIG_SIGNALFD is not set | ||
| 74 | # CONFIG_TIMERFD is not set | ||
| 75 | # CONFIG_EVENTFD is not set | ||
| 76 | CONFIG_SHMEM=y | ||
| 77 | # CONFIG_AIO is not set | ||
| 78 | |||
| 79 | # | ||
| 80 | # Performance Counters | ||
| 81 | # | ||
| 82 | # CONFIG_VM_EVENT_COUNTERS is not set | ||
| 83 | # CONFIG_SLUB_DEBUG is not set | ||
| 84 | # CONFIG_STRIP_ASM_SYMS is not set | ||
| 85 | # CONFIG_COMPAT_BRK is not set | ||
| 86 | # CONFIG_SLAB is not set | ||
| 87 | CONFIG_SLUB=y | ||
| 88 | # CONFIG_SLOB is not set | ||
| 89 | # CONFIG_PROFILING is not set | ||
| 90 | # CONFIG_MARKERS is not set | ||
| 91 | CONFIG_HAVE_OPROFILE=y | ||
| 92 | # CONFIG_KPROBES is not set | ||
| 93 | CONFIG_HAVE_KPROBES=y | ||
| 94 | CONFIG_HAVE_KRETPROBES=y | ||
| 95 | |||
| 96 | # | ||
| 97 | # GCOV-based kernel profiling | ||
| 98 | # | ||
| 99 | # CONFIG_SLOW_WORK is not set | ||
| 100 | CONFIG_HAVE_GENERIC_DMA_COHERENT=y | ||
| 101 | CONFIG_RT_MUTEXES=y | ||
| 102 | CONFIG_BASE_SMALL=0 | ||
| 103 | CONFIG_MODULES=y | ||
| 104 | # CONFIG_MODULE_FORCE_LOAD is not set | ||
| 105 | CONFIG_MODULE_UNLOAD=y | ||
| 106 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
| 107 | # CONFIG_MODVERSIONS is not set | ||
| 108 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
| 109 | CONFIG_BLOCK=y | ||
| 110 | CONFIG_LBDAF=y | ||
| 111 | # CONFIG_BLK_DEV_BSG is not set | ||
| 112 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
| 113 | |||
| 114 | # | ||
| 115 | # IO Schedulers | ||
| 116 | # | ||
| 117 | CONFIG_IOSCHED_NOOP=y | ||
| 118 | # CONFIG_IOSCHED_AS is not set | ||
| 119 | # CONFIG_IOSCHED_DEADLINE is not set | ||
| 120 | # CONFIG_IOSCHED_CFQ is not set | ||
| 121 | # CONFIG_DEFAULT_AS is not set | ||
| 122 | # CONFIG_DEFAULT_DEADLINE is not set | ||
| 123 | # CONFIG_DEFAULT_CFQ is not set | ||
| 124 | CONFIG_DEFAULT_NOOP=y | ||
| 125 | CONFIG_DEFAULT_IOSCHED="noop" | ||
| 126 | # CONFIG_FREEZER is not set | ||
| 127 | |||
| 128 | # | ||
| 129 | # System Type | ||
| 130 | # | ||
| 131 | # CONFIG_ARCH_AAEC2000 is not set | ||
| 132 | # CONFIG_ARCH_INTEGRATOR is not set | ||
| 133 | # CONFIG_ARCH_REALVIEW is not set | ||
| 134 | # CONFIG_ARCH_VERSATILE is not set | ||
| 135 | # CONFIG_ARCH_AT91 is not set | ||
| 136 | # CONFIG_ARCH_CLPS711X is not set | ||
| 137 | # CONFIG_ARCH_GEMINI is not set | ||
| 138 | # CONFIG_ARCH_EBSA110 is not set | ||
| 139 | # CONFIG_ARCH_EP93XX is not set | ||
| 140 | # CONFIG_ARCH_FOOTBRIDGE is not set | ||
| 141 | # CONFIG_ARCH_MXC is not set | ||
| 142 | # CONFIG_ARCH_STMP3XXX is not set | ||
| 143 | # CONFIG_ARCH_NETX is not set | ||
| 144 | # CONFIG_ARCH_H720X is not set | ||
| 145 | # CONFIG_ARCH_IOP13XX is not set | ||
| 146 | # CONFIG_ARCH_IOP32X is not set | ||
| 147 | # CONFIG_ARCH_IOP33X is not set | ||
| 148 | # CONFIG_ARCH_IXP23XX is not set | ||
| 149 | # CONFIG_ARCH_IXP2000 is not set | ||
| 150 | # CONFIG_ARCH_IXP4XX is not set | ||
| 151 | # CONFIG_ARCH_L7200 is not set | ||
| 152 | # CONFIG_ARCH_KIRKWOOD is not set | ||
| 153 | # CONFIG_ARCH_LOKI is not set | ||
| 154 | # CONFIG_ARCH_MV78XX0 is not set | ||
| 155 | # CONFIG_ARCH_ORION5X is not set | ||
| 156 | # CONFIG_ARCH_MMP is not set | ||
| 157 | # CONFIG_ARCH_KS8695 is not set | ||
| 158 | # CONFIG_ARCH_NS9XXX is not set | ||
| 159 | # CONFIG_ARCH_W90X900 is not set | ||
| 160 | # CONFIG_ARCH_PNX4008 is not set | ||
| 161 | # CONFIG_ARCH_PXA is not set | ||
| 162 | # CONFIG_ARCH_MSM is not set | ||
| 163 | # CONFIG_ARCH_RPC is not set | ||
| 164 | # CONFIG_ARCH_SA1100 is not set | ||
| 165 | # CONFIG_ARCH_S3C2410 is not set | ||
| 166 | # CONFIG_ARCH_S3C64XX is not set | ||
| 167 | # CONFIG_ARCH_SHARK is not set | ||
| 168 | # CONFIG_ARCH_LH7A40X is not set | ||
| 169 | # CONFIG_ARCH_U300 is not set | ||
| 170 | # CONFIG_ARCH_DAVINCI is not set | ||
| 171 | # CONFIG_ARCH_OMAP is not set | ||
| 172 | CONFIG_ARCH_BCMRING=y | ||
| 173 | # CONFIG_ARCH_FPGA11107 is not set | ||
| 174 | CONFIG_ARCH_BCM11107=y | ||
| 175 | |||
| 176 | # | ||
| 177 | # BCMRING Options | ||
| 178 | # | ||
| 179 | CONFIG_BCM_ZRELADDR=0x8000 | ||
| 180 | |||
| 181 | # | ||
| 182 | # Processor Type | ||
| 183 | # | ||
| 184 | CONFIG_CPU_32=y | ||
| 185 | CONFIG_CPU_V6=y | ||
| 186 | CONFIG_CPU_32v6K=y | ||
| 187 | CONFIG_CPU_32v6=y | ||
| 188 | CONFIG_CPU_ABRT_EV6=y | ||
| 189 | CONFIG_CPU_PABRT_NOIFAR=y | ||
| 190 | CONFIG_CPU_CACHE_V6=y | ||
| 191 | CONFIG_CPU_CACHE_VIPT=y | ||
| 192 | CONFIG_CPU_COPY_V6=y | ||
| 193 | CONFIG_CPU_TLB_V6=y | ||
| 194 | CONFIG_CPU_HAS_ASID=y | ||
| 195 | CONFIG_CPU_CP15=y | ||
| 196 | CONFIG_CPU_CP15_MMU=y | ||
| 197 | |||
| 198 | # | ||
| 199 | # Processor Features | ||
| 200 | # | ||
| 201 | CONFIG_ARM_THUMB=y | ||
| 202 | # CONFIG_CPU_ICACHE_DISABLE is not set | ||
| 203 | # CONFIG_CPU_DCACHE_DISABLE is not set | ||
| 204 | # CONFIG_CPU_BPREDICT_DISABLE is not set | ||
| 205 | # CONFIG_ARM_ERRATA_411920 is not set | ||
| 206 | CONFIG_COMMON_CLKDEV=y | ||
| 207 | |||
| 208 | # | ||
| 209 | # Bus support | ||
| 210 | # | ||
| 211 | CONFIG_ARM_AMBA=y | ||
| 212 | # CONFIG_PCI_SYSCALL is not set | ||
| 213 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
| 214 | |||
| 215 | # | ||
| 216 | # Kernel Features | ||
| 217 | # | ||
| 218 | CONFIG_TICK_ONESHOT=y | ||
| 219 | CONFIG_NO_HZ=y | ||
| 220 | # CONFIG_HIGH_RES_TIMERS is not set | ||
| 221 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | ||
| 222 | CONFIG_VMSPLIT_3G=y | ||
| 223 | # CONFIG_VMSPLIT_2G is not set | ||
| 224 | # CONFIG_VMSPLIT_1G is not set | ||
| 225 | CONFIG_PAGE_OFFSET=0xC0000000 | ||
| 226 | CONFIG_PREEMPT=y | ||
| 227 | CONFIG_HZ=100 | ||
| 228 | CONFIG_AEABI=y | ||
| 229 | # CONFIG_OABI_COMPAT is not set | ||
| 230 | # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set | ||
| 231 | # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set | ||
| 232 | # CONFIG_HIGHMEM is not set | ||
| 233 | CONFIG_SELECT_MEMORY_MODEL=y | ||
| 234 | CONFIG_FLATMEM_MANUAL=y | ||
| 235 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
| 236 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
| 237 | CONFIG_FLATMEM=y | ||
| 238 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
| 239 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
| 240 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
| 241 | # CONFIG_PHYS_ADDR_T_64BIT is not set | ||
| 242 | CONFIG_ZONE_DMA_FLAG=0 | ||
| 243 | CONFIG_VIRT_TO_BUS=y | ||
| 244 | CONFIG_HAVE_MLOCK=y | ||
| 245 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | ||
| 246 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
| 247 | CONFIG_ALIGNMENT_TRAP=y | ||
| 248 | CONFIG_UACCESS_WITH_MEMCPY=y | ||
| 249 | |||
| 250 | # | ||
| 251 | # Boot options | ||
| 252 | # | ||
| 253 | CONFIG_ZBOOT_ROM_TEXT=0x0e000000 | ||
| 254 | CONFIG_ZBOOT_ROM_BSS=0x0ea00000 | ||
| 255 | CONFIG_ZBOOT_ROM=y | ||
| 256 | CONFIG_CMDLINE="" | ||
| 257 | # CONFIG_KEXEC is not set | ||
| 258 | |||
| 259 | # | ||
| 260 | # CPU Power Management | ||
| 261 | # | ||
| 262 | # CONFIG_CPU_IDLE is not set | ||
| 263 | |||
| 264 | # | ||
| 265 | # Floating point emulation | ||
| 266 | # | ||
| 267 | |||
| 268 | # | ||
| 269 | # At least one emulation must be selected | ||
| 270 | # | ||
| 271 | # CONFIG_VFP is not set | ||
| 272 | |||
| 273 | # | ||
| 274 | # Userspace binary formats | ||
| 275 | # | ||
| 276 | CONFIG_BINFMT_ELF=y | ||
| 277 | CONFIG_HAVE_AOUT=y | ||
| 278 | # CONFIG_BINFMT_AOUT is not set | ||
| 279 | # CONFIG_BINFMT_MISC is not set | ||
| 280 | |||
| 281 | # | ||
| 282 | # Power management options | ||
| 283 | # | ||
| 284 | # CONFIG_PM is not set | ||
| 285 | CONFIG_ARCH_SUSPEND_POSSIBLE=y | ||
| 286 | CONFIG_NET=y | ||
| 287 | |||
| 288 | # | ||
| 289 | # Networking options | ||
| 290 | # | ||
| 291 | # CONFIG_PACKET is not set | ||
| 292 | # CONFIG_UNIX is not set | ||
| 293 | # CONFIG_NET_KEY is not set | ||
| 294 | # CONFIG_INET is not set | ||
| 295 | # CONFIG_NETWORK_SECMARK is not set | ||
| 296 | # CONFIG_NETFILTER is not set | ||
| 297 | # CONFIG_ATM is not set | ||
| 298 | # CONFIG_BRIDGE is not set | ||
| 299 | # CONFIG_NET_DSA is not set | ||
| 300 | # CONFIG_VLAN_8021Q is not set | ||
| 301 | # CONFIG_DECNET is not set | ||
| 302 | # CONFIG_LLC2 is not set | ||
| 303 | # CONFIG_IPX is not set | ||
| 304 | # CONFIG_ATALK is not set | ||
| 305 | # CONFIG_X25 is not set | ||
| 306 | # CONFIG_LAPB is not set | ||
| 307 | # CONFIG_WAN_ROUTER is not set | ||
| 308 | # CONFIG_PHONET is not set | ||
| 309 | # CONFIG_IEEE802154 is not set | ||
| 310 | # CONFIG_NET_SCHED is not set | ||
| 311 | # CONFIG_DCB is not set | ||
| 312 | |||
| 313 | # | ||
| 314 | # Network testing | ||
| 315 | # | ||
| 316 | # CONFIG_NET_PKTGEN is not set | ||
| 317 | # CONFIG_HAMRADIO is not set | ||
| 318 | # CONFIG_CAN is not set | ||
| 319 | # CONFIG_IRDA is not set | ||
| 320 | # CONFIG_BT is not set | ||
| 321 | # CONFIG_WIRELESS is not set | ||
| 322 | # CONFIG_WIMAX is not set | ||
| 323 | # CONFIG_RFKILL is not set | ||
| 324 | # CONFIG_NET_9P is not set | ||
| 325 | |||
| 326 | # | ||
| 327 | # Device Drivers | ||
| 328 | # | ||
| 329 | |||
| 330 | # | ||
| 331 | # Generic Driver Options | ||
| 332 | # | ||
| 333 | CONFIG_STANDALONE=y | ||
| 334 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
| 335 | # CONFIG_SYS_HYPERVISOR is not set | ||
| 336 | # CONFIG_CONNECTOR is not set | ||
| 337 | CONFIG_MTD=y | ||
| 338 | # CONFIG_MTD_DEBUG is not set | ||
| 339 | CONFIG_MTD_CONCAT=y | ||
| 340 | CONFIG_MTD_PARTITIONS=y | ||
| 341 | # CONFIG_MTD_TESTS is not set | ||
| 342 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
| 343 | CONFIG_MTD_CMDLINE_PARTS=y | ||
| 344 | # CONFIG_MTD_AFS_PARTS is not set | ||
| 345 | # CONFIG_MTD_AR7_PARTS is not set | ||
| 346 | |||
| 347 | # | ||
| 348 | # User Modules And Translation Layers | ||
| 349 | # | ||
| 350 | CONFIG_MTD_CHAR=y | ||
| 351 | CONFIG_MTD_BLKDEVS=y | ||
| 352 | CONFIG_MTD_BLOCK=y | ||
| 353 | # CONFIG_FTL is not set | ||
| 354 | # CONFIG_NFTL is not set | ||
| 355 | # CONFIG_INFTL is not set | ||
| 356 | # CONFIG_RFD_FTL is not set | ||
| 357 | # CONFIG_SSFDC is not set | ||
| 358 | # CONFIG_MTD_OOPS is not set | ||
| 359 | |||
| 360 | # | ||
| 361 | # RAM/ROM/Flash chip drivers | ||
| 362 | # | ||
| 363 | CONFIG_MTD_CFI=y | ||
| 364 | # CONFIG_MTD_JEDECPROBE is not set | ||
| 365 | CONFIG_MTD_GEN_PROBE=y | ||
| 366 | CONFIG_MTD_CFI_ADV_OPTIONS=y | ||
| 367 | CONFIG_MTD_CFI_NOSWAP=y | ||
| 368 | # CONFIG_MTD_CFI_BE_BYTE_SWAP is not set | ||
| 369 | # CONFIG_MTD_CFI_LE_BYTE_SWAP is not set | ||
| 370 | CONFIG_MTD_CFI_GEOMETRY=y | ||
| 371 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
| 372 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
| 373 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
| 374 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
| 375 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
| 376 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
| 377 | CONFIG_MTD_CFI_I1=y | ||
| 378 | # CONFIG_MTD_CFI_I2 is not set | ||
| 379 | # CONFIG_MTD_CFI_I4 is not set | ||
| 380 | # CONFIG_MTD_CFI_I8 is not set | ||
| 381 | # CONFIG_MTD_OTP is not set | ||
| 382 | # CONFIG_MTD_CFI_INTELEXT is not set | ||
| 383 | # CONFIG_MTD_CFI_AMDSTD is not set | ||
| 384 | # CONFIG_MTD_CFI_STAA is not set | ||
| 385 | CONFIG_MTD_CFI_UTIL=y | ||
| 386 | # CONFIG_MTD_RAM is not set | ||
| 387 | # CONFIG_MTD_ROM is not set | ||
| 388 | # CONFIG_MTD_ABSENT is not set | ||
| 389 | |||
| 390 | # | ||
| 391 | # Mapping drivers for chip access | ||
| 392 | # | ||
| 393 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
| 394 | # CONFIG_MTD_PHYSMAP is not set | ||
| 395 | # CONFIG_MTD_ARM_INTEGRATOR is not set | ||
| 396 | # CONFIG_MTD_PLATRAM is not set | ||
| 397 | |||
| 398 | # | ||
| 399 | # Self-contained MTD device drivers | ||
| 400 | # | ||
| 401 | # CONFIG_MTD_SLRAM is not set | ||
| 402 | # CONFIG_MTD_PHRAM is not set | ||
| 403 | # CONFIG_MTD_MTDRAM is not set | ||
| 404 | # CONFIG_MTD_BLOCK2MTD is not set | ||
| 405 | |||
| 406 | # | ||
| 407 | # Disk-On-Chip Device Drivers | ||
| 408 | # | ||
| 409 | # CONFIG_MTD_DOC2000 is not set | ||
| 410 | # CONFIG_MTD_DOC2001 is not set | ||
| 411 | # CONFIG_MTD_DOC2001PLUS is not set | ||
| 412 | CONFIG_MTD_NAND=y | ||
| 413 | CONFIG_MTD_NAND_VERIFY_WRITE=y | ||
| 414 | # CONFIG_MTD_NAND_ECC_SMC is not set | ||
| 415 | # CONFIG_MTD_NAND_MUSEUM_IDS is not set | ||
| 416 | CONFIG_MTD_NAND_IDS=y | ||
| 417 | CONFIG_MTD_NAND_BCM_UMI=y | ||
| 418 | CONFIG_MTD_NAND_BCM_UMI_HWCS=y | ||
| 419 | # CONFIG_MTD_NAND_DISKONCHIP is not set | ||
| 420 | # CONFIG_MTD_NAND_NANDSIM is not set | ||
| 421 | # CONFIG_MTD_NAND_PLATFORM is not set | ||
| 422 | # CONFIG_MTD_ONENAND is not set | ||
| 423 | |||
| 424 | # | ||
| 425 | # LPDDR flash memory drivers | ||
| 426 | # | ||
| 427 | # CONFIG_MTD_LPDDR is not set | ||
| 428 | |||
| 429 | # | ||
| 430 | # UBI - Unsorted block images | ||
| 431 | # | ||
| 432 | # CONFIG_MTD_UBI is not set | ||
| 433 | # CONFIG_PARPORT is not set | ||
| 434 | CONFIG_BLK_DEV=y | ||
| 435 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
| 436 | # CONFIG_BLK_DEV_LOOP is not set | ||
| 437 | # CONFIG_BLK_DEV_NBD is not set | ||
| 438 | # CONFIG_BLK_DEV_RAM is not set | ||
| 439 | # CONFIG_CDROM_PKTCDVD is not set | ||
| 440 | # CONFIG_ATA_OVER_ETH is not set | ||
| 441 | # CONFIG_MISC_DEVICES is not set | ||
| 442 | CONFIG_HAVE_IDE=y | ||
| 443 | # CONFIG_IDE is not set | ||
| 444 | |||
| 445 | # | ||
| 446 | # SCSI device support | ||
| 447 | # | ||
| 448 | # CONFIG_RAID_ATTRS is not set | ||
| 449 | # CONFIG_SCSI is not set | ||
| 450 | # CONFIG_SCSI_DMA is not set | ||
| 451 | # CONFIG_SCSI_NETLINK is not set | ||
| 452 | # CONFIG_ATA is not set | ||
| 453 | # CONFIG_MD is not set | ||
| 454 | # CONFIG_NETDEVICES is not set | ||
| 455 | # CONFIG_ISDN is not set | ||
| 456 | |||
| 457 | # | ||
| 458 | # Input device support | ||
| 459 | # | ||
| 460 | CONFIG_INPUT=y | ||
| 461 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
| 462 | # CONFIG_INPUT_POLLDEV is not set | ||
| 463 | |||
| 464 | # | ||
| 465 | # Userland interfaces | ||
| 466 | # | ||
| 467 | # CONFIG_INPUT_MOUSEDEV is not set | ||
| 468 | # CONFIG_INPUT_JOYDEV is not set | ||
| 469 | # CONFIG_INPUT_EVDEV is not set | ||
| 470 | # CONFIG_INPUT_EVBUG is not set | ||
| 471 | |||
| 472 | # | ||
| 473 | # Input Device Drivers | ||
| 474 | # | ||
| 475 | # CONFIG_INPUT_KEYBOARD is not set | ||
| 476 | # CONFIG_INPUT_MOUSE is not set | ||
| 477 | # CONFIG_INPUT_JOYSTICK is not set | ||
| 478 | # CONFIG_INPUT_TABLET is not set | ||
| 479 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
| 480 | # CONFIG_INPUT_MISC is not set | ||
| 481 | |||
| 482 | # | ||
| 483 | # Hardware I/O ports | ||
| 484 | # | ||
| 485 | # CONFIG_SERIO is not set | ||
| 486 | # CONFIG_GAMEPORT is not set | ||
| 487 | |||
| 488 | # | ||
| 489 | # Character devices | ||
| 490 | # | ||
| 491 | CONFIG_VT=y | ||
| 492 | # CONFIG_CONSOLE_TRANSLATIONS is not set | ||
| 493 | CONFIG_VT_CONSOLE=y | ||
| 494 | CONFIG_HW_CONSOLE=y | ||
| 495 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | ||
| 496 | # CONFIG_DEVKMEM is not set | ||
| 497 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
| 498 | |||
| 499 | # | ||
| 500 | # Serial drivers | ||
| 501 | # | ||
| 502 | # CONFIG_SERIAL_8250 is not set | ||
| 503 | |||
| 504 | # | ||
| 505 | # Non-8250 serial port support | ||
| 506 | # | ||
| 507 | # CONFIG_SERIAL_AMBA_PL010 is not set | ||
| 508 | CONFIG_SERIAL_AMBA_PL011=y | ||
| 509 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y | ||
| 510 | CONFIG_SERIAL_CORE=y | ||
| 511 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
| 512 | CONFIG_UNIX98_PTYS=y | ||
| 513 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
| 514 | CONFIG_LEGACY_PTYS=y | ||
| 515 | CONFIG_LEGACY_PTY_COUNT=64 | ||
| 516 | # CONFIG_IPMI_HANDLER is not set | ||
| 517 | # CONFIG_HW_RANDOM is not set | ||
| 518 | # CONFIG_R3964 is not set | ||
| 519 | # CONFIG_RAW_DRIVER is not set | ||
| 520 | # CONFIG_TCG_TPM is not set | ||
| 521 | # CONFIG_I2C is not set | ||
| 522 | # CONFIG_SPI is not set | ||
| 523 | CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y | ||
| 524 | # CONFIG_GPIOLIB is not set | ||
| 525 | # CONFIG_W1 is not set | ||
| 526 | # CONFIG_POWER_SUPPLY is not set | ||
| 527 | # CONFIG_HWMON is not set | ||
| 528 | # CONFIG_THERMAL is not set | ||
| 529 | # CONFIG_THERMAL_HWMON is not set | ||
| 530 | # CONFIG_WATCHDOG is not set | ||
| 531 | CONFIG_SSB_POSSIBLE=y | ||
| 532 | |||
| 533 | # | ||
| 534 | # Sonics Silicon Backplane | ||
| 535 | # | ||
| 536 | # CONFIG_SSB is not set | ||
| 537 | |||
| 538 | # | ||
| 539 | # Multifunction device drivers | ||
| 540 | # | ||
| 541 | # CONFIG_MFD_CORE is not set | ||
| 542 | # CONFIG_MFD_SM501 is not set | ||
| 543 | # CONFIG_HTC_PASIC3 is not set | ||
| 544 | # CONFIG_MFD_TMIO is not set | ||
| 545 | # CONFIG_MEDIA_SUPPORT is not set | ||
| 546 | |||
| 547 | # | ||
| 548 | # Graphics support | ||
| 549 | # | ||
| 550 | # CONFIG_VGASTATE is not set | ||
| 551 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
| 552 | # CONFIG_FB is not set | ||
| 553 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
| 554 | |||
| 555 | # | ||
| 556 | # Display device support | ||
| 557 | # | ||
| 558 | # CONFIG_DISPLAY_SUPPORT is not set | ||
| 559 | |||
| 560 | # | ||
| 561 | # Console display driver support | ||
| 562 | # | ||
| 563 | # CONFIG_VGA_CONSOLE is not set | ||
| 564 | CONFIG_DUMMY_CONSOLE=y | ||
| 565 | # CONFIG_SOUND is not set | ||
| 566 | # CONFIG_HID_SUPPORT is not set | ||
| 567 | # CONFIG_USB_SUPPORT is not set | ||
| 568 | # CONFIG_MMC is not set | ||
| 569 | # CONFIG_MEMSTICK is not set | ||
| 570 | # CONFIG_ACCESSIBILITY is not set | ||
| 571 | # CONFIG_NEW_LEDS is not set | ||
| 572 | CONFIG_RTC_LIB=y | ||
| 573 | # CONFIG_RTC_CLASS is not set | ||
| 574 | # CONFIG_DMADEVICES is not set | ||
| 575 | # CONFIG_AUXDISPLAY is not set | ||
| 576 | # CONFIG_REGULATOR is not set | ||
| 577 | # CONFIG_UIO is not set | ||
| 578 | # CONFIG_STAGING is not set | ||
| 579 | |||
| 580 | # | ||
| 581 | # File systems | ||
| 582 | # | ||
| 583 | # CONFIG_EXT2_FS is not set | ||
| 584 | # CONFIG_EXT3_FS is not set | ||
| 585 | # CONFIG_EXT4_FS is not set | ||
| 586 | # CONFIG_REISERFS_FS is not set | ||
| 587 | # CONFIG_JFS_FS is not set | ||
| 588 | CONFIG_FS_POSIX_ACL=y | ||
| 589 | # CONFIG_XFS_FS is not set | ||
| 590 | # CONFIG_GFS2_FS is not set | ||
| 591 | # CONFIG_OCFS2_FS is not set | ||
| 592 | # CONFIG_BTRFS_FS is not set | ||
| 593 | # CONFIG_FILE_LOCKING is not set | ||
| 594 | # CONFIG_FSNOTIFY is not set | ||
| 595 | # CONFIG_INOTIFY is not set | ||
| 596 | # CONFIG_QUOTA is not set | ||
| 597 | # CONFIG_AUTOFS_FS is not set | ||
| 598 | # CONFIG_AUTOFS4_FS is not set | ||
| 599 | # CONFIG_FUSE_FS is not set | ||
| 600 | |||
| 601 | # | ||
| 602 | # Caches | ||
| 603 | # | ||
| 604 | # CONFIG_FSCACHE is not set | ||
| 605 | |||
| 606 | # | ||
| 607 | # CD-ROM/DVD Filesystems | ||
| 608 | # | ||
| 609 | # CONFIG_ISO9660_FS is not set | ||
| 610 | # CONFIG_UDF_FS is not set | ||
| 611 | |||
| 612 | # | ||
| 613 | # DOS/FAT/NT Filesystems | ||
| 614 | # | ||
| 615 | # CONFIG_MSDOS_FS is not set | ||
| 616 | # CONFIG_VFAT_FS is not set | ||
| 617 | # CONFIG_NTFS_FS is not set | ||
| 618 | |||
| 619 | # | ||
| 620 | # Pseudo filesystems | ||
| 621 | # | ||
| 622 | CONFIG_PROC_FS=y | ||
| 623 | CONFIG_PROC_SYSCTL=y | ||
| 624 | # CONFIG_PROC_PAGE_MONITOR is not set | ||
| 625 | CONFIG_SYSFS=y | ||
| 626 | CONFIG_TMPFS=y | ||
| 627 | # CONFIG_TMPFS_POSIX_ACL is not set | ||
| 628 | # CONFIG_HUGETLB_PAGE is not set | ||
| 629 | # CONFIG_CONFIGFS_FS is not set | ||
| 630 | CONFIG_MISC_FILESYSTEMS=y | ||
| 631 | # CONFIG_ADFS_FS is not set | ||
| 632 | # CONFIG_AFFS_FS is not set | ||
| 633 | # CONFIG_HFS_FS is not set | ||
| 634 | # CONFIG_HFSPLUS_FS is not set | ||
| 635 | # CONFIG_BEFS_FS is not set | ||
| 636 | # CONFIG_BFS_FS is not set | ||
| 637 | # CONFIG_EFS_FS is not set | ||
| 638 | CONFIG_JFFS2_FS=y | ||
| 639 | CONFIG_JFFS2_FS_DEBUG=0 | ||
| 640 | CONFIG_JFFS2_FS_WRITEBUFFER=y | ||
| 641 | # CONFIG_JFFS2_FS_WBUF_VERIFY is not set | ||
| 642 | CONFIG_JFFS2_SUMMARY=y | ||
| 643 | CONFIG_JFFS2_FS_XATTR=y | ||
| 644 | CONFIG_JFFS2_FS_POSIX_ACL=y | ||
| 645 | # CONFIG_JFFS2_FS_SECURITY is not set | ||
| 646 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | ||
| 647 | CONFIG_JFFS2_ZLIB=y | ||
| 648 | # CONFIG_JFFS2_LZO is not set | ||
| 649 | CONFIG_JFFS2_RTIME=y | ||
| 650 | # CONFIG_JFFS2_RUBIN is not set | ||
| 651 | # CONFIG_CRAMFS is not set | ||
| 652 | # CONFIG_SQUASHFS is not set | ||
| 653 | # CONFIG_VXFS_FS is not set | ||
| 654 | # CONFIG_MINIX_FS is not set | ||
| 655 | # CONFIG_OMFS_FS is not set | ||
| 656 | # CONFIG_HPFS_FS is not set | ||
| 657 | # CONFIG_QNX4FS_FS is not set | ||
| 658 | # CONFIG_ROMFS_FS is not set | ||
| 659 | # CONFIG_SYSV_FS is not set | ||
| 660 | # CONFIG_UFS_FS is not set | ||
| 661 | # CONFIG_NILFS2_FS is not set | ||
| 662 | # CONFIG_NETWORK_FILESYSTEMS is not set | ||
| 663 | |||
| 664 | # | ||
| 665 | # Partition Types | ||
| 666 | # | ||
| 667 | # CONFIG_PARTITION_ADVANCED is not set | ||
| 668 | CONFIG_MSDOS_PARTITION=y | ||
| 669 | # CONFIG_NLS is not set | ||
| 670 | |||
| 671 | # | ||
| 672 | # Kernel hacking | ||
| 673 | # | ||
| 674 | # CONFIG_PRINTK_TIME is not set | ||
| 675 | # CONFIG_ENABLE_WARN_DEPRECATED is not set | ||
| 676 | CONFIG_ENABLE_MUST_CHECK=y | ||
| 677 | CONFIG_FRAME_WARN=1024 | ||
| 678 | CONFIG_MAGIC_SYSRQ=y | ||
| 679 | # CONFIG_UNUSED_SYMBOLS is not set | ||
| 680 | # CONFIG_DEBUG_FS is not set | ||
| 681 | CONFIG_HEADERS_CHECK=y | ||
| 682 | # CONFIG_DEBUG_KERNEL is not set | ||
| 683 | # CONFIG_DEBUG_BUGVERBOSE is not set | ||
| 684 | # CONFIG_DEBUG_MEMORY_INIT is not set | ||
| 685 | CONFIG_FRAME_POINTER=y | ||
| 686 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
| 687 | # CONFIG_LATENCYTOP is not set | ||
| 688 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set | ||
| 689 | CONFIG_HAVE_FUNCTION_TRACER=y | ||
| 690 | CONFIG_TRACING_SUPPORT=y | ||
| 691 | # CONFIG_FTRACE is not set | ||
| 692 | # CONFIG_BUILD_DOCSRC is not set | ||
| 693 | # CONFIG_SAMPLES is not set | ||
| 694 | CONFIG_HAVE_ARCH_KGDB=y | ||
| 695 | # CONFIG_ARM_UNWIND is not set | ||
| 696 | # CONFIG_DEBUG_USER is not set | ||
| 697 | |||
| 698 | # | ||
| 699 | # Security options | ||
| 700 | # | ||
| 701 | # CONFIG_KEYS is not set | ||
| 702 | # CONFIG_SECURITY is not set | ||
| 703 | # CONFIG_SECURITYFS is not set | ||
| 704 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
| 705 | # CONFIG_CRYPTO is not set | ||
| 706 | # CONFIG_BINARY_PRINTF is not set | ||
| 707 | |||
| 708 | # | ||
| 709 | # Library routines | ||
| 710 | # | ||
| 711 | CONFIG_BITREVERSE=y | ||
| 712 | CONFIG_GENERIC_FIND_LAST_BIT=y | ||
| 713 | # CONFIG_CRC_CCITT is not set | ||
| 714 | # CONFIG_CRC16 is not set | ||
| 715 | # CONFIG_CRC_T10DIF is not set | ||
| 716 | # CONFIG_CRC_ITU_T is not set | ||
| 717 | CONFIG_CRC32=y | ||
| 718 | # CONFIG_CRC7 is not set | ||
| 719 | # CONFIG_LIBCRC32C is not set | ||
| 720 | CONFIG_ZLIB_INFLATE=y | ||
| 721 | CONFIG_ZLIB_DEFLATE=y | ||
| 722 | CONFIG_HAS_IOMEM=y | ||
| 723 | CONFIG_HAS_IOPORT=y | ||
| 724 | CONFIG_HAS_DMA=y | ||
| 725 | CONFIG_NLATTR=y | ||
diff --git a/arch/arm/configs/cpu9260_defconfig b/arch/arm/configs/cpu9260_defconfig new file mode 100644 index 000000000000..601e7f3d5e97 --- /dev/null +++ b/arch/arm/configs/cpu9260_defconfig | |||
| @@ -0,0 +1,1338 @@ | |||
| 1 | # | ||
| 2 | # Automatically generated make config: don't edit | ||
| 3 | # Linux kernel version: 2.6.31-rc3 | ||
| 4 | # Tue Jul 14 14:57:55 2009 | ||
| 5 | # | ||
| 6 | CONFIG_ARM=y | ||
| 7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||
| 8 | CONFIG_GENERIC_GPIO=y | ||
| 9 | CONFIG_GENERIC_TIME=y | ||
| 10 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
| 11 | CONFIG_MMU=y | ||
| 12 | CONFIG_GENERIC_HARDIRQS=y | ||
| 13 | CONFIG_STACKTRACE_SUPPORT=y | ||
| 14 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | ||
| 15 | CONFIG_LOCKDEP_SUPPORT=y | ||
| 16 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
| 17 | CONFIG_HARDIRQS_SW_RESEND=y | ||
| 18 | CONFIG_GENERIC_IRQ_PROBE=y | ||
| 19 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
| 20 | CONFIG_GENERIC_HWEIGHT=y | ||
| 21 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
| 22 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | ||
| 23 | CONFIG_VECTORS_BASE=0xffff0000 | ||
| 24 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
| 25 | CONFIG_CONSTRUCTORS=y | ||
| 26 | |||
| 27 | # | ||
| 28 | # General setup | ||
| 29 | # | ||
| 30 | CONFIG_EXPERIMENTAL=y | ||
| 31 | CONFIG_BROKEN_ON_SMP=y | ||
| 32 | CONFIG_LOCK_KERNEL=y | ||
| 33 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
| 34 | CONFIG_LOCALVERSION="" | ||
| 35 | # CONFIG_LOCALVERSION_AUTO is not set | ||
| 36 | # CONFIG_SWAP is not set | ||
| 37 | CONFIG_SYSVIPC=y | ||
| 38 | CONFIG_SYSVIPC_SYSCTL=y | ||
| 39 | # CONFIG_POSIX_MQUEUE is not set | ||
| 40 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
| 41 | # CONFIG_TASKSTATS is not set | ||
| 42 | # CONFIG_AUDIT is not set | ||
| 43 | |||
| 44 | # | ||
| 45 | # RCU Subsystem | ||
| 46 | # | ||
| 47 | CONFIG_CLASSIC_RCU=y | ||
| 48 | # CONFIG_TREE_RCU is not set | ||
| 49 | # CONFIG_PREEMPT_RCU is not set | ||
| 50 | # CONFIG_TREE_RCU_TRACE is not set | ||
| 51 | # CONFIG_PREEMPT_RCU_TRACE is not set | ||
| 52 | # CONFIG_IKCONFIG is not set | ||
| 53 | CONFIG_LOG_BUF_SHIFT=14 | ||
| 54 | # CONFIG_GROUP_SCHED is not set | ||
| 55 | # CONFIG_CGROUPS is not set | ||
| 56 | CONFIG_SYSFS_DEPRECATED=y | ||
| 57 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
| 58 | # CONFIG_RELAY is not set | ||
| 59 | CONFIG_NAMESPACES=y | ||
| 60 | # CONFIG_UTS_NS is not set | ||
| 61 | # CONFIG_IPC_NS is not set | ||
| 62 | # CONFIG_USER_NS is not set | ||
| 63 | # CONFIG_PID_NS is not set | ||
| 64 | # CONFIG_NET_NS is not set | ||
| 65 | # CONFIG_BLK_DEV_INITRD is not set | ||
| 66 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
| 67 | CONFIG_SYSCTL=y | ||
| 68 | CONFIG_ANON_INODES=y | ||
| 69 | # CONFIG_EMBEDDED is not set | ||
| 70 | CONFIG_UID16=y | ||
| 71 | CONFIG_SYSCTL_SYSCALL=y | ||
| 72 | CONFIG_KALLSYMS=y | ||
| 73 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
| 74 | CONFIG_HOTPLUG=y | ||
| 75 | CONFIG_PRINTK=y | ||
| 76 | CONFIG_BUG=y | ||
| 77 | CONFIG_ELF_CORE=y | ||
| 78 | CONFIG_BASE_FULL=y | ||
| 79 | CONFIG_FUTEX=y | ||
| 80 | CONFIG_EPOLL=y | ||
| 81 | CONFIG_SIGNALFD=y | ||
| 82 | CONFIG_TIMERFD=y | ||
| 83 | CONFIG_EVENTFD=y | ||
| 84 | CONFIG_SHMEM=y | ||
| 85 | CONFIG_AIO=y | ||
| 86 | |||
| 87 | # | ||
| 88 | # Performance Counters | ||
| 89 | # | ||
| 90 | CONFIG_VM_EVENT_COUNTERS=y | ||
| 91 | CONFIG_SLUB_DEBUG=y | ||
| 92 | # CONFIG_STRIP_ASM_SYMS is not set | ||
| 93 | CONFIG_COMPAT_BRK=y | ||
| 94 | # CONFIG_SLAB is not set | ||
| 95 | CONFIG_SLUB=y | ||
| 96 | # CONFIG_SLOB is not set | ||
| 97 | # CONFIG_PROFILING is not set | ||
| 98 | # CONFIG_MARKERS is not set | ||
| 99 | CONFIG_HAVE_OPROFILE=y | ||
| 100 | # CONFIG_KPROBES is not set | ||
| 101 | CONFIG_HAVE_KPROBES=y | ||
| 102 | CONFIG_HAVE_KRETPROBES=y | ||
| 103 | CONFIG_HAVE_CLK=y | ||
| 104 | |||
| 105 | # | ||
| 106 | # GCOV-based kernel profiling | ||
| 107 | # | ||
| 108 | # CONFIG_SLOW_WORK is not set | ||
| 109 | CONFIG_HAVE_GENERIC_DMA_COHERENT=y | ||
| 110 | CONFIG_SLABINFO=y | ||
| 111 | CONFIG_RT_MUTEXES=y | ||
| 112 | CONFIG_BASE_SMALL=0 | ||
| 113 | CONFIG_MODULES=y | ||
| 114 | # CONFIG_MODULE_FORCE_LOAD is not set | ||
| 115 | CONFIG_MODULE_UNLOAD=y | ||
| 116 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
| 117 | # CONFIG_MODVERSIONS is not set | ||
| 118 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
| 119 | CONFIG_BLOCK=y | ||
| 120 | CONFIG_LBDAF=y | ||
| 121 | # CONFIG_BLK_DEV_BSG is not set | ||
| 122 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
| 123 | |||
| 124 | # | ||
| 125 | # IO Schedulers | ||
| 126 | # | ||
| 127 | CONFIG_IOSCHED_NOOP=y | ||
| 128 | # CONFIG_IOSCHED_AS is not set | ||
| 129 | CONFIG_IOSCHED_DEADLINE=y | ||
| 130 | # CONFIG_IOSCHED_CFQ is not set | ||
| 131 | # CONFIG_DEFAULT_AS is not set | ||
| 132 | CONFIG_DEFAULT_DEADLINE=y | ||
| 133 | # CONFIG_DEFAULT_CFQ is not set | ||
| 134 | # CONFIG_DEFAULT_NOOP is not set | ||
| 135 | CONFIG_DEFAULT_IOSCHED="deadline" | ||
| 136 | # CONFIG_FREEZER is not set | ||
| 137 | |||
| 138 | # | ||
| 139 | # System Type | ||
| 140 | # | ||
| 141 | # CONFIG_ARCH_AAEC2000 is not set | ||
| 142 | # CONFIG_ARCH_INTEGRATOR is not set | ||
| 143 | # CONFIG_ARCH_REALVIEW is not set | ||
| 144 | # CONFIG_ARCH_VERSATILE is not set | ||
| 145 | CONFIG_ARCH_AT91=y | ||
| 146 | # CONFIG_ARCH_CLPS711X is not set | ||
| 147 | # CONFIG_ARCH_GEMINI is not set | ||
| 148 | # CONFIG_ARCH_EBSA110 is not set | ||
| 149 | # CONFIG_ARCH_EP93XX is not set | ||
| 150 | # CONFIG_ARCH_FOOTBRIDGE is not set | ||
| 151 | # CONFIG_ARCH_MXC is not set | ||
| 152 | # CONFIG_ARCH_STMP3XXX is not set | ||
| 153 | # CONFIG_ARCH_NETX is not set | ||
| 154 | # CONFIG_ARCH_H720X is not set | ||
| 155 | # CONFIG_ARCH_IOP13XX is not set | ||
| 156 | # CONFIG_ARCH_IOP32X is not set | ||
| 157 | # CONFIG_ARCH_IOP33X is not set | ||
| 158 | # CONFIG_ARCH_IXP23XX is not set | ||
| 159 | # CONFIG_ARCH_IXP2000 is not set | ||
| 160 | # CONFIG_ARCH_IXP4XX is not set | ||
| 161 | # CONFIG_ARCH_L7200 is not set | ||
| 162 | # CONFIG_ARCH_KIRKWOOD is not set | ||
| 163 | # CONFIG_ARCH_LOKI is not set | ||
| 164 | # CONFIG_ARCH_MV78XX0 is not set | ||
| 165 | # CONFIG_ARCH_ORION5X is not set | ||
| 166 | # CONFIG_ARCH_MMP is not set | ||
| 167 | # CONFIG_ARCH_KS8695 is not set | ||
| 168 | # CONFIG_ARCH_NS9XXX is not set | ||
| 169 | # CONFIG_ARCH_W90X900 is not set | ||
| 170 | # CONFIG_ARCH_PNX4008 is not set | ||
| 171 | # CONFIG_ARCH_PXA is not set | ||
| 172 | # CONFIG_ARCH_MSM is not set | ||
| 173 | # CONFIG_ARCH_RPC is not set | ||
| 174 | # CONFIG_ARCH_SA1100 is not set | ||
| 175 | # CONFIG_ARCH_S3C2410 is not set | ||
| 176 | # CONFIG_ARCH_S3C64XX is not set | ||
| 177 | # CONFIG_ARCH_SHARK is not set | ||
| 178 | # CONFIG_ARCH_LH7A40X is not set | ||
| 179 | # CONFIG_ARCH_U300 is not set | ||
| 180 | # CONFIG_ARCH_DAVINCI is not set | ||
| 181 | # CONFIG_ARCH_OMAP is not set | ||
| 182 | |||
| 183 | # | ||
| 184 | # Atmel AT91 System-on-Chip | ||
| 185 | # | ||
| 186 | # CONFIG_ARCH_AT91RM9200 is not set | ||
| 187 | CONFIG_ARCH_AT91SAM9260=y | ||
| 188 | # CONFIG_ARCH_AT91SAM9261 is not set | ||
| 189 | # CONFIG_ARCH_AT91SAM9263 is not set | ||
| 190 | # CONFIG_ARCH_AT91SAM9RL is not set | ||
| 191 | # CONFIG_ARCH_AT91SAM9G20 is not set | ||
| 192 | # CONFIG_ARCH_AT91CAP9 is not set | ||
| 193 | # CONFIG_ARCH_AT91X40 is not set | ||
| 194 | CONFIG_AT91_PMC_UNIT=y | ||
| 195 | |||
| 196 | # | ||
| 197 | # AT91SAM9260 Variants | ||
| 198 | # | ||
| 199 | # CONFIG_ARCH_AT91SAM9260_SAM9XE is not set | ||
| 200 | |||
| 201 | # | ||
| 202 | # AT91SAM9260 / AT91SAM9XE Board Type | ||
| 203 | # | ||
| 204 | # CONFIG_MACH_AT91SAM9260EK is not set | ||
| 205 | # CONFIG_MACH_CAM60 is not set | ||
| 206 | # CONFIG_MACH_SAM9_L9260 is not set | ||
| 207 | # CONFIG_MACH_AFEB9260 is not set | ||
| 208 | # CONFIG_MACH_USB_A9260 is not set | ||
| 209 | # CONFIG_MACH_QIL_A9260 is not set | ||
| 210 | CONFIG_MACH_CPU9260=y | ||
| 211 | |||
| 212 | # | ||
| 213 | # AT91 Board Options | ||
| 214 | # | ||
| 215 | |||
| 216 | # | ||
| 217 | # AT91 Feature Selections | ||
| 218 | # | ||
| 219 | # CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set | ||
| 220 | CONFIG_AT91_TIMER_HZ=100 | ||
| 221 | CONFIG_AT91_EARLY_DBGU=y | ||
| 222 | # CONFIG_AT91_EARLY_USART0 is not set | ||
| 223 | # CONFIG_AT91_EARLY_USART1 is not set | ||
| 224 | # CONFIG_AT91_EARLY_USART2 is not set | ||
| 225 | # CONFIG_AT91_EARLY_USART3 is not set | ||
| 226 | # CONFIG_AT91_EARLY_USART4 is not set | ||
| 227 | # CONFIG_AT91_EARLY_USART5 is not set | ||
| 228 | |||
| 229 | # | ||
| 230 | # Processor Type | ||
| 231 | # | ||
| 232 | CONFIG_CPU_32=y | ||
| 233 | CONFIG_CPU_ARM926T=y | ||
| 234 | CONFIG_CPU_32v5=y | ||
| 235 | CONFIG_CPU_ABRT_EV5TJ=y | ||
| 236 | CONFIG_CPU_PABRT_NOIFAR=y | ||
| 237 | CONFIG_CPU_CACHE_VIVT=y | ||
| 238 | CONFIG_CPU_COPY_V4WB=y | ||
| 239 | CONFIG_CPU_TLB_V4WBI=y | ||
| 240 | CONFIG_CPU_CP15=y | ||
| 241 | CONFIG_CPU_CP15_MMU=y | ||
| 242 | |||
| 243 | # | ||
| 244 | # Processor Features | ||
| 245 | # | ||
| 246 | # CONFIG_ARM_THUMB is not set | ||
| 247 | # CONFIG_CPU_ICACHE_DISABLE is not set | ||
| 248 | # CONFIG_CPU_DCACHE_DISABLE is not set | ||
| 249 | # CONFIG_CPU_DCACHE_WRITETHROUGH is not set | ||
| 250 | # CONFIG_CPU_CACHE_ROUND_ROBIN is not set | ||
| 251 | |||
| 252 | # | ||
| 253 | # Bus support | ||
| 254 | # | ||
| 255 | # CONFIG_PCI_SYSCALL is not set | ||
| 256 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
| 257 | # CONFIG_PCCARD is not set | ||
| 258 | |||
| 259 | # | ||
| 260 | # Kernel Features | ||
| 261 | # | ||
| 262 | # CONFIG_NO_HZ is not set | ||
| 263 | # CONFIG_HIGH_RES_TIMERS is not set | ||
| 264 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | ||
| 265 | CONFIG_VMSPLIT_3G=y | ||
| 266 | # CONFIG_VMSPLIT_2G is not set | ||
| 267 | # CONFIG_VMSPLIT_1G is not set | ||
| 268 | CONFIG_PAGE_OFFSET=0xC0000000 | ||
| 269 | CONFIG_PREEMPT=y | ||
| 270 | CONFIG_HZ=100 | ||
| 271 | CONFIG_AEABI=y | ||
| 272 | CONFIG_OABI_COMPAT=y | ||
| 273 | # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set | ||
| 274 | # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set | ||
| 275 | # CONFIG_HIGHMEM is not set | ||
| 276 | CONFIG_SELECT_MEMORY_MODEL=y | ||
| 277 | CONFIG_FLATMEM_MANUAL=y | ||
| 278 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
| 279 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
| 280 | CONFIG_FLATMEM=y | ||
| 281 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
| 282 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
| 283 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | ||
| 284 | # CONFIG_PHYS_ADDR_T_64BIT is not set | ||
| 285 | CONFIG_ZONE_DMA_FLAG=0 | ||
| 286 | CONFIG_VIRT_TO_BUS=y | ||
| 287 | CONFIG_HAVE_MLOCK=y | ||
| 288 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | ||
| 289 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
| 290 | # CONFIG_LEDS is not set | ||
| 291 | CONFIG_ALIGNMENT_TRAP=y | ||
| 292 | # CONFIG_UACCESS_WITH_MEMCPY is not set | ||
| 293 | |||
| 294 | # | ||
| 295 | # Boot options | ||
| 296 | # | ||
| 297 | CONFIG_ZBOOT_ROM_TEXT=0x0 | ||
| 298 | CONFIG_ZBOOT_ROM_BSS=0x0 | ||
| 299 | CONFIG_CMDLINE="" | ||
| 300 | # CONFIG_XIP_KERNEL is not set | ||
| 301 | # CONFIG_KEXEC is not set | ||
| 302 | |||
| 303 | # | ||
| 304 | # CPU Power Management | ||
| 305 | # | ||
| 306 | # CONFIG_CPU_IDLE is not set | ||
| 307 | |||
| 308 | # | ||
| 309 | # Floating point emulation | ||
| 310 | # | ||
| 311 | |||
| 312 | # | ||
| 313 | # At least one emulation must be selected | ||
| 314 | # | ||
| 315 | # CONFIG_FPE_NWFPE is not set | ||
| 316 | # CONFIG_FPE_FASTFPE is not set | ||
| 317 | # CONFIG_VFP is not set | ||
| 318 | |||
| 319 | # | ||
| 320 | # Userspace binary formats | ||
| 321 | # | ||
| 322 | CONFIG_BINFMT_ELF=y | ||
| 323 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
| 324 | CONFIG_HAVE_AOUT=y | ||
| 325 | # CONFIG_BINFMT_AOUT is not set | ||
| 326 | # CONFIG_BINFMT_MISC is not set | ||
| 327 | |||
| 328 | # | ||
| 329 | # Power management options | ||
| 330 | # | ||
| 331 | # CONFIG_PM is not set | ||
| 332 | CONFIG_ARCH_SUSPEND_POSSIBLE=y | ||
| 333 | CONFIG_NET=y | ||
| 334 | |||
| 335 | # | ||
| 336 | # Networking options | ||
| 337 | # | ||
| 338 | CONFIG_PACKET=y | ||
| 339 | # CONFIG_PACKET_MMAP is not set | ||
| 340 | CONFIG_UNIX=y | ||
| 341 | # CONFIG_NET_KEY is not set | ||
| 342 | CONFIG_INET=y | ||
| 343 | # CONFIG_IP_MULTICAST is not set | ||
| 344 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
| 345 | CONFIG_IP_FIB_HASH=y | ||
| 346 | CONFIG_IP_PNP=y | ||
| 347 | # CONFIG_IP_PNP_DHCP is not set | ||
| 348 | # CONFIG_IP_PNP_BOOTP is not set | ||
| 349 | # CONFIG_IP_PNP_RARP is not set | ||
| 350 | # CONFIG_NET_IPIP is not set | ||
| 351 | # CONFIG_NET_IPGRE is not set | ||
| 352 | # CONFIG_ARPD is not set | ||
| 353 | # CONFIG_SYN_COOKIES is not set | ||
| 354 | # CONFIG_INET_AH is not set | ||
| 355 | # CONFIG_INET_ESP is not set | ||
| 356 | # CONFIG_INET_IPCOMP is not set | ||
| 357 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
| 358 | # CONFIG_INET_TUNNEL is not set | ||
| 359 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
| 360 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
| 361 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
| 362 | CONFIG_INET_LRO=y | ||
| 363 | CONFIG_INET_DIAG=y | ||
| 364 | CONFIG_INET_TCP_DIAG=y | ||
| 365 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
| 366 | CONFIG_TCP_CONG_CUBIC=y | ||
| 367 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
| 368 | # CONFIG_TCP_MD5SIG is not set | ||
| 369 | # CONFIG_IPV6 is not set | ||
| 370 | # CONFIG_NETWORK_SECMARK is not set | ||
| 371 | # CONFIG_NETFILTER is not set | ||
| 372 | # CONFIG_IP_DCCP is not set | ||
| 373 | # CONFIG_IP_SCTP is not set | ||
| 374 | # CONFIG_TIPC is not set | ||
| 375 | # CONFIG_ATM is not set | ||
| 376 | # CONFIG_BRIDGE is not set | ||
| 377 | # CONFIG_NET_DSA is not set | ||
| 378 | # CONFIG_VLAN_8021Q is not set | ||
| 379 | # CONFIG_DECNET is not set | ||
| 380 | # CONFIG_LLC2 is not set | ||
| 381 | # CONFIG_IPX is not set | ||
| 382 | # CONFIG_ATALK is not set | ||
| 383 | # CONFIG_X25 is not set | ||
| 384 | # CONFIG_LAPB is not set | ||
| 385 | # CONFIG_ECONET is not set | ||
| 386 | # CONFIG_WAN_ROUTER is not set | ||
| 387 | # CONFIG_PHONET is not set | ||
| 388 | # CONFIG_IEEE802154 is not set | ||
| 389 | # CONFIG_NET_SCHED is not set | ||
| 390 | # CONFIG_DCB is not set | ||
| 391 | |||
| 392 | # | ||
| 393 | # Network testing | ||
| 394 | # | ||
| 395 | # CONFIG_NET_PKTGEN is not set | ||
| 396 | # CONFIG_HAMRADIO is not set | ||
| 397 | # CONFIG_CAN is not set | ||
| 398 | # CONFIG_IRDA is not set | ||
| 399 | # CONFIG_BT is not set | ||
| 400 | # CONFIG_AF_RXRPC is not set | ||
| 401 | # CONFIG_WIRELESS is not set | ||
| 402 | # CONFIG_WIMAX is not set | ||
| 403 | # CONFIG_RFKILL is not set | ||
| 404 | # CONFIG_NET_9P is not set | ||
| 405 | |||
| 406 | # | ||
| 407 | # Device Drivers | ||
| 408 | # | ||
| 409 | |||
| 410 | # | ||
| 411 | # Generic Driver Options | ||
| 412 | # | ||
| 413 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
| 414 | CONFIG_STANDALONE=y | ||
| 415 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
| 416 | CONFIG_FW_LOADER=y | ||
| 417 | CONFIG_FIRMWARE_IN_KERNEL=y | ||
| 418 | CONFIG_EXTRA_FIRMWARE="" | ||
| 419 | # CONFIG_SYS_HYPERVISOR is not set | ||
| 420 | # CONFIG_CONNECTOR is not set | ||
| 421 | CONFIG_MTD=y | ||
| 422 | # CONFIG_MTD_DEBUG is not set | ||
| 423 | # CONFIG_MTD_CONCAT is not set | ||
| 424 | CONFIG_MTD_PARTITIONS=y | ||
| 425 | # CONFIG_MTD_TESTS is not set | ||
| 426 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
| 427 | CONFIG_MTD_CMDLINE_PARTS=y | ||
| 428 | # CONFIG_MTD_AFS_PARTS is not set | ||
| 429 | # CONFIG_MTD_AR7_PARTS is not set | ||
| 430 | |||
| 431 | # | ||
| 432 | # User Modules And Translation Layers | ||
| 433 | # | ||
| 434 | CONFIG_MTD_CHAR=y | ||
| 435 | CONFIG_MTD_BLKDEVS=y | ||
| 436 | CONFIG_MTD_BLOCK=y | ||
| 437 | # CONFIG_FTL is not set | ||
| 438 | # CONFIG_NFTL is not set | ||
| 439 | # CONFIG_INFTL is not set | ||
| 440 | # CONFIG_RFD_FTL is not set | ||
| 441 | # CONFIG_SSFDC is not set | ||
| 442 | # CONFIG_MTD_OOPS is not set | ||
| 443 | |||
| 444 | # | ||
| 445 | # RAM/ROM/Flash chip drivers | ||
| 446 | # | ||
| 447 | CONFIG_MTD_CFI=y | ||
| 448 | # CONFIG_MTD_JEDECPROBE is not set | ||
| 449 | CONFIG_MTD_GEN_PROBE=y | ||
| 450 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
| 451 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
| 452 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
| 453 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
| 454 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
| 455 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
| 456 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
| 457 | CONFIG_MTD_CFI_I1=y | ||
| 458 | CONFIG_MTD_CFI_I2=y | ||
| 459 | # CONFIG_MTD_CFI_I4 is not set | ||
| 460 | # CONFIG_MTD_CFI_I8 is not set | ||
| 461 | CONFIG_MTD_CFI_INTELEXT=y | ||
| 462 | # CONFIG_MTD_CFI_AMDSTD is not set | ||
| 463 | # CONFIG_MTD_CFI_STAA is not set | ||
| 464 | CONFIG_MTD_CFI_UTIL=y | ||
| 465 | CONFIG_MTD_RAM=y | ||
| 466 | # CONFIG_MTD_ROM is not set | ||
| 467 | # CONFIG_MTD_ABSENT is not set | ||
| 468 | |||
| 469 | # | ||
| 470 | # Mapping drivers for chip access | ||
| 471 | # | ||
| 472 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
| 473 | CONFIG_MTD_PHYSMAP=y | ||
| 474 | # CONFIG_MTD_PHYSMAP_COMPAT is not set | ||
| 475 | # CONFIG_MTD_ARM_INTEGRATOR is not set | ||
| 476 | CONFIG_MTD_PLATRAM=y | ||
| 477 | |||
| 478 | # | ||
| 479 | # Self-contained MTD device drivers | ||
| 480 | # | ||
| 481 | # CONFIG_MTD_SLRAM is not set | ||
| 482 | # CONFIG_MTD_PHRAM is not set | ||
| 483 | # CONFIG_MTD_MTDRAM is not set | ||
| 484 | # CONFIG_MTD_BLOCK2MTD is not set | ||
| 485 | |||
| 486 | # | ||
| 487 | # Disk-On-Chip Device Drivers | ||
| 488 | # | ||
| 489 | # CONFIG_MTD_DOC2000 is not set | ||
| 490 | # CONFIG_MTD_DOC2001 is not set | ||
| 491 | # CONFIG_MTD_DOC2001PLUS is not set | ||
| 492 | CONFIG_MTD_NAND=y | ||
| 493 | # CONFIG_MTD_NAND_VERIFY_WRITE is not set | ||
| 494 | # CONFIG_MTD_NAND_ECC_SMC is not set | ||
| 495 | # CONFIG_MTD_NAND_MUSEUM_IDS is not set | ||
| 496 | # CONFIG_MTD_NAND_GPIO is not set | ||
| 497 | CONFIG_MTD_NAND_IDS=y | ||
| 498 | # CONFIG_MTD_NAND_DISKONCHIP is not set | ||
| 499 | CONFIG_MTD_NAND_ATMEL=y | ||
| 500 | CONFIG_MTD_NAND_ATMEL_ECC_HW=y | ||
| 501 | # CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set | ||
| 502 | # CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set | ||
| 503 | # CONFIG_MTD_NAND_NANDSIM is not set | ||
| 504 | # CONFIG_MTD_NAND_PLATFORM is not set | ||
| 505 | # CONFIG_MTD_ALAUDA is not set | ||
| 506 | # CONFIG_MTD_ONENAND is not set | ||
| 507 | |||
| 508 | # | ||
| 509 | # LPDDR flash memory drivers | ||
| 510 | # | ||
| 511 | # CONFIG_MTD_LPDDR is not set | ||
| 512 | |||
| 513 | # | ||
| 514 | # UBI - Unsorted block images | ||
| 515 | # | ||
| 516 | # CONFIG_MTD_UBI is not set | ||
| 517 | # CONFIG_PARPORT is not set | ||
| 518 | CONFIG_BLK_DEV=y | ||
| 519 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
| 520 | CONFIG_BLK_DEV_LOOP=y | ||
| 521 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
| 522 | CONFIG_BLK_DEV_NBD=y | ||
| 523 | # CONFIG_BLK_DEV_UB is not set | ||
| 524 | CONFIG_BLK_DEV_RAM=y | ||
| 525 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
| 526 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
| 527 | # CONFIG_BLK_DEV_XIP is not set | ||
| 528 | # CONFIG_CDROM_PKTCDVD is not set | ||
| 529 | # CONFIG_ATA_OVER_ETH is not set | ||
| 530 | # CONFIG_MG_DISK is not set | ||
| 531 | # CONFIG_MISC_DEVICES is not set | ||
| 532 | CONFIG_HAVE_IDE=y | ||
| 533 | # CONFIG_IDE is not set | ||
| 534 | |||
| 535 | # | ||
| 536 | # SCSI device support | ||
| 537 | # | ||
| 538 | # CONFIG_RAID_ATTRS is not set | ||
| 539 | CONFIG_SCSI=y | ||
| 540 | CONFIG_SCSI_DMA=y | ||
| 541 | # CONFIG_SCSI_TGT is not set | ||
| 542 | # CONFIG_SCSI_NETLINK is not set | ||
| 543 | CONFIG_SCSI_PROC_FS=y | ||
| 544 | |||
| 545 | # | ||
| 546 | # SCSI support type (disk, tape, CD-ROM) | ||
| 547 | # | ||
| 548 | CONFIG_BLK_DEV_SD=y | ||
| 549 | # CONFIG_CHR_DEV_ST is not set | ||
| 550 | # CONFIG_CHR_DEV_OSST is not set | ||
| 551 | # CONFIG_BLK_DEV_SR is not set | ||
| 552 | # CONFIG_CHR_DEV_SG is not set | ||
| 553 | # CONFIG_CHR_DEV_SCH is not set | ||
| 554 | CONFIG_SCSI_MULTI_LUN=y | ||
| 555 | # CONFIG_SCSI_CONSTANTS is not set | ||
| 556 | # CONFIG_SCSI_LOGGING is not set | ||
| 557 | # CONFIG_SCSI_SCAN_ASYNC is not set | ||
| 558 | CONFIG_SCSI_WAIT_SCAN=m | ||
| 559 | |||
| 560 | # | ||
| 561 | # SCSI Transports | ||
| 562 | # | ||
| 563 | # CONFIG_SCSI_SPI_ATTRS is not set | ||
| 564 | # CONFIG_SCSI_FC_ATTRS is not set | ||
| 565 | # CONFIG_SCSI_ISCSI_ATTRS is not set | ||
| 566 | # CONFIG_SCSI_SAS_LIBSAS is not set | ||
| 567 | # CONFIG_SCSI_SRP_ATTRS is not set | ||
| 568 | # CONFIG_SCSI_LOWLEVEL is not set | ||
| 569 | # CONFIG_SCSI_DH is not set | ||
| 570 | # CONFIG_SCSI_OSD_INITIATOR is not set | ||
| 571 | # CONFIG_ATA is not set | ||
| 572 | # CONFIG_MD is not set | ||
| 573 | CONFIG_NETDEVICES=y | ||
| 574 | # CONFIG_DUMMY is not set | ||
| 575 | # CONFIG_BONDING is not set | ||
| 576 | # CONFIG_MACVLAN is not set | ||
| 577 | # CONFIG_EQUALIZER is not set | ||
| 578 | # CONFIG_TUN is not set | ||
| 579 | # CONFIG_VETH is not set | ||
| 580 | CONFIG_PHYLIB=y | ||
| 581 | |||
| 582 | # | ||
| 583 | # MII PHY device drivers | ||
| 584 | # | ||
| 585 | # CONFIG_MARVELL_PHY is not set | ||
| 586 | # CONFIG_DAVICOM_PHY is not set | ||
| 587 | # CONFIG_QSEMI_PHY is not set | ||
| 588 | # CONFIG_LXT_PHY is not set | ||
| 589 | # CONFIG_CICADA_PHY is not set | ||
| 590 | # CONFIG_VITESSE_PHY is not set | ||
| 591 | CONFIG_SMSC_PHY=y | ||
| 592 | # CONFIG_BROADCOM_PHY is not set | ||
| 593 | # CONFIG_ICPLUS_PHY is not set | ||
| 594 | # CONFIG_REALTEK_PHY is not set | ||
| 595 | # CONFIG_NATIONAL_PHY is not set | ||
| 596 | # CONFIG_STE10XP is not set | ||
| 597 | # CONFIG_LSI_ET1011C_PHY is not set | ||
| 598 | # CONFIG_FIXED_PHY is not set | ||
| 599 | # CONFIG_MDIO_BITBANG is not set | ||
| 600 | CONFIG_NET_ETHERNET=y | ||
| 601 | CONFIG_MII=y | ||
| 602 | CONFIG_MACB=y | ||
| 603 | # CONFIG_AX88796 is not set | ||
| 604 | # CONFIG_SMC91X is not set | ||
| 605 | # CONFIG_DM9000 is not set | ||
| 606 | # CONFIG_ETHOC is not set | ||
| 607 | # CONFIG_SMC911X is not set | ||
| 608 | # CONFIG_SMSC911X is not set | ||
| 609 | # CONFIG_DNET is not set | ||
| 610 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
| 611 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
| 612 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
| 613 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
| 614 | # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set | ||
| 615 | # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set | ||
| 616 | # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set | ||
| 617 | # CONFIG_B44 is not set | ||
| 618 | # CONFIG_KS8842 is not set | ||
| 619 | # CONFIG_NETDEV_1000 is not set | ||
| 620 | # CONFIG_NETDEV_10000 is not set | ||
| 621 | |||
| 622 | # | ||
| 623 | # Wireless LAN | ||
| 624 | # | ||
| 625 | # CONFIG_WLAN_PRE80211 is not set | ||
| 626 | # CONFIG_WLAN_80211 is not set | ||
| 627 | |||
| 628 | # | ||
| 629 | # Enable WiMAX (Networking options) to see the WiMAX drivers | ||
| 630 | # | ||
| 631 | |||
| 632 | # | ||
| 633 | # USB Network Adapters | ||
| 634 | # | ||
| 635 | # CONFIG_USB_CATC is not set | ||
| 636 | # CONFIG_USB_KAWETH is not set | ||
| 637 | # CONFIG_USB_PEGASUS is not set | ||
| 638 | # CONFIG_USB_RTL8150 is not set | ||
| 639 | # CONFIG_USB_USBNET is not set | ||
| 640 | # CONFIG_WAN is not set | ||
| 641 | CONFIG_PPP=y | ||
| 642 | # CONFIG_PPP_MULTILINK is not set | ||
| 643 | # CONFIG_PPP_FILTER is not set | ||
| 644 | CONFIG_PPP_ASYNC=y | ||
| 645 | # CONFIG_PPP_SYNC_TTY is not set | ||
| 646 | CONFIG_PPP_DEFLATE=y | ||
| 647 | CONFIG_PPP_BSDCOMP=y | ||
| 648 | # CONFIG_PPP_MPPE is not set | ||
| 649 | # CONFIG_PPPOE is not set | ||
| 650 | # CONFIG_PPPOL2TP is not set | ||
| 651 | # CONFIG_SLIP is not set | ||
| 652 | CONFIG_SLHC=y | ||
| 653 | # CONFIG_NETCONSOLE is not set | ||
| 654 | # CONFIG_NETPOLL is not set | ||
| 655 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
| 656 | # CONFIG_ISDN is not set | ||
| 657 | |||
| 658 | # | ||
| 659 | # Input device support | ||
| 660 | # | ||
| 661 | CONFIG_INPUT=y | ||
| 662 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
| 663 | # CONFIG_INPUT_POLLDEV is not set | ||
| 664 | |||
| 665 | # | ||
| 666 | # Userland interfaces | ||
| 667 | # | ||
| 668 | CONFIG_INPUT_MOUSEDEV=y | ||
| 669 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
| 670 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
| 671 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
| 672 | # CONFIG_INPUT_JOYDEV is not set | ||
| 673 | # CONFIG_INPUT_EVDEV is not set | ||
| 674 | # CONFIG_INPUT_EVBUG is not set | ||
| 675 | |||
| 676 | # | ||
| 677 | # Input Device Drivers | ||
| 678 | # | ||
| 679 | CONFIG_INPUT_KEYBOARD=y | ||
| 680 | # CONFIG_KEYBOARD_ATKBD is not set | ||
| 681 | # CONFIG_KEYBOARD_LKKBD is not set | ||
| 682 | CONFIG_KEYBOARD_GPIO=y | ||
| 683 | # CONFIG_KEYBOARD_MATRIX is not set | ||
| 684 | # CONFIG_KEYBOARD_LM8323 is not set | ||
| 685 | # CONFIG_KEYBOARD_NEWTON is not set | ||
| 686 | # CONFIG_KEYBOARD_STOWAWAY is not set | ||
| 687 | # CONFIG_KEYBOARD_SUNKBD is not set | ||
| 688 | # CONFIG_KEYBOARD_XTKBD is not set | ||
| 689 | # CONFIG_INPUT_MOUSE is not set | ||
| 690 | # CONFIG_INPUT_JOYSTICK is not set | ||
| 691 | # CONFIG_INPUT_TABLET is not set | ||
| 692 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
| 693 | # CONFIG_INPUT_MISC is not set | ||
| 694 | |||
| 695 | # | ||
| 696 | # Hardware I/O ports | ||
| 697 | # | ||
| 698 | # CONFIG_SERIO is not set | ||
| 699 | # CONFIG_GAMEPORT is not set | ||
| 700 | |||
| 701 | # | ||
| 702 | # Character devices | ||
| 703 | # | ||
| 704 | CONFIG_VT=y | ||
| 705 | CONFIG_CONSOLE_TRANSLATIONS=y | ||
| 706 | CONFIG_VT_CONSOLE=y | ||
| 707 | CONFIG_HW_CONSOLE=y | ||
| 708 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | ||
| 709 | CONFIG_DEVKMEM=y | ||
| 710 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
| 711 | |||
| 712 | # | ||
| 713 | # Serial drivers | ||
| 714 | # | ||
| 715 | # CONFIG_SERIAL_8250 is not set | ||
| 716 | |||
| 717 | # | ||
| 718 | # Non-8250 serial port support | ||
| 719 | # | ||
| 720 | CONFIG_SERIAL_ATMEL=y | ||
| 721 | CONFIG_SERIAL_ATMEL_CONSOLE=y | ||
| 722 | CONFIG_SERIAL_ATMEL_PDC=y | ||
| 723 | # CONFIG_SERIAL_ATMEL_TTYAT is not set | ||
| 724 | CONFIG_SERIAL_CORE=y | ||
| 725 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
| 726 | CONFIG_UNIX98_PTYS=y | ||
| 727 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
| 728 | CONFIG_LEGACY_PTYS=y | ||
| 729 | CONFIG_LEGACY_PTY_COUNT=32 | ||
| 730 | # CONFIG_IPMI_HANDLER is not set | ||
| 731 | # CONFIG_HW_RANDOM is not set | ||
| 732 | # CONFIG_R3964 is not set | ||
| 733 | # CONFIG_RAW_DRIVER is not set | ||
| 734 | # CONFIG_TCG_TPM is not set | ||
| 735 | CONFIG_I2C=y | ||
| 736 | CONFIG_I2C_BOARDINFO=y | ||
| 737 | CONFIG_I2C_CHARDEV=y | ||
| 738 | CONFIG_I2C_HELPER_AUTO=y | ||
| 739 | CONFIG_I2C_ALGOBIT=y | ||
| 740 | |||
| 741 | # | ||
| 742 | # I2C Hardware Bus support | ||
| 743 | # | ||
| 744 | |||
| 745 | # | ||
| 746 | # I2C system bus drivers (mostly embedded / system-on-chip) | ||
| 747 | # | ||
| 748 | # CONFIG_I2C_DESIGNWARE is not set | ||
| 749 | CONFIG_I2C_GPIO=y | ||
| 750 | # CONFIG_I2C_OCORES is not set | ||
| 751 | # CONFIG_I2C_SIMTEC is not set | ||
| 752 | |||
| 753 | # | ||
| 754 | # External I2C/SMBus adapter drivers | ||
| 755 | # | ||
| 756 | # CONFIG_I2C_PARPORT_LIGHT is not set | ||
| 757 | # CONFIG_I2C_TAOS_EVM is not set | ||
| 758 | # CONFIG_I2C_TINY_USB is not set | ||
| 759 | |||
| 760 | # | ||
| 761 | # Other I2C/SMBus bus drivers | ||
| 762 | # | ||
| 763 | # CONFIG_I2C_PCA_PLATFORM is not set | ||
| 764 | # CONFIG_I2C_STUB is not set | ||
| 765 | |||
| 766 | # | ||
| 767 | # Miscellaneous I2C Chip support | ||
| 768 | # | ||
| 769 | # CONFIG_DS1682 is not set | ||
| 770 | # CONFIG_SENSORS_PCF8574 is not set | ||
| 771 | # CONFIG_PCF8575 is not set | ||
| 772 | # CONFIG_SENSORS_PCA9539 is not set | ||
| 773 | # CONFIG_SENSORS_TSL2550 is not set | ||
| 774 | # CONFIG_I2C_DEBUG_CORE is not set | ||
| 775 | # CONFIG_I2C_DEBUG_ALGO is not set | ||
| 776 | # CONFIG_I2C_DEBUG_BUS is not set | ||
| 777 | # CONFIG_I2C_DEBUG_CHIP is not set | ||
| 778 | # CONFIG_SPI is not set | ||
| 779 | CONFIG_ARCH_REQUIRE_GPIOLIB=y | ||
| 780 | CONFIG_GPIOLIB=y | ||
| 781 | CONFIG_GPIO_SYSFS=y | ||
| 782 | |||
| 783 | # | ||
| 784 | # Memory mapped GPIO expanders: | ||
| 785 | # | ||
| 786 | |||
| 787 | # | ||
| 788 | # I2C GPIO expanders: | ||
| 789 | # | ||
| 790 | # CONFIG_GPIO_MAX732X is not set | ||
| 791 | # CONFIG_GPIO_PCA953X is not set | ||
| 792 | # CONFIG_GPIO_PCF857X is not set | ||
| 793 | |||
| 794 | # | ||
| 795 | # PCI GPIO expanders: | ||
| 796 | # | ||
| 797 | |||
| 798 | # | ||
| 799 | # SPI GPIO expanders: | ||
| 800 | # | ||
| 801 | # CONFIG_W1 is not set | ||
| 802 | # CONFIG_POWER_SUPPLY is not set | ||
| 803 | # CONFIG_HWMON is not set | ||
| 804 | # CONFIG_THERMAL is not set | ||
| 805 | # CONFIG_THERMAL_HWMON is not set | ||
| 806 | CONFIG_WATCHDOG=y | ||
| 807 | CONFIG_WATCHDOG_NOWAYOUT=y | ||
| 808 | |||
| 809 | # | ||
| 810 | # Watchdog Device Drivers | ||
| 811 | # | ||
| 812 | # CONFIG_SOFT_WATCHDOG is not set | ||
| 813 | CONFIG_AT91SAM9X_WATCHDOG=y | ||
| 814 | |||
| 815 | # | ||
| 816 | # USB-based Watchdog Cards | ||
| 817 | # | ||
| 818 | # CONFIG_USBPCWATCHDOG is not set | ||
| 819 | CONFIG_SSB_POSSIBLE=y | ||
| 820 | |||
| 821 | # | ||
| 822 | # Sonics Silicon Backplane | ||
| 823 | # | ||
| 824 | # CONFIG_SSB is not set | ||
| 825 | |||
| 826 | # | ||
| 827 | # Multifunction device drivers | ||
| 828 | # | ||
| 829 | # CONFIG_MFD_CORE is not set | ||
| 830 | # CONFIG_MFD_SM501 is not set | ||
| 831 | # CONFIG_MFD_ASIC3 is not set | ||
| 832 | # CONFIG_HTC_EGPIO is not set | ||
| 833 | # CONFIG_HTC_PASIC3 is not set | ||
| 834 | # CONFIG_TPS65010 is not set | ||
| 835 | # CONFIG_TWL4030_CORE is not set | ||
| 836 | # CONFIG_MFD_TMIO is not set | ||
| 837 | # CONFIG_MFD_T7L66XB is not set | ||
| 838 | # CONFIG_MFD_TC6387XB is not set | ||
| 839 | # CONFIG_MFD_TC6393XB is not set | ||
| 840 | # CONFIG_PMIC_DA903X is not set | ||
| 841 | # CONFIG_MFD_WM8400 is not set | ||
| 842 | # CONFIG_MFD_WM8350_I2C is not set | ||
| 843 | # CONFIG_MFD_PCF50633 is not set | ||
| 844 | # CONFIG_AB3100_CORE is not set | ||
| 845 | # CONFIG_MEDIA_SUPPORT is not set | ||
| 846 | |||
| 847 | # | ||
| 848 | # Graphics support | ||
| 849 | # | ||
| 850 | # CONFIG_VGASTATE is not set | ||
| 851 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
| 852 | # CONFIG_FB is not set | ||
| 853 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
| 854 | |||
| 855 | # | ||
| 856 | # Display device support | ||
| 857 | # | ||
| 858 | # CONFIG_DISPLAY_SUPPORT is not set | ||
| 859 | |||
| 860 | # | ||
| 861 | # Console display driver support | ||
| 862 | # | ||
| 863 | # CONFIG_VGA_CONSOLE is not set | ||
| 864 | CONFIG_DUMMY_CONSOLE=y | ||
| 865 | # CONFIG_SOUND is not set | ||
| 866 | # CONFIG_HID_SUPPORT is not set | ||
| 867 | CONFIG_USB_SUPPORT=y | ||
| 868 | CONFIG_USB_ARCH_HAS_HCD=y | ||
| 869 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
| 870 | # CONFIG_USB_ARCH_HAS_EHCI is not set | ||
| 871 | CONFIG_USB=y | ||
| 872 | # CONFIG_USB_DEBUG is not set | ||
| 873 | # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set | ||
| 874 | |||
| 875 | # | ||
| 876 | # Miscellaneous USB options | ||
| 877 | # | ||
| 878 | # CONFIG_USB_DEVICEFS is not set | ||
| 879 | # CONFIG_USB_DEVICE_CLASS is not set | ||
| 880 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
| 881 | # CONFIG_USB_OTG is not set | ||
| 882 | # CONFIG_USB_MON is not set | ||
| 883 | # CONFIG_USB_WUSB is not set | ||
| 884 | # CONFIG_USB_WUSB_CBAF is not set | ||
| 885 | |||
| 886 | # | ||
| 887 | # USB Host Controller Drivers | ||
| 888 | # | ||
| 889 | # CONFIG_USB_C67X00_HCD is not set | ||
| 890 | # CONFIG_USB_OXU210HP_HCD is not set | ||
| 891 | # CONFIG_USB_ISP116X_HCD is not set | ||
| 892 | # CONFIG_USB_ISP1760_HCD is not set | ||
| 893 | CONFIG_USB_OHCI_HCD=y | ||
| 894 | # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set | ||
| 895 | # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set | ||
| 896 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
| 897 | # CONFIG_USB_SL811_HCD is not set | ||
| 898 | # CONFIG_USB_R8A66597_HCD is not set | ||
| 899 | # CONFIG_USB_HWA_HCD is not set | ||
| 900 | # CONFIG_USB_MUSB_HDRC is not set | ||
| 901 | # CONFIG_USB_GADGET_MUSB_HDRC is not set | ||
| 902 | |||
| 903 | # | ||
| 904 | # USB Device Class drivers | ||
| 905 | # | ||
| 906 | # CONFIG_USB_ACM is not set | ||
| 907 | # CONFIG_USB_PRINTER is not set | ||
| 908 | # CONFIG_USB_WDM is not set | ||
| 909 | # CONFIG_USB_TMC is not set | ||
| 910 | |||
| 911 | # | ||
| 912 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may | ||
| 913 | # | ||
| 914 | |||
| 915 | # | ||
| 916 | # also be needed; see USB_STORAGE Help for more info | ||
| 917 | # | ||
| 918 | CONFIG_USB_STORAGE=y | ||
| 919 | # CONFIG_USB_STORAGE_DEBUG is not set | ||
| 920 | # CONFIG_USB_STORAGE_DATAFAB is not set | ||
| 921 | # CONFIG_USB_STORAGE_FREECOM is not set | ||
| 922 | # CONFIG_USB_STORAGE_ISD200 is not set | ||
| 923 | # CONFIG_USB_STORAGE_USBAT is not set | ||
| 924 | # CONFIG_USB_STORAGE_SDDR09 is not set | ||
| 925 | # CONFIG_USB_STORAGE_SDDR55 is not set | ||
| 926 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | ||
| 927 | # CONFIG_USB_STORAGE_ALAUDA is not set | ||
| 928 | # CONFIG_USB_STORAGE_ONETOUCH is not set | ||
| 929 | # CONFIG_USB_STORAGE_KARMA is not set | ||
| 930 | # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set | ||
| 931 | # CONFIG_USB_LIBUSUAL is not set | ||
| 932 | |||
| 933 | # | ||
| 934 | # USB Imaging devices | ||
| 935 | # | ||
| 936 | # CONFIG_USB_MDC800 is not set | ||
| 937 | # CONFIG_USB_MICROTEK is not set | ||
| 938 | |||
| 939 | # | ||
| 940 | # USB port drivers | ||
| 941 | # | ||
| 942 | # CONFIG_USB_SERIAL is not set | ||
| 943 | |||
| 944 | # | ||
| 945 | # USB Miscellaneous drivers | ||
| 946 | # | ||
| 947 | # CONFIG_USB_EMI62 is not set | ||
| 948 | # CONFIG_USB_EMI26 is not set | ||
| 949 | # CONFIG_USB_ADUTUX is not set | ||
| 950 | # CONFIG_USB_SEVSEG is not set | ||
| 951 | # CONFIG_USB_RIO500 is not set | ||
| 952 | # CONFIG_USB_LEGOTOWER is not set | ||
| 953 | # CONFIG_USB_LCD is not set | ||
| 954 | # CONFIG_USB_BERRY_CHARGE is not set | ||
| 955 | # CONFIG_USB_LED is not set | ||
| 956 | # CONFIG_USB_CYPRESS_CY7C63 is not set | ||
| 957 | # CONFIG_USB_CYTHERM is not set | ||
| 958 | # CONFIG_USB_IDMOUSE is not set | ||
| 959 | # CONFIG_USB_FTDI_ELAN is not set | ||
| 960 | # CONFIG_USB_APPLEDISPLAY is not set | ||
| 961 | # CONFIG_USB_LD is not set | ||
| 962 | # CONFIG_USB_TRANCEVIBRATOR is not set | ||
| 963 | # CONFIG_USB_IOWARRIOR is not set | ||
| 964 | # CONFIG_USB_ISIGHTFW is not set | ||
| 965 | # CONFIG_USB_VST is not set | ||
| 966 | CONFIG_USB_GADGET=y | ||
| 967 | # CONFIG_USB_GADGET_DEBUG_FILES is not set | ||
| 968 | CONFIG_USB_GADGET_VBUS_DRAW=2 | ||
| 969 | CONFIG_USB_GADGET_SELECTED=y | ||
| 970 | CONFIG_USB_GADGET_AT91=y | ||
| 971 | CONFIG_USB_AT91=y | ||
| 972 | # CONFIG_USB_GADGET_ATMEL_USBA is not set | ||
| 973 | # CONFIG_USB_GADGET_FSL_USB2 is not set | ||
| 974 | # CONFIG_USB_GADGET_LH7A40X is not set | ||
| 975 | # CONFIG_USB_GADGET_OMAP is not set | ||
| 976 | # CONFIG_USB_GADGET_PXA25X is not set | ||
| 977 | # CONFIG_USB_GADGET_PXA27X is not set | ||
| 978 | # CONFIG_USB_GADGET_S3C_HSOTG is not set | ||
| 979 | # CONFIG_USB_GADGET_IMX is not set | ||
| 980 | # CONFIG_USB_GADGET_S3C2410 is not set | ||
| 981 | # CONFIG_USB_GADGET_M66592 is not set | ||
| 982 | # CONFIG_USB_GADGET_AMD5536UDC is not set | ||
| 983 | # CONFIG_USB_GADGET_FSL_QE is not set | ||
| 984 | # CONFIG_USB_GADGET_CI13XXX is not set | ||
| 985 | # CONFIG_USB_GADGET_NET2280 is not set | ||
| 986 | # CONFIG_USB_GADGET_GOKU is not set | ||
| 987 | # CONFIG_USB_GADGET_LANGWELL is not set | ||
| 988 | # CONFIG_USB_GADGET_DUMMY_HCD is not set | ||
| 989 | # CONFIG_USB_GADGET_DUALSPEED is not set | ||
| 990 | # CONFIG_USB_ZERO is not set | ||
| 991 | # CONFIG_USB_AUDIO is not set | ||
| 992 | CONFIG_USB_ETH=y | ||
| 993 | CONFIG_USB_ETH_RNDIS=y | ||
| 994 | # CONFIG_USB_GADGETFS is not set | ||
| 995 | # CONFIG_USB_FILE_STORAGE is not set | ||
| 996 | # CONFIG_USB_G_SERIAL is not set | ||
| 997 | # CONFIG_USB_MIDI_GADGET is not set | ||
| 998 | # CONFIG_USB_G_PRINTER is not set | ||
| 999 | # CONFIG_USB_CDC_COMPOSITE is not set | ||
| 1000 | |||
| 1001 | # | ||
| 1002 | # OTG and related infrastructure | ||
| 1003 | # | ||
| 1004 | # CONFIG_USB_GPIO_VBUS is not set | ||
| 1005 | # CONFIG_NOP_USB_XCEIV is not set | ||
| 1006 | CONFIG_MMC=y | ||
| 1007 | # CONFIG_MMC_DEBUG is not set | ||
| 1008 | # CONFIG_MMC_UNSAFE_RESUME is not set | ||
| 1009 | |||
| 1010 | # | ||
| 1011 | # MMC/SD/SDIO Card Drivers | ||
| 1012 | # | ||
| 1013 | CONFIG_MMC_BLOCK=y | ||
| 1014 | CONFIG_MMC_BLOCK_BOUNCE=y | ||
| 1015 | # CONFIG_SDIO_UART is not set | ||
| 1016 | # CONFIG_MMC_TEST is not set | ||
| 1017 | |||
| 1018 | # | ||
| 1019 | # MMC/SD/SDIO Host Controller Drivers | ||
| 1020 | # | ||
| 1021 | # CONFIG_MMC_SDHCI is not set | ||
| 1022 | CONFIG_MMC_AT91=y | ||
| 1023 | # CONFIG_MEMSTICK is not set | ||
| 1024 | # CONFIG_ACCESSIBILITY is not set | ||
| 1025 | CONFIG_NEW_LEDS=y | ||
| 1026 | CONFIG_LEDS_CLASS=y | ||
| 1027 | |||
| 1028 | # | ||
| 1029 | # LED drivers | ||
| 1030 | # | ||
| 1031 | # CONFIG_LEDS_PCA9532 is not set | ||
| 1032 | CONFIG_LEDS_GPIO=y | ||
| 1033 | CONFIG_LEDS_GPIO_PLATFORM=y | ||
| 1034 | # CONFIG_LEDS_LP3944 is not set | ||
| 1035 | # CONFIG_LEDS_PCA955X is not set | ||
| 1036 | # CONFIG_LEDS_BD2802 is not set | ||
| 1037 | |||
| 1038 | # | ||
| 1039 | # LED Triggers | ||
| 1040 | # | ||
| 1041 | CONFIG_LEDS_TRIGGERS=y | ||
| 1042 | CONFIG_LEDS_TRIGGER_TIMER=y | ||
| 1043 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
| 1044 | # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set | ||
| 1045 | CONFIG_LEDS_TRIGGER_GPIO=y | ||
| 1046 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=y | ||
| 1047 | |||
| 1048 | # | ||
| 1049 | # iptables trigger is under Netfilter config (LED target) | ||
| 1050 | # | ||
| 1051 | CONFIG_RTC_LIB=y | ||
| 1052 | CONFIG_RTC_CLASS=y | ||
| 1053 | # CONFIG_RTC_HCTOSYS is not set | ||
| 1054 | # CONFIG_RTC_DEBUG is not set | ||
| 1055 | |||
| 1056 | # | ||
| 1057 | # RTC interfaces | ||
| 1058 | # | ||
| 1059 | CONFIG_RTC_INTF_SYSFS=y | ||
| 1060 | CONFIG_RTC_INTF_PROC=y | ||
| 1061 | CONFIG_RTC_INTF_DEV=y | ||
| 1062 | # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set | ||
| 1063 | # CONFIG_RTC_DRV_TEST is not set | ||
| 1064 | |||
| 1065 | # | ||
| 1066 | # I2C RTC drivers | ||
| 1067 | # | ||
| 1068 | CONFIG_RTC_DRV_DS1307=y | ||
| 1069 | # CONFIG_RTC_DRV_DS1374 is not set | ||
| 1070 | # CONFIG_RTC_DRV_DS1672 is not set | ||
| 1071 | # CONFIG_RTC_DRV_MAX6900 is not set | ||
| 1072 | # CONFIG_RTC_DRV_RS5C372 is not set | ||
| 1073 | # CONFIG_RTC_DRV_ISL1208 is not set | ||
| 1074 | # CONFIG_RTC_DRV_X1205 is not set | ||
| 1075 | # CONFIG_RTC_DRV_PCF8563 is not set | ||
| 1076 | # CONFIG_RTC_DRV_PCF8583 is not set | ||
| 1077 | # CONFIG_RTC_DRV_M41T80 is not set | ||
| 1078 | # CONFIG_RTC_DRV_S35390A is not set | ||
| 1079 | # CONFIG_RTC_DRV_FM3130 is not set | ||
| 1080 | # CONFIG_RTC_DRV_RX8581 is not set | ||
| 1081 | # CONFIG_RTC_DRV_RX8025 is not set | ||
| 1082 | |||
| 1083 | # | ||
| 1084 | # SPI RTC drivers | ||
| 1085 | # | ||
| 1086 | |||
| 1087 | # | ||
| 1088 | # Platform RTC drivers | ||
| 1089 | # | ||
| 1090 | # CONFIG_RTC_DRV_CMOS is not set | ||
| 1091 | # CONFIG_RTC_DRV_DS1286 is not set | ||
| 1092 | # CONFIG_RTC_DRV_DS1511 is not set | ||
| 1093 | # CONFIG_RTC_DRV_DS1553 is not set | ||
| 1094 | # CONFIG_RTC_DRV_DS1742 is not set | ||
| 1095 | # CONFIG_RTC_DRV_STK17TA8 is not set | ||
| 1096 | # CONFIG_RTC_DRV_M48T86 is not set | ||
| 1097 | # CONFIG_RTC_DRV_M48T35 is not set | ||
| 1098 | # CONFIG_RTC_DRV_M48T59 is not set | ||
| 1099 | # CONFIG_RTC_DRV_BQ4802 is not set | ||
| 1100 | # CONFIG_RTC_DRV_V3020 is not set | ||
| 1101 | |||
| 1102 | # | ||
| 1103 | # on-CPU RTC drivers | ||
| 1104 | # | ||
| 1105 | # CONFIG_RTC_DRV_AT91SAM9 is not set | ||
| 1106 | # CONFIG_DMADEVICES is not set | ||
| 1107 | # CONFIG_AUXDISPLAY is not set | ||
| 1108 | # CONFIG_REGULATOR is not set | ||
| 1109 | # CONFIG_UIO is not set | ||
| 1110 | # CONFIG_STAGING is not set | ||
| 1111 | |||
| 1112 | # | ||
| 1113 | # File systems | ||
| 1114 | # | ||
| 1115 | CONFIG_EXT2_FS=y | ||
| 1116 | # CONFIG_EXT2_FS_XATTR is not set | ||
| 1117 | # CONFIG_EXT2_FS_XIP is not set | ||
| 1118 | CONFIG_EXT3_FS=y | ||
| 1119 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
| 1120 | # CONFIG_EXT3_FS_XATTR is not set | ||
| 1121 | # CONFIG_EXT4_FS is not set | ||
| 1122 | CONFIG_JBD=y | ||
| 1123 | # CONFIG_REISERFS_FS is not set | ||
| 1124 | # CONFIG_JFS_FS is not set | ||
| 1125 | # CONFIG_FS_POSIX_ACL is not set | ||
| 1126 | # CONFIG_XFS_FS is not set | ||
| 1127 | # CONFIG_GFS2_FS is not set | ||
| 1128 | # CONFIG_OCFS2_FS is not set | ||
| 1129 | # CONFIG_BTRFS_FS is not set | ||
| 1130 | CONFIG_FILE_LOCKING=y | ||
| 1131 | CONFIG_FSNOTIFY=y | ||
| 1132 | CONFIG_DNOTIFY=y | ||
| 1133 | CONFIG_INOTIFY=y | ||
| 1134 | CONFIG_INOTIFY_USER=y | ||
| 1135 | # CONFIG_QUOTA is not set | ||
| 1136 | # CONFIG_AUTOFS_FS is not set | ||
| 1137 | CONFIG_AUTOFS4_FS=y | ||
| 1138 | # CONFIG_FUSE_FS is not set | ||
| 1139 | |||
| 1140 | # | ||
| 1141 | # Caches | ||
| 1142 | # | ||
| 1143 | # CONFIG_FSCACHE is not set | ||
| 1144 | |||
| 1145 | # | ||
| 1146 | # CD-ROM/DVD Filesystems | ||
| 1147 | # | ||
| 1148 | # CONFIG_ISO9660_FS is not set | ||
| 1149 | # CONFIG_UDF_FS is not set | ||
| 1150 | |||
| 1151 | # | ||
| 1152 | # DOS/FAT/NT Filesystems | ||
| 1153 | # | ||
| 1154 | CONFIG_FAT_FS=y | ||
| 1155 | CONFIG_MSDOS_FS=y | ||
| 1156 | CONFIG_VFAT_FS=y | ||
| 1157 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
| 1158 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
| 1159 | # CONFIG_NTFS_FS is not set | ||
| 1160 | |||
| 1161 | # | ||
| 1162 | # Pseudo filesystems | ||
| 1163 | # | ||
| 1164 | CONFIG_PROC_FS=y | ||
| 1165 | CONFIG_PROC_SYSCTL=y | ||
| 1166 | CONFIG_PROC_PAGE_MONITOR=y | ||
| 1167 | CONFIG_SYSFS=y | ||
| 1168 | CONFIG_TMPFS=y | ||
| 1169 | # CONFIG_TMPFS_POSIX_ACL is not set | ||
| 1170 | # CONFIG_HUGETLB_PAGE is not set | ||
| 1171 | # CONFIG_CONFIGFS_FS is not set | ||
| 1172 | CONFIG_MISC_FILESYSTEMS=y | ||
| 1173 | # CONFIG_ADFS_FS is not set | ||
| 1174 | # CONFIG_AFFS_FS is not set | ||
| 1175 | # CONFIG_HFS_FS is not set | ||
| 1176 | # CONFIG_HFSPLUS_FS is not set | ||
| 1177 | # CONFIG_BEFS_FS is not set | ||
| 1178 | # CONFIG_BFS_FS is not set | ||
| 1179 | # CONFIG_EFS_FS is not set | ||
| 1180 | CONFIG_JFFS2_FS=y | ||
| 1181 | CONFIG_JFFS2_FS_DEBUG=0 | ||
| 1182 | CONFIG_JFFS2_FS_WRITEBUFFER=y | ||
| 1183 | # CONFIG_JFFS2_FS_WBUF_VERIFY is not set | ||
| 1184 | CONFIG_JFFS2_SUMMARY=y | ||
| 1185 | # CONFIG_JFFS2_FS_XATTR is not set | ||
| 1186 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | ||
| 1187 | CONFIG_JFFS2_ZLIB=y | ||
| 1188 | # CONFIG_JFFS2_LZO is not set | ||
| 1189 | CONFIG_JFFS2_RTIME=y | ||
| 1190 | # CONFIG_JFFS2_RUBIN is not set | ||
| 1191 | CONFIG_CRAMFS=y | ||
| 1192 | # CONFIG_SQUASHFS is not set | ||
| 1193 | # CONFIG_VXFS_FS is not set | ||
| 1194 | CONFIG_MINIX_FS=y | ||
| 1195 | # CONFIG_OMFS_FS is not set | ||
| 1196 | # CONFIG_HPFS_FS is not set | ||
| 1197 | # CONFIG_QNX4FS_FS is not set | ||
| 1198 | # CONFIG_ROMFS_FS is not set | ||
| 1199 | # CONFIG_SYSV_FS is not set | ||
| 1200 | # CONFIG_UFS_FS is not set | ||
| 1201 | # CONFIG_NILFS2_FS is not set | ||
| 1202 | CONFIG_NETWORK_FILESYSTEMS=y | ||
| 1203 | CONFIG_NFS_FS=y | ||
| 1204 | CONFIG_NFS_V3=y | ||
| 1205 | # CONFIG_NFS_V3_ACL is not set | ||
| 1206 | # CONFIG_NFS_V4 is not set | ||
| 1207 | CONFIG_ROOT_NFS=y | ||
| 1208 | # CONFIG_NFSD is not set | ||
| 1209 | CONFIG_LOCKD=y | ||
| 1210 | CONFIG_LOCKD_V4=y | ||
| 1211 | CONFIG_NFS_COMMON=y | ||
| 1212 | CONFIG_SUNRPC=y | ||
| 1213 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
| 1214 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
| 1215 | # CONFIG_SMB_FS is not set | ||
| 1216 | # CONFIG_CIFS is not set | ||
| 1217 | # CONFIG_NCP_FS is not set | ||
| 1218 | # CONFIG_CODA_FS is not set | ||
| 1219 | # CONFIG_AFS_FS is not set | ||
| 1220 | |||
| 1221 | # | ||
| 1222 | # Partition Types | ||
| 1223 | # | ||
| 1224 | CONFIG_PARTITION_ADVANCED=y | ||
| 1225 | # CONFIG_ACORN_PARTITION is not set | ||
| 1226 | # CONFIG_OSF_PARTITION is not set | ||
| 1227 | # CONFIG_AMIGA_PARTITION is not set | ||
| 1228 | # CONFIG_ATARI_PARTITION is not set | ||
| 1229 | # CONFIG_MAC_PARTITION is not set | ||
| 1230 | CONFIG_MSDOS_PARTITION=y | ||
| 1231 | # CONFIG_BSD_DISKLABEL is not set | ||
| 1232 | # CONFIG_MINIX_SUBPARTITION is not set | ||
| 1233 | # CONFIG_SOLARIS_X86_PARTITION is not set | ||
| 1234 | # CONFIG_UNIXWARE_DISKLABEL is not set | ||
| 1235 | # CONFIG_LDM_PARTITION is not set | ||
| 1236 | # CONFIG_SGI_PARTITION is not set | ||
| 1237 | # CONFIG_ULTRIX_PARTITION is not set | ||
| 1238 | # CONFIG_SUN_PARTITION is not set | ||
| 1239 | # CONFIG_KARMA_PARTITION is not set | ||
| 1240 | # CONFIG_EFI_PARTITION is not set | ||
| 1241 | # CONFIG_SYSV68_PARTITION is not set | ||
| 1242 | CONFIG_NLS=y | ||
| 1243 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
| 1244 | CONFIG_NLS_CODEPAGE_437=y | ||
| 1245 | # CONFIG_NLS_CODEPAGE_737 is not set | ||
| 1246 | # CONFIG_NLS_CODEPAGE_775 is not set | ||
| 1247 | # CONFIG_NLS_CODEPAGE_850 is not set | ||
| 1248 | # CONFIG_NLS_CODEPAGE_852 is not set | ||
| 1249 | # CONFIG_NLS_CODEPAGE_855 is not set | ||
| 1250 | # CONFIG_NLS_CODEPAGE_857 is not set | ||
| 1251 | # CONFIG_NLS_CODEPAGE_860 is not set | ||
| 1252 | # CONFIG_NLS_CODEPAGE_861 is not set | ||
| 1253 | # CONFIG_NLS_CODEPAGE_862 is not set | ||
| 1254 | # CONFIG_NLS_CODEPAGE_863 is not set | ||
| 1255 | # CONFIG_NLS_CODEPAGE_864 is not set | ||
| 1256 | # CONFIG_NLS_CODEPAGE_865 is not set | ||
| 1257 | # CONFIG_NLS_CODEPAGE_866 is not set | ||
| 1258 | # CONFIG_NLS_CODEPAGE_869 is not set | ||
| 1259 | # CONFIG_NLS_CODEPAGE_936 is not set | ||
| 1260 | # CONFIG_NLS_CODEPAGE_950 is not set | ||
| 1261 | # CONFIG_NLS_CODEPAGE_932 is not set | ||
| 1262 | # CONFIG_NLS_CODEPAGE_949 is not set | ||
| 1263 | # CONFIG_NLS_CODEPAGE_874 is not set | ||
| 1264 | # CONFIG_NLS_ISO8859_8 is not set | ||
| 1265 | # CONFIG_NLS_CODEPAGE_1250 is not set | ||
| 1266 | # CONFIG_NLS_CODEPAGE_1251 is not set | ||
| 1267 | # CONFIG_NLS_ASCII is not set | ||
| 1268 | CONFIG_NLS_ISO8859_1=y | ||
| 1269 | # CONFIG_NLS_ISO8859_2 is not set | ||
| 1270 | # CONFIG_NLS_ISO8859_3 is not set | ||
| 1271 | # CONFIG_NLS_ISO8859_4 is not set | ||
| 1272 | # CONFIG_NLS_ISO8859_5 is not set | ||
| 1273 | # CONFIG_NLS_ISO8859_6 is not set | ||
| 1274 | # CONFIG_NLS_ISO8859_7 is not set | ||
| 1275 | # CONFIG_NLS_ISO8859_9 is not set | ||
| 1276 | # CONFIG_NLS_ISO8859_13 is not set | ||
| 1277 | # CONFIG_NLS_ISO8859_14 is not set | ||
| 1278 | # CONFIG_NLS_ISO8859_15 is not set | ||
| 1279 | # CONFIG_NLS_KOI8_R is not set | ||
| 1280 | # CONFIG_NLS_KOI8_U is not set | ||
| 1281 | CONFIG_NLS_UTF8=y | ||
| 1282 | # CONFIG_DLM is not set | ||
| 1283 | |||
| 1284 | # | ||
| 1285 | # Kernel hacking | ||
| 1286 | # | ||
| 1287 | # CONFIG_PRINTK_TIME is not set | ||
| 1288 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
| 1289 | CONFIG_ENABLE_MUST_CHECK=y | ||
| 1290 | CONFIG_FRAME_WARN=1024 | ||
| 1291 | # CONFIG_MAGIC_SYSRQ is not set | ||
| 1292 | # CONFIG_UNUSED_SYMBOLS is not set | ||
| 1293 | # CONFIG_DEBUG_FS is not set | ||
| 1294 | # CONFIG_HEADERS_CHECK is not set | ||
| 1295 | # CONFIG_DEBUG_KERNEL is not set | ||
| 1296 | # CONFIG_SLUB_DEBUG_ON is not set | ||
| 1297 | # CONFIG_SLUB_STATS is not set | ||
| 1298 | CONFIG_DEBUG_BUGVERBOSE=y | ||
| 1299 | CONFIG_DEBUG_MEMORY_INIT=y | ||
| 1300 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
| 1301 | # CONFIG_LATENCYTOP is not set | ||
| 1302 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set | ||
| 1303 | CONFIG_HAVE_FUNCTION_TRACER=y | ||
| 1304 | CONFIG_TRACING_SUPPORT=y | ||
| 1305 | # CONFIG_FTRACE is not set | ||
| 1306 | # CONFIG_SAMPLES is not set | ||
| 1307 | CONFIG_HAVE_ARCH_KGDB=y | ||
| 1308 | CONFIG_ARM_UNWIND=y | ||
| 1309 | # CONFIG_DEBUG_USER is not set | ||
| 1310 | |||
| 1311 | # | ||
| 1312 | # Security options | ||
| 1313 | # | ||
| 1314 | # CONFIG_KEYS is not set | ||
| 1315 | # CONFIG_SECURITY is not set | ||
| 1316 | # CONFIG_SECURITYFS is not set | ||
| 1317 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
| 1318 | # CONFIG_CRYPTO is not set | ||
| 1319 | # CONFIG_BINARY_PRINTF is not set | ||
| 1320 | |||
| 1321 | # | ||
| 1322 | # Library routines | ||
| 1323 | # | ||
| 1324 | CONFIG_BITREVERSE=y | ||
| 1325 | CONFIG_GENERIC_FIND_LAST_BIT=y | ||
| 1326 | CONFIG_CRC_CCITT=y | ||
| 1327 | # CONFIG_CRC16 is not set | ||
| 1328 | # CONFIG_CRC_T10DIF is not set | ||
| 1329 | # CONFIG_CRC_ITU_T is not set | ||
| 1330 | CONFIG_CRC32=y | ||
| 1331 | # CONFIG_CRC7 is not set | ||
| 1332 | # CONFIG_LIBCRC32C is not set | ||
| 1333 | CONFIG_ZLIB_INFLATE=y | ||
| 1334 | CONFIG_ZLIB_DEFLATE=y | ||
| 1335 | CONFIG_HAS_IOMEM=y | ||
| 1336 | CONFIG_HAS_IOPORT=y | ||
| 1337 | CONFIG_HAS_DMA=y | ||
| 1338 | CONFIG_NLATTR=y | ||
diff --git a/arch/arm/configs/cpu9g20_defconfig b/arch/arm/configs/cpu9g20_defconfig new file mode 100644 index 000000000000..b5b9cbbc6977 --- /dev/null +++ b/arch/arm/configs/cpu9g20_defconfig | |||
| @@ -0,0 +1,1328 @@ | |||
| 1 | # | ||
| 2 | # Automatically generated make config: don't edit | ||
| 3 | # Linux kernel version: 2.6.31-rc3 | ||
| 4 | # Tue Jul 14 15:03:43 2009 | ||
| 5 | # | ||
| 6 | CONFIG_ARM=y | ||
| 7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||
| 8 | CONFIG_GENERIC_GPIO=y | ||
| 9 | CONFIG_GENERIC_TIME=y | ||
| 10 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
| 11 | CONFIG_MMU=y | ||
| 12 | CONFIG_GENERIC_HARDIRQS=y | ||
| 13 | CONFIG_STACKTRACE_SUPPORT=y | ||
| 14 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | ||
| 15 | CONFIG_LOCKDEP_SUPPORT=y | ||
| 16 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
| 17 | CONFIG_HARDIRQS_SW_RESEND=y | ||
| 18 | CONFIG_GENERIC_IRQ_PROBE=y | ||
| 19 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
| 20 | CONFIG_GENERIC_HWEIGHT=y | ||
| 21 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
| 22 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | ||
| 23 | CONFIG_VECTORS_BASE=0xffff0000 | ||
| 24 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
| 25 | CONFIG_CONSTRUCTORS=y | ||
| 26 | |||
| 27 | # | ||
| 28 | # General setup | ||
| 29 | # | ||
| 30 | CONFIG_EXPERIMENTAL=y | ||
| 31 | CONFIG_BROKEN_ON_SMP=y | ||
| 32 | CONFIG_LOCK_KERNEL=y | ||
| 33 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
| 34 | CONFIG_LOCALVERSION="" | ||
| 35 | # CONFIG_LOCALVERSION_AUTO is not set | ||
| 36 | # CONFIG_SWAP is not set | ||
| 37 | CONFIG_SYSVIPC=y | ||
| 38 | CONFIG_SYSVIPC_SYSCTL=y | ||
| 39 | # CONFIG_POSIX_MQUEUE is not set | ||
| 40 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
| 41 | # CONFIG_TASKSTATS is not set | ||
| 42 | # CONFIG_AUDIT is not set | ||
| 43 | |||
| 44 | # | ||
| 45 | # RCU Subsystem | ||
| 46 | # | ||
| 47 | CONFIG_CLASSIC_RCU=y | ||
| 48 | # CONFIG_TREE_RCU is not set | ||
| 49 | # CONFIG_PREEMPT_RCU is not set | ||
| 50 | # CONFIG_TREE_RCU_TRACE is not set | ||
| 51 | # CONFIG_PREEMPT_RCU_TRACE is not set | ||
| 52 | # CONFIG_IKCONFIG is not set | ||
| 53 | CONFIG_LOG_BUF_SHIFT=14 | ||
| 54 | # CONFIG_GROUP_SCHED is not set | ||
| 55 | # CONFIG_CGROUPS is not set | ||
| 56 | CONFIG_SYSFS_DEPRECATED=y | ||
| 57 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
| 58 | # CONFIG_RELAY is not set | ||
| 59 | CONFIG_NAMESPACES=y | ||
| 60 | # CONFIG_UTS_NS is not set | ||
| 61 | # CONFIG_IPC_NS is not set | ||
| 62 | # CONFIG_USER_NS is not set | ||
| 63 | # CONFIG_PID_NS is not set | ||
| 64 | # CONFIG_NET_NS is not set | ||
| 65 | # CONFIG_BLK_DEV_INITRD is not set | ||
| 66 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
| 67 | CONFIG_SYSCTL=y | ||
| 68 | CONFIG_ANON_INODES=y | ||
| 69 | # CONFIG_EMBEDDED is not set | ||
| 70 | CONFIG_UID16=y | ||
| 71 | CONFIG_SYSCTL_SYSCALL=y | ||
| 72 | CONFIG_KALLSYMS=y | ||
| 73 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
| 74 | CONFIG_HOTPLUG=y | ||
| 75 | CONFIG_PRINTK=y | ||
| 76 | CONFIG_BUG=y | ||
| 77 | CONFIG_ELF_CORE=y | ||
| 78 | CONFIG_BASE_FULL=y | ||
| 79 | CONFIG_FUTEX=y | ||
| 80 | CONFIG_EPOLL=y | ||
| 81 | CONFIG_SIGNALFD=y | ||
| 82 | CONFIG_TIMERFD=y | ||
| 83 | CONFIG_EVENTFD=y | ||
| 84 | CONFIG_SHMEM=y | ||
| 85 | CONFIG_AIO=y | ||
| 86 | |||
| 87 | # | ||
| 88 | # Performance Counters | ||
| 89 | # | ||
| 90 | CONFIG_VM_EVENT_COUNTERS=y | ||
| 91 | CONFIG_SLUB_DEBUG=y | ||
| 92 | # CONFIG_STRIP_ASM_SYMS is not set | ||
| 93 | CONFIG_COMPAT_BRK=y | ||
| 94 | # CONFIG_SLAB is not set | ||
| 95 | CONFIG_SLUB=y | ||
| 96 | # CONFIG_SLOB is not set | ||
| 97 | # CONFIG_PROFILING is not set | ||
| 98 | # CONFIG_MARKERS is not set | ||
| 99 | CONFIG_HAVE_OPROFILE=y | ||
| 100 | # CONFIG_KPROBES is not set | ||
| 101 | CONFIG_HAVE_KPROBES=y | ||
| 102 | CONFIG_HAVE_KRETPROBES=y | ||
| 103 | CONFIG_HAVE_CLK=y | ||
| 104 | |||
| 105 | # | ||
| 106 | # GCOV-based kernel profiling | ||
| 107 | # | ||
| 108 | # CONFIG_SLOW_WORK is not set | ||
| 109 | CONFIG_HAVE_GENERIC_DMA_COHERENT=y | ||
| 110 | CONFIG_SLABINFO=y | ||
| 111 | CONFIG_RT_MUTEXES=y | ||
| 112 | CONFIG_BASE_SMALL=0 | ||
| 113 | CONFIG_MODULES=y | ||
| 114 | # CONFIG_MODULE_FORCE_LOAD is not set | ||
| 115 | CONFIG_MODULE_UNLOAD=y | ||
| 116 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
| 117 | # CONFIG_MODVERSIONS is not set | ||
| 118 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
| 119 | CONFIG_BLOCK=y | ||
| 120 | CONFIG_LBDAF=y | ||
| 121 | # CONFIG_BLK_DEV_BSG is not set | ||
| 122 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
| 123 | |||
| 124 | # | ||
| 125 | # IO Schedulers | ||
| 126 | # | ||
| 127 | CONFIG_IOSCHED_NOOP=y | ||
| 128 | # CONFIG_IOSCHED_AS is not set | ||
| 129 | CONFIG_IOSCHED_DEADLINE=y | ||
| 130 | # CONFIG_IOSCHED_CFQ is not set | ||
| 131 | # CONFIG_DEFAULT_AS is not set | ||
| 132 | CONFIG_DEFAULT_DEADLINE=y | ||
| 133 | # CONFIG_DEFAULT_CFQ is not set | ||
| 134 | # CONFIG_DEFAULT_NOOP is not set | ||
| 135 | CONFIG_DEFAULT_IOSCHED="deadline" | ||
| 136 | # CONFIG_FREEZER is not set | ||
| 137 | |||
| 138 | # | ||
| 139 | # System Type | ||
| 140 | # | ||
| 141 | # CONFIG_ARCH_AAEC2000 is not set | ||
| 142 | # CONFIG_ARCH_INTEGRATOR is not set | ||
| 143 | # CONFIG_ARCH_REALVIEW is not set | ||
| 144 | # CONFIG_ARCH_VERSATILE is not set | ||
| 145 | CONFIG_ARCH_AT91=y | ||
| 146 | # CONFIG_ARCH_CLPS711X is not set | ||
| 147 | # CONFIG_ARCH_GEMINI is not set | ||
| 148 | # CONFIG_ARCH_EBSA110 is not set | ||
| 149 | # CONFIG_ARCH_EP93XX is not set | ||
| 150 | # CONFIG_ARCH_FOOTBRIDGE is not set | ||
| 151 | # CONFIG_ARCH_MXC is not set | ||
| 152 | # CONFIG_ARCH_STMP3XXX is not set | ||
| 153 | # CONFIG_ARCH_NETX is not set | ||
| 154 | # CONFIG_ARCH_H720X is not set | ||
| 155 | # CONFIG_ARCH_IOP13XX is not set | ||
| 156 | # CONFIG_ARCH_IOP32X is not set | ||
| 157 | # CONFIG_ARCH_IOP33X is not set | ||
| 158 | # CONFIG_ARCH_IXP23XX is not set | ||
| 159 | # CONFIG_ARCH_IXP2000 is not set | ||
| 160 | # CONFIG_ARCH_IXP4XX is not set | ||
| 161 | # CONFIG_ARCH_L7200 is not set | ||
| 162 | # CONFIG_ARCH_KIRKWOOD is not set | ||
| 163 | # CONFIG_ARCH_LOKI is not set | ||
| 164 | # CONFIG_ARCH_MV78XX0 is not set | ||
| 165 | # CONFIG_ARCH_ORION5X is not set | ||
| 166 | # CONFIG_ARCH_MMP is not set | ||
| 167 | # CONFIG_ARCH_KS8695 is not set | ||
| 168 | # CONFIG_ARCH_NS9XXX is not set | ||
| 169 | # CONFIG_ARCH_W90X900 is not set | ||
| 170 | # CONFIG_ARCH_PNX4008 is not set | ||
| 171 | # CONFIG_ARCH_PXA is not set | ||
| 172 | # CONFIG_ARCH_MSM is not set | ||
| 173 | # CONFIG_ARCH_RPC is not set | ||
| 174 | # CONFIG_ARCH_SA1100 is not set | ||
| 175 | # CONFIG_ARCH_S3C2410 is not set | ||
| 176 | # CONFIG_ARCH_S3C64XX is not set | ||
| 177 | # CONFIG_ARCH_SHARK is not set | ||
| 178 | # CONFIG_ARCH_LH7A40X is not set | ||
| 179 | # CONFIG_ARCH_U300 is not set | ||
| 180 | # CONFIG_ARCH_DAVINCI is not set | ||
| 181 | # CONFIG_ARCH_OMAP is not set | ||
| 182 | |||
| 183 | # | ||
| 184 | # Atmel AT91 System-on-Chip | ||
| 185 | # | ||
| 186 | # CONFIG_ARCH_AT91RM9200 is not set | ||
| 187 | # CONFIG_ARCH_AT91SAM9260 is not set | ||
| 188 | # CONFIG_ARCH_AT91SAM9261 is not set | ||
| 189 | # CONFIG_ARCH_AT91SAM9263 is not set | ||
| 190 | # CONFIG_ARCH_AT91SAM9RL is not set | ||
| 191 | CONFIG_ARCH_AT91SAM9G20=y | ||
| 192 | # CONFIG_ARCH_AT91CAP9 is not set | ||
| 193 | # CONFIG_ARCH_AT91X40 is not set | ||
| 194 | CONFIG_AT91_PMC_UNIT=y | ||
| 195 | |||
| 196 | # | ||
| 197 | # AT91SAM9G20 Board Type | ||
| 198 | # | ||
| 199 | # CONFIG_MACH_AT91SAM9G20EK is not set | ||
| 200 | CONFIG_MACH_CPU9G20=y | ||
| 201 | |||
| 202 | # | ||
| 203 | # AT91 Board Options | ||
| 204 | # | ||
| 205 | |||
| 206 | # | ||
| 207 | # AT91 Feature Selections | ||
| 208 | # | ||
| 209 | # CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set | ||
| 210 | CONFIG_AT91_TIMER_HZ=100 | ||
| 211 | CONFIG_AT91_EARLY_DBGU=y | ||
| 212 | # CONFIG_AT91_EARLY_USART0 is not set | ||
| 213 | # CONFIG_AT91_EARLY_USART1 is not set | ||
| 214 | # CONFIG_AT91_EARLY_USART2 is not set | ||
| 215 | # CONFIG_AT91_EARLY_USART3 is not set | ||
| 216 | # CONFIG_AT91_EARLY_USART4 is not set | ||
| 217 | # CONFIG_AT91_EARLY_USART5 is not set | ||
| 218 | |||
| 219 | # | ||
| 220 | # Processor Type | ||
| 221 | # | ||
| 222 | CONFIG_CPU_32=y | ||
| 223 | CONFIG_CPU_ARM926T=y | ||
| 224 | CONFIG_CPU_32v5=y | ||
| 225 | CONFIG_CPU_ABRT_EV5TJ=y | ||
| 226 | CONFIG_CPU_PABRT_NOIFAR=y | ||
| 227 | CONFIG_CPU_CACHE_VIVT=y | ||
| 228 | CONFIG_CPU_COPY_V4WB=y | ||
| 229 | CONFIG_CPU_TLB_V4WBI=y | ||
| 230 | CONFIG_CPU_CP15=y | ||
| 231 | CONFIG_CPU_CP15_MMU=y | ||
| 232 | |||
| 233 | # | ||
| 234 | # Processor Features | ||
| 235 | # | ||
| 236 | # CONFIG_ARM_THUMB is not set | ||
| 237 | # CONFIG_CPU_ICACHE_DISABLE is not set | ||
| 238 | # CONFIG_CPU_DCACHE_DISABLE is not set | ||
| 239 | # CONFIG_CPU_DCACHE_WRITETHROUGH is not set | ||
| 240 | # CONFIG_CPU_CACHE_ROUND_ROBIN is not set | ||
| 241 | |||
| 242 | # | ||
| 243 | # Bus support | ||
| 244 | # | ||
| 245 | # CONFIG_PCI_SYSCALL is not set | ||
| 246 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
| 247 | # CONFIG_PCCARD is not set | ||
| 248 | |||
| 249 | # | ||
| 250 | # Kernel Features | ||
| 251 | # | ||
| 252 | # CONFIG_NO_HZ is not set | ||
| 253 | # CONFIG_HIGH_RES_TIMERS is not set | ||
| 254 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | ||
| 255 | CONFIG_VMSPLIT_3G=y | ||
| 256 | # CONFIG_VMSPLIT_2G is not set | ||
| 257 | # CONFIG_VMSPLIT_1G is not set | ||
| 258 | CONFIG_PAGE_OFFSET=0xC0000000 | ||
| 259 | CONFIG_PREEMPT=y | ||
| 260 | CONFIG_HZ=100 | ||
| 261 | CONFIG_AEABI=y | ||
| 262 | CONFIG_OABI_COMPAT=y | ||
| 263 | # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set | ||
| 264 | # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set | ||
| 265 | # CONFIG_HIGHMEM is not set | ||
| 266 | CONFIG_SELECT_MEMORY_MODEL=y | ||
| 267 | CONFIG_FLATMEM_MANUAL=y | ||
| 268 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
| 269 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
| 270 | CONFIG_FLATMEM=y | ||
| 271 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
| 272 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
| 273 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | ||
| 274 | # CONFIG_PHYS_ADDR_T_64BIT is not set | ||
| 275 | CONFIG_ZONE_DMA_FLAG=0 | ||
| 276 | CONFIG_VIRT_TO_BUS=y | ||
| 277 | CONFIG_HAVE_MLOCK=y | ||
| 278 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | ||
| 279 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
| 280 | # CONFIG_LEDS is not set | ||
| 281 | CONFIG_ALIGNMENT_TRAP=y | ||
| 282 | # CONFIG_UACCESS_WITH_MEMCPY is not set | ||
| 283 | |||
| 284 | # | ||
| 285 | # Boot options | ||
| 286 | # | ||
| 287 | CONFIG_ZBOOT_ROM_TEXT=0x0 | ||
| 288 | CONFIG_ZBOOT_ROM_BSS=0x0 | ||
| 289 | CONFIG_CMDLINE="" | ||
| 290 | # CONFIG_XIP_KERNEL is not set | ||
| 291 | # CONFIG_KEXEC is not set | ||
| 292 | |||
| 293 | # | ||
| 294 | # CPU Power Management | ||
| 295 | # | ||
| 296 | # CONFIG_CPU_IDLE is not set | ||
| 297 | |||
| 298 | # | ||
| 299 | # Floating point emulation | ||
| 300 | # | ||
| 301 | |||
| 302 | # | ||
| 303 | # At least one emulation must be selected | ||
| 304 | # | ||
| 305 | # CONFIG_FPE_NWFPE is not set | ||
| 306 | # CONFIG_FPE_FASTFPE is not set | ||
| 307 | # CONFIG_VFP is not set | ||
| 308 | |||
| 309 | # | ||
| 310 | # Userspace binary formats | ||
| 311 | # | ||
| 312 | CONFIG_BINFMT_ELF=y | ||
| 313 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
| 314 | CONFIG_HAVE_AOUT=y | ||
| 315 | # CONFIG_BINFMT_AOUT is not set | ||
| 316 | # CONFIG_BINFMT_MISC is not set | ||
| 317 | |||
| 318 | # | ||
| 319 | # Power management options | ||
| 320 | # | ||
| 321 | # CONFIG_PM is not set | ||
| 322 | CONFIG_ARCH_SUSPEND_POSSIBLE=y | ||
| 323 | CONFIG_NET=y | ||
| 324 | |||
| 325 | # | ||
| 326 | # Networking options | ||
| 327 | # | ||
| 328 | CONFIG_PACKET=y | ||
| 329 | # CONFIG_PACKET_MMAP is not set | ||
| 330 | CONFIG_UNIX=y | ||
| 331 | # CONFIG_NET_KEY is not set | ||
| 332 | CONFIG_INET=y | ||
| 333 | # CONFIG_IP_MULTICAST is not set | ||
| 334 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
| 335 | CONFIG_IP_FIB_HASH=y | ||
| 336 | CONFIG_IP_PNP=y | ||
| 337 | # CONFIG_IP_PNP_DHCP is not set | ||
| 338 | # CONFIG_IP_PNP_BOOTP is not set | ||
| 339 | # CONFIG_IP_PNP_RARP is not set | ||
| 340 | # CONFIG_NET_IPIP is not set | ||
| 341 | # CONFIG_NET_IPGRE is not set | ||
| 342 | # CONFIG_ARPD is not set | ||
| 343 | # CONFIG_SYN_COOKIES is not set | ||
| 344 | # CONFIG_INET_AH is not set | ||
| 345 | # CONFIG_INET_ESP is not set | ||
| 346 | # CONFIG_INET_IPCOMP is not set | ||
| 347 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
| 348 | # CONFIG_INET_TUNNEL is not set | ||
| 349 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
| 350 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
| 351 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
| 352 | CONFIG_INET_LRO=y | ||
| 353 | CONFIG_INET_DIAG=y | ||
| 354 | CONFIG_INET_TCP_DIAG=y | ||
| 355 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
| 356 | CONFIG_TCP_CONG_CUBIC=y | ||
| 357 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
| 358 | # CONFIG_TCP_MD5SIG is not set | ||
| 359 | # CONFIG_IPV6 is not set | ||
| 360 | # CONFIG_NETWORK_SECMARK is not set | ||
| 361 | # CONFIG_NETFILTER is not set | ||
| 362 | # CONFIG_IP_DCCP is not set | ||
| 363 | # CONFIG_IP_SCTP is not set | ||
| 364 | # CONFIG_TIPC is not set | ||
| 365 | # CONFIG_ATM is not set | ||
| 366 | # CONFIG_BRIDGE is not set | ||
| 367 | # CONFIG_NET_DSA is not set | ||
| 368 | # CONFIG_VLAN_8021Q is not set | ||
| 369 | # CONFIG_DECNET is not set | ||
| 370 | # CONFIG_LLC2 is not set | ||
| 371 | # CONFIG_IPX is not set | ||
| 372 | # CONFIG_ATALK is not set | ||
| 373 | # CONFIG_X25 is not set | ||
| 374 | # CONFIG_LAPB is not set | ||
| 375 | # CONFIG_ECONET is not set | ||
| 376 | # CONFIG_WAN_ROUTER is not set | ||
| 377 | # CONFIG_PHONET is not set | ||
| 378 | # CONFIG_IEEE802154 is not set | ||
| 379 | # CONFIG_NET_SCHED is not set | ||
| 380 | # CONFIG_DCB is not set | ||
| 381 | |||
| 382 | # | ||
| 383 | # Network testing | ||
| 384 | # | ||
| 385 | # CONFIG_NET_PKTGEN is not set | ||
| 386 | # CONFIG_HAMRADIO is not set | ||
| 387 | # CONFIG_CAN is not set | ||
| 388 | # CONFIG_IRDA is not set | ||
| 389 | # CONFIG_BT is not set | ||
| 390 | # CONFIG_AF_RXRPC is not set | ||
| 391 | # CONFIG_WIRELESS is not set | ||
| 392 | # CONFIG_WIMAX is not set | ||
| 393 | # CONFIG_RFKILL is not set | ||
| 394 | # CONFIG_NET_9P is not set | ||
| 395 | |||
| 396 | # | ||
| 397 | # Device Drivers | ||
| 398 | # | ||
| 399 | |||
| 400 | # | ||
| 401 | # Generic Driver Options | ||
| 402 | # | ||
| 403 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
| 404 | CONFIG_STANDALONE=y | ||
| 405 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
| 406 | CONFIG_FW_LOADER=y | ||
| 407 | CONFIG_FIRMWARE_IN_KERNEL=y | ||
| 408 | CONFIG_EXTRA_FIRMWARE="" | ||
| 409 | # CONFIG_SYS_HYPERVISOR is not set | ||
| 410 | # CONFIG_CONNECTOR is not set | ||
| 411 | CONFIG_MTD=y | ||
| 412 | # CONFIG_MTD_DEBUG is not set | ||
| 413 | # CONFIG_MTD_CONCAT is not set | ||
| 414 | CONFIG_MTD_PARTITIONS=y | ||
| 415 | # CONFIG_MTD_TESTS is not set | ||
| 416 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
| 417 | CONFIG_MTD_CMDLINE_PARTS=y | ||
| 418 | # CONFIG_MTD_AFS_PARTS is not set | ||
| 419 | # CONFIG_MTD_AR7_PARTS is not set | ||
| 420 | |||
| 421 | # | ||
| 422 | # User Modules And Translation Layers | ||
| 423 | # | ||
| 424 | CONFIG_MTD_CHAR=y | ||
| 425 | CONFIG_MTD_BLKDEVS=y | ||
| 426 | CONFIG_MTD_BLOCK=y | ||
| 427 | # CONFIG_FTL is not set | ||
| 428 | # CONFIG_NFTL is not set | ||
| 429 | # CONFIG_INFTL is not set | ||
| 430 | # CONFIG_RFD_FTL is not set | ||
| 431 | # CONFIG_SSFDC is not set | ||
| 432 | # CONFIG_MTD_OOPS is not set | ||
| 433 | |||
| 434 | # | ||
| 435 | # RAM/ROM/Flash chip drivers | ||
| 436 | # | ||
| 437 | CONFIG_MTD_CFI=y | ||
| 438 | # CONFIG_MTD_JEDECPROBE is not set | ||
| 439 | CONFIG_MTD_GEN_PROBE=y | ||
| 440 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
| 441 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
| 442 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
| 443 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
| 444 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
| 445 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
| 446 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
| 447 | CONFIG_MTD_CFI_I1=y | ||
| 448 | CONFIG_MTD_CFI_I2=y | ||
| 449 | # CONFIG_MTD_CFI_I4 is not set | ||
| 450 | # CONFIG_MTD_CFI_I8 is not set | ||
| 451 | CONFIG_MTD_CFI_INTELEXT=y | ||
| 452 | # CONFIG_MTD_CFI_AMDSTD is not set | ||
| 453 | # CONFIG_MTD_CFI_STAA is not set | ||
| 454 | CONFIG_MTD_CFI_UTIL=y | ||
| 455 | CONFIG_MTD_RAM=y | ||
| 456 | # CONFIG_MTD_ROM is not set | ||
| 457 | # CONFIG_MTD_ABSENT is not set | ||
| 458 | |||
| 459 | # | ||
| 460 | # Mapping drivers for chip access | ||
| 461 | # | ||
| 462 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
| 463 | CONFIG_MTD_PHYSMAP=y | ||
| 464 | # CONFIG_MTD_PHYSMAP_COMPAT is not set | ||
| 465 | # CONFIG_MTD_ARM_INTEGRATOR is not set | ||
| 466 | CONFIG_MTD_PLATRAM=y | ||
| 467 | |||
| 468 | # | ||
| 469 | # Self-contained MTD device drivers | ||
| 470 | # | ||
| 471 | # CONFIG_MTD_SLRAM is not set | ||
| 472 | # CONFIG_MTD_PHRAM is not set | ||
| 473 | # CONFIG_MTD_MTDRAM is not set | ||
| 474 | # CONFIG_MTD_BLOCK2MTD is not set | ||
| 475 | |||
| 476 | # | ||
| 477 | # Disk-On-Chip Device Drivers | ||
| 478 | # | ||
| 479 | # CONFIG_MTD_DOC2000 is not set | ||
| 480 | # CONFIG_MTD_DOC2001 is not set | ||
| 481 | # CONFIG_MTD_DOC2001PLUS is not set | ||
| 482 | CONFIG_MTD_NAND=y | ||
| 483 | # CONFIG_MTD_NAND_VERIFY_WRITE is not set | ||
| 484 | # CONFIG_MTD_NAND_ECC_SMC is not set | ||
| 485 | # CONFIG_MTD_NAND_MUSEUM_IDS is not set | ||
| 486 | # CONFIG_MTD_NAND_GPIO is not set | ||
| 487 | CONFIG_MTD_NAND_IDS=y | ||
| 488 | # CONFIG_MTD_NAND_DISKONCHIP is not set | ||
| 489 | CONFIG_MTD_NAND_ATMEL=y | ||
| 490 | # CONFIG_MTD_NAND_ATMEL_ECC_HW is not set | ||
| 491 | CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y | ||
| 492 | # CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set | ||
| 493 | # CONFIG_MTD_NAND_NANDSIM is not set | ||
| 494 | # CONFIG_MTD_NAND_PLATFORM is not set | ||
| 495 | # CONFIG_MTD_ALAUDA is not set | ||
| 496 | # CONFIG_MTD_ONENAND is not set | ||
| 497 | |||
| 498 | # | ||
| 499 | # LPDDR flash memory drivers | ||
| 500 | # | ||
| 501 | # CONFIG_MTD_LPDDR is not set | ||
| 502 | |||
| 503 | # | ||
| 504 | # UBI - Unsorted block images | ||
| 505 | # | ||
| 506 | # CONFIG_MTD_UBI is not set | ||
| 507 | # CONFIG_PARPORT is not set | ||
| 508 | CONFIG_BLK_DEV=y | ||
| 509 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
| 510 | CONFIG_BLK_DEV_LOOP=y | ||
| 511 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
| 512 | CONFIG_BLK_DEV_NBD=y | ||
| 513 | # CONFIG_BLK_DEV_UB is not set | ||
| 514 | CONFIG_BLK_DEV_RAM=y | ||
| 515 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
| 516 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
| 517 | # CONFIG_BLK_DEV_XIP is not set | ||
| 518 | # CONFIG_CDROM_PKTCDVD is not set | ||
| 519 | # CONFIG_ATA_OVER_ETH is not set | ||
| 520 | # CONFIG_MG_DISK is not set | ||
| 521 | # CONFIG_MISC_DEVICES is not set | ||
| 522 | CONFIG_HAVE_IDE=y | ||
| 523 | # CONFIG_IDE is not set | ||
| 524 | |||
| 525 | # | ||
| 526 | # SCSI device support | ||
| 527 | # | ||
| 528 | # CONFIG_RAID_ATTRS is not set | ||
| 529 | CONFIG_SCSI=y | ||
| 530 | CONFIG_SCSI_DMA=y | ||
| 531 | # CONFIG_SCSI_TGT is not set | ||
| 532 | # CONFIG_SCSI_NETLINK is not set | ||
| 533 | CONFIG_SCSI_PROC_FS=y | ||
| 534 | |||
| 535 | # | ||
| 536 | # SCSI support type (disk, tape, CD-ROM) | ||
| 537 | # | ||
| 538 | CONFIG_BLK_DEV_SD=y | ||
| 539 | # CONFIG_CHR_DEV_ST is not set | ||
| 540 | # CONFIG_CHR_DEV_OSST is not set | ||
| 541 | # CONFIG_BLK_DEV_SR is not set | ||
| 542 | # CONFIG_CHR_DEV_SG is not set | ||
| 543 | # CONFIG_CHR_DEV_SCH is not set | ||
| 544 | CONFIG_SCSI_MULTI_LUN=y | ||
| 545 | # CONFIG_SCSI_CONSTANTS is not set | ||
| 546 | # CONFIG_SCSI_LOGGING is not set | ||
| 547 | # CONFIG_SCSI_SCAN_ASYNC is not set | ||
| 548 | CONFIG_SCSI_WAIT_SCAN=m | ||
| 549 | |||
| 550 | # | ||
| 551 | # SCSI Transports | ||
| 552 | # | ||
| 553 | # CONFIG_SCSI_SPI_ATTRS is not set | ||
| 554 | # CONFIG_SCSI_FC_ATTRS is not set | ||
| 555 | # CONFIG_SCSI_ISCSI_ATTRS is not set | ||
| 556 | # CONFIG_SCSI_SAS_LIBSAS is not set | ||
| 557 | # CONFIG_SCSI_SRP_ATTRS is not set | ||
| 558 | # CONFIG_SCSI_LOWLEVEL is not set | ||
| 559 | # CONFIG_SCSI_DH is not set | ||
| 560 | # CONFIG_SCSI_OSD_INITIATOR is not set | ||
| 561 | # CONFIG_ATA is not set | ||
| 562 | # CONFIG_MD is not set | ||
| 563 | CONFIG_NETDEVICES=y | ||
| 564 | # CONFIG_DUMMY is not set | ||
| 565 | # CONFIG_BONDING is not set | ||
| 566 | # CONFIG_MACVLAN is not set | ||
| 567 | # CONFIG_EQUALIZER is not set | ||
| 568 | # CONFIG_TUN is not set | ||
| 569 | # CONFIG_VETH is not set | ||
| 570 | CONFIG_PHYLIB=y | ||
| 571 | |||
| 572 | # | ||
| 573 | # MII PHY device drivers | ||
| 574 | # | ||
| 575 | # CONFIG_MARVELL_PHY is not set | ||
| 576 | # CONFIG_DAVICOM_PHY is not set | ||
| 577 | # CONFIG_QSEMI_PHY is not set | ||
| 578 | # CONFIG_LXT_PHY is not set | ||
| 579 | # CONFIG_CICADA_PHY is not set | ||
| 580 | # CONFIG_VITESSE_PHY is not set | ||
| 581 | CONFIG_SMSC_PHY=y | ||
| 582 | # CONFIG_BROADCOM_PHY is not set | ||
| 583 | # CONFIG_ICPLUS_PHY is not set | ||
| 584 | # CONFIG_REALTEK_PHY is not set | ||
| 585 | # CONFIG_NATIONAL_PHY is not set | ||
| 586 | # CONFIG_STE10XP is not set | ||
| 587 | # CONFIG_LSI_ET1011C_PHY is not set | ||
| 588 | # CONFIG_FIXED_PHY is not set | ||
| 589 | # CONFIG_MDIO_BITBANG is not set | ||
| 590 | CONFIG_NET_ETHERNET=y | ||
| 591 | CONFIG_MII=y | ||
| 592 | CONFIG_MACB=y | ||
| 593 | # CONFIG_AX88796 is not set | ||
| 594 | # CONFIG_SMC91X is not set | ||
| 595 | # CONFIG_DM9000 is not set | ||
| 596 | # CONFIG_ETHOC is not set | ||
| 597 | # CONFIG_SMC911X is not set | ||
| 598 | # CONFIG_SMSC911X is not set | ||
| 599 | # CONFIG_DNET is not set | ||
| 600 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
| 601 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
| 602 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
| 603 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
| 604 | # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set | ||
| 605 | # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set | ||
| 606 | # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set | ||
| 607 | # CONFIG_B44 is not set | ||
| 608 | # CONFIG_KS8842 is not set | ||
| 609 | # CONFIG_NETDEV_1000 is not set | ||
| 610 | # CONFIG_NETDEV_10000 is not set | ||
| 611 | |||
| 612 | # | ||
| 613 | # Wireless LAN | ||
| 614 | # | ||
| 615 | # CONFIG_WLAN_PRE80211 is not set | ||
| 616 | # CONFIG_WLAN_80211 is not set | ||
| 617 | |||
| 618 | # | ||
| 619 | # Enable WiMAX (Networking options) to see the WiMAX drivers | ||
| 620 | # | ||
| 621 | |||
| 622 | # | ||
| 623 | # USB Network Adapters | ||
| 624 | # | ||
| 625 | # CONFIG_USB_CATC is not set | ||
| 626 | # CONFIG_USB_KAWETH is not set | ||
| 627 | # CONFIG_USB_PEGASUS is not set | ||
| 628 | # CONFIG_USB_RTL8150 is not set | ||
| 629 | # CONFIG_USB_USBNET is not set | ||
| 630 | # CONFIG_WAN is not set | ||
| 631 | CONFIG_PPP=y | ||
| 632 | # CONFIG_PPP_MULTILINK is not set | ||
| 633 | # CONFIG_PPP_FILTER is not set | ||
| 634 | CONFIG_PPP_ASYNC=y | ||
| 635 | # CONFIG_PPP_SYNC_TTY is not set | ||
| 636 | CONFIG_PPP_DEFLATE=y | ||
| 637 | CONFIG_PPP_BSDCOMP=y | ||
| 638 | # CONFIG_PPP_MPPE is not set | ||
| 639 | # CONFIG_PPPOE is not set | ||
| 640 | # CONFIG_PPPOL2TP is not set | ||
| 641 | # CONFIG_SLIP is not set | ||
| 642 | CONFIG_SLHC=y | ||
| 643 | # CONFIG_NETCONSOLE is not set | ||
| 644 | # CONFIG_NETPOLL is not set | ||
| 645 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
| 646 | # CONFIG_ISDN is not set | ||
| 647 | |||
| 648 | # | ||
| 649 | # Input device support | ||
| 650 | # | ||
| 651 | CONFIG_INPUT=y | ||
| 652 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
| 653 | # CONFIG_INPUT_POLLDEV is not set | ||
| 654 | |||
| 655 | # | ||
| 656 | # Userland interfaces | ||
| 657 | # | ||
| 658 | CONFIG_INPUT_MOUSEDEV=y | ||
| 659 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
| 660 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
| 661 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
| 662 | # CONFIG_INPUT_JOYDEV is not set | ||
| 663 | # CONFIG_INPUT_EVDEV is not set | ||
| 664 | # CONFIG_INPUT_EVBUG is not set | ||
| 665 | |||
| 666 | # | ||
| 667 | # Input Device Drivers | ||
| 668 | # | ||
| 669 | CONFIG_INPUT_KEYBOARD=y | ||
| 670 | # CONFIG_KEYBOARD_ATKBD is not set | ||
| 671 | # CONFIG_KEYBOARD_LKKBD is not set | ||
| 672 | CONFIG_KEYBOARD_GPIO=y | ||
| 673 | # CONFIG_KEYBOARD_MATRIX is not set | ||
| 674 | # CONFIG_KEYBOARD_LM8323 is not set | ||
| 675 | # CONFIG_KEYBOARD_NEWTON is not set | ||
| 676 | # CONFIG_KEYBOARD_STOWAWAY is not set | ||
| 677 | # CONFIG_KEYBOARD_SUNKBD is not set | ||
| 678 | # CONFIG_KEYBOARD_XTKBD is not set | ||
| 679 | # CONFIG_INPUT_MOUSE is not set | ||
| 680 | # CONFIG_INPUT_JOYSTICK is not set | ||
| 681 | # CONFIG_INPUT_TABLET is not set | ||
| 682 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
| 683 | # CONFIG_INPUT_MISC is not set | ||
| 684 | |||
| 685 | # | ||
| 686 | # Hardware I/O ports | ||
| 687 | # | ||
| 688 | # CONFIG_SERIO is not set | ||
| 689 | # CONFIG_GAMEPORT is not set | ||
| 690 | |||
| 691 | # | ||
| 692 | # Character devices | ||
| 693 | # | ||
| 694 | CONFIG_VT=y | ||
| 695 | CONFIG_CONSOLE_TRANSLATIONS=y | ||
| 696 | CONFIG_VT_CONSOLE=y | ||
| 697 | CONFIG_HW_CONSOLE=y | ||
| 698 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | ||
| 699 | CONFIG_DEVKMEM=y | ||
| 700 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
| 701 | |||
| 702 | # | ||
| 703 | # Serial drivers | ||
| 704 | # | ||
| 705 | # CONFIG_SERIAL_8250 is not set | ||
| 706 | |||
| 707 | # | ||
| 708 | # Non-8250 serial port support | ||
| 709 | # | ||
| 710 | CONFIG_SERIAL_ATMEL=y | ||
| 711 | CONFIG_SERIAL_ATMEL_CONSOLE=y | ||
| 712 | CONFIG_SERIAL_ATMEL_PDC=y | ||
| 713 | # CONFIG_SERIAL_ATMEL_TTYAT is not set | ||
| 714 | CONFIG_SERIAL_CORE=y | ||
| 715 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
| 716 | CONFIG_UNIX98_PTYS=y | ||
| 717 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
| 718 | CONFIG_LEGACY_PTYS=y | ||
| 719 | CONFIG_LEGACY_PTY_COUNT=32 | ||
| 720 | # CONFIG_IPMI_HANDLER is not set | ||
| 721 | # CONFIG_HW_RANDOM is not set | ||
| 722 | # CONFIG_R3964 is not set | ||
| 723 | # CONFIG_RAW_DRIVER is not set | ||
| 724 | # CONFIG_TCG_TPM is not set | ||
| 725 | CONFIG_I2C=y | ||
| 726 | CONFIG_I2C_BOARDINFO=y | ||
| 727 | CONFIG_I2C_CHARDEV=y | ||
| 728 | CONFIG_I2C_HELPER_AUTO=y | ||
| 729 | CONFIG_I2C_ALGOBIT=y | ||
| 730 | |||
| 731 | # | ||
| 732 | # I2C Hardware Bus support | ||
| 733 | # | ||
| 734 | |||
| 735 | # | ||
| 736 | # I2C system bus drivers (mostly embedded / system-on-chip) | ||
| 737 | # | ||
| 738 | # CONFIG_I2C_DESIGNWARE is not set | ||
| 739 | CONFIG_I2C_GPIO=y | ||
| 740 | # CONFIG_I2C_OCORES is not set | ||
| 741 | # CONFIG_I2C_SIMTEC is not set | ||
| 742 | |||
| 743 | # | ||
| 744 | # External I2C/SMBus adapter drivers | ||
| 745 | # | ||
| 746 | # CONFIG_I2C_PARPORT_LIGHT is not set | ||
| 747 | # CONFIG_I2C_TAOS_EVM is not set | ||
| 748 | # CONFIG_I2C_TINY_USB is not set | ||
| 749 | |||
| 750 | # | ||
| 751 | # Other I2C/SMBus bus drivers | ||
| 752 | # | ||
| 753 | # CONFIG_I2C_PCA_PLATFORM is not set | ||
| 754 | # CONFIG_I2C_STUB is not set | ||
| 755 | |||
| 756 | # | ||
| 757 | # Miscellaneous I2C Chip support | ||
| 758 | # | ||
| 759 | # CONFIG_DS1682 is not set | ||
| 760 | # CONFIG_SENSORS_PCF8574 is not set | ||
| 761 | # CONFIG_PCF8575 is not set | ||
| 762 | # CONFIG_SENSORS_PCA9539 is not set | ||
| 763 | # CONFIG_SENSORS_TSL2550 is not set | ||
| 764 | # CONFIG_I2C_DEBUG_CORE is not set | ||
| 765 | # CONFIG_I2C_DEBUG_ALGO is not set | ||
| 766 | # CONFIG_I2C_DEBUG_BUS is not set | ||
| 767 | # CONFIG_I2C_DEBUG_CHIP is not set | ||
| 768 | # CONFIG_SPI is not set | ||
| 769 | CONFIG_ARCH_REQUIRE_GPIOLIB=y | ||
| 770 | CONFIG_GPIOLIB=y | ||
| 771 | CONFIG_GPIO_SYSFS=y | ||
| 772 | |||
| 773 | # | ||
| 774 | # Memory mapped GPIO expanders: | ||
| 775 | # | ||
| 776 | |||
| 777 | # | ||
| 778 | # I2C GPIO expanders: | ||
| 779 | # | ||
| 780 | # CONFIG_GPIO_MAX732X is not set | ||
| 781 | # CONFIG_GPIO_PCA953X is not set | ||
| 782 | # CONFIG_GPIO_PCF857X is not set | ||
| 783 | |||
| 784 | # | ||
| 785 | # PCI GPIO expanders: | ||
| 786 | # | ||
| 787 | |||
| 788 | # | ||
| 789 | # SPI GPIO expanders: | ||
| 790 | # | ||
| 791 | # CONFIG_W1 is not set | ||
| 792 | # CONFIG_POWER_SUPPLY is not set | ||
| 793 | # CONFIG_HWMON is not set | ||
| 794 | # CONFIG_THERMAL is not set | ||
| 795 | # CONFIG_THERMAL_HWMON is not set | ||
| 796 | CONFIG_WATCHDOG=y | ||
| 797 | CONFIG_WATCHDOG_NOWAYOUT=y | ||
| 798 | |||
| 799 | # | ||
| 800 | # Watchdog Device Drivers | ||
| 801 | # | ||
| 802 | # CONFIG_SOFT_WATCHDOG is not set | ||
| 803 | CONFIG_AT91SAM9X_WATCHDOG=y | ||
| 804 | |||
| 805 | # | ||
| 806 | # USB-based Watchdog Cards | ||
| 807 | # | ||
| 808 | # CONFIG_USBPCWATCHDOG is not set | ||
| 809 | CONFIG_SSB_POSSIBLE=y | ||
| 810 | |||
| 811 | # | ||
| 812 | # Sonics Silicon Backplane | ||
| 813 | # | ||
| 814 | # CONFIG_SSB is not set | ||
| 815 | |||
| 816 | # | ||
| 817 | # Multifunction device drivers | ||
| 818 | # | ||
| 819 | # CONFIG_MFD_CORE is not set | ||
| 820 | # CONFIG_MFD_SM501 is not set | ||
| 821 | # CONFIG_MFD_ASIC3 is not set | ||
| 822 | # CONFIG_HTC_EGPIO is not set | ||
| 823 | # CONFIG_HTC_PASIC3 is not set | ||
| 824 | # CONFIG_TPS65010 is not set | ||
| 825 | # CONFIG_TWL4030_CORE is not set | ||
| 826 | # CONFIG_MFD_TMIO is not set | ||
| 827 | # CONFIG_MFD_T7L66XB is not set | ||
| 828 | # CONFIG_MFD_TC6387XB is not set | ||
| 829 | # CONFIG_MFD_TC6393XB is not set | ||
| 830 | # CONFIG_PMIC_DA903X is not set | ||
| 831 | # CONFIG_MFD_WM8400 is not set | ||
| 832 | # CONFIG_MFD_WM8350_I2C is not set | ||
| 833 | # CONFIG_MFD_PCF50633 is not set | ||
| 834 | # CONFIG_AB3100_CORE is not set | ||
| 835 | # CONFIG_MEDIA_SUPPORT is not set | ||
| 836 | |||
| 837 | # | ||
| 838 | # Graphics support | ||
| 839 | # | ||
| 840 | # CONFIG_VGASTATE is not set | ||
| 841 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
| 842 | # CONFIG_FB is not set | ||
| 843 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
| 844 | |||
| 845 | # | ||
| 846 | # Display device support | ||
| 847 | # | ||
| 848 | # CONFIG_DISPLAY_SUPPORT is not set | ||
| 849 | |||
| 850 | # | ||
| 851 | # Console display driver support | ||
| 852 | # | ||
| 853 | # CONFIG_VGA_CONSOLE is not set | ||
| 854 | CONFIG_DUMMY_CONSOLE=y | ||
| 855 | # CONFIG_SOUND is not set | ||
| 856 | # CONFIG_HID_SUPPORT is not set | ||
| 857 | CONFIG_USB_SUPPORT=y | ||
| 858 | CONFIG_USB_ARCH_HAS_HCD=y | ||
| 859 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
| 860 | # CONFIG_USB_ARCH_HAS_EHCI is not set | ||
| 861 | CONFIG_USB=y | ||
| 862 | # CONFIG_USB_DEBUG is not set | ||
| 863 | # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set | ||
| 864 | |||
| 865 | # | ||
| 866 | # Miscellaneous USB options | ||
| 867 | # | ||
| 868 | # CONFIG_USB_DEVICEFS is not set | ||
| 869 | # CONFIG_USB_DEVICE_CLASS is not set | ||
| 870 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
| 871 | # CONFIG_USB_OTG is not set | ||
| 872 | # CONFIG_USB_MON is not set | ||
| 873 | # CONFIG_USB_WUSB is not set | ||
| 874 | # CONFIG_USB_WUSB_CBAF is not set | ||
| 875 | |||
| 876 | # | ||
| 877 | # USB Host Controller Drivers | ||
| 878 | # | ||
| 879 | # CONFIG_USB_C67X00_HCD is not set | ||
| 880 | # CONFIG_USB_OXU210HP_HCD is not set | ||
| 881 | # CONFIG_USB_ISP116X_HCD is not set | ||
| 882 | # CONFIG_USB_ISP1760_HCD is not set | ||
| 883 | CONFIG_USB_OHCI_HCD=y | ||
| 884 | # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set | ||
| 885 | # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set | ||
| 886 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
| 887 | # CONFIG_USB_SL811_HCD is not set | ||
| 888 | # CONFIG_USB_R8A66597_HCD is not set | ||
| 889 | # CONFIG_USB_HWA_HCD is not set | ||
| 890 | # CONFIG_USB_MUSB_HDRC is not set | ||
| 891 | # CONFIG_USB_GADGET_MUSB_HDRC is not set | ||
| 892 | |||
| 893 | # | ||
| 894 | # USB Device Class drivers | ||
| 895 | # | ||
| 896 | # CONFIG_USB_ACM is not set | ||
| 897 | # CONFIG_USB_PRINTER is not set | ||
| 898 | # CONFIG_USB_WDM is not set | ||
| 899 | # CONFIG_USB_TMC is not set | ||
| 900 | |||
| 901 | # | ||
| 902 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may | ||
| 903 | # | ||
| 904 | |||
| 905 | # | ||
| 906 | # also be needed; see USB_STORAGE Help for more info | ||
| 907 | # | ||
| 908 | CONFIG_USB_STORAGE=y | ||
| 909 | # CONFIG_USB_STORAGE_DEBUG is not set | ||
| 910 | # CONFIG_USB_STORAGE_DATAFAB is not set | ||
| 911 | # CONFIG_USB_STORAGE_FREECOM is not set | ||
| 912 | # CONFIG_USB_STORAGE_ISD200 is not set | ||
| 913 | # CONFIG_USB_STORAGE_USBAT is not set | ||
| 914 | # CONFIG_USB_STORAGE_SDDR09 is not set | ||
| 915 | # CONFIG_USB_STORAGE_SDDR55 is not set | ||
| 916 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | ||
| 917 | # CONFIG_USB_STORAGE_ALAUDA is not set | ||
| 918 | # CONFIG_USB_STORAGE_ONETOUCH is not set | ||
| 919 | # CONFIG_USB_STORAGE_KARMA is not set | ||
| 920 | # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set | ||
| 921 | # CONFIG_USB_LIBUSUAL is not set | ||
| 922 | |||
| 923 | # | ||
| 924 | # USB Imaging devices | ||
| 925 | # | ||
| 926 | # CONFIG_USB_MDC800 is not set | ||
| 927 | # CONFIG_USB_MICROTEK is not set | ||
| 928 | |||
| 929 | # | ||
| 930 | # USB port drivers | ||
| 931 | # | ||
| 932 | # CONFIG_USB_SERIAL is not set | ||
| 933 | |||
| 934 | # | ||
| 935 | # USB Miscellaneous drivers | ||
| 936 | # | ||
| 937 | # CONFIG_USB_EMI62 is not set | ||
| 938 | # CONFIG_USB_EMI26 is not set | ||
| 939 | # CONFIG_USB_ADUTUX is not set | ||
| 940 | # CONFIG_USB_SEVSEG is not set | ||
| 941 | # CONFIG_USB_RIO500 is not set | ||
| 942 | # CONFIG_USB_LEGOTOWER is not set | ||
| 943 | # CONFIG_USB_LCD is not set | ||
| 944 | # CONFIG_USB_BERRY_CHARGE is not set | ||
| 945 | # CONFIG_USB_LED is not set | ||
| 946 | # CONFIG_USB_CYPRESS_CY7C63 is not set | ||
| 947 | # CONFIG_USB_CYTHERM is not set | ||
| 948 | # CONFIG_USB_IDMOUSE is not set | ||
| 949 | # CONFIG_USB_FTDI_ELAN is not set | ||
| 950 | # CONFIG_USB_APPLEDISPLAY is not set | ||
| 951 | # CONFIG_USB_LD is not set | ||
| 952 | # CONFIG_USB_TRANCEVIBRATOR is not set | ||
| 953 | # CONFIG_USB_IOWARRIOR is not set | ||
| 954 | # CONFIG_USB_ISIGHTFW is not set | ||
| 955 | # CONFIG_USB_VST is not set | ||
| 956 | CONFIG_USB_GADGET=y | ||
| 957 | # CONFIG_USB_GADGET_DEBUG_FILES is not set | ||
| 958 | CONFIG_USB_GADGET_VBUS_DRAW=2 | ||
| 959 | CONFIG_USB_GADGET_SELECTED=y | ||
| 960 | CONFIG_USB_GADGET_AT91=y | ||
| 961 | CONFIG_USB_AT91=y | ||
| 962 | # CONFIG_USB_GADGET_ATMEL_USBA is not set | ||
| 963 | # CONFIG_USB_GADGET_FSL_USB2 is not set | ||
| 964 | # CONFIG_USB_GADGET_LH7A40X is not set | ||
| 965 | # CONFIG_USB_GADGET_OMAP is not set | ||
| 966 | # CONFIG_USB_GADGET_PXA25X is not set | ||
| 967 | # CONFIG_USB_GADGET_PXA27X is not set | ||
| 968 | # CONFIG_USB_GADGET_S3C_HSOTG is not set | ||
| 969 | # CONFIG_USB_GADGET_IMX is not set | ||
| 970 | # CONFIG_USB_GADGET_S3C2410 is not set | ||
| 971 | # CONFIG_USB_GADGET_M66592 is not set | ||
| 972 | # CONFIG_USB_GADGET_AMD5536UDC is not set | ||
| 973 | # CONFIG_USB_GADGET_FSL_QE is not set | ||
| 974 | # CONFIG_USB_GADGET_CI13XXX is not set | ||
| 975 | # CONFIG_USB_GADGET_NET2280 is not set | ||
| 976 | # CONFIG_USB_GADGET_GOKU is not set | ||
| 977 | # CONFIG_USB_GADGET_LANGWELL is not set | ||
| 978 | # CONFIG_USB_GADGET_DUMMY_HCD is not set | ||
| 979 | # CONFIG_USB_GADGET_DUALSPEED is not set | ||
| 980 | # CONFIG_USB_ZERO is not set | ||
| 981 | # CONFIG_USB_AUDIO is not set | ||
| 982 | CONFIG_USB_ETH=y | ||
| 983 | CONFIG_USB_ETH_RNDIS=y | ||
| 984 | # CONFIG_USB_GADGETFS is not set | ||
| 985 | # CONFIG_USB_FILE_STORAGE is not set | ||
| 986 | # CONFIG_USB_G_SERIAL is not set | ||
| 987 | # CONFIG_USB_MIDI_GADGET is not set | ||
| 988 | # CONFIG_USB_G_PRINTER is not set | ||
| 989 | # CONFIG_USB_CDC_COMPOSITE is not set | ||
| 990 | |||
| 991 | # | ||
| 992 | # OTG and related infrastructure | ||
| 993 | # | ||
| 994 | # CONFIG_USB_GPIO_VBUS is not set | ||
| 995 | # CONFIG_NOP_USB_XCEIV is not set | ||
| 996 | CONFIG_MMC=y | ||
| 997 | # CONFIG_MMC_DEBUG is not set | ||
| 998 | # CONFIG_MMC_UNSAFE_RESUME is not set | ||
| 999 | |||
| 1000 | # | ||
| 1001 | # MMC/SD/SDIO Card Drivers | ||
| 1002 | # | ||
| 1003 | CONFIG_MMC_BLOCK=y | ||
| 1004 | CONFIG_MMC_BLOCK_BOUNCE=y | ||
| 1005 | # CONFIG_SDIO_UART is not set | ||
| 1006 | # CONFIG_MMC_TEST is not set | ||
| 1007 | |||
| 1008 | # | ||
| 1009 | # MMC/SD/SDIO Host Controller Drivers | ||
| 1010 | # | ||
| 1011 | # CONFIG_MMC_SDHCI is not set | ||
| 1012 | CONFIG_MMC_AT91=y | ||
| 1013 | # CONFIG_MEMSTICK is not set | ||
| 1014 | # CONFIG_ACCESSIBILITY is not set | ||
| 1015 | CONFIG_NEW_LEDS=y | ||
| 1016 | CONFIG_LEDS_CLASS=y | ||
| 1017 | |||
| 1018 | # | ||
| 1019 | # LED drivers | ||
| 1020 | # | ||
| 1021 | # CONFIG_LEDS_PCA9532 is not set | ||
| 1022 | CONFIG_LEDS_GPIO=y | ||
| 1023 | CONFIG_LEDS_GPIO_PLATFORM=y | ||
| 1024 | # CONFIG_LEDS_LP3944 is not set | ||
| 1025 | # CONFIG_LEDS_PCA955X is not set | ||
| 1026 | # CONFIG_LEDS_BD2802 is not set | ||
| 1027 | |||
| 1028 | # | ||
| 1029 | # LED Triggers | ||
| 1030 | # | ||
| 1031 | CONFIG_LEDS_TRIGGERS=y | ||
| 1032 | CONFIG_LEDS_TRIGGER_TIMER=y | ||
| 1033 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
| 1034 | # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set | ||
| 1035 | CONFIG_LEDS_TRIGGER_GPIO=y | ||
| 1036 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=y | ||
| 1037 | |||
| 1038 | # | ||
| 1039 | # iptables trigger is under Netfilter config (LED target) | ||
| 1040 | # | ||
| 1041 | CONFIG_RTC_LIB=y | ||
| 1042 | CONFIG_RTC_CLASS=y | ||
| 1043 | # CONFIG_RTC_HCTOSYS is not set | ||
| 1044 | # CONFIG_RTC_DEBUG is not set | ||
| 1045 | |||
| 1046 | # | ||
| 1047 | # RTC interfaces | ||
| 1048 | # | ||
| 1049 | CONFIG_RTC_INTF_SYSFS=y | ||
| 1050 | CONFIG_RTC_INTF_PROC=y | ||
| 1051 | CONFIG_RTC_INTF_DEV=y | ||
| 1052 | # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set | ||
| 1053 | # CONFIG_RTC_DRV_TEST is not set | ||
| 1054 | |||
| 1055 | # | ||
| 1056 | # I2C RTC drivers | ||
| 1057 | # | ||
| 1058 | CONFIG_RTC_DRV_DS1307=y | ||
| 1059 | # CONFIG_RTC_DRV_DS1374 is not set | ||
| 1060 | # CONFIG_RTC_DRV_DS1672 is not set | ||
| 1061 | # CONFIG_RTC_DRV_MAX6900 is not set | ||
| 1062 | # CONFIG_RTC_DRV_RS5C372 is not set | ||
| 1063 | # CONFIG_RTC_DRV_ISL1208 is not set | ||
| 1064 | # CONFIG_RTC_DRV_X1205 is not set | ||
| 1065 | # CONFIG_RTC_DRV_PCF8563 is not set | ||
| 1066 | # CONFIG_RTC_DRV_PCF8583 is not set | ||
| 1067 | # CONFIG_RTC_DRV_M41T80 is not set | ||
| 1068 | # CONFIG_RTC_DRV_S35390A is not set | ||
| 1069 | # CONFIG_RTC_DRV_FM3130 is not set | ||
| 1070 | # CONFIG_RTC_DRV_RX8581 is not set | ||
| 1071 | # CONFIG_RTC_DRV_RX8025 is not set | ||
| 1072 | |||
| 1073 | # | ||
| 1074 | # SPI RTC drivers | ||
| 1075 | # | ||
| 1076 | |||
| 1077 | # | ||
| 1078 | # Platform RTC drivers | ||
| 1079 | # | ||
| 1080 | # CONFIG_RTC_DRV_CMOS is not set | ||
| 1081 | # CONFIG_RTC_DRV_DS1286 is not set | ||
| 1082 | # CONFIG_RTC_DRV_DS1511 is not set | ||
| 1083 | # CONFIG_RTC_DRV_DS1553 is not set | ||
| 1084 | # CONFIG_RTC_DRV_DS1742 is not set | ||
| 1085 | # CONFIG_RTC_DRV_STK17TA8 is not set | ||
| 1086 | # CONFIG_RTC_DRV_M48T86 is not set | ||
| 1087 | # CONFIG_RTC_DRV_M48T35 is not set | ||
| 1088 | # CONFIG_RTC_DRV_M48T59 is not set | ||
| 1089 | # CONFIG_RTC_DRV_BQ4802 is not set | ||
| 1090 | # CONFIG_RTC_DRV_V3020 is not set | ||
| 1091 | |||
| 1092 | # | ||
| 1093 | # on-CPU RTC drivers | ||
| 1094 | # | ||
| 1095 | # CONFIG_RTC_DRV_AT91SAM9 is not set | ||
| 1096 | # CONFIG_DMADEVICES is not set | ||
| 1097 | # CONFIG_AUXDISPLAY is not set | ||
| 1098 | # CONFIG_REGULATOR is not set | ||
| 1099 | # CONFIG_UIO is not set | ||
| 1100 | # CONFIG_STAGING is not set | ||
| 1101 | |||
| 1102 | # | ||
| 1103 | # File systems | ||
| 1104 | # | ||
| 1105 | CONFIG_EXT2_FS=y | ||
| 1106 | # CONFIG_EXT2_FS_XATTR is not set | ||
| 1107 | # CONFIG_EXT2_FS_XIP is not set | ||
| 1108 | CONFIG_EXT3_FS=y | ||
| 1109 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
| 1110 | # CONFIG_EXT3_FS_XATTR is not set | ||
| 1111 | # CONFIG_EXT4_FS is not set | ||
| 1112 | CONFIG_JBD=y | ||
| 1113 | # CONFIG_REISERFS_FS is not set | ||
| 1114 | # CONFIG_JFS_FS is not set | ||
| 1115 | # CONFIG_FS_POSIX_ACL is not set | ||
| 1116 | # CONFIG_XFS_FS is not set | ||
| 1117 | # CONFIG_GFS2_FS is not set | ||
| 1118 | # CONFIG_OCFS2_FS is not set | ||
| 1119 | # CONFIG_BTRFS_FS is not set | ||
| 1120 | CONFIG_FILE_LOCKING=y | ||
| 1121 | CONFIG_FSNOTIFY=y | ||
| 1122 | CONFIG_DNOTIFY=y | ||
| 1123 | CONFIG_INOTIFY=y | ||
| 1124 | CONFIG_INOTIFY_USER=y | ||
| 1125 | # CONFIG_QUOTA is not set | ||
| 1126 | # CONFIG_AUTOFS_FS is not set | ||
| 1127 | CONFIG_AUTOFS4_FS=y | ||
| 1128 | # CONFIG_FUSE_FS is not set | ||
| 1129 | |||
| 1130 | # | ||
| 1131 | # Caches | ||
| 1132 | # | ||
| 1133 | # CONFIG_FSCACHE is not set | ||
| 1134 | |||
| 1135 | # | ||
| 1136 | # CD-ROM/DVD Filesystems | ||
| 1137 | # | ||
| 1138 | # CONFIG_ISO9660_FS is not set | ||
| 1139 | # CONFIG_UDF_FS is not set | ||
| 1140 | |||
| 1141 | # | ||
| 1142 | # DOS/FAT/NT Filesystems | ||
| 1143 | # | ||
| 1144 | CONFIG_FAT_FS=y | ||
| 1145 | CONFIG_MSDOS_FS=y | ||
| 1146 | CONFIG_VFAT_FS=y | ||
| 1147 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
| 1148 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
| 1149 | # CONFIG_NTFS_FS is not set | ||
| 1150 | |||
| 1151 | # | ||
| 1152 | # Pseudo filesystems | ||
| 1153 | # | ||
| 1154 | CONFIG_PROC_FS=y | ||
| 1155 | CONFIG_PROC_SYSCTL=y | ||
| 1156 | CONFIG_PROC_PAGE_MONITOR=y | ||
| 1157 | CONFIG_SYSFS=y | ||
| 1158 | CONFIG_TMPFS=y | ||
| 1159 | # CONFIG_TMPFS_POSIX_ACL is not set | ||
| 1160 | # CONFIG_HUGETLB_PAGE is not set | ||
| 1161 | # CONFIG_CONFIGFS_FS is not set | ||
| 1162 | CONFIG_MISC_FILESYSTEMS=y | ||
| 1163 | # CONFIG_ADFS_FS is not set | ||
| 1164 | # CONFIG_AFFS_FS is not set | ||
| 1165 | # CONFIG_HFS_FS is not set | ||
| 1166 | # CONFIG_HFSPLUS_FS is not set | ||
| 1167 | # CONFIG_BEFS_FS is not set | ||
| 1168 | # CONFIG_BFS_FS is not set | ||
| 1169 | # CONFIG_EFS_FS is not set | ||
| 1170 | CONFIG_JFFS2_FS=y | ||
| 1171 | CONFIG_JFFS2_FS_DEBUG=0 | ||
| 1172 | CONFIG_JFFS2_FS_WRITEBUFFER=y | ||
| 1173 | # CONFIG_JFFS2_FS_WBUF_VERIFY is not set | ||
| 1174 | CONFIG_JFFS2_SUMMARY=y | ||
| 1175 | # CONFIG_JFFS2_FS_XATTR is not set | ||
| 1176 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | ||
| 1177 | CONFIG_JFFS2_ZLIB=y | ||
| 1178 | # CONFIG_JFFS2_LZO is not set | ||
| 1179 | CONFIG_JFFS2_RTIME=y | ||
| 1180 | # CONFIG_JFFS2_RUBIN is not set | ||
| 1181 | CONFIG_CRAMFS=y | ||
| 1182 | # CONFIG_SQUASHFS is not set | ||
| 1183 | # CONFIG_VXFS_FS is not set | ||
| 1184 | CONFIG_MINIX_FS=y | ||
| 1185 | # CONFIG_OMFS_FS is not set | ||
| 1186 | # CONFIG_HPFS_FS is not set | ||
| 1187 | # CONFIG_QNX4FS_FS is not set | ||
| 1188 | # CONFIG_ROMFS_FS is not set | ||
| 1189 | # CONFIG_SYSV_FS is not set | ||
| 1190 | # CONFIG_UFS_FS is not set | ||
| 1191 | # CONFIG_NILFS2_FS is not set | ||
| 1192 | CONFIG_NETWORK_FILESYSTEMS=y | ||
| 1193 | CONFIG_NFS_FS=y | ||
| 1194 | CONFIG_NFS_V3=y | ||
| 1195 | # CONFIG_NFS_V3_ACL is not set | ||
| 1196 | # CONFIG_NFS_V4 is not set | ||
| 1197 | CONFIG_ROOT_NFS=y | ||
| 1198 | # CONFIG_NFSD is not set | ||
| 1199 | CONFIG_LOCKD=y | ||
| 1200 | CONFIG_LOCKD_V4=y | ||
| 1201 | CONFIG_NFS_COMMON=y | ||
| 1202 | CONFIG_SUNRPC=y | ||
| 1203 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
| 1204 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
| 1205 | # CONFIG_SMB_FS is not set | ||
| 1206 | # CONFIG_CIFS is not set | ||
| 1207 | # CONFIG_NCP_FS is not set | ||
| 1208 | # CONFIG_CODA_FS is not set | ||
| 1209 | # CONFIG_AFS_FS is not set | ||
| 1210 | |||
| 1211 | # | ||
| 1212 | # Partition Types | ||
| 1213 | # | ||
| 1214 | CONFIG_PARTITION_ADVANCED=y | ||
| 1215 | # CONFIG_ACORN_PARTITION is not set | ||
| 1216 | # CONFIG_OSF_PARTITION is not set | ||
| 1217 | # CONFIG_AMIGA_PARTITION is not set | ||
| 1218 | # CONFIG_ATARI_PARTITION is not set | ||
| 1219 | # CONFIG_MAC_PARTITION is not set | ||
| 1220 | CONFIG_MSDOS_PARTITION=y | ||
| 1221 | # CONFIG_BSD_DISKLABEL is not set | ||
| 1222 | # CONFIG_MINIX_SUBPARTITION is not set | ||
| 1223 | # CONFIG_SOLARIS_X86_PARTITION is not set | ||
| 1224 | # CONFIG_UNIXWARE_DISKLABEL is not set | ||
| 1225 | # CONFIG_LDM_PARTITION is not set | ||
| 1226 | # CONFIG_SGI_PARTITION is not set | ||
| 1227 | # CONFIG_ULTRIX_PARTITION is not set | ||
| 1228 | # CONFIG_SUN_PARTITION is not set | ||
| 1229 | # CONFIG_KARMA_PARTITION is not set | ||
| 1230 | # CONFIG_EFI_PARTITION is not set | ||
| 1231 | # CONFIG_SYSV68_PARTITION is not set | ||
| 1232 | CONFIG_NLS=y | ||
| 1233 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
| 1234 | CONFIG_NLS_CODEPAGE_437=y | ||
| 1235 | # CONFIG_NLS_CODEPAGE_737 is not set | ||
| 1236 | # CONFIG_NLS_CODEPAGE_775 is not set | ||
| 1237 | # CONFIG_NLS_CODEPAGE_850 is not set | ||
| 1238 | # CONFIG_NLS_CODEPAGE_852 is not set | ||
| 1239 | # CONFIG_NLS_CODEPAGE_855 is not set | ||
| 1240 | # CONFIG_NLS_CODEPAGE_857 is not set | ||
| 1241 | # CONFIG_NLS_CODEPAGE_860 is not set | ||
| 1242 | # CONFIG_NLS_CODEPAGE_861 is not set | ||
| 1243 | # CONFIG_NLS_CODEPAGE_862 is not set | ||
| 1244 | # CONFIG_NLS_CODEPAGE_863 is not set | ||
| 1245 | # CONFIG_NLS_CODEPAGE_864 is not set | ||
| 1246 | # CONFIG_NLS_CODEPAGE_865 is not set | ||
| 1247 | # CONFIG_NLS_CODEPAGE_866 is not set | ||
| 1248 | # CONFIG_NLS_CODEPAGE_869 is not set | ||
| 1249 | # CONFIG_NLS_CODEPAGE_936 is not set | ||
| 1250 | # CONFIG_NLS_CODEPAGE_950 is not set | ||
| 1251 | # CONFIG_NLS_CODEPAGE_932 is not set | ||
| 1252 | # CONFIG_NLS_CODEPAGE_949 is not set | ||
| 1253 | # CONFIG_NLS_CODEPAGE_874 is not set | ||
| 1254 | # CONFIG_NLS_ISO8859_8 is not set | ||
| 1255 | # CONFIG_NLS_CODEPAGE_1250 is not set | ||
| 1256 | # CONFIG_NLS_CODEPAGE_1251 is not set | ||
| 1257 | # CONFIG_NLS_ASCII is not set | ||
| 1258 | CONFIG_NLS_ISO8859_1=y | ||
| 1259 | # CONFIG_NLS_ISO8859_2 is not set | ||
| 1260 | # CONFIG_NLS_ISO8859_3 is not set | ||
| 1261 | # CONFIG_NLS_ISO8859_4 is not set | ||
| 1262 | # CONFIG_NLS_ISO8859_5 is not set | ||
| 1263 | # CONFIG_NLS_ISO8859_6 is not set | ||
| 1264 | # CONFIG_NLS_ISO8859_7 is not set | ||
| 1265 | # CONFIG_NLS_ISO8859_9 is not set | ||
| 1266 | # CONFIG_NLS_ISO8859_13 is not set | ||
| 1267 | # CONFIG_NLS_ISO8859_14 is not set | ||
| 1268 | # CONFIG_NLS_ISO8859_15 is not set | ||
| 1269 | # CONFIG_NLS_KOI8_R is not set | ||
| 1270 | # CONFIG_NLS_KOI8_U is not set | ||
| 1271 | CONFIG_NLS_UTF8=y | ||
| 1272 | # CONFIG_DLM is not set | ||
| 1273 | |||
| 1274 | # | ||
| 1275 | # Kernel hacking | ||
| 1276 | # | ||
| 1277 | # CONFIG_PRINTK_TIME is not set | ||
| 1278 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
| 1279 | CONFIG_ENABLE_MUST_CHECK=y | ||
| 1280 | CONFIG_FRAME_WARN=1024 | ||
| 1281 | # CONFIG_MAGIC_SYSRQ is not set | ||
| 1282 | # CONFIG_UNUSED_SYMBOLS is not set | ||
| 1283 | # CONFIG_DEBUG_FS is not set | ||
| 1284 | # CONFIG_HEADERS_CHECK is not set | ||
| 1285 | # CONFIG_DEBUG_KERNEL is not set | ||
| 1286 | # CONFIG_SLUB_DEBUG_ON is not set | ||
| 1287 | # CONFIG_SLUB_STATS is not set | ||
| 1288 | CONFIG_DEBUG_BUGVERBOSE=y | ||
| 1289 | CONFIG_DEBUG_MEMORY_INIT=y | ||
| 1290 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
| 1291 | # CONFIG_LATENCYTOP is not set | ||
| 1292 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set | ||
| 1293 | CONFIG_HAVE_FUNCTION_TRACER=y | ||
| 1294 | CONFIG_TRACING_SUPPORT=y | ||
| 1295 | # CONFIG_FTRACE is not set | ||
| 1296 | # CONFIG_SAMPLES is not set | ||
| 1297 | CONFIG_HAVE_ARCH_KGDB=y | ||
| 1298 | CONFIG_ARM_UNWIND=y | ||
| 1299 | # CONFIG_DEBUG_USER is not set | ||
| 1300 | |||
| 1301 | # | ||
| 1302 | # Security options | ||
| 1303 | # | ||
| 1304 | # CONFIG_KEYS is not set | ||
| 1305 | # CONFIG_SECURITY is not set | ||
| 1306 | # CONFIG_SECURITYFS is not set | ||
| 1307 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
| 1308 | # CONFIG_CRYPTO is not set | ||
| 1309 | # CONFIG_BINARY_PRINTF is not set | ||
| 1310 | |||
| 1311 | # | ||
| 1312 | # Library routines | ||
| 1313 | # | ||
| 1314 | CONFIG_BITREVERSE=y | ||
| 1315 | CONFIG_GENERIC_FIND_LAST_BIT=y | ||
| 1316 | CONFIG_CRC_CCITT=y | ||
| 1317 | # CONFIG_CRC16 is not set | ||
| 1318 | # CONFIG_CRC_T10DIF is not set | ||
| 1319 | # CONFIG_CRC_ITU_T is not set | ||
| 1320 | CONFIG_CRC32=y | ||
| 1321 | # CONFIG_CRC7 is not set | ||
| 1322 | # CONFIG_LIBCRC32C is not set | ||
| 1323 | CONFIG_ZLIB_INFLATE=y | ||
| 1324 | CONFIG_ZLIB_DEFLATE=y | ||
| 1325 | CONFIG_HAS_IOMEM=y | ||
| 1326 | CONFIG_HAS_IOPORT=y | ||
| 1327 | CONFIG_HAS_DMA=y | ||
| 1328 | CONFIG_NLATTR=y | ||
diff --git a/arch/arm/configs/cpuat91_defconfig b/arch/arm/configs/cpuat91_defconfig new file mode 100644 index 000000000000..4901827253fb --- /dev/null +++ b/arch/arm/configs/cpuat91_defconfig | |||
| @@ -0,0 +1,1316 @@ | |||
| 1 | # | ||
| 2 | # Automatically generated make config: don't edit | ||
| 3 | # Linux kernel version: 2.6.31-rc3 | ||
| 4 | # Tue Jul 14 14:45:01 2009 | ||
| 5 | # | ||
| 6 | CONFIG_ARM=y | ||
| 7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||
| 8 | CONFIG_GENERIC_GPIO=y | ||
| 9 | CONFIG_GENERIC_TIME=y | ||
| 10 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
| 11 | CONFIG_MMU=y | ||
| 12 | CONFIG_GENERIC_HARDIRQS=y | ||
| 13 | CONFIG_STACKTRACE_SUPPORT=y | ||
| 14 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | ||
| 15 | CONFIG_LOCKDEP_SUPPORT=y | ||
| 16 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
| 17 | CONFIG_HARDIRQS_SW_RESEND=y | ||
| 18 | CONFIG_GENERIC_IRQ_PROBE=y | ||
| 19 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
| 20 | CONFIG_GENERIC_HWEIGHT=y | ||
| 21 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
| 22 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | ||
| 23 | CONFIG_VECTORS_BASE=0xffff0000 | ||
| 24 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
| 25 | CONFIG_CONSTRUCTORS=y | ||
| 26 | |||
| 27 | # | ||
| 28 | # General setup | ||
| 29 | # | ||
| 30 | CONFIG_EXPERIMENTAL=y | ||
| 31 | CONFIG_BROKEN_ON_SMP=y | ||
| 32 | CONFIG_LOCK_KERNEL=y | ||
| 33 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
| 34 | CONFIG_LOCALVERSION="" | ||
| 35 | # CONFIG_LOCALVERSION_AUTO is not set | ||
| 36 | # CONFIG_SWAP is not set | ||
| 37 | CONFIG_SYSVIPC=y | ||
| 38 | CONFIG_SYSVIPC_SYSCTL=y | ||
| 39 | # CONFIG_POSIX_MQUEUE is not set | ||
| 40 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
| 41 | # CONFIG_TASKSTATS is not set | ||
| 42 | # CONFIG_AUDIT is not set | ||
| 43 | |||
| 44 | # | ||
| 45 | # RCU Subsystem | ||
| 46 | # | ||
| 47 | CONFIG_CLASSIC_RCU=y | ||
| 48 | # CONFIG_TREE_RCU is not set | ||
| 49 | # CONFIG_PREEMPT_RCU is not set | ||
| 50 | # CONFIG_TREE_RCU_TRACE is not set | ||
| 51 | # CONFIG_PREEMPT_RCU_TRACE is not set | ||
| 52 | # CONFIG_IKCONFIG is not set | ||
| 53 | CONFIG_LOG_BUF_SHIFT=14 | ||
| 54 | # CONFIG_GROUP_SCHED is not set | ||
| 55 | # CONFIG_CGROUPS is not set | ||
| 56 | CONFIG_SYSFS_DEPRECATED=y | ||
| 57 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
| 58 | # CONFIG_RELAY is not set | ||
| 59 | CONFIG_NAMESPACES=y | ||
| 60 | # CONFIG_UTS_NS is not set | ||
| 61 | # CONFIG_IPC_NS is not set | ||
| 62 | # CONFIG_USER_NS is not set | ||
| 63 | # CONFIG_PID_NS is not set | ||
| 64 | # CONFIG_NET_NS is not set | ||
| 65 | # CONFIG_BLK_DEV_INITRD is not set | ||
| 66 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
| 67 | CONFIG_SYSCTL=y | ||
| 68 | CONFIG_ANON_INODES=y | ||
| 69 | # CONFIG_EMBEDDED is not set | ||
| 70 | CONFIG_UID16=y | ||
| 71 | CONFIG_SYSCTL_SYSCALL=y | ||
| 72 | CONFIG_KALLSYMS=y | ||
| 73 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
| 74 | CONFIG_HOTPLUG=y | ||
| 75 | CONFIG_PRINTK=y | ||
| 76 | CONFIG_BUG=y | ||
| 77 | CONFIG_ELF_CORE=y | ||
| 78 | CONFIG_BASE_FULL=y | ||
| 79 | CONFIG_FUTEX=y | ||
| 80 | CONFIG_EPOLL=y | ||
| 81 | CONFIG_SIGNALFD=y | ||
| 82 | CONFIG_TIMERFD=y | ||
| 83 | CONFIG_EVENTFD=y | ||
| 84 | CONFIG_SHMEM=y | ||
| 85 | CONFIG_AIO=y | ||
| 86 | |||
| 87 | # | ||
| 88 | # Performance Counters | ||
| 89 | # | ||
| 90 | CONFIG_VM_EVENT_COUNTERS=y | ||
| 91 | CONFIG_SLUB_DEBUG=y | ||
| 92 | # CONFIG_STRIP_ASM_SYMS is not set | ||
| 93 | CONFIG_COMPAT_BRK=y | ||
| 94 | # CONFIG_SLAB is not set | ||
| 95 | CONFIG_SLUB=y | ||
| 96 | # CONFIG_SLOB is not set | ||
| 97 | # CONFIG_PROFILING is not set | ||
| 98 | # CONFIG_MARKERS is not set | ||
| 99 | CONFIG_HAVE_OPROFILE=y | ||
| 100 | # CONFIG_KPROBES is not set | ||
| 101 | CONFIG_HAVE_KPROBES=y | ||
| 102 | CONFIG_HAVE_KRETPROBES=y | ||
| 103 | CONFIG_HAVE_CLK=y | ||
| 104 | |||
| 105 | # | ||
| 106 | # GCOV-based kernel profiling | ||
| 107 | # | ||
| 108 | # CONFIG_SLOW_WORK is not set | ||
| 109 | CONFIG_HAVE_GENERIC_DMA_COHERENT=y | ||
| 110 | CONFIG_SLABINFO=y | ||
| 111 | CONFIG_RT_MUTEXES=y | ||
| 112 | CONFIG_BASE_SMALL=0 | ||
| 113 | CONFIG_MODULES=y | ||
| 114 | # CONFIG_MODULE_FORCE_LOAD is not set | ||
| 115 | CONFIG_MODULE_UNLOAD=y | ||
| 116 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
| 117 | # CONFIG_MODVERSIONS is not set | ||
| 118 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
| 119 | CONFIG_BLOCK=y | ||
| 120 | CONFIG_LBDAF=y | ||
| 121 | # CONFIG_BLK_DEV_BSG is not set | ||
| 122 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
| 123 | |||
| 124 | # | ||
| 125 | # IO Schedulers | ||
| 126 | # | ||
| 127 | CONFIG_IOSCHED_NOOP=y | ||
| 128 | # CONFIG_IOSCHED_AS is not set | ||
| 129 | CONFIG_IOSCHED_DEADLINE=y | ||
| 130 | # CONFIG_IOSCHED_CFQ is not set | ||
| 131 | # CONFIG_DEFAULT_AS is not set | ||
| 132 | CONFIG_DEFAULT_DEADLINE=y | ||
| 133 | # CONFIG_DEFAULT_CFQ is not set | ||
| 134 | # CONFIG_DEFAULT_NOOP is not set | ||
| 135 | CONFIG_DEFAULT_IOSCHED="deadline" | ||
| 136 | # CONFIG_FREEZER is not set | ||
| 137 | |||
| 138 | # | ||
| 139 | # System Type | ||
| 140 | # | ||
| 141 | # CONFIG_ARCH_AAEC2000 is not set | ||
| 142 | # CONFIG_ARCH_INTEGRATOR is not set | ||
| 143 | # CONFIG_ARCH_REALVIEW is not set | ||
| 144 | # CONFIG_ARCH_VERSATILE is not set | ||
| 145 | CONFIG_ARCH_AT91=y | ||
| 146 | # CONFIG_ARCH_CLPS711X is not set | ||
| 147 | # CONFIG_ARCH_GEMINI is not set | ||
| 148 | # CONFIG_ARCH_EBSA110 is not set | ||
| 149 | # CONFIG_ARCH_EP93XX is not set | ||
| 150 | # CONFIG_ARCH_FOOTBRIDGE is not set | ||
| 151 | # CONFIG_ARCH_MXC is not set | ||
| 152 | # CONFIG_ARCH_STMP3XXX is not set | ||
| 153 | # CONFIG_ARCH_NETX is not set | ||
| 154 | # CONFIG_ARCH_H720X is not set | ||
| 155 | # CONFIG_ARCH_IOP13XX is not set | ||
| 156 | # CONFIG_ARCH_IOP32X is not set | ||
| 157 | # CONFIG_ARCH_IOP33X is not set | ||
| 158 | # CONFIG_ARCH_IXP23XX is not set | ||
| 159 | # CONFIG_ARCH_IXP2000 is not set | ||
| 160 | # CONFIG_ARCH_IXP4XX is not set | ||
| 161 | # CONFIG_ARCH_L7200 is not set | ||
| 162 | # CONFIG_ARCH_KIRKWOOD is not set | ||
| 163 | # CONFIG_ARCH_LOKI is not set | ||
| 164 | # CONFIG_ARCH_MV78XX0 is not set | ||
| 165 | # CONFIG_ARCH_ORION5X is not set | ||
| 166 | # CONFIG_ARCH_MMP is not set | ||
| 167 | # CONFIG_ARCH_KS8695 is not set | ||
| 168 | # CONFIG_ARCH_NS9XXX is not set | ||
| 169 | # CONFIG_ARCH_W90X900 is not set | ||
| 170 | # CONFIG_ARCH_PNX4008 is not set | ||
| 171 | # CONFIG_ARCH_PXA is not set | ||
| 172 | # CONFIG_ARCH_MSM is not set | ||
| 173 | # CONFIG_ARCH_RPC is not set | ||
| 174 | # CONFIG_ARCH_SA1100 is not set | ||
| 175 | # CONFIG_ARCH_S3C2410 is not set | ||
| 176 | # CONFIG_ARCH_S3C64XX is not set | ||
| 177 | # CONFIG_ARCH_SHARK is not set | ||
| 178 | # CONFIG_ARCH_LH7A40X is not set | ||
| 179 | # CONFIG_ARCH_U300 is not set | ||
| 180 | # CONFIG_ARCH_DAVINCI is not set | ||
| 181 | # CONFIG_ARCH_OMAP is not set | ||
| 182 | |||
| 183 | # | ||
| 184 | # Atmel AT91 System-on-Chip | ||
| 185 | # | ||
| 186 | CONFIG_ARCH_AT91RM9200=y | ||
| 187 | # CONFIG_ARCH_AT91SAM9260 is not set | ||
| 188 | # CONFIG_ARCH_AT91SAM9261 is not set | ||
| 189 | # CONFIG_ARCH_AT91SAM9263 is not set | ||
| 190 | # CONFIG_ARCH_AT91SAM9RL is not set | ||
| 191 | # CONFIG_ARCH_AT91SAM9G20 is not set | ||
| 192 | # CONFIG_ARCH_AT91CAP9 is not set | ||
| 193 | # CONFIG_ARCH_AT91X40 is not set | ||
| 194 | CONFIG_AT91_PMC_UNIT=y | ||
| 195 | |||
| 196 | # | ||
| 197 | # AT91RM9200 Board Type | ||
| 198 | # | ||
| 199 | # CONFIG_MACH_ONEARM is not set | ||
| 200 | # CONFIG_ARCH_AT91RM9200DK is not set | ||
| 201 | # CONFIG_MACH_AT91RM9200EK is not set | ||
| 202 | # CONFIG_MACH_CSB337 is not set | ||
| 203 | # CONFIG_MACH_CSB637 is not set | ||
| 204 | # CONFIG_MACH_CARMEVA is not set | ||
| 205 | # CONFIG_MACH_ATEB9200 is not set | ||
| 206 | # CONFIG_MACH_KB9200 is not set | ||
| 207 | # CONFIG_MACH_PICOTUX2XX is not set | ||
| 208 | # CONFIG_MACH_KAFA is not set | ||
| 209 | # CONFIG_MACH_ECBAT91 is not set | ||
| 210 | # CONFIG_MACH_YL9200 is not set | ||
| 211 | CONFIG_MACH_CPUAT91=y | ||
| 212 | |||
| 213 | # | ||
| 214 | # AT91 Board Options | ||
| 215 | # | ||
| 216 | |||
| 217 | # | ||
| 218 | # AT91 Feature Selections | ||
| 219 | # | ||
| 220 | # CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set | ||
| 221 | CONFIG_AT91_TIMER_HZ=100 | ||
| 222 | CONFIG_AT91_EARLY_DBGU=y | ||
| 223 | # CONFIG_AT91_EARLY_USART0 is not set | ||
| 224 | # CONFIG_AT91_EARLY_USART1 is not set | ||
| 225 | # CONFIG_AT91_EARLY_USART2 is not set | ||
| 226 | # CONFIG_AT91_EARLY_USART3 is not set | ||
| 227 | # CONFIG_AT91_EARLY_USART4 is not set | ||
| 228 | # CONFIG_AT91_EARLY_USART5 is not set | ||
| 229 | |||
| 230 | # | ||
| 231 | # Processor Type | ||
| 232 | # | ||
| 233 | CONFIG_CPU_32=y | ||
| 234 | CONFIG_CPU_ARM920T=y | ||
| 235 | CONFIG_CPU_32v4T=y | ||
| 236 | CONFIG_CPU_ABRT_EV4T=y | ||
| 237 | CONFIG_CPU_PABRT_NOIFAR=y | ||
| 238 | CONFIG_CPU_CACHE_V4WT=y | ||
| 239 | CONFIG_CPU_CACHE_VIVT=y | ||
| 240 | CONFIG_CPU_COPY_V4WB=y | ||
| 241 | CONFIG_CPU_TLB_V4WBI=y | ||
| 242 | CONFIG_CPU_CP15=y | ||
| 243 | CONFIG_CPU_CP15_MMU=y | ||
| 244 | |||
| 245 | # | ||
| 246 | # Processor Features | ||
| 247 | # | ||
| 248 | # CONFIG_ARM_THUMB is not set | ||
| 249 | # CONFIG_CPU_ICACHE_DISABLE is not set | ||
| 250 | # CONFIG_CPU_DCACHE_DISABLE is not set | ||
| 251 | # CONFIG_CPU_DCACHE_WRITETHROUGH is not set | ||
| 252 | |||
| 253 | # | ||
| 254 | # Bus support | ||
| 255 | # | ||
| 256 | # CONFIG_PCI_SYSCALL is not set | ||
| 257 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
| 258 | # CONFIG_PCCARD is not set | ||
| 259 | |||
| 260 | # | ||
| 261 | # Kernel Features | ||
| 262 | # | ||
| 263 | # CONFIG_NO_HZ is not set | ||
| 264 | # CONFIG_HIGH_RES_TIMERS is not set | ||
| 265 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | ||
| 266 | CONFIG_VMSPLIT_3G=y | ||
| 267 | # CONFIG_VMSPLIT_2G is not set | ||
| 268 | # CONFIG_VMSPLIT_1G is not set | ||
| 269 | CONFIG_PAGE_OFFSET=0xC0000000 | ||
| 270 | CONFIG_PREEMPT=y | ||
| 271 | CONFIG_HZ=100 | ||
| 272 | # CONFIG_AEABI is not set | ||
| 273 | # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set | ||
| 274 | # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set | ||
| 275 | # CONFIG_HIGHMEM is not set | ||
| 276 | CONFIG_SELECT_MEMORY_MODEL=y | ||
| 277 | CONFIG_FLATMEM_MANUAL=y | ||
| 278 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
| 279 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
| 280 | CONFIG_FLATMEM=y | ||
| 281 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
| 282 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
| 283 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | ||
| 284 | # CONFIG_PHYS_ADDR_T_64BIT is not set | ||
| 285 | CONFIG_ZONE_DMA_FLAG=0 | ||
| 286 | CONFIG_VIRT_TO_BUS=y | ||
| 287 | CONFIG_HAVE_MLOCK=y | ||
| 288 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | ||
| 289 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
| 290 | # CONFIG_LEDS is not set | ||
| 291 | CONFIG_ALIGNMENT_TRAP=y | ||
| 292 | # CONFIG_UACCESS_WITH_MEMCPY is not set | ||
| 293 | |||
| 294 | # | ||
| 295 | # Boot options | ||
| 296 | # | ||
| 297 | CONFIG_ZBOOT_ROM_TEXT=0x0 | ||
| 298 | CONFIG_ZBOOT_ROM_BSS=0x0 | ||
| 299 | CONFIG_CMDLINE="" | ||
| 300 | # CONFIG_XIP_KERNEL is not set | ||
| 301 | # CONFIG_KEXEC is not set | ||
| 302 | |||
| 303 | # | ||
| 304 | # CPU Power Management | ||
| 305 | # | ||
| 306 | # CONFIG_CPU_IDLE is not set | ||
| 307 | |||
| 308 | # | ||
| 309 | # Floating point emulation | ||
| 310 | # | ||
| 311 | |||
| 312 | # | ||
| 313 | # At least one emulation must be selected | ||
| 314 | # | ||
| 315 | # CONFIG_FPE_NWFPE is not set | ||
| 316 | # CONFIG_FPE_FASTFPE is not set | ||
| 317 | |||
| 318 | # | ||
| 319 | # Userspace binary formats | ||
| 320 | # | ||
| 321 | CONFIG_BINFMT_ELF=y | ||
| 322 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
| 323 | CONFIG_HAVE_AOUT=y | ||
| 324 | # CONFIG_BINFMT_AOUT is not set | ||
| 325 | # CONFIG_BINFMT_MISC is not set | ||
| 326 | # CONFIG_ARTHUR is not set | ||
| 327 | |||
| 328 | # | ||
| 329 | # Power management options | ||
| 330 | # | ||
| 331 | # CONFIG_PM is not set | ||
| 332 | CONFIG_ARCH_SUSPEND_POSSIBLE=y | ||
| 333 | CONFIG_NET=y | ||
| 334 | |||
| 335 | # | ||
| 336 | # Networking options | ||
| 337 | # | ||
| 338 | CONFIG_PACKET=y | ||
| 339 | # CONFIG_PACKET_MMAP is not set | ||
| 340 | CONFIG_UNIX=y | ||
| 341 | # CONFIG_NET_KEY is not set | ||
| 342 | CONFIG_INET=y | ||
| 343 | # CONFIG_IP_MULTICAST is not set | ||
| 344 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
| 345 | CONFIG_IP_FIB_HASH=y | ||
| 346 | CONFIG_IP_PNP=y | ||
| 347 | # CONFIG_IP_PNP_DHCP is not set | ||
| 348 | # CONFIG_IP_PNP_BOOTP is not set | ||
| 349 | # CONFIG_IP_PNP_RARP is not set | ||
| 350 | # CONFIG_NET_IPIP is not set | ||
| 351 | # CONFIG_NET_IPGRE is not set | ||
| 352 | # CONFIG_ARPD is not set | ||
| 353 | # CONFIG_SYN_COOKIES is not set | ||
| 354 | # CONFIG_INET_AH is not set | ||
| 355 | # CONFIG_INET_ESP is not set | ||
| 356 | # CONFIG_INET_IPCOMP is not set | ||
| 357 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
| 358 | # CONFIG_INET_TUNNEL is not set | ||
| 359 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
| 360 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
| 361 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
| 362 | CONFIG_INET_LRO=y | ||
| 363 | CONFIG_INET_DIAG=y | ||
| 364 | CONFIG_INET_TCP_DIAG=y | ||
| 365 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
| 366 | CONFIG_TCP_CONG_CUBIC=y | ||
| 367 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
| 368 | # CONFIG_TCP_MD5SIG is not set | ||
| 369 | # CONFIG_IPV6 is not set | ||
| 370 | # CONFIG_NETWORK_SECMARK is not set | ||
| 371 | # CONFIG_NETFILTER is not set | ||
| 372 | # CONFIG_IP_DCCP is not set | ||
| 373 | # CONFIG_IP_SCTP is not set | ||
| 374 | # CONFIG_TIPC is not set | ||
| 375 | # CONFIG_ATM is not set | ||
| 376 | # CONFIG_BRIDGE is not set | ||
| 377 | # CONFIG_NET_DSA is not set | ||
| 378 | # CONFIG_VLAN_8021Q is not set | ||
| 379 | # CONFIG_DECNET is not set | ||
| 380 | # CONFIG_LLC2 is not set | ||
| 381 | # CONFIG_IPX is not set | ||
| 382 | # CONFIG_ATALK is not set | ||
| 383 | # CONFIG_X25 is not set | ||
| 384 | # CONFIG_LAPB is not set | ||
| 385 | # CONFIG_ECONET is not set | ||
| 386 | # CONFIG_WAN_ROUTER is not set | ||
| 387 | # CONFIG_PHONET is not set | ||
| 388 | # CONFIG_IEEE802154 is not set | ||
| 389 | # CONFIG_NET_SCHED is not set | ||
| 390 | # CONFIG_DCB is not set | ||
| 391 | |||
| 392 | # | ||
| 393 | # Network testing | ||
| 394 | # | ||
| 395 | # CONFIG_NET_PKTGEN is not set | ||
| 396 | # CONFIG_HAMRADIO is not set | ||
| 397 | # CONFIG_CAN is not set | ||
| 398 | # CONFIG_IRDA is not set | ||
| 399 | # CONFIG_BT is not set | ||
| 400 | # CONFIG_AF_RXRPC is not set | ||
| 401 | # CONFIG_WIRELESS is not set | ||
| 402 | # CONFIG_WIMAX is not set | ||
| 403 | # CONFIG_RFKILL is not set | ||
| 404 | # CONFIG_NET_9P is not set | ||
| 405 | |||
| 406 | # | ||
| 407 | # Device Drivers | ||
| 408 | # | ||
| 409 | |||
| 410 | # | ||
| 411 | # Generic Driver Options | ||
| 412 | # | ||
| 413 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
| 414 | CONFIG_STANDALONE=y | ||
| 415 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
| 416 | CONFIG_FW_LOADER=y | ||
| 417 | CONFIG_FIRMWARE_IN_KERNEL=y | ||
| 418 | CONFIG_EXTRA_FIRMWARE="" | ||
| 419 | # CONFIG_SYS_HYPERVISOR is not set | ||
| 420 | # CONFIG_CONNECTOR is not set | ||
| 421 | CONFIG_MTD=y | ||
| 422 | # CONFIG_MTD_DEBUG is not set | ||
| 423 | # CONFIG_MTD_CONCAT is not set | ||
| 424 | CONFIG_MTD_PARTITIONS=y | ||
| 425 | # CONFIG_MTD_TESTS is not set | ||
| 426 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
| 427 | CONFIG_MTD_CMDLINE_PARTS=y | ||
| 428 | # CONFIG_MTD_AFS_PARTS is not set | ||
| 429 | # CONFIG_MTD_AR7_PARTS is not set | ||
| 430 | |||
| 431 | # | ||
| 432 | # User Modules And Translation Layers | ||
| 433 | # | ||
| 434 | CONFIG_MTD_CHAR=y | ||
| 435 | CONFIG_MTD_BLKDEVS=y | ||
| 436 | CONFIG_MTD_BLOCK=y | ||
| 437 | # CONFIG_FTL is not set | ||
| 438 | # CONFIG_NFTL is not set | ||
| 439 | # CONFIG_INFTL is not set | ||
| 440 | # CONFIG_RFD_FTL is not set | ||
| 441 | # CONFIG_SSFDC is not set | ||
| 442 | # CONFIG_MTD_OOPS is not set | ||
| 443 | |||
| 444 | # | ||
| 445 | # RAM/ROM/Flash chip drivers | ||
| 446 | # | ||
| 447 | CONFIG_MTD_CFI=y | ||
| 448 | # CONFIG_MTD_JEDECPROBE is not set | ||
| 449 | CONFIG_MTD_GEN_PROBE=y | ||
| 450 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
| 451 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
| 452 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
| 453 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
| 454 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
| 455 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
| 456 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
| 457 | CONFIG_MTD_CFI_I1=y | ||
| 458 | CONFIG_MTD_CFI_I2=y | ||
| 459 | # CONFIG_MTD_CFI_I4 is not set | ||
| 460 | # CONFIG_MTD_CFI_I8 is not set | ||
| 461 | CONFIG_MTD_CFI_INTELEXT=y | ||
| 462 | # CONFIG_MTD_CFI_AMDSTD is not set | ||
| 463 | # CONFIG_MTD_CFI_STAA is not set | ||
| 464 | CONFIG_MTD_CFI_UTIL=y | ||
| 465 | CONFIG_MTD_RAM=y | ||
| 466 | # CONFIG_MTD_ROM is not set | ||
| 467 | # CONFIG_MTD_ABSENT is not set | ||
| 468 | |||
| 469 | # | ||
| 470 | # Mapping drivers for chip access | ||
| 471 | # | ||
| 472 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
| 473 | CONFIG_MTD_PHYSMAP=y | ||
| 474 | # CONFIG_MTD_PHYSMAP_COMPAT is not set | ||
| 475 | # CONFIG_MTD_ARM_INTEGRATOR is not set | ||
| 476 | CONFIG_MTD_PLATRAM=y | ||
| 477 | |||
| 478 | # | ||
| 479 | # Self-contained MTD device drivers | ||
| 480 | # | ||
| 481 | # CONFIG_MTD_SLRAM is not set | ||
| 482 | # CONFIG_MTD_PHRAM is not set | ||
| 483 | # CONFIG_MTD_MTDRAM is not set | ||
| 484 | # CONFIG_MTD_BLOCK2MTD is not set | ||
| 485 | |||
| 486 | # | ||
| 487 | # Disk-On-Chip Device Drivers | ||
| 488 | # | ||
| 489 | # CONFIG_MTD_DOC2000 is not set | ||
| 490 | # CONFIG_MTD_DOC2001 is not set | ||
| 491 | # CONFIG_MTD_DOC2001PLUS is not set | ||
| 492 | # CONFIG_MTD_NAND is not set | ||
| 493 | # CONFIG_MTD_ONENAND is not set | ||
| 494 | |||
| 495 | # | ||
| 496 | # LPDDR flash memory drivers | ||
| 497 | # | ||
| 498 | # CONFIG_MTD_LPDDR is not set | ||
| 499 | |||
| 500 | # | ||
| 501 | # UBI - Unsorted block images | ||
| 502 | # | ||
| 503 | # CONFIG_MTD_UBI is not set | ||
| 504 | # CONFIG_PARPORT is not set | ||
| 505 | CONFIG_BLK_DEV=y | ||
| 506 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
| 507 | CONFIG_BLK_DEV_LOOP=y | ||
| 508 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
| 509 | CONFIG_BLK_DEV_NBD=y | ||
| 510 | # CONFIG_BLK_DEV_UB is not set | ||
| 511 | CONFIG_BLK_DEV_RAM=y | ||
| 512 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
| 513 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
| 514 | # CONFIG_BLK_DEV_XIP is not set | ||
| 515 | # CONFIG_CDROM_PKTCDVD is not set | ||
| 516 | # CONFIG_ATA_OVER_ETH is not set | ||
| 517 | # CONFIG_MG_DISK is not set | ||
| 518 | # CONFIG_MISC_DEVICES is not set | ||
| 519 | CONFIG_HAVE_IDE=y | ||
| 520 | # CONFIG_IDE is not set | ||
| 521 | |||
| 522 | # | ||
| 523 | # SCSI device support | ||
| 524 | # | ||
| 525 | # CONFIG_RAID_ATTRS is not set | ||
| 526 | CONFIG_SCSI=y | ||
| 527 | CONFIG_SCSI_DMA=y | ||
| 528 | # CONFIG_SCSI_TGT is not set | ||
| 529 | # CONFIG_SCSI_NETLINK is not set | ||
| 530 | CONFIG_SCSI_PROC_FS=y | ||
| 531 | |||
| 532 | # | ||
| 533 | # SCSI support type (disk, tape, CD-ROM) | ||
| 534 | # | ||
| 535 | CONFIG_BLK_DEV_SD=y | ||
| 536 | # CONFIG_CHR_DEV_ST is not set | ||
| 537 | # CONFIG_CHR_DEV_OSST is not set | ||
| 538 | # CONFIG_BLK_DEV_SR is not set | ||
| 539 | # CONFIG_CHR_DEV_SG is not set | ||
| 540 | # CONFIG_CHR_DEV_SCH is not set | ||
| 541 | CONFIG_SCSI_MULTI_LUN=y | ||
| 542 | # CONFIG_SCSI_CONSTANTS is not set | ||
| 543 | # CONFIG_SCSI_LOGGING is not set | ||
| 544 | # CONFIG_SCSI_SCAN_ASYNC is not set | ||
| 545 | CONFIG_SCSI_WAIT_SCAN=m | ||
| 546 | |||
| 547 | # | ||
| 548 | # SCSI Transports | ||
| 549 | # | ||
| 550 | # CONFIG_SCSI_SPI_ATTRS is not set | ||
| 551 | # CONFIG_SCSI_FC_ATTRS is not set | ||
| 552 | # CONFIG_SCSI_ISCSI_ATTRS is not set | ||
| 553 | # CONFIG_SCSI_SAS_LIBSAS is not set | ||
| 554 | # CONFIG_SCSI_SRP_ATTRS is not set | ||
| 555 | # CONFIG_SCSI_LOWLEVEL is not set | ||
| 556 | # CONFIG_SCSI_DH is not set | ||
| 557 | # CONFIG_SCSI_OSD_INITIATOR is not set | ||
| 558 | # CONFIG_ATA is not set | ||
| 559 | # CONFIG_MD is not set | ||
| 560 | CONFIG_NETDEVICES=y | ||
| 561 | # CONFIG_DUMMY is not set | ||
| 562 | # CONFIG_BONDING is not set | ||
| 563 | # CONFIG_MACVLAN is not set | ||
| 564 | # CONFIG_EQUALIZER is not set | ||
| 565 | # CONFIG_TUN is not set | ||
| 566 | # CONFIG_VETH is not set | ||
| 567 | CONFIG_PHYLIB=y | ||
| 568 | |||
| 569 | # | ||
| 570 | # MII PHY device drivers | ||
| 571 | # | ||
| 572 | # CONFIG_MARVELL_PHY is not set | ||
| 573 | # CONFIG_DAVICOM_PHY is not set | ||
| 574 | # CONFIG_QSEMI_PHY is not set | ||
| 575 | # CONFIG_LXT_PHY is not set | ||
| 576 | # CONFIG_CICADA_PHY is not set | ||
| 577 | # CONFIG_VITESSE_PHY is not set | ||
| 578 | # CONFIG_SMSC_PHY is not set | ||
| 579 | # CONFIG_BROADCOM_PHY is not set | ||
| 580 | # CONFIG_ICPLUS_PHY is not set | ||
| 581 | # CONFIG_REALTEK_PHY is not set | ||
| 582 | # CONFIG_NATIONAL_PHY is not set | ||
| 583 | # CONFIG_STE10XP is not set | ||
| 584 | # CONFIG_LSI_ET1011C_PHY is not set | ||
| 585 | # CONFIG_FIXED_PHY is not set | ||
| 586 | # CONFIG_MDIO_BITBANG is not set | ||
| 587 | CONFIG_NET_ETHERNET=y | ||
| 588 | CONFIG_MII=y | ||
| 589 | CONFIG_ARM_AT91_ETHER=y | ||
| 590 | # CONFIG_AX88796 is not set | ||
| 591 | # CONFIG_SMC91X is not set | ||
| 592 | # CONFIG_DM9000 is not set | ||
| 593 | # CONFIG_ETHOC is not set | ||
| 594 | # CONFIG_SMC911X is not set | ||
| 595 | # CONFIG_SMSC911X is not set | ||
| 596 | # CONFIG_DNET is not set | ||
| 597 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
| 598 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
| 599 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
| 600 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
| 601 | # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set | ||
| 602 | # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set | ||
| 603 | # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set | ||
| 604 | # CONFIG_B44 is not set | ||
| 605 | # CONFIG_KS8842 is not set | ||
| 606 | # CONFIG_NETDEV_1000 is not set | ||
| 607 | # CONFIG_NETDEV_10000 is not set | ||
| 608 | |||
| 609 | # | ||
| 610 | # Wireless LAN | ||
| 611 | # | ||
| 612 | # CONFIG_WLAN_PRE80211 is not set | ||
| 613 | # CONFIG_WLAN_80211 is not set | ||
| 614 | |||
| 615 | # | ||
| 616 | # Enable WiMAX (Networking options) to see the WiMAX drivers | ||
| 617 | # | ||
| 618 | |||
| 619 | # | ||
| 620 | # USB Network Adapters | ||
| 621 | # | ||
| 622 | # CONFIG_USB_CATC is not set | ||
| 623 | # CONFIG_USB_KAWETH is not set | ||
| 624 | # CONFIG_USB_PEGASUS is not set | ||
| 625 | # CONFIG_USB_RTL8150 is not set | ||
| 626 | # CONFIG_USB_USBNET is not set | ||
| 627 | # CONFIG_WAN is not set | ||
| 628 | CONFIG_PPP=y | ||
| 629 | # CONFIG_PPP_MULTILINK is not set | ||
| 630 | # CONFIG_PPP_FILTER is not set | ||
| 631 | CONFIG_PPP_ASYNC=y | ||
| 632 | # CONFIG_PPP_SYNC_TTY is not set | ||
| 633 | CONFIG_PPP_DEFLATE=y | ||
| 634 | CONFIG_PPP_BSDCOMP=y | ||
| 635 | # CONFIG_PPP_MPPE is not set | ||
| 636 | # CONFIG_PPPOE is not set | ||
| 637 | # CONFIG_PPPOL2TP is not set | ||
| 638 | # CONFIG_SLIP is not set | ||
| 639 | CONFIG_SLHC=y | ||
| 640 | # CONFIG_NETCONSOLE is not set | ||
| 641 | # CONFIG_NETPOLL is not set | ||
| 642 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
| 643 | # CONFIG_ISDN is not set | ||
| 644 | |||
| 645 | # | ||
| 646 | # Input device support | ||
| 647 | # | ||
| 648 | CONFIG_INPUT=y | ||
| 649 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
| 650 | # CONFIG_INPUT_POLLDEV is not set | ||
| 651 | |||
| 652 | # | ||
| 653 | # Userland interfaces | ||
| 654 | # | ||
| 655 | CONFIG_INPUT_MOUSEDEV=y | ||
| 656 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
| 657 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
| 658 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
| 659 | # CONFIG_INPUT_JOYDEV is not set | ||
| 660 | # CONFIG_INPUT_EVDEV is not set | ||
| 661 | # CONFIG_INPUT_EVBUG is not set | ||
| 662 | |||
| 663 | # | ||
| 664 | # Input Device Drivers | ||
| 665 | # | ||
| 666 | # CONFIG_INPUT_KEYBOARD is not set | ||
| 667 | # CONFIG_INPUT_MOUSE is not set | ||
| 668 | # CONFIG_INPUT_JOYSTICK is not set | ||
| 669 | # CONFIG_INPUT_TABLET is not set | ||
| 670 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
| 671 | # CONFIG_INPUT_MISC is not set | ||
| 672 | |||
| 673 | # | ||
| 674 | # Hardware I/O ports | ||
| 675 | # | ||
| 676 | # CONFIG_SERIO is not set | ||
| 677 | # CONFIG_GAMEPORT is not set | ||
| 678 | |||
| 679 | # | ||
| 680 | # Character devices | ||
| 681 | # | ||
| 682 | CONFIG_VT=y | ||
| 683 | CONFIG_CONSOLE_TRANSLATIONS=y | ||
| 684 | CONFIG_VT_CONSOLE=y | ||
| 685 | CONFIG_HW_CONSOLE=y | ||
| 686 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | ||
| 687 | CONFIG_DEVKMEM=y | ||
| 688 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
| 689 | |||
| 690 | # | ||
| 691 | # Serial drivers | ||
| 692 | # | ||
| 693 | # CONFIG_SERIAL_8250 is not set | ||
| 694 | |||
| 695 | # | ||
| 696 | # Non-8250 serial port support | ||
| 697 | # | ||
| 698 | CONFIG_SERIAL_ATMEL=y | ||
| 699 | CONFIG_SERIAL_ATMEL_CONSOLE=y | ||
| 700 | CONFIG_SERIAL_ATMEL_PDC=y | ||
| 701 | # CONFIG_SERIAL_ATMEL_TTYAT is not set | ||
| 702 | CONFIG_SERIAL_CORE=y | ||
| 703 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
| 704 | CONFIG_UNIX98_PTYS=y | ||
| 705 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
| 706 | CONFIG_LEGACY_PTYS=y | ||
| 707 | CONFIG_LEGACY_PTY_COUNT=32 | ||
| 708 | # CONFIG_IPMI_HANDLER is not set | ||
| 709 | # CONFIG_HW_RANDOM is not set | ||
| 710 | # CONFIG_R3964 is not set | ||
| 711 | # CONFIG_RAW_DRIVER is not set | ||
| 712 | # CONFIG_TCG_TPM is not set | ||
| 713 | CONFIG_I2C=y | ||
| 714 | CONFIG_I2C_BOARDINFO=y | ||
| 715 | CONFIG_I2C_CHARDEV=y | ||
| 716 | CONFIG_I2C_HELPER_AUTO=y | ||
| 717 | CONFIG_I2C_ALGOBIT=y | ||
| 718 | |||
| 719 | # | ||
| 720 | # I2C Hardware Bus support | ||
| 721 | # | ||
| 722 | |||
| 723 | # | ||
| 724 | # I2C system bus drivers (mostly embedded / system-on-chip) | ||
| 725 | # | ||
| 726 | # CONFIG_I2C_DESIGNWARE is not set | ||
| 727 | CONFIG_I2C_GPIO=y | ||
| 728 | # CONFIG_I2C_OCORES is not set | ||
| 729 | # CONFIG_I2C_SIMTEC is not set | ||
| 730 | |||
| 731 | # | ||
| 732 | # External I2C/SMBus adapter drivers | ||
| 733 | # | ||
| 734 | # CONFIG_I2C_PARPORT_LIGHT is not set | ||
| 735 | # CONFIG_I2C_TAOS_EVM is not set | ||
| 736 | # CONFIG_I2C_TINY_USB is not set | ||
| 737 | |||
| 738 | # | ||
| 739 | # Other I2C/SMBus bus drivers | ||
| 740 | # | ||
| 741 | # CONFIG_I2C_PCA_PLATFORM is not set | ||
| 742 | # CONFIG_I2C_STUB is not set | ||
| 743 | |||
| 744 | # | ||
| 745 | # Miscellaneous I2C Chip support | ||
| 746 | # | ||
| 747 | # CONFIG_DS1682 is not set | ||
| 748 | # CONFIG_SENSORS_PCF8574 is not set | ||
| 749 | # CONFIG_PCF8575 is not set | ||
| 750 | # CONFIG_SENSORS_PCA9539 is not set | ||
| 751 | # CONFIG_SENSORS_TSL2550 is not set | ||
| 752 | # CONFIG_I2C_DEBUG_CORE is not set | ||
| 753 | # CONFIG_I2C_DEBUG_ALGO is not set | ||
| 754 | # CONFIG_I2C_DEBUG_BUS is not set | ||
| 755 | # CONFIG_I2C_DEBUG_CHIP is not set | ||
| 756 | # CONFIG_SPI is not set | ||
| 757 | CONFIG_ARCH_REQUIRE_GPIOLIB=y | ||
| 758 | CONFIG_GPIOLIB=y | ||
| 759 | CONFIG_GPIO_SYSFS=y | ||
| 760 | |||
| 761 | # | ||
| 762 | # Memory mapped GPIO expanders: | ||
| 763 | # | ||
| 764 | |||
| 765 | # | ||
| 766 | # I2C GPIO expanders: | ||
| 767 | # | ||
| 768 | # CONFIG_GPIO_MAX732X is not set | ||
| 769 | # CONFIG_GPIO_PCA953X is not set | ||
| 770 | # CONFIG_GPIO_PCF857X is not set | ||
| 771 | |||
| 772 | # | ||
| 773 | # PCI GPIO expanders: | ||
| 774 | # | ||
| 775 | |||
| 776 | # | ||
| 777 | # SPI GPIO expanders: | ||
| 778 | # | ||
| 779 | # CONFIG_W1 is not set | ||
| 780 | # CONFIG_POWER_SUPPLY is not set | ||
| 781 | # CONFIG_HWMON is not set | ||
| 782 | # CONFIG_THERMAL is not set | ||
| 783 | # CONFIG_THERMAL_HWMON is not set | ||
| 784 | CONFIG_WATCHDOG=y | ||
| 785 | CONFIG_WATCHDOG_NOWAYOUT=y | ||
| 786 | |||
| 787 | # | ||
| 788 | # Watchdog Device Drivers | ||
| 789 | # | ||
| 790 | # CONFIG_SOFT_WATCHDOG is not set | ||
| 791 | CONFIG_AT91RM9200_WATCHDOG=y | ||
| 792 | |||
| 793 | # | ||
| 794 | # USB-based Watchdog Cards | ||
| 795 | # | ||
| 796 | # CONFIG_USBPCWATCHDOG is not set | ||
| 797 | CONFIG_SSB_POSSIBLE=y | ||
| 798 | |||
| 799 | # | ||
| 800 | # Sonics Silicon Backplane | ||
| 801 | # | ||
| 802 | # CONFIG_SSB is not set | ||
| 803 | |||
| 804 | # | ||
| 805 | # Multifunction device drivers | ||
| 806 | # | ||
| 807 | # CONFIG_MFD_CORE is not set | ||
| 808 | # CONFIG_MFD_SM501 is not set | ||
| 809 | # CONFIG_MFD_ASIC3 is not set | ||
| 810 | # CONFIG_HTC_EGPIO is not set | ||
| 811 | # CONFIG_HTC_PASIC3 is not set | ||
| 812 | # CONFIG_TPS65010 is not set | ||
| 813 | # CONFIG_TWL4030_CORE is not set | ||
| 814 | # CONFIG_MFD_TMIO is not set | ||
| 815 | # CONFIG_MFD_T7L66XB is not set | ||
| 816 | # CONFIG_MFD_TC6387XB is not set | ||
| 817 | # CONFIG_MFD_TC6393XB is not set | ||
| 818 | # CONFIG_PMIC_DA903X is not set | ||
| 819 | # CONFIG_MFD_WM8400 is not set | ||
| 820 | # CONFIG_MFD_WM8350_I2C is not set | ||
| 821 | # CONFIG_MFD_PCF50633 is not set | ||
| 822 | # CONFIG_AB3100_CORE is not set | ||
| 823 | # CONFIG_MEDIA_SUPPORT is not set | ||
| 824 | |||
| 825 | # | ||
| 826 | # Graphics support | ||
| 827 | # | ||
| 828 | # CONFIG_VGASTATE is not set | ||
| 829 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
| 830 | # CONFIG_FB is not set | ||
| 831 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
| 832 | |||
| 833 | # | ||
| 834 | # Display device support | ||
| 835 | # | ||
| 836 | # CONFIG_DISPLAY_SUPPORT is not set | ||
| 837 | |||
| 838 | # | ||
| 839 | # Console display driver support | ||
| 840 | # | ||
| 841 | # CONFIG_VGA_CONSOLE is not set | ||
| 842 | CONFIG_DUMMY_CONSOLE=y | ||
| 843 | # CONFIG_SOUND is not set | ||
| 844 | # CONFIG_HID_SUPPORT is not set | ||
| 845 | CONFIG_USB_SUPPORT=y | ||
| 846 | CONFIG_USB_ARCH_HAS_HCD=y | ||
| 847 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
| 848 | # CONFIG_USB_ARCH_HAS_EHCI is not set | ||
| 849 | CONFIG_USB=y | ||
| 850 | # CONFIG_USB_DEBUG is not set | ||
| 851 | # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set | ||
| 852 | |||
| 853 | # | ||
| 854 | # Miscellaneous USB options | ||
| 855 | # | ||
| 856 | # CONFIG_USB_DEVICEFS is not set | ||
| 857 | # CONFIG_USB_DEVICE_CLASS is not set | ||
| 858 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
| 859 | # CONFIG_USB_OTG is not set | ||
| 860 | # CONFIG_USB_MON is not set | ||
| 861 | # CONFIG_USB_WUSB is not set | ||
| 862 | # CONFIG_USB_WUSB_CBAF is not set | ||
| 863 | |||
| 864 | # | ||
| 865 | # USB Host Controller Drivers | ||
| 866 | # | ||
| 867 | # CONFIG_USB_C67X00_HCD is not set | ||
| 868 | # CONFIG_USB_OXU210HP_HCD is not set | ||
| 869 | # CONFIG_USB_ISP116X_HCD is not set | ||
| 870 | # CONFIG_USB_ISP1760_HCD is not set | ||
| 871 | CONFIG_USB_OHCI_HCD=y | ||
| 872 | # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set | ||
| 873 | # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set | ||
| 874 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
| 875 | # CONFIG_USB_SL811_HCD is not set | ||
| 876 | # CONFIG_USB_R8A66597_HCD is not set | ||
| 877 | # CONFIG_USB_HWA_HCD is not set | ||
| 878 | # CONFIG_USB_MUSB_HDRC is not set | ||
| 879 | # CONFIG_USB_GADGET_MUSB_HDRC is not set | ||
| 880 | |||
| 881 | # | ||
| 882 | # USB Device Class drivers | ||
| 883 | # | ||
| 884 | # CONFIG_USB_ACM is not set | ||
| 885 | # CONFIG_USB_PRINTER is not set | ||
| 886 | # CONFIG_USB_WDM is not set | ||
| 887 | # CONFIG_USB_TMC is not set | ||
| 888 | |||
| 889 | # | ||
| 890 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may | ||
| 891 | # | ||
| 892 | |||
| 893 | # | ||
| 894 | # also be needed; see USB_STORAGE Help for more info | ||
| 895 | # | ||
| 896 | CONFIG_USB_STORAGE=y | ||
| 897 | # CONFIG_USB_STORAGE_DEBUG is not set | ||
| 898 | # CONFIG_USB_STORAGE_DATAFAB is not set | ||
| 899 | # CONFIG_USB_STORAGE_FREECOM is not set | ||
| 900 | # CONFIG_USB_STORAGE_ISD200 is not set | ||
| 901 | # CONFIG_USB_STORAGE_USBAT is not set | ||
| 902 | # CONFIG_USB_STORAGE_SDDR09 is not set | ||
| 903 | # CONFIG_USB_STORAGE_SDDR55 is not set | ||
| 904 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | ||
| 905 | # CONFIG_USB_STORAGE_ALAUDA is not set | ||
| 906 | # CONFIG_USB_STORAGE_ONETOUCH is not set | ||
| 907 | # CONFIG_USB_STORAGE_KARMA is not set | ||
| 908 | # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set | ||
| 909 | # CONFIG_USB_LIBUSUAL is not set | ||
| 910 | |||
| 911 | # | ||
| 912 | # USB Imaging devices | ||
| 913 | # | ||
| 914 | # CONFIG_USB_MDC800 is not set | ||
| 915 | # CONFIG_USB_MICROTEK is not set | ||
| 916 | |||
| 917 | # | ||
| 918 | # USB port drivers | ||
| 919 | # | ||
| 920 | # CONFIG_USB_SERIAL is not set | ||
| 921 | |||
| 922 | # | ||
| 923 | # USB Miscellaneous drivers | ||
| 924 | # | ||
| 925 | # CONFIG_USB_EMI62 is not set | ||
| 926 | # CONFIG_USB_EMI26 is not set | ||
| 927 | # CONFIG_USB_ADUTUX is not set | ||
| 928 | # CONFIG_USB_SEVSEG is not set | ||
| 929 | # CONFIG_USB_RIO500 is not set | ||
| 930 | # CONFIG_USB_LEGOTOWER is not set | ||
| 931 | # CONFIG_USB_LCD is not set | ||
| 932 | # CONFIG_USB_BERRY_CHARGE is not set | ||
| 933 | # CONFIG_USB_LED is not set | ||
| 934 | # CONFIG_USB_CYPRESS_CY7C63 is not set | ||
| 935 | # CONFIG_USB_CYTHERM is not set | ||
| 936 | # CONFIG_USB_IDMOUSE is not set | ||
| 937 | # CONFIG_USB_FTDI_ELAN is not set | ||
| 938 | # CONFIG_USB_APPLEDISPLAY is not set | ||
| 939 | # CONFIG_USB_LD is not set | ||
| 940 | # CONFIG_USB_TRANCEVIBRATOR is not set | ||
| 941 | # CONFIG_USB_IOWARRIOR is not set | ||
| 942 | # CONFIG_USB_ISIGHTFW is not set | ||
| 943 | # CONFIG_USB_VST is not set | ||
| 944 | CONFIG_USB_GADGET=y | ||
| 945 | # CONFIG_USB_GADGET_DEBUG_FILES is not set | ||
| 946 | CONFIG_USB_GADGET_VBUS_DRAW=2 | ||
| 947 | CONFIG_USB_GADGET_SELECTED=y | ||
| 948 | CONFIG_USB_GADGET_AT91=y | ||
| 949 | CONFIG_USB_AT91=y | ||
| 950 | # CONFIG_USB_GADGET_ATMEL_USBA is not set | ||
| 951 | # CONFIG_USB_GADGET_FSL_USB2 is not set | ||
| 952 | # CONFIG_USB_GADGET_LH7A40X is not set | ||
| 953 | # CONFIG_USB_GADGET_OMAP is not set | ||
| 954 | # CONFIG_USB_GADGET_PXA25X is not set | ||
| 955 | # CONFIG_USB_GADGET_PXA27X is not set | ||
| 956 | # CONFIG_USB_GADGET_S3C_HSOTG is not set | ||
| 957 | # CONFIG_USB_GADGET_IMX is not set | ||
| 958 | # CONFIG_USB_GADGET_S3C2410 is not set | ||
| 959 | # CONFIG_USB_GADGET_M66592 is not set | ||
| 960 | # CONFIG_USB_GADGET_AMD5536UDC is not set | ||
| 961 | # CONFIG_USB_GADGET_FSL_QE is not set | ||
| 962 | # CONFIG_USB_GADGET_CI13XXX is not set | ||
| 963 | # CONFIG_USB_GADGET_NET2280 is not set | ||
| 964 | # CONFIG_USB_GADGET_GOKU is not set | ||
| 965 | # CONFIG_USB_GADGET_LANGWELL is not set | ||
| 966 | # CONFIG_USB_GADGET_DUMMY_HCD is not set | ||
| 967 | # CONFIG_USB_GADGET_DUALSPEED is not set | ||
| 968 | # CONFIG_USB_ZERO is not set | ||
| 969 | # CONFIG_USB_AUDIO is not set | ||
| 970 | CONFIG_USB_ETH=y | ||
| 971 | CONFIG_USB_ETH_RNDIS=y | ||
| 972 | # CONFIG_USB_GADGETFS is not set | ||
| 973 | # CONFIG_USB_FILE_STORAGE is not set | ||
| 974 | # CONFIG_USB_G_SERIAL is not set | ||
| 975 | # CONFIG_USB_MIDI_GADGET is not set | ||
| 976 | # CONFIG_USB_G_PRINTER is not set | ||
| 977 | # CONFIG_USB_CDC_COMPOSITE is not set | ||
| 978 | |||
| 979 | # | ||
| 980 | # OTG and related infrastructure | ||
| 981 | # | ||
| 982 | # CONFIG_USB_GPIO_VBUS is not set | ||
| 983 | # CONFIG_NOP_USB_XCEIV is not set | ||
| 984 | CONFIG_MMC=y | ||
| 985 | # CONFIG_MMC_DEBUG is not set | ||
| 986 | # CONFIG_MMC_UNSAFE_RESUME is not set | ||
| 987 | |||
| 988 | # | ||
| 989 | # MMC/SD/SDIO Card Drivers | ||
| 990 | # | ||
| 991 | CONFIG_MMC_BLOCK=y | ||
| 992 | CONFIG_MMC_BLOCK_BOUNCE=y | ||
| 993 | # CONFIG_SDIO_UART is not set | ||
| 994 | # CONFIG_MMC_TEST is not set | ||
| 995 | |||
| 996 | # | ||
| 997 | # MMC/SD/SDIO Host Controller Drivers | ||
| 998 | # | ||
| 999 | # CONFIG_MMC_SDHCI is not set | ||
| 1000 | CONFIG_MMC_AT91=y | ||
| 1001 | # CONFIG_MEMSTICK is not set | ||
| 1002 | # CONFIG_ACCESSIBILITY is not set | ||
| 1003 | CONFIG_NEW_LEDS=y | ||
| 1004 | CONFIG_LEDS_CLASS=y | ||
| 1005 | |||
| 1006 | # | ||
| 1007 | # LED drivers | ||
| 1008 | # | ||
| 1009 | # CONFIG_LEDS_PCA9532 is not set | ||
| 1010 | CONFIG_LEDS_GPIO=y | ||
| 1011 | CONFIG_LEDS_GPIO_PLATFORM=y | ||
| 1012 | # CONFIG_LEDS_LP3944 is not set | ||
| 1013 | # CONFIG_LEDS_PCA955X is not set | ||
| 1014 | # CONFIG_LEDS_BD2802 is not set | ||
| 1015 | |||
| 1016 | # | ||
| 1017 | # LED Triggers | ||
| 1018 | # | ||
| 1019 | CONFIG_LEDS_TRIGGERS=y | ||
| 1020 | CONFIG_LEDS_TRIGGER_TIMER=y | ||
| 1021 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
| 1022 | # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set | ||
| 1023 | CONFIG_LEDS_TRIGGER_GPIO=y | ||
| 1024 | CONFIG_LEDS_TRIGGER_DEFAULT_ON=y | ||
| 1025 | |||
| 1026 | # | ||
| 1027 | # iptables trigger is under Netfilter config (LED target) | ||
| 1028 | # | ||
| 1029 | CONFIG_RTC_LIB=y | ||
| 1030 | CONFIG_RTC_CLASS=y | ||
| 1031 | # CONFIG_RTC_HCTOSYS is not set | ||
| 1032 | # CONFIG_RTC_DEBUG is not set | ||
| 1033 | |||
| 1034 | # | ||
| 1035 | # RTC interfaces | ||
| 1036 | # | ||
| 1037 | CONFIG_RTC_INTF_SYSFS=y | ||
| 1038 | CONFIG_RTC_INTF_PROC=y | ||
| 1039 | CONFIG_RTC_INTF_DEV=y | ||
| 1040 | # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set | ||
| 1041 | # CONFIG_RTC_DRV_TEST is not set | ||
| 1042 | |||
| 1043 | # | ||
| 1044 | # I2C RTC drivers | ||
| 1045 | # | ||
| 1046 | CONFIG_RTC_DRV_DS1307=y | ||
| 1047 | # CONFIG_RTC_DRV_DS1374 is not set | ||
| 1048 | # CONFIG_RTC_DRV_DS1672 is not set | ||
| 1049 | # CONFIG_RTC_DRV_MAX6900 is not set | ||
| 1050 | # CONFIG_RTC_DRV_RS5C372 is not set | ||
| 1051 | # CONFIG_RTC_DRV_ISL1208 is not set | ||
| 1052 | # CONFIG_RTC_DRV_X1205 is not set | ||
| 1053 | CONFIG_RTC_DRV_PCF8563=y | ||
| 1054 | # CONFIG_RTC_DRV_PCF8583 is not set | ||
| 1055 | # CONFIG_RTC_DRV_M41T80 is not set | ||
| 1056 | # CONFIG_RTC_DRV_S35390A is not set | ||
| 1057 | # CONFIG_RTC_DRV_FM3130 is not set | ||
| 1058 | # CONFIG_RTC_DRV_RX8581 is not set | ||
| 1059 | # CONFIG_RTC_DRV_RX8025 is not set | ||
| 1060 | |||
| 1061 | # | ||
| 1062 | # SPI RTC drivers | ||
| 1063 | # | ||
| 1064 | |||
| 1065 | # | ||
| 1066 | # Platform RTC drivers | ||
| 1067 | # | ||
| 1068 | # CONFIG_RTC_DRV_CMOS is not set | ||
| 1069 | # CONFIG_RTC_DRV_DS1286 is not set | ||
| 1070 | # CONFIG_RTC_DRV_DS1511 is not set | ||
| 1071 | # CONFIG_RTC_DRV_DS1553 is not set | ||
| 1072 | # CONFIG_RTC_DRV_DS1742 is not set | ||
| 1073 | # CONFIG_RTC_DRV_STK17TA8 is not set | ||
| 1074 | # CONFIG_RTC_DRV_M48T86 is not set | ||
| 1075 | # CONFIG_RTC_DRV_M48T35 is not set | ||
| 1076 | # CONFIG_RTC_DRV_M48T59 is not set | ||
| 1077 | # CONFIG_RTC_DRV_BQ4802 is not set | ||
| 1078 | # CONFIG_RTC_DRV_V3020 is not set | ||
| 1079 | |||
| 1080 | # | ||
| 1081 | # on-CPU RTC drivers | ||
| 1082 | # | ||
| 1083 | # CONFIG_RTC_DRV_AT91RM9200 is not set | ||
| 1084 | # CONFIG_DMADEVICES is not set | ||
| 1085 | # CONFIG_AUXDISPLAY is not set | ||
| 1086 | # CONFIG_REGULATOR is not set | ||
| 1087 | # CONFIG_UIO is not set | ||
| 1088 | # CONFIG_STAGING is not set | ||
| 1089 | |||
| 1090 | # | ||
| 1091 | # File systems | ||
| 1092 | # | ||
| 1093 | CONFIG_EXT2_FS=y | ||
| 1094 | # CONFIG_EXT2_FS_XATTR is not set | ||
| 1095 | # CONFIG_EXT2_FS_XIP is not set | ||
| 1096 | CONFIG_EXT3_FS=y | ||
| 1097 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
| 1098 | # CONFIG_EXT3_FS_XATTR is not set | ||
| 1099 | # CONFIG_EXT4_FS is not set | ||
| 1100 | CONFIG_JBD=y | ||
| 1101 | # CONFIG_REISERFS_FS is not set | ||
| 1102 | # CONFIG_JFS_FS is not set | ||
| 1103 | # CONFIG_FS_POSIX_ACL is not set | ||
| 1104 | # CONFIG_XFS_FS is not set | ||
| 1105 | # CONFIG_GFS2_FS is not set | ||
| 1106 | # CONFIG_OCFS2_FS is not set | ||
| 1107 | # CONFIG_BTRFS_FS is not set | ||
| 1108 | CONFIG_FILE_LOCKING=y | ||
| 1109 | CONFIG_FSNOTIFY=y | ||
| 1110 | CONFIG_DNOTIFY=y | ||
| 1111 | CONFIG_INOTIFY=y | ||
| 1112 | CONFIG_INOTIFY_USER=y | ||
| 1113 | # CONFIG_QUOTA is not set | ||
| 1114 | # CONFIG_AUTOFS_FS is not set | ||
| 1115 | CONFIG_AUTOFS4_FS=y | ||
| 1116 | # CONFIG_FUSE_FS is not set | ||
| 1117 | |||
| 1118 | # | ||
| 1119 | # Caches | ||
| 1120 | # | ||
| 1121 | # CONFIG_FSCACHE is not set | ||
| 1122 | |||
| 1123 | # | ||
| 1124 | # CD-ROM/DVD Filesystems | ||
| 1125 | # | ||
| 1126 | # CONFIG_ISO9660_FS is not set | ||
| 1127 | # CONFIG_UDF_FS is not set | ||
| 1128 | |||
| 1129 | # | ||
| 1130 | # DOS/FAT/NT Filesystems | ||
| 1131 | # | ||
| 1132 | CONFIG_FAT_FS=y | ||
| 1133 | CONFIG_MSDOS_FS=y | ||
| 1134 | CONFIG_VFAT_FS=y | ||
| 1135 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
| 1136 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
| 1137 | # CONFIG_NTFS_FS is not set | ||
| 1138 | |||
| 1139 | # | ||
| 1140 | # Pseudo filesystems | ||
| 1141 | # | ||
| 1142 | CONFIG_PROC_FS=y | ||
| 1143 | CONFIG_PROC_SYSCTL=y | ||
| 1144 | CONFIG_PROC_PAGE_MONITOR=y | ||
| 1145 | CONFIG_SYSFS=y | ||
| 1146 | CONFIG_TMPFS=y | ||
| 1147 | # CONFIG_TMPFS_POSIX_ACL is not set | ||
| 1148 | # CONFIG_HUGETLB_PAGE is not set | ||
| 1149 | # CONFIG_CONFIGFS_FS is not set | ||
| 1150 | CONFIG_MISC_FILESYSTEMS=y | ||
| 1151 | # CONFIG_ADFS_FS is not set | ||
| 1152 | # CONFIG_AFFS_FS is not set | ||
| 1153 | # CONFIG_HFS_FS is not set | ||
| 1154 | # CONFIG_HFSPLUS_FS is not set | ||
| 1155 | # CONFIG_BEFS_FS is not set | ||
| 1156 | # CONFIG_BFS_FS is not set | ||
| 1157 | # CONFIG_EFS_FS is not set | ||
| 1158 | CONFIG_JFFS2_FS=y | ||
| 1159 | CONFIG_JFFS2_FS_DEBUG=0 | ||
| 1160 | CONFIG_JFFS2_FS_WRITEBUFFER=y | ||
| 1161 | # CONFIG_JFFS2_FS_WBUF_VERIFY is not set | ||
| 1162 | CONFIG_JFFS2_SUMMARY=y | ||
| 1163 | # CONFIG_JFFS2_FS_XATTR is not set | ||
| 1164 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | ||
| 1165 | CONFIG_JFFS2_ZLIB=y | ||
| 1166 | # CONFIG_JFFS2_LZO is not set | ||
| 1167 | CONFIG_JFFS2_RTIME=y | ||
| 1168 | # CONFIG_JFFS2_RUBIN is not set | ||
| 1169 | CONFIG_CRAMFS=y | ||
| 1170 | # CONFIG_SQUASHFS is not set | ||
| 1171 | # CONFIG_VXFS_FS is not set | ||
| 1172 | CONFIG_MINIX_FS=y | ||
| 1173 | # CONFIG_OMFS_FS is not set | ||
| 1174 | # CONFIG_HPFS_FS is not set | ||
| 1175 | # CONFIG_QNX4FS_FS is not set | ||
| 1176 | # CONFIG_ROMFS_FS is not set | ||
| 1177 | # CONFIG_SYSV_FS is not set | ||
| 1178 | # CONFIG_UFS_FS is not set | ||
| 1179 | # CONFIG_NILFS2_FS is not set | ||
| 1180 | CONFIG_NETWORK_FILESYSTEMS=y | ||
| 1181 | CONFIG_NFS_FS=y | ||
| 1182 | CONFIG_NFS_V3=y | ||
| 1183 | # CONFIG_NFS_V3_ACL is not set | ||
| 1184 | # CONFIG_NFS_V4 is not set | ||
| 1185 | CONFIG_ROOT_NFS=y | ||
| 1186 | # CONFIG_NFSD is not set | ||
| 1187 | CONFIG_LOCKD=y | ||
| 1188 | CONFIG_LOCKD_V4=y | ||
| 1189 | CONFIG_NFS_COMMON=y | ||
| 1190 | CONFIG_SUNRPC=y | ||
| 1191 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
| 1192 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
| 1193 | # CONFIG_SMB_FS is not set | ||
| 1194 | # CONFIG_CIFS is not set | ||
| 1195 | # CONFIG_NCP_FS is not set | ||
| 1196 | # CONFIG_CODA_FS is not set | ||
| 1197 | # CONFIG_AFS_FS is not set | ||
| 1198 | |||
| 1199 | # | ||
| 1200 | # Partition Types | ||
| 1201 | # | ||
| 1202 | CONFIG_PARTITION_ADVANCED=y | ||
| 1203 | # CONFIG_ACORN_PARTITION is not set | ||
| 1204 | # CONFIG_OSF_PARTITION is not set | ||
| 1205 | # CONFIG_AMIGA_PARTITION is not set | ||
| 1206 | # CONFIG_ATARI_PARTITION is not set | ||
| 1207 | # CONFIG_MAC_PARTITION is not set | ||
| 1208 | CONFIG_MSDOS_PARTITION=y | ||
| 1209 | # CONFIG_BSD_DISKLABEL is not set | ||
| 1210 | # CONFIG_MINIX_SUBPARTITION is not set | ||
| 1211 | # CONFIG_SOLARIS_X86_PARTITION is not set | ||
| 1212 | # CONFIG_UNIXWARE_DISKLABEL is not set | ||
| 1213 | # CONFIG_LDM_PARTITION is not set | ||
| 1214 | # CONFIG_SGI_PARTITION is not set | ||
| 1215 | # CONFIG_ULTRIX_PARTITION is not set | ||
| 1216 | # CONFIG_SUN_PARTITION is not set | ||
| 1217 | # CONFIG_KARMA_PARTITION is not set | ||
| 1218 | # CONFIG_EFI_PARTITION is not set | ||
| 1219 | # CONFIG_SYSV68_PARTITION is not set | ||
| 1220 | CONFIG_NLS=y | ||
| 1221 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
| 1222 | CONFIG_NLS_CODEPAGE_437=y | ||
| 1223 | # CONFIG_NLS_CODEPAGE_737 is not set | ||
| 1224 | # CONFIG_NLS_CODEPAGE_775 is not set | ||
| 1225 | # CONFIG_NLS_CODEPAGE_850 is not set | ||
| 1226 | # CONFIG_NLS_CODEPAGE_852 is not set | ||
| 1227 | # CONFIG_NLS_CODEPAGE_855 is not set | ||
| 1228 | # CONFIG_NLS_CODEPAGE_857 is not set | ||
| 1229 | # CONFIG_NLS_CODEPAGE_860 is not set | ||
| 1230 | # CONFIG_NLS_CODEPAGE_861 is not set | ||
| 1231 | # CONFIG_NLS_CODEPAGE_862 is not set | ||
| 1232 | # CONFIG_NLS_CODEPAGE_863 is not set | ||
| 1233 | # CONFIG_NLS_CODEPAGE_864 is not set | ||
| 1234 | # CONFIG_NLS_CODEPAGE_865 is not set | ||
| 1235 | # CONFIG_NLS_CODEPAGE_866 is not set | ||
| 1236 | # CONFIG_NLS_CODEPAGE_869 is not set | ||
| 1237 | # CONFIG_NLS_CODEPAGE_936 is not set | ||
| 1238 | # CONFIG_NLS_CODEPAGE_950 is not set | ||
| 1239 | # CONFIG_NLS_CODEPAGE_932 is not set | ||
| 1240 | # CONFIG_NLS_CODEPAGE_949 is not set | ||
| 1241 | # CONFIG_NLS_CODEPAGE_874 is not set | ||
| 1242 | # CONFIG_NLS_ISO8859_8 is not set | ||
| 1243 | # CONFIG_NLS_CODEPAGE_1250 is not set | ||
| 1244 | # CONFIG_NLS_CODEPAGE_1251 is not set | ||
| 1245 | # CONFIG_NLS_ASCII is not set | ||
| 1246 | CONFIG_NLS_ISO8859_1=y | ||
| 1247 | # CONFIG_NLS_ISO8859_2 is not set | ||
| 1248 | # CONFIG_NLS_ISO8859_3 is not set | ||
| 1249 | # CONFIG_NLS_ISO8859_4 is not set | ||
| 1250 | # CONFIG_NLS_ISO8859_5 is not set | ||
| 1251 | # CONFIG_NLS_ISO8859_6 is not set | ||
| 1252 | # CONFIG_NLS_ISO8859_7 is not set | ||
| 1253 | # CONFIG_NLS_ISO8859_9 is not set | ||
| 1254 | # CONFIG_NLS_ISO8859_13 is not set | ||
| 1255 | # CONFIG_NLS_ISO8859_14 is not set | ||
| 1256 | # CONFIG_NLS_ISO8859_15 is not set | ||
| 1257 | # CONFIG_NLS_KOI8_R is not set | ||
| 1258 | # CONFIG_NLS_KOI8_U is not set | ||
| 1259 | CONFIG_NLS_UTF8=y | ||
| 1260 | # CONFIG_DLM is not set | ||
| 1261 | |||
| 1262 | # | ||
| 1263 | # Kernel hacking | ||
| 1264 | # | ||
| 1265 | # CONFIG_PRINTK_TIME is not set | ||
| 1266 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
| 1267 | CONFIG_ENABLE_MUST_CHECK=y | ||
| 1268 | CONFIG_FRAME_WARN=1024 | ||
| 1269 | # CONFIG_MAGIC_SYSRQ is not set | ||
| 1270 | # CONFIG_UNUSED_SYMBOLS is not set | ||
| 1271 | # CONFIG_DEBUG_FS is not set | ||
| 1272 | # CONFIG_HEADERS_CHECK is not set | ||
| 1273 | # CONFIG_DEBUG_KERNEL is not set | ||
| 1274 | # CONFIG_SLUB_DEBUG_ON is not set | ||
| 1275 | # CONFIG_SLUB_STATS is not set | ||
| 1276 | CONFIG_DEBUG_BUGVERBOSE=y | ||
| 1277 | CONFIG_DEBUG_MEMORY_INIT=y | ||
| 1278 | CONFIG_FRAME_POINTER=y | ||
| 1279 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
| 1280 | # CONFIG_LATENCYTOP is not set | ||
| 1281 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set | ||
| 1282 | CONFIG_HAVE_FUNCTION_TRACER=y | ||
| 1283 | CONFIG_TRACING_SUPPORT=y | ||
| 1284 | # CONFIG_FTRACE is not set | ||
| 1285 | # CONFIG_SAMPLES is not set | ||
| 1286 | CONFIG_HAVE_ARCH_KGDB=y | ||
| 1287 | # CONFIG_DEBUG_USER is not set | ||
| 1288 | |||
| 1289 | # | ||
| 1290 | # Security options | ||
| 1291 | # | ||
| 1292 | # CONFIG_KEYS is not set | ||
| 1293 | # CONFIG_SECURITY is not set | ||
| 1294 | # CONFIG_SECURITYFS is not set | ||
| 1295 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
| 1296 | # CONFIG_CRYPTO is not set | ||
| 1297 | # CONFIG_BINARY_PRINTF is not set | ||
| 1298 | |||
| 1299 | # | ||
| 1300 | # Library routines | ||
| 1301 | # | ||
| 1302 | CONFIG_BITREVERSE=y | ||
| 1303 | CONFIG_GENERIC_FIND_LAST_BIT=y | ||
| 1304 | CONFIG_CRC_CCITT=y | ||
| 1305 | # CONFIG_CRC16 is not set | ||
| 1306 | # CONFIG_CRC_T10DIF is not set | ||
| 1307 | # CONFIG_CRC_ITU_T is not set | ||
| 1308 | CONFIG_CRC32=y | ||
| 1309 | # CONFIG_CRC7 is not set | ||
| 1310 | # CONFIG_LIBCRC32C is not set | ||
| 1311 | CONFIG_ZLIB_INFLATE=y | ||
| 1312 | CONFIG_ZLIB_DEFLATE=y | ||
| 1313 | CONFIG_HAS_IOMEM=y | ||
| 1314 | CONFIG_HAS_IOPORT=y | ||
| 1315 | CONFIG_HAS_DMA=y | ||
| 1316 | CONFIG_NLATTR=y | ||
diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig index f3074e49f2fa..df9bfbea8612 100644 --- a/arch/arm/configs/jornada720_defconfig +++ b/arch/arm/configs/jornada720_defconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.27-rc6 | 3 | # Linux kernel version: 2.6.31-rc6 |
| 4 | # Tue Sep 16 18:56:58 2008 | 4 | # Fri Aug 21 15:41:39 2009 |
| 5 | # | 5 | # |
| 6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
| 7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | 7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y |
| @@ -9,7 +9,6 @@ CONFIG_GENERIC_GPIO=y | |||
| 9 | CONFIG_GENERIC_TIME=y | 9 | CONFIG_GENERIC_TIME=y |
| 10 | CONFIG_GENERIC_CLOCKEVENTS=y | 10 | CONFIG_GENERIC_CLOCKEVENTS=y |
| 11 | CONFIG_MMU=y | 11 | CONFIG_MMU=y |
| 12 | # CONFIG_NO_IOPORT is not set | ||
| 13 | CONFIG_GENERIC_HARDIRQS=y | 12 | CONFIG_GENERIC_HARDIRQS=y |
| 14 | CONFIG_STACKTRACE_SUPPORT=y | 13 | CONFIG_STACKTRACE_SUPPORT=y |
| 15 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | 14 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y |
| @@ -18,16 +17,14 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y | |||
| 18 | CONFIG_HARDIRQS_SW_RESEND=y | 17 | CONFIG_HARDIRQS_SW_RESEND=y |
| 19 | CONFIG_GENERIC_IRQ_PROBE=y | 18 | CONFIG_GENERIC_IRQ_PROBE=y |
| 20 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 19 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
| 21 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set | ||
| 22 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | ||
| 23 | CONFIG_GENERIC_HWEIGHT=y | 20 | CONFIG_GENERIC_HWEIGHT=y |
| 24 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 21 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
| 25 | CONFIG_ARCH_SUPPORTS_AOUT=y | ||
| 26 | CONFIG_ZONE_DMA=y | 22 | CONFIG_ZONE_DMA=y |
| 27 | CONFIG_ARCH_MTD_XIP=y | 23 | CONFIG_ARCH_MTD_XIP=y |
| 28 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | 24 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y |
| 29 | CONFIG_VECTORS_BASE=0xffff0000 | 25 | CONFIG_VECTORS_BASE=0xffff0000 |
| 30 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 26 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
| 27 | CONFIG_CONSTRUCTORS=y | ||
| 31 | 28 | ||
| 32 | # | 29 | # |
| 33 | # General setup | 30 | # General setup |
| @@ -44,10 +41,19 @@ CONFIG_SYSVIPC_SYSCTL=y | |||
| 44 | # CONFIG_BSD_PROCESS_ACCT is not set | 41 | # CONFIG_BSD_PROCESS_ACCT is not set |
| 45 | # CONFIG_TASKSTATS is not set | 42 | # CONFIG_TASKSTATS is not set |
| 46 | # CONFIG_AUDIT is not set | 43 | # CONFIG_AUDIT is not set |
| 44 | |||
| 45 | # | ||
| 46 | # RCU Subsystem | ||
| 47 | # | ||
| 48 | CONFIG_CLASSIC_RCU=y | ||
| 49 | # CONFIG_TREE_RCU is not set | ||
| 50 | # CONFIG_PREEMPT_RCU is not set | ||
| 51 | # CONFIG_TREE_RCU_TRACE is not set | ||
| 52 | # CONFIG_PREEMPT_RCU_TRACE is not set | ||
| 47 | # CONFIG_IKCONFIG is not set | 53 | # CONFIG_IKCONFIG is not set |
| 48 | CONFIG_LOG_BUF_SHIFT=14 | 54 | CONFIG_LOG_BUF_SHIFT=14 |
| 49 | # CONFIG_CGROUPS is not set | ||
| 50 | # CONFIG_GROUP_SCHED is not set | 55 | # CONFIG_GROUP_SCHED is not set |
| 56 | # CONFIG_CGROUPS is not set | ||
| 51 | CONFIG_SYSFS_DEPRECATED=y | 57 | CONFIG_SYSFS_DEPRECATED=y |
| 52 | CONFIG_SYSFS_DEPRECATED_V2=y | 58 | CONFIG_SYSFS_DEPRECATED_V2=y |
| 53 | # CONFIG_RELAY is not set | 59 | # CONFIG_RELAY is not set |
| @@ -56,9 +62,11 @@ CONFIG_NAMESPACES=y | |||
| 56 | # CONFIG_IPC_NS is not set | 62 | # CONFIG_IPC_NS is not set |
| 57 | # CONFIG_USER_NS is not set | 63 | # CONFIG_USER_NS is not set |
| 58 | # CONFIG_PID_NS is not set | 64 | # CONFIG_PID_NS is not set |
| 65 | # CONFIG_NET_NS is not set | ||
| 59 | # CONFIG_BLK_DEV_INITRD is not set | 66 | # CONFIG_BLK_DEV_INITRD is not set |
| 60 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 67 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
| 61 | CONFIG_SYSCTL=y | 68 | CONFIG_SYSCTL=y |
| 69 | CONFIG_ANON_INODES=y | ||
| 62 | # CONFIG_EMBEDDED is not set | 70 | # CONFIG_EMBEDDED is not set |
| 63 | CONFIG_UID16=y | 71 | CONFIG_UID16=y |
| 64 | CONFIG_SYSCTL_SYSCALL=y | 72 | CONFIG_SYSCTL_SYSCALL=y |
| @@ -69,17 +77,22 @@ CONFIG_HOTPLUG=y | |||
| 69 | CONFIG_PRINTK=y | 77 | CONFIG_PRINTK=y |
| 70 | CONFIG_BUG=y | 78 | CONFIG_BUG=y |
| 71 | CONFIG_ELF_CORE=y | 79 | CONFIG_ELF_CORE=y |
| 72 | CONFIG_COMPAT_BRK=y | ||
| 73 | CONFIG_BASE_FULL=y | 80 | CONFIG_BASE_FULL=y |
| 74 | CONFIG_FUTEX=y | 81 | CONFIG_FUTEX=y |
| 75 | CONFIG_ANON_INODES=y | ||
| 76 | CONFIG_EPOLL=y | 82 | CONFIG_EPOLL=y |
| 77 | CONFIG_SIGNALFD=y | 83 | CONFIG_SIGNALFD=y |
| 78 | CONFIG_TIMERFD=y | 84 | CONFIG_TIMERFD=y |
| 79 | CONFIG_EVENTFD=y | 85 | CONFIG_EVENTFD=y |
| 80 | CONFIG_SHMEM=y | 86 | CONFIG_SHMEM=y |
| 87 | CONFIG_AIO=y | ||
| 88 | |||
| 89 | # | ||
| 90 | # Performance Counters | ||
| 91 | # | ||
| 81 | CONFIG_VM_EVENT_COUNTERS=y | 92 | CONFIG_VM_EVENT_COUNTERS=y |
| 82 | CONFIG_SLUB_DEBUG=y | 93 | CONFIG_SLUB_DEBUG=y |
| 94 | # CONFIG_STRIP_ASM_SYMS is not set | ||
| 95 | CONFIG_COMPAT_BRK=y | ||
| 83 | # CONFIG_SLAB is not set | 96 | # CONFIG_SLAB is not set |
| 84 | CONFIG_SLUB=y | 97 | CONFIG_SLUB=y |
| 85 | # CONFIG_SLOB is not set | 98 | # CONFIG_SLOB is not set |
| @@ -87,30 +100,25 @@ CONFIG_SLUB=y | |||
| 87 | # CONFIG_MARKERS is not set | 100 | # CONFIG_MARKERS is not set |
| 88 | CONFIG_HAVE_OPROFILE=y | 101 | CONFIG_HAVE_OPROFILE=y |
| 89 | # CONFIG_KPROBES is not set | 102 | # CONFIG_KPROBES is not set |
| 90 | # CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set | ||
| 91 | # CONFIG_HAVE_IOREMAP_PROT is not set | ||
| 92 | CONFIG_HAVE_KPROBES=y | 103 | CONFIG_HAVE_KPROBES=y |
| 93 | CONFIG_HAVE_KRETPROBES=y | 104 | CONFIG_HAVE_KRETPROBES=y |
| 94 | # CONFIG_HAVE_ARCH_TRACEHOOK is not set | ||
| 95 | # CONFIG_HAVE_DMA_ATTRS is not set | ||
| 96 | # CONFIG_USE_GENERIC_SMP_HELPERS is not set | ||
| 97 | CONFIG_HAVE_CLK=y | 105 | CONFIG_HAVE_CLK=y |
| 98 | CONFIG_PROC_PAGE_MONITOR=y | 106 | |
| 107 | # | ||
| 108 | # GCOV-based kernel profiling | ||
| 109 | # | ||
| 110 | # CONFIG_SLOW_WORK is not set | ||
| 99 | CONFIG_HAVE_GENERIC_DMA_COHERENT=y | 111 | CONFIG_HAVE_GENERIC_DMA_COHERENT=y |
| 100 | CONFIG_SLABINFO=y | 112 | CONFIG_SLABINFO=y |
| 101 | CONFIG_RT_MUTEXES=y | 113 | CONFIG_RT_MUTEXES=y |
| 102 | # CONFIG_TINY_SHMEM is not set | ||
| 103 | CONFIG_BASE_SMALL=0 | 114 | CONFIG_BASE_SMALL=0 |
| 104 | CONFIG_MODULES=y | 115 | CONFIG_MODULES=y |
| 105 | # CONFIG_MODULE_FORCE_LOAD is not set | 116 | # CONFIG_MODULE_FORCE_LOAD is not set |
| 106 | # CONFIG_MODULE_UNLOAD is not set | 117 | # CONFIG_MODULE_UNLOAD is not set |
| 107 | # CONFIG_MODVERSIONS is not set | 118 | # CONFIG_MODVERSIONS is not set |
| 108 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 119 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
| 109 | CONFIG_KMOD=y | ||
| 110 | CONFIG_BLOCK=y | 120 | CONFIG_BLOCK=y |
| 111 | # CONFIG_LBD is not set | 121 | CONFIG_LBDAF=y |
| 112 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
| 113 | # CONFIG_LSF is not set | ||
| 114 | # CONFIG_BLK_DEV_BSG is not set | 122 | # CONFIG_BLK_DEV_BSG is not set |
| 115 | # CONFIG_BLK_DEV_INTEGRITY is not set | 123 | # CONFIG_BLK_DEV_INTEGRITY is not set |
| 116 | 124 | ||
| @@ -126,7 +134,7 @@ CONFIG_IOSCHED_CFQ=y | |||
| 126 | CONFIG_DEFAULT_CFQ=y | 134 | CONFIG_DEFAULT_CFQ=y |
| 127 | # CONFIG_DEFAULT_NOOP is not set | 135 | # CONFIG_DEFAULT_NOOP is not set |
| 128 | CONFIG_DEFAULT_IOSCHED="cfq" | 136 | CONFIG_DEFAULT_IOSCHED="cfq" |
| 129 | CONFIG_CLASSIC_RCU=y | 137 | CONFIG_FREEZER=y |
| 130 | 138 | ||
| 131 | # | 139 | # |
| 132 | # System Type | 140 | # System Type |
| @@ -136,14 +144,15 @@ CONFIG_CLASSIC_RCU=y | |||
| 136 | # CONFIG_ARCH_REALVIEW is not set | 144 | # CONFIG_ARCH_REALVIEW is not set |
| 137 | # CONFIG_ARCH_VERSATILE is not set | 145 | # CONFIG_ARCH_VERSATILE is not set |
| 138 | # CONFIG_ARCH_AT91 is not set | 146 | # CONFIG_ARCH_AT91 is not set |
| 139 | # CONFIG_ARCH_CLPS7500 is not set | ||
| 140 | # CONFIG_ARCH_CLPS711X is not set | 147 | # CONFIG_ARCH_CLPS711X is not set |
| 148 | # CONFIG_ARCH_GEMINI is not set | ||
| 141 | # CONFIG_ARCH_EBSA110 is not set | 149 | # CONFIG_ARCH_EBSA110 is not set |
| 142 | # CONFIG_ARCH_EP93XX is not set | 150 | # CONFIG_ARCH_EP93XX is not set |
| 143 | # CONFIG_ARCH_FOOTBRIDGE is not set | 151 | # CONFIG_ARCH_FOOTBRIDGE is not set |
| 152 | # CONFIG_ARCH_MXC is not set | ||
| 153 | # CONFIG_ARCH_STMP3XXX is not set | ||
| 144 | # CONFIG_ARCH_NETX is not set | 154 | # CONFIG_ARCH_NETX is not set |
| 145 | # CONFIG_ARCH_H720X is not set | 155 | # CONFIG_ARCH_H720X is not set |
| 146 | # CONFIG_ARCH_IMX is not set | ||
| 147 | # CONFIG_ARCH_IOP13XX is not set | 156 | # CONFIG_ARCH_IOP13XX is not set |
| 148 | # CONFIG_ARCH_IOP32X is not set | 157 | # CONFIG_ARCH_IOP32X is not set |
| 149 | # CONFIG_ARCH_IOP33X is not set | 158 | # CONFIG_ARCH_IOP33X is not set |
| @@ -152,23 +161,25 @@ CONFIG_CLASSIC_RCU=y | |||
| 152 | # CONFIG_ARCH_IXP4XX is not set | 161 | # CONFIG_ARCH_IXP4XX is not set |
| 153 | # CONFIG_ARCH_L7200 is not set | 162 | # CONFIG_ARCH_L7200 is not set |
| 154 | # CONFIG_ARCH_KIRKWOOD is not set | 163 | # CONFIG_ARCH_KIRKWOOD is not set |
| 155 | # CONFIG_ARCH_KS8695 is not set | ||
| 156 | # CONFIG_ARCH_NS9XXX is not set | ||
| 157 | # CONFIG_ARCH_LOKI is not set | 164 | # CONFIG_ARCH_LOKI is not set |
| 158 | # CONFIG_ARCH_MV78XX0 is not set | 165 | # CONFIG_ARCH_MV78XX0 is not set |
| 159 | # CONFIG_ARCH_MXC is not set | ||
| 160 | # CONFIG_ARCH_ORION5X is not set | 166 | # CONFIG_ARCH_ORION5X is not set |
| 167 | # CONFIG_ARCH_MMP is not set | ||
| 168 | # CONFIG_ARCH_KS8695 is not set | ||
| 169 | # CONFIG_ARCH_NS9XXX is not set | ||
| 170 | # CONFIG_ARCH_W90X900 is not set | ||
| 161 | # CONFIG_ARCH_PNX4008 is not set | 171 | # CONFIG_ARCH_PNX4008 is not set |
| 162 | # CONFIG_ARCH_PXA is not set | 172 | # CONFIG_ARCH_PXA is not set |
| 173 | # CONFIG_ARCH_MSM is not set | ||
| 163 | # CONFIG_ARCH_RPC is not set | 174 | # CONFIG_ARCH_RPC is not set |
| 164 | CONFIG_ARCH_SA1100=y | 175 | CONFIG_ARCH_SA1100=y |
| 165 | # CONFIG_ARCH_S3C2410 is not set | 176 | # CONFIG_ARCH_S3C2410 is not set |
| 177 | # CONFIG_ARCH_S3C64XX is not set | ||
| 166 | # CONFIG_ARCH_SHARK is not set | 178 | # CONFIG_ARCH_SHARK is not set |
| 167 | # CONFIG_ARCH_LH7A40X is not set | 179 | # CONFIG_ARCH_LH7A40X is not set |
| 180 | # CONFIG_ARCH_U300 is not set | ||
| 168 | # CONFIG_ARCH_DAVINCI is not set | 181 | # CONFIG_ARCH_DAVINCI is not set |
| 169 | # CONFIG_ARCH_OMAP is not set | 182 | # CONFIG_ARCH_OMAP is not set |
| 170 | # CONFIG_ARCH_MSM7X00A is not set | ||
| 171 | CONFIG_DMABOUNCE=y | ||
| 172 | 183 | ||
| 173 | # | 184 | # |
| 174 | # SA11x0 Implementations | 185 | # SA11x0 Implementations |
| @@ -189,14 +200,6 @@ CONFIG_SA1100_JORNADA720_SSP=y | |||
| 189 | CONFIG_SA1100_SSP=y | 200 | CONFIG_SA1100_SSP=y |
| 190 | 201 | ||
| 191 | # | 202 | # |
| 192 | # Boot options | ||
| 193 | # | ||
| 194 | |||
| 195 | # | ||
| 196 | # Power management | ||
| 197 | # | ||
| 198 | |||
| 199 | # | ||
| 200 | # Processor Type | 203 | # Processor Type |
| 201 | # | 204 | # |
| 202 | CONFIG_CPU_32=y | 205 | CONFIG_CPU_32=y |
| @@ -215,8 +218,8 @@ CONFIG_CPU_CP15_MMU=y | |||
| 215 | # | 218 | # |
| 216 | # CONFIG_CPU_ICACHE_DISABLE is not set | 219 | # CONFIG_CPU_ICACHE_DISABLE is not set |
| 217 | # CONFIG_CPU_DCACHE_DISABLE is not set | 220 | # CONFIG_CPU_DCACHE_DISABLE is not set |
| 218 | # CONFIG_OUTER_CACHE is not set | ||
| 219 | CONFIG_SA1111=y | 221 | CONFIG_SA1111=y |
| 222 | CONFIG_DMABOUNCE=y | ||
| 220 | CONFIG_FORCE_MAX_ZONEORDER=9 | 223 | CONFIG_FORCE_MAX_ZONEORDER=9 |
| 221 | 224 | ||
| 222 | # | 225 | # |
| @@ -246,30 +249,36 @@ CONFIG_TICK_ONESHOT=y | |||
| 246 | # CONFIG_NO_HZ is not set | 249 | # CONFIG_NO_HZ is not set |
| 247 | # CONFIG_HIGH_RES_TIMERS is not set | 250 | # CONFIG_HIGH_RES_TIMERS is not set |
| 248 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | 251 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y |
| 252 | CONFIG_VMSPLIT_3G=y | ||
| 253 | # CONFIG_VMSPLIT_2G is not set | ||
| 254 | # CONFIG_VMSPLIT_1G is not set | ||
| 255 | CONFIG_PAGE_OFFSET=0xC0000000 | ||
| 249 | # CONFIG_PREEMPT is not set | 256 | # CONFIG_PREEMPT is not set |
| 250 | CONFIG_HZ=100 | 257 | CONFIG_HZ=100 |
| 251 | # CONFIG_AEABI is not set | 258 | # CONFIG_AEABI is not set |
| 252 | CONFIG_ARCH_DISCONTIGMEM_ENABLE=y | ||
| 253 | CONFIG_ARCH_SPARSEMEM_ENABLE=y | 259 | CONFIG_ARCH_SPARSEMEM_ENABLE=y |
| 254 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y | 260 | CONFIG_ARCH_SPARSEMEM_DEFAULT=y |
| 255 | CONFIG_NODES_SHIFT=2 | 261 | # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set |
| 262 | # CONFIG_HIGHMEM is not set | ||
| 256 | CONFIG_SELECT_MEMORY_MODEL=y | 263 | CONFIG_SELECT_MEMORY_MODEL=y |
| 257 | # CONFIG_FLATMEM_MANUAL is not set | 264 | # CONFIG_FLATMEM_MANUAL is not set |
| 258 | CONFIG_DISCONTIGMEM_MANUAL=y | 265 | # CONFIG_DISCONTIGMEM_MANUAL is not set |
| 259 | # CONFIG_SPARSEMEM_MANUAL is not set | 266 | CONFIG_SPARSEMEM_MANUAL=y |
| 260 | CONFIG_DISCONTIGMEM=y | 267 | CONFIG_SPARSEMEM=y |
| 261 | CONFIG_FLAT_NODE_MEM_MAP=y | 268 | CONFIG_HAVE_MEMORY_PRESENT=y |
| 262 | CONFIG_NEED_MULTIPLE_NODES=y | 269 | CONFIG_SPARSEMEM_EXTREME=y |
| 263 | # CONFIG_SPARSEMEM_STATIC is not set | ||
| 264 | # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set | ||
| 265 | CONFIG_PAGEFLAGS_EXTENDED=y | 270 | CONFIG_PAGEFLAGS_EXTENDED=y |
| 266 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | 271 | CONFIG_SPLIT_PTLOCK_CPUS=4096 |
| 267 | # CONFIG_RESOURCES_64BIT is not set | 272 | # CONFIG_PHYS_ADDR_T_64BIT is not set |
| 268 | CONFIG_ZONE_DMA_FLAG=1 | 273 | CONFIG_ZONE_DMA_FLAG=1 |
| 269 | CONFIG_BOUNCE=y | 274 | CONFIG_BOUNCE=y |
| 270 | CONFIG_VIRT_TO_BUS=y | 275 | CONFIG_VIRT_TO_BUS=y |
| 276 | CONFIG_HAVE_MLOCK=y | ||
| 277 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | ||
| 278 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
| 271 | # CONFIG_LEDS is not set | 279 | # CONFIG_LEDS is not set |
| 272 | CONFIG_ALIGNMENT_TRAP=y | 280 | CONFIG_ALIGNMENT_TRAP=y |
| 281 | # CONFIG_UACCESS_WITH_MEMCPY is not set | ||
| 273 | 282 | ||
| 274 | # | 283 | # |
| 275 | # Boot options | 284 | # Boot options |
| @@ -281,9 +290,10 @@ CONFIG_CMDLINE="" | |||
| 281 | # CONFIG_KEXEC is not set | 290 | # CONFIG_KEXEC is not set |
| 282 | 291 | ||
| 283 | # | 292 | # |
| 284 | # CPU Frequency scaling | 293 | # CPU Power Management |
| 285 | # | 294 | # |
| 286 | # CONFIG_CPU_FREQ is not set | 295 | # CONFIG_CPU_FREQ is not set |
| 296 | # CONFIG_CPU_IDLE is not set | ||
| 287 | 297 | ||
| 288 | # | 298 | # |
| 289 | # Floating point emulation | 299 | # Floating point emulation |
| @@ -294,12 +304,14 @@ CONFIG_CMDLINE="" | |||
| 294 | # | 304 | # |
| 295 | CONFIG_FPE_NWFPE=y | 305 | CONFIG_FPE_NWFPE=y |
| 296 | # CONFIG_FPE_NWFPE_XP is not set | 306 | # CONFIG_FPE_NWFPE_XP is not set |
| 297 | CONFIG_FPE_FASTFPE=y | 307 | # CONFIG_FPE_FASTFPE is not set |
| 298 | 308 | ||
| 299 | # | 309 | # |
| 300 | # Userspace binary formats | 310 | # Userspace binary formats |
| 301 | # | 311 | # |
| 302 | CONFIG_BINFMT_ELF=y | 312 | CONFIG_BINFMT_ELF=y |
| 313 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
| 314 | CONFIG_HAVE_AOUT=y | ||
| 303 | CONFIG_BINFMT_AOUT=y | 315 | CONFIG_BINFMT_AOUT=y |
| 304 | # CONFIG_BINFMT_MISC is not set | 316 | # CONFIG_BINFMT_MISC is not set |
| 305 | # CONFIG_ARTHUR is not set | 317 | # CONFIG_ARTHUR is not set |
| @@ -353,7 +365,6 @@ CONFIG_INET_TCP_DIAG=y | |||
| 353 | CONFIG_TCP_CONG_CUBIC=y | 365 | CONFIG_TCP_CONG_CUBIC=y |
| 354 | CONFIG_DEFAULT_TCP_CONG="cubic" | 366 | CONFIG_DEFAULT_TCP_CONG="cubic" |
| 355 | # CONFIG_TCP_MD5SIG is not set | 367 | # CONFIG_TCP_MD5SIG is not set |
| 356 | # CONFIG_IP_VS is not set | ||
| 357 | # CONFIG_IPV6 is not set | 368 | # CONFIG_IPV6 is not set |
| 358 | # CONFIG_NETWORK_SECMARK is not set | 369 | # CONFIG_NETWORK_SECMARK is not set |
| 359 | CONFIG_NETFILTER=y | 370 | CONFIG_NETFILTER=y |
| @@ -367,10 +378,12 @@ CONFIG_NETFILTER_ADVANCED=y | |||
| 367 | # CONFIG_NETFILTER_NETLINK_LOG is not set | 378 | # CONFIG_NETFILTER_NETLINK_LOG is not set |
| 368 | # CONFIG_NF_CONNTRACK is not set | 379 | # CONFIG_NF_CONNTRACK is not set |
| 369 | # CONFIG_NETFILTER_XTABLES is not set | 380 | # CONFIG_NETFILTER_XTABLES is not set |
| 381 | # CONFIG_IP_VS is not set | ||
| 370 | 382 | ||
| 371 | # | 383 | # |
| 372 | # IP: Netfilter Configuration | 384 | # IP: Netfilter Configuration |
| 373 | # | 385 | # |
| 386 | # CONFIG_NF_DEFRAG_IPV4 is not set | ||
| 374 | # CONFIG_IP_NF_QUEUE is not set | 387 | # CONFIG_IP_NF_QUEUE is not set |
| 375 | # CONFIG_IP_NF_IPTABLES is not set | 388 | # CONFIG_IP_NF_IPTABLES is not set |
| 376 | # CONFIG_IP_NF_ARPTABLES is not set | 389 | # CONFIG_IP_NF_ARPTABLES is not set |
| @@ -379,6 +392,7 @@ CONFIG_NETFILTER_ADVANCED=y | |||
| 379 | # CONFIG_TIPC is not set | 392 | # CONFIG_TIPC is not set |
| 380 | # CONFIG_ATM is not set | 393 | # CONFIG_ATM is not set |
| 381 | # CONFIG_BRIDGE is not set | 394 | # CONFIG_BRIDGE is not set |
| 395 | # CONFIG_NET_DSA is not set | ||
| 382 | # CONFIG_VLAN_8021Q is not set | 396 | # CONFIG_VLAN_8021Q is not set |
| 383 | # CONFIG_DECNET is not set | 397 | # CONFIG_DECNET is not set |
| 384 | # CONFIG_LLC2 is not set | 398 | # CONFIG_LLC2 is not set |
| @@ -388,7 +402,10 @@ CONFIG_NETFILTER_ADVANCED=y | |||
| 388 | # CONFIG_LAPB is not set | 402 | # CONFIG_LAPB is not set |
| 389 | # CONFIG_ECONET is not set | 403 | # CONFIG_ECONET is not set |
| 390 | # CONFIG_WAN_ROUTER is not set | 404 | # CONFIG_WAN_ROUTER is not set |
| 405 | # CONFIG_PHONET is not set | ||
| 406 | # CONFIG_IEEE802154 is not set | ||
| 391 | # CONFIG_NET_SCHED is not set | 407 | # CONFIG_NET_SCHED is not set |
| 408 | # CONFIG_DCB is not set | ||
| 392 | 409 | ||
| 393 | # | 410 | # |
| 394 | # Network testing | 411 | # Network testing |
| @@ -431,14 +448,17 @@ CONFIG_IRCOMM=m | |||
| 431 | CONFIG_SA1100_FIR=m | 448 | CONFIG_SA1100_FIR=m |
| 432 | # CONFIG_BT is not set | 449 | # CONFIG_BT is not set |
| 433 | # CONFIG_AF_RXRPC is not set | 450 | # CONFIG_AF_RXRPC is not set |
| 451 | CONFIG_WIRELESS=y | ||
| 452 | # CONFIG_CFG80211 is not set | ||
| 453 | # CONFIG_WIRELESS_OLD_REGULATORY is not set | ||
| 454 | # CONFIG_WIRELESS_EXT is not set | ||
| 455 | # CONFIG_LIB80211 is not set | ||
| 434 | 456 | ||
| 435 | # | 457 | # |
| 436 | # Wireless | 458 | # CFG80211 needs to be enabled for MAC80211 |
| 437 | # | 459 | # |
| 438 | # CONFIG_CFG80211 is not set | 460 | CONFIG_MAC80211_DEFAULT_PS_VALUE=0 |
| 439 | # CONFIG_WIRELESS_EXT is not set | 461 | # CONFIG_WIMAX is not set |
| 440 | # CONFIG_MAC80211 is not set | ||
| 441 | # CONFIG_IEEE80211 is not set | ||
| 442 | # CONFIG_RFKILL is not set | 462 | # CONFIG_RFKILL is not set |
| 443 | # CONFIG_NET_9P is not set | 463 | # CONFIG_NET_9P is not set |
| 444 | 464 | ||
| @@ -464,29 +484,34 @@ CONFIG_EXTRA_FIRMWARE="" | |||
| 464 | # CONFIG_PNP is not set | 484 | # CONFIG_PNP is not set |
| 465 | CONFIG_BLK_DEV=y | 485 | CONFIG_BLK_DEV=y |
| 466 | # CONFIG_BLK_DEV_COW_COMMON is not set | 486 | # CONFIG_BLK_DEV_COW_COMMON is not set |
| 467 | CONFIG_BLK_DEV_LOOP=m | 487 | CONFIG_BLK_DEV_LOOP=y |
| 468 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | 488 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set |
| 469 | CONFIG_BLK_DEV_NBD=m | 489 | CONFIG_BLK_DEV_NBD=y |
| 470 | # CONFIG_BLK_DEV_RAM is not set | 490 | # CONFIG_BLK_DEV_RAM is not set |
| 471 | # CONFIG_CDROM_PKTCDVD is not set | 491 | # CONFIG_CDROM_PKTCDVD is not set |
| 472 | # CONFIG_ATA_OVER_ETH is not set | 492 | # CONFIG_ATA_OVER_ETH is not set |
| 493 | # CONFIG_MG_DISK is not set | ||
| 473 | CONFIG_MISC_DEVICES=y | 494 | CONFIG_MISC_DEVICES=y |
| 474 | # CONFIG_EEPROM_93CX6 is not set | ||
| 475 | # CONFIG_ENCLOSURE_SERVICES is not set | 495 | # CONFIG_ENCLOSURE_SERVICES is not set |
| 496 | # CONFIG_C2PORT is not set | ||
| 497 | |||
| 498 | # | ||
| 499 | # EEPROM support | ||
| 500 | # | ||
| 501 | # CONFIG_EEPROM_93CX6 is not set | ||
| 476 | CONFIG_HAVE_IDE=y | 502 | CONFIG_HAVE_IDE=y |
| 477 | CONFIG_IDE=y | 503 | CONFIG_IDE=y |
| 478 | CONFIG_BLK_DEV_IDE=y | ||
| 479 | 504 | ||
| 480 | # | 505 | # |
| 481 | # Please see Documentation/ide/ide.txt for help/info on IDE drives | 506 | # Please see Documentation/ide/ide.txt for help/info on IDE drives |
| 482 | # | 507 | # |
| 483 | # CONFIG_BLK_DEV_IDE_SATA is not set | 508 | # CONFIG_BLK_DEV_IDE_SATA is not set |
| 484 | CONFIG_BLK_DEV_IDEDISK=y | 509 | CONFIG_IDE_GD=y |
| 485 | # CONFIG_IDEDISK_MULTI_MODE is not set | 510 | CONFIG_IDE_GD_ATA=y |
| 511 | # CONFIG_IDE_GD_ATAPI is not set | ||
| 486 | CONFIG_BLK_DEV_IDECS=y | 512 | CONFIG_BLK_DEV_IDECS=y |
| 487 | # CONFIG_BLK_DEV_IDECD is not set | 513 | # CONFIG_BLK_DEV_IDECD is not set |
| 488 | # CONFIG_BLK_DEV_IDETAPE is not set | 514 | # CONFIG_BLK_DEV_IDETAPE is not set |
| 489 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | ||
| 490 | # CONFIG_IDE_TASK_IOCTL is not set | 515 | # CONFIG_IDE_TASK_IOCTL is not set |
| 491 | CONFIG_IDE_PROC_FS=y | 516 | CONFIG_IDE_PROC_FS=y |
| 492 | 517 | ||
| @@ -513,8 +538,34 @@ CONFIG_DUMMY=y | |||
| 513 | # CONFIG_TUN is not set | 538 | # CONFIG_TUN is not set |
| 514 | # CONFIG_VETH is not set | 539 | # CONFIG_VETH is not set |
| 515 | # CONFIG_ARCNET is not set | 540 | # CONFIG_ARCNET is not set |
| 516 | # CONFIG_NET_ETHERNET is not set | 541 | # CONFIG_PHYLIB is not set |
| 517 | CONFIG_MII=m | 542 | CONFIG_NET_ETHERNET=y |
| 543 | # CONFIG_MII is not set | ||
| 544 | # CONFIG_AX88796 is not set | ||
| 545 | # CONFIG_NET_VENDOR_3COM is not set | ||
| 546 | # CONFIG_NET_VENDOR_SMC is not set | ||
| 547 | # CONFIG_SMC91X is not set | ||
| 548 | # CONFIG_DM9000 is not set | ||
| 549 | # CONFIG_ETHOC is not set | ||
| 550 | # CONFIG_SMC911X is not set | ||
| 551 | # CONFIG_SMSC911X is not set | ||
| 552 | # CONFIG_NET_VENDOR_RACAL is not set | ||
| 553 | # CONFIG_DNET is not set | ||
| 554 | # CONFIG_AT1700 is not set | ||
| 555 | # CONFIG_DEPCA is not set | ||
| 556 | # CONFIG_HP100 is not set | ||
| 557 | # CONFIG_NET_ISA is not set | ||
| 558 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
| 559 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
| 560 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
| 561 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
| 562 | # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set | ||
| 563 | # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set | ||
| 564 | # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set | ||
| 565 | # CONFIG_NET_PCI is not set | ||
| 566 | # CONFIG_B44 is not set | ||
| 567 | # CONFIG_CS89x0 is not set | ||
| 568 | # CONFIG_KS8842 is not set | ||
| 518 | # CONFIG_NETDEV_1000 is not set | 569 | # CONFIG_NETDEV_1000 is not set |
| 519 | # CONFIG_NETDEV_10000 is not set | 570 | # CONFIG_NETDEV_10000 is not set |
| 520 | # CONFIG_TR is not set | 571 | # CONFIG_TR is not set |
| @@ -523,17 +574,27 @@ CONFIG_MII=m | |||
| 523 | # Wireless LAN | 574 | # Wireless LAN |
| 524 | # | 575 | # |
| 525 | # CONFIG_WLAN_PRE80211 is not set | 576 | # CONFIG_WLAN_PRE80211 is not set |
| 526 | # CONFIG_WLAN_80211 is not set | 577 | CONFIG_WLAN_80211=y |
| 527 | # CONFIG_IWLWIFI_LEDS is not set | 578 | # CONFIG_PCMCIA_RAYCS is not set |
| 579 | # CONFIG_LIBERTAS is not set | ||
| 580 | # CONFIG_ATMEL is not set | ||
| 581 | # CONFIG_AIRO_CS is not set | ||
| 582 | # CONFIG_PCMCIA_WL3501 is not set | ||
| 583 | # CONFIG_HOSTAP is not set | ||
| 584 | # CONFIG_HERMES is not set | ||
| 585 | |||
| 586 | # | ||
| 587 | # Enable WiMAX (Networking options) to see the WiMAX drivers | ||
| 588 | # | ||
| 528 | CONFIG_NET_PCMCIA=y | 589 | CONFIG_NET_PCMCIA=y |
| 529 | CONFIG_PCMCIA_3C589=m | 590 | # CONFIG_PCMCIA_3C589 is not set |
| 530 | CONFIG_PCMCIA_3C574=m | 591 | # CONFIG_PCMCIA_3C574 is not set |
| 531 | CONFIG_PCMCIA_FMVJ18X=m | 592 | # CONFIG_PCMCIA_FMVJ18X is not set |
| 532 | CONFIG_PCMCIA_PCNET=m | 593 | # CONFIG_PCMCIA_PCNET is not set |
| 533 | CONFIG_PCMCIA_NMCLAN=m | 594 | # CONFIG_PCMCIA_NMCLAN is not set |
| 534 | CONFIG_PCMCIA_SMC91C92=m | 595 | # CONFIG_PCMCIA_SMC91C92 is not set |
| 535 | CONFIG_PCMCIA_XIRC2PS=m | 596 | # CONFIG_PCMCIA_XIRC2PS is not set |
| 536 | CONFIG_PCMCIA_AXNET=m | 597 | # CONFIG_PCMCIA_AXNET is not set |
| 537 | # CONFIG_WAN is not set | 598 | # CONFIG_WAN is not set |
| 538 | # CONFIG_PPP is not set | 599 | # CONFIG_PPP is not set |
| 539 | # CONFIG_SLIP is not set | 600 | # CONFIG_SLIP is not set |
| @@ -565,20 +626,23 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240 | |||
| 565 | # | 626 | # |
| 566 | CONFIG_INPUT_KEYBOARD=y | 627 | CONFIG_INPUT_KEYBOARD=y |
| 567 | # CONFIG_KEYBOARD_ATKBD is not set | 628 | # CONFIG_KEYBOARD_ATKBD is not set |
| 568 | # CONFIG_KEYBOARD_SUNKBD is not set | ||
| 569 | # CONFIG_KEYBOARD_LKKBD is not set | 629 | # CONFIG_KEYBOARD_LKKBD is not set |
| 570 | # CONFIG_KEYBOARD_XTKBD is not set | 630 | # CONFIG_KEYBOARD_GPIO is not set |
| 631 | # CONFIG_KEYBOARD_MATRIX is not set | ||
| 632 | CONFIG_KEYBOARD_HP7XX=y | ||
| 571 | # CONFIG_KEYBOARD_NEWTON is not set | 633 | # CONFIG_KEYBOARD_NEWTON is not set |
| 572 | # CONFIG_KEYBOARD_STOWAWAY is not set | 634 | # CONFIG_KEYBOARD_STOWAWAY is not set |
| 573 | CONFIG_KEYBOARD_HP7XX=y | 635 | # CONFIG_KEYBOARD_SUNKBD is not set |
| 574 | # CONFIG_KEYBOARD_GPIO is not set | 636 | # CONFIG_KEYBOARD_XTKBD is not set |
| 575 | # CONFIG_INPUT_MOUSE is not set | 637 | # CONFIG_INPUT_MOUSE is not set |
| 576 | # CONFIG_INPUT_JOYSTICK is not set | 638 | # CONFIG_INPUT_JOYSTICK is not set |
| 577 | # CONFIG_INPUT_TABLET is not set | 639 | # CONFIG_INPUT_TABLET is not set |
| 578 | CONFIG_INPUT_TOUCHSCREEN=y | 640 | CONFIG_INPUT_TOUCHSCREEN=y |
| 641 | # CONFIG_TOUCHSCREEN_AD7879 is not set | ||
| 579 | # CONFIG_TOUCHSCREEN_FUJITSU is not set | 642 | # CONFIG_TOUCHSCREEN_FUJITSU is not set |
| 580 | # CONFIG_TOUCHSCREEN_GUNZE is not set | 643 | # CONFIG_TOUCHSCREEN_GUNZE is not set |
| 581 | # CONFIG_TOUCHSCREEN_ELO is not set | 644 | # CONFIG_TOUCHSCREEN_ELO is not set |
| 645 | # CONFIG_TOUCHSCREEN_WACOM_W8001 is not set | ||
| 582 | # CONFIG_TOUCHSCREEN_MTOUCH is not set | 646 | # CONFIG_TOUCHSCREEN_MTOUCH is not set |
| 583 | # CONFIG_TOUCHSCREEN_INEXIO is not set | 647 | # CONFIG_TOUCHSCREEN_INEXIO is not set |
| 584 | # CONFIG_TOUCHSCREEN_MK712 is not set | 648 | # CONFIG_TOUCHSCREEN_MK712 is not set |
| @@ -587,8 +651,8 @@ CONFIG_TOUCHSCREEN_HP7XX=y | |||
| 587 | # CONFIG_TOUCHSCREEN_PENMOUNT is not set | 651 | # CONFIG_TOUCHSCREEN_PENMOUNT is not set |
| 588 | # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set | 652 | # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set |
| 589 | # CONFIG_TOUCHSCREEN_TOUCHWIN is not set | 653 | # CONFIG_TOUCHSCREEN_TOUCHWIN is not set |
| 590 | # CONFIG_TOUCHSCREEN_UCB1400 is not set | ||
| 591 | # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set | 654 | # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set |
| 655 | # CONFIG_TOUCHSCREEN_W90X900 is not set | ||
| 592 | # CONFIG_INPUT_MISC is not set | 656 | # CONFIG_INPUT_MISC is not set |
| 593 | 657 | ||
| 594 | # | 658 | # |
| @@ -624,11 +688,12 @@ CONFIG_SERIAL_SA1100_CONSOLE=y | |||
| 624 | CONFIG_SERIAL_CORE=y | 688 | CONFIG_SERIAL_CORE=y |
| 625 | CONFIG_SERIAL_CORE_CONSOLE=y | 689 | CONFIG_SERIAL_CORE_CONSOLE=y |
| 626 | CONFIG_UNIX98_PTYS=y | 690 | CONFIG_UNIX98_PTYS=y |
| 691 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
| 627 | CONFIG_LEGACY_PTYS=y | 692 | CONFIG_LEGACY_PTYS=y |
| 628 | CONFIG_LEGACY_PTY_COUNT=32 | 693 | CONFIG_LEGACY_PTY_COUNT=32 |
| 629 | # CONFIG_IPMI_HANDLER is not set | 694 | # CONFIG_IPMI_HANDLER is not set |
| 630 | CONFIG_HW_RANDOM=m | 695 | CONFIG_HW_RANDOM=m |
| 631 | # CONFIG_NVRAM is not set | 696 | # CONFIG_HW_RANDOM_TIMERIOMEM is not set |
| 632 | # CONFIG_DTLK is not set | 697 | # CONFIG_DTLK is not set |
| 633 | # CONFIG_R3964 is not set | 698 | # CONFIG_R3964 is not set |
| 634 | 699 | ||
| @@ -650,6 +715,10 @@ CONFIG_GPIOLIB=y | |||
| 650 | # CONFIG_GPIO_SYSFS is not set | 715 | # CONFIG_GPIO_SYSFS is not set |
| 651 | 716 | ||
| 652 | # | 717 | # |
| 718 | # Memory mapped GPIO expanders: | ||
| 719 | # | ||
| 720 | |||
| 721 | # | ||
| 653 | # I2C GPIO expanders: | 722 | # I2C GPIO expanders: |
| 654 | # | 723 | # |
| 655 | 724 | ||
| @@ -663,12 +732,14 @@ CONFIG_GPIOLIB=y | |||
| 663 | # CONFIG_W1 is not set | 732 | # CONFIG_W1 is not set |
| 664 | # CONFIG_POWER_SUPPLY is not set | 733 | # CONFIG_POWER_SUPPLY is not set |
| 665 | # CONFIG_HWMON is not set | 734 | # CONFIG_HWMON is not set |
| 735 | # CONFIG_THERMAL is not set | ||
| 736 | # CONFIG_THERMAL_HWMON is not set | ||
| 666 | # CONFIG_WATCHDOG is not set | 737 | # CONFIG_WATCHDOG is not set |
| 738 | CONFIG_SSB_POSSIBLE=y | ||
| 667 | 739 | ||
| 668 | # | 740 | # |
| 669 | # Sonics Silicon Backplane | 741 | # Sonics Silicon Backplane |
| 670 | # | 742 | # |
| 671 | CONFIG_SSB_POSSIBLE=y | ||
| 672 | # CONFIG_SSB is not set | 743 | # CONFIG_SSB is not set |
| 673 | 744 | ||
| 674 | # | 745 | # |
| @@ -676,6 +747,7 @@ CONFIG_SSB_POSSIBLE=y | |||
| 676 | # | 747 | # |
| 677 | # CONFIG_MFD_CORE is not set | 748 | # CONFIG_MFD_CORE is not set |
| 678 | # CONFIG_MFD_SM501 is not set | 749 | # CONFIG_MFD_SM501 is not set |
| 750 | # CONFIG_MFD_ASIC3 is not set | ||
| 679 | # CONFIG_HTC_EGPIO is not set | 751 | # CONFIG_HTC_EGPIO is not set |
| 680 | # CONFIG_HTC_PASIC3 is not set | 752 | # CONFIG_HTC_PASIC3 is not set |
| 681 | # CONFIG_MFD_TMIO is not set | 753 | # CONFIG_MFD_TMIO is not set |
| @@ -687,22 +759,7 @@ CONFIG_SSB_POSSIBLE=y | |||
| 687 | # Multimedia Capabilities Port drivers | 759 | # Multimedia Capabilities Port drivers |
| 688 | # | 760 | # |
| 689 | # CONFIG_MCP_SA11X0 is not set | 761 | # CONFIG_MCP_SA11X0 is not set |
| 690 | 762 | # CONFIG_MEDIA_SUPPORT is not set | |
| 691 | # | ||
| 692 | # Multimedia devices | ||
| 693 | # | ||
| 694 | |||
| 695 | # | ||
| 696 | # Multimedia core support | ||
| 697 | # | ||
| 698 | # CONFIG_VIDEO_DEV is not set | ||
| 699 | # CONFIG_DVB_CORE is not set | ||
| 700 | # CONFIG_VIDEO_MEDIA is not set | ||
| 701 | |||
| 702 | # | ||
| 703 | # Multimedia drivers | ||
| 704 | # | ||
| 705 | # CONFIG_DAB is not set | ||
| 706 | 763 | ||
| 707 | # | 764 | # |
| 708 | # Graphics support | 765 | # Graphics support |
| @@ -712,6 +769,7 @@ CONFIG_SSB_POSSIBLE=y | |||
| 712 | CONFIG_FB=y | 769 | CONFIG_FB=y |
| 713 | # CONFIG_FIRMWARE_EDID is not set | 770 | # CONFIG_FIRMWARE_EDID is not set |
| 714 | # CONFIG_FB_DDC is not set | 771 | # CONFIG_FB_DDC is not set |
| 772 | # CONFIG_FB_BOOT_VESA_SUPPORT is not set | ||
| 715 | CONFIG_FB_CFB_FILLRECT=y | 773 | CONFIG_FB_CFB_FILLRECT=y |
| 716 | CONFIG_FB_CFB_COPYAREA=y | 774 | CONFIG_FB_CFB_COPYAREA=y |
| 717 | CONFIG_FB_CFB_IMAGEBLIT=y | 775 | CONFIG_FB_CFB_IMAGEBLIT=y |
| @@ -733,7 +791,17 @@ CONFIG_FB_CFB_IMAGEBLIT=y | |||
| 733 | # CONFIG_FB_SA1100 is not set | 791 | # CONFIG_FB_SA1100 is not set |
| 734 | CONFIG_FB_S1D13XXX=y | 792 | CONFIG_FB_S1D13XXX=y |
| 735 | # CONFIG_FB_VIRTUAL is not set | 793 | # CONFIG_FB_VIRTUAL is not set |
| 736 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | 794 | # CONFIG_FB_METRONOME is not set |
| 795 | # CONFIG_FB_MB862XX is not set | ||
| 796 | # CONFIG_FB_BROADSHEET is not set | ||
| 797 | CONFIG_BACKLIGHT_LCD_SUPPORT=y | ||
| 798 | CONFIG_LCD_CLASS_DEVICE=y | ||
| 799 | # CONFIG_LCD_ILI9320 is not set | ||
| 800 | # CONFIG_LCD_PLATFORM is not set | ||
| 801 | CONFIG_LCD_HP700=y | ||
| 802 | CONFIG_BACKLIGHT_CLASS_DEVICE=y | ||
| 803 | # CONFIG_BACKLIGHT_GENERIC is not set | ||
| 804 | CONFIG_BACKLIGHT_HP700=y | ||
| 737 | 805 | ||
| 738 | # | 806 | # |
| 739 | # Display device support | 807 | # Display device support |
| @@ -757,6 +825,8 @@ CONFIG_FONT_8x16=y | |||
| 757 | # CONFIG_HID_SUPPORT is not set | 825 | # CONFIG_HID_SUPPORT is not set |
| 758 | # CONFIG_USB_SUPPORT is not set | 826 | # CONFIG_USB_SUPPORT is not set |
| 759 | # CONFIG_MMC is not set | 827 | # CONFIG_MMC is not set |
| 828 | # CONFIG_MEMSTICK is not set | ||
| 829 | # CONFIG_ACCESSIBILITY is not set | ||
| 760 | # CONFIG_NEW_LEDS is not set | 830 | # CONFIG_NEW_LEDS is not set |
| 761 | CONFIG_RTC_LIB=y | 831 | CONFIG_RTC_LIB=y |
| 762 | CONFIG_RTC_CLASS=y | 832 | CONFIG_RTC_CLASS=y |
| @@ -781,12 +851,15 @@ CONFIG_RTC_INTF_DEV=y | |||
| 781 | # Platform RTC drivers | 851 | # Platform RTC drivers |
| 782 | # | 852 | # |
| 783 | # CONFIG_RTC_DRV_CMOS is not set | 853 | # CONFIG_RTC_DRV_CMOS is not set |
| 854 | # CONFIG_RTC_DRV_DS1286 is not set | ||
| 784 | # CONFIG_RTC_DRV_DS1511 is not set | 855 | # CONFIG_RTC_DRV_DS1511 is not set |
| 785 | # CONFIG_RTC_DRV_DS1553 is not set | 856 | # CONFIG_RTC_DRV_DS1553 is not set |
| 786 | # CONFIG_RTC_DRV_DS1742 is not set | 857 | # CONFIG_RTC_DRV_DS1742 is not set |
| 787 | # CONFIG_RTC_DRV_STK17TA8 is not set | 858 | # CONFIG_RTC_DRV_STK17TA8 is not set |
| 788 | # CONFIG_RTC_DRV_M48T86 is not set | 859 | # CONFIG_RTC_DRV_M48T86 is not set |
| 860 | # CONFIG_RTC_DRV_M48T35 is not set | ||
| 789 | # CONFIG_RTC_DRV_M48T59 is not set | 861 | # CONFIG_RTC_DRV_M48T59 is not set |
| 862 | # CONFIG_RTC_DRV_BQ4802 is not set | ||
| 790 | # CONFIG_RTC_DRV_V3020 is not set | 863 | # CONFIG_RTC_DRV_V3020 is not set |
| 791 | 864 | ||
| 792 | # | 865 | # |
| @@ -794,15 +867,10 @@ CONFIG_RTC_INTF_DEV=y | |||
| 794 | # | 867 | # |
| 795 | CONFIG_RTC_DRV_SA1100=y | 868 | CONFIG_RTC_DRV_SA1100=y |
| 796 | # CONFIG_DMADEVICES is not set | 869 | # CONFIG_DMADEVICES is not set |
| 797 | 870 | # CONFIG_AUXDISPLAY is not set | |
| 798 | # | ||
| 799 | # Voltage and Current regulators | ||
| 800 | # | ||
| 801 | # CONFIG_REGULATOR is not set | 871 | # CONFIG_REGULATOR is not set |
| 802 | # CONFIG_REGULATOR_FIXED_VOLTAGE is not set | ||
| 803 | # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set | ||
| 804 | # CONFIG_REGULATOR_BQ24022 is not set | ||
| 805 | # CONFIG_UIO is not set | 872 | # CONFIG_UIO is not set |
| 873 | # CONFIG_STAGING is not set | ||
| 806 | 874 | ||
| 807 | # | 875 | # |
| 808 | # File systems | 876 | # File systems |
| @@ -811,12 +879,16 @@ CONFIG_EXT2_FS=y | |||
| 811 | # CONFIG_EXT2_FS_XATTR is not set | 879 | # CONFIG_EXT2_FS_XATTR is not set |
| 812 | # CONFIG_EXT2_FS_XIP is not set | 880 | # CONFIG_EXT2_FS_XIP is not set |
| 813 | # CONFIG_EXT3_FS is not set | 881 | # CONFIG_EXT3_FS is not set |
| 814 | # CONFIG_EXT4DEV_FS is not set | 882 | # CONFIG_EXT4_FS is not set |
| 815 | # CONFIG_REISERFS_FS is not set | 883 | # CONFIG_REISERFS_FS is not set |
| 816 | # CONFIG_JFS_FS is not set | 884 | # CONFIG_JFS_FS is not set |
| 817 | # CONFIG_FS_POSIX_ACL is not set | 885 | # CONFIG_FS_POSIX_ACL is not set |
| 818 | # CONFIG_XFS_FS is not set | 886 | # CONFIG_XFS_FS is not set |
| 887 | # CONFIG_GFS2_FS is not set | ||
| 819 | # CONFIG_OCFS2_FS is not set | 888 | # CONFIG_OCFS2_FS is not set |
| 889 | # CONFIG_BTRFS_FS is not set | ||
| 890 | CONFIG_FILE_LOCKING=y | ||
| 891 | CONFIG_FSNOTIFY=y | ||
| 820 | CONFIG_DNOTIFY=y | 892 | CONFIG_DNOTIFY=y |
| 821 | CONFIG_INOTIFY=y | 893 | CONFIG_INOTIFY=y |
| 822 | CONFIG_INOTIFY_USER=y | 894 | CONFIG_INOTIFY_USER=y |
| @@ -826,6 +898,11 @@ CONFIG_INOTIFY_USER=y | |||
| 826 | # CONFIG_FUSE_FS is not set | 898 | # CONFIG_FUSE_FS is not set |
| 827 | 899 | ||
| 828 | # | 900 | # |
| 901 | # Caches | ||
| 902 | # | ||
| 903 | # CONFIG_FSCACHE is not set | ||
| 904 | |||
| 905 | # | ||
| 829 | # CD-ROM/DVD Filesystems | 906 | # CD-ROM/DVD Filesystems |
| 830 | # | 907 | # |
| 831 | # CONFIG_ISO9660_FS is not set | 908 | # CONFIG_ISO9660_FS is not set |
| @@ -846,14 +923,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | |||
| 846 | # | 923 | # |
| 847 | CONFIG_PROC_FS=y | 924 | CONFIG_PROC_FS=y |
| 848 | CONFIG_PROC_SYSCTL=y | 925 | CONFIG_PROC_SYSCTL=y |
| 926 | CONFIG_PROC_PAGE_MONITOR=y | ||
| 849 | CONFIG_SYSFS=y | 927 | CONFIG_SYSFS=y |
| 850 | # CONFIG_TMPFS is not set | 928 | # CONFIG_TMPFS is not set |
| 851 | # CONFIG_HUGETLB_PAGE is not set | 929 | # CONFIG_HUGETLB_PAGE is not set |
| 852 | # CONFIG_CONFIGFS_FS is not set | 930 | # CONFIG_CONFIGFS_FS is not set |
| 853 | 931 | CONFIG_MISC_FILESYSTEMS=y | |
| 854 | # | ||
| 855 | # Miscellaneous filesystems | ||
| 856 | # | ||
| 857 | # CONFIG_ADFS_FS is not set | 932 | # CONFIG_ADFS_FS is not set |
| 858 | # CONFIG_AFFS_FS is not set | 933 | # CONFIG_AFFS_FS is not set |
| 859 | # CONFIG_HFS_FS is not set | 934 | # CONFIG_HFS_FS is not set |
| @@ -862,6 +937,7 @@ CONFIG_SYSFS=y | |||
| 862 | # CONFIG_BFS_FS is not set | 937 | # CONFIG_BFS_FS is not set |
| 863 | # CONFIG_EFS_FS is not set | 938 | # CONFIG_EFS_FS is not set |
| 864 | # CONFIG_CRAMFS is not set | 939 | # CONFIG_CRAMFS is not set |
| 940 | # CONFIG_SQUASHFS is not set | ||
| 865 | # CONFIG_VXFS_FS is not set | 941 | # CONFIG_VXFS_FS is not set |
| 866 | # CONFIG_MINIX_FS is not set | 942 | # CONFIG_MINIX_FS is not set |
| 867 | # CONFIG_OMFS_FS is not set | 943 | # CONFIG_OMFS_FS is not set |
| @@ -870,6 +946,7 @@ CONFIG_SYSFS=y | |||
| 870 | # CONFIG_ROMFS_FS is not set | 946 | # CONFIG_ROMFS_FS is not set |
| 871 | # CONFIG_SYSV_FS is not set | 947 | # CONFIG_SYSV_FS is not set |
| 872 | # CONFIG_UFS_FS is not set | 948 | # CONFIG_UFS_FS is not set |
| 949 | # CONFIG_NILFS2_FS is not set | ||
| 873 | # CONFIG_NETWORK_FILESYSTEMS is not set | 950 | # CONFIG_NETWORK_FILESYSTEMS is not set |
| 874 | 951 | ||
| 875 | # | 952 | # |
| @@ -935,12 +1012,16 @@ CONFIG_DEBUG_KERNEL=y | |||
| 935 | CONFIG_DETECT_SOFTLOCKUP=y | 1012 | CONFIG_DETECT_SOFTLOCKUP=y |
| 936 | # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set | 1013 | # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set |
| 937 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 | 1014 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 |
| 1015 | CONFIG_DETECT_HUNG_TASK=y | ||
| 1016 | # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set | ||
| 1017 | CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 | ||
| 938 | CONFIG_SCHED_DEBUG=y | 1018 | CONFIG_SCHED_DEBUG=y |
| 939 | # CONFIG_SCHEDSTATS is not set | 1019 | # CONFIG_SCHEDSTATS is not set |
| 940 | # CONFIG_TIMER_STATS is not set | 1020 | # CONFIG_TIMER_STATS is not set |
| 941 | # CONFIG_DEBUG_OBJECTS is not set | 1021 | # CONFIG_DEBUG_OBJECTS is not set |
| 942 | # CONFIG_SLUB_DEBUG_ON is not set | 1022 | # CONFIG_SLUB_DEBUG_ON is not set |
| 943 | # CONFIG_SLUB_STATS is not set | 1023 | # CONFIG_SLUB_STATS is not set |
| 1024 | # CONFIG_DEBUG_KMEMLEAK is not set | ||
| 944 | # CONFIG_DEBUG_RT_MUTEXES is not set | 1025 | # CONFIG_DEBUG_RT_MUTEXES is not set |
| 945 | # CONFIG_RT_MUTEX_TESTER is not set | 1026 | # CONFIG_RT_MUTEX_TESTER is not set |
| 946 | # CONFIG_DEBUG_SPINLOCK is not set | 1027 | # CONFIG_DEBUG_SPINLOCK is not set |
| @@ -958,19 +1039,20 @@ CONFIG_DEBUG_BUGVERBOSE=y | |||
| 958 | CONFIG_DEBUG_MEMORY_INIT=y | 1039 | CONFIG_DEBUG_MEMORY_INIT=y |
| 959 | # CONFIG_DEBUG_LIST is not set | 1040 | # CONFIG_DEBUG_LIST is not set |
| 960 | # CONFIG_DEBUG_SG is not set | 1041 | # CONFIG_DEBUG_SG is not set |
| 1042 | # CONFIG_DEBUG_NOTIFIERS is not set | ||
| 961 | CONFIG_FRAME_POINTER=y | 1043 | CONFIG_FRAME_POINTER=y |
| 962 | # CONFIG_BOOT_PRINTK_DELAY is not set | 1044 | # CONFIG_BOOT_PRINTK_DELAY is not set |
| 963 | # CONFIG_RCU_TORTURE_TEST is not set | 1045 | # CONFIG_RCU_TORTURE_TEST is not set |
| 1046 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
| 964 | # CONFIG_BACKTRACE_SELF_TEST is not set | 1047 | # CONFIG_BACKTRACE_SELF_TEST is not set |
| 1048 | # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set | ||
| 965 | # CONFIG_FAULT_INJECTION is not set | 1049 | # CONFIG_FAULT_INJECTION is not set |
| 966 | # CONFIG_LATENCYTOP is not set | 1050 | # CONFIG_LATENCYTOP is not set |
| 967 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set | 1051 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set |
| 968 | CONFIG_HAVE_FTRACE=y | 1052 | # CONFIG_PAGE_POISONING is not set |
| 969 | CONFIG_HAVE_DYNAMIC_FTRACE=y | 1053 | CONFIG_HAVE_FUNCTION_TRACER=y |
| 1054 | CONFIG_TRACING_SUPPORT=y | ||
| 970 | # CONFIG_FTRACE is not set | 1055 | # CONFIG_FTRACE is not set |
| 971 | # CONFIG_IRQSOFF_TRACER is not set | ||
| 972 | # CONFIG_SCHED_TRACER is not set | ||
| 973 | # CONFIG_CONTEXT_SWITCH_TRACER is not set | ||
| 974 | # CONFIG_SAMPLES is not set | 1056 | # CONFIG_SAMPLES is not set |
| 975 | CONFIG_HAVE_ARCH_KGDB=y | 1057 | CONFIG_HAVE_ARCH_KGDB=y |
| 976 | # CONFIG_KGDB is not set | 1058 | # CONFIG_KGDB is not set |
| @@ -985,13 +1067,16 @@ CONFIG_DEBUG_LL=y | |||
| 985 | # | 1067 | # |
| 986 | # CONFIG_KEYS is not set | 1068 | # CONFIG_KEYS is not set |
| 987 | # CONFIG_SECURITY is not set | 1069 | # CONFIG_SECURITY is not set |
| 1070 | # CONFIG_SECURITYFS is not set | ||
| 988 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | 1071 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set |
| 989 | CONFIG_CRYPTO=y | 1072 | CONFIG_CRYPTO=y |
| 990 | 1073 | ||
| 991 | # | 1074 | # |
| 992 | # Crypto core or helper | 1075 | # Crypto core or helper |
| 993 | # | 1076 | # |
| 1077 | # CONFIG_CRYPTO_FIPS is not set | ||
| 994 | # CONFIG_CRYPTO_MANAGER is not set | 1078 | # CONFIG_CRYPTO_MANAGER is not set |
| 1079 | # CONFIG_CRYPTO_MANAGER2 is not set | ||
| 995 | # CONFIG_CRYPTO_GF128MUL is not set | 1080 | # CONFIG_CRYPTO_GF128MUL is not set |
| 996 | # CONFIG_CRYPTO_NULL is not set | 1081 | # CONFIG_CRYPTO_NULL is not set |
| 997 | # CONFIG_CRYPTO_CRYPTD is not set | 1082 | # CONFIG_CRYPTO_CRYPTD is not set |
| @@ -1062,15 +1147,21 @@ CONFIG_CRYPTO=y | |||
| 1062 | # Compression | 1147 | # Compression |
| 1063 | # | 1148 | # |
| 1064 | # CONFIG_CRYPTO_DEFLATE is not set | 1149 | # CONFIG_CRYPTO_DEFLATE is not set |
| 1150 | # CONFIG_CRYPTO_ZLIB is not set | ||
| 1065 | # CONFIG_CRYPTO_LZO is not set | 1151 | # CONFIG_CRYPTO_LZO is not set |
| 1152 | |||
| 1153 | # | ||
| 1154 | # Random Number Generation | ||
| 1155 | # | ||
| 1156 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
| 1066 | CONFIG_CRYPTO_HW=y | 1157 | CONFIG_CRYPTO_HW=y |
| 1158 | # CONFIG_BINARY_PRINTF is not set | ||
| 1067 | 1159 | ||
| 1068 | # | 1160 | # |
| 1069 | # Library routines | 1161 | # Library routines |
| 1070 | # | 1162 | # |
| 1071 | CONFIG_BITREVERSE=y | 1163 | CONFIG_BITREVERSE=y |
| 1072 | # CONFIG_GENERIC_FIND_FIRST_BIT is not set | 1164 | CONFIG_GENERIC_FIND_LAST_BIT=y |
| 1073 | # CONFIG_GENERIC_FIND_NEXT_BIT is not set | ||
| 1074 | CONFIG_CRC_CCITT=m | 1165 | CONFIG_CRC_CCITT=m |
| 1075 | # CONFIG_CRC16 is not set | 1166 | # CONFIG_CRC16 is not set |
| 1076 | # CONFIG_CRC_T10DIF is not set | 1167 | # CONFIG_CRC_T10DIF is not set |
| @@ -1078,7 +1169,7 @@ CONFIG_CRC_CCITT=m | |||
| 1078 | CONFIG_CRC32=y | 1169 | CONFIG_CRC32=y |
| 1079 | # CONFIG_CRC7 is not set | 1170 | # CONFIG_CRC7 is not set |
| 1080 | # CONFIG_LIBCRC32C is not set | 1171 | # CONFIG_LIBCRC32C is not set |
| 1081 | CONFIG_PLIST=y | ||
| 1082 | CONFIG_HAS_IOMEM=y | 1172 | CONFIG_HAS_IOMEM=y |
| 1083 | CONFIG_HAS_IOPORT=y | 1173 | CONFIG_HAS_IOPORT=y |
| 1084 | CONFIG_HAS_DMA=y | 1174 | CONFIG_HAS_DMA=y |
| 1175 | CONFIG_NLATTR=y | ||
diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig index 0a1abb978d7e..af74cc2de8b6 100644 --- a/arch/arm/configs/kirkwood_defconfig +++ b/arch/arm/configs/kirkwood_defconfig | |||
| @@ -629,7 +629,7 @@ CONFIG_SCSI_LOWLEVEL=y | |||
| 629 | CONFIG_ATA=y | 629 | CONFIG_ATA=y |
| 630 | # CONFIG_ATA_NONSTANDARD is not set | 630 | # CONFIG_ATA_NONSTANDARD is not set |
| 631 | CONFIG_SATA_PMP=y | 631 | CONFIG_SATA_PMP=y |
| 632 | # CONFIG_SATA_AHCI is not set | 632 | CONFIG_SATA_AHCI=y |
| 633 | # CONFIG_SATA_SIL24 is not set | 633 | # CONFIG_SATA_SIL24 is not set |
| 634 | CONFIG_ATA_SFF=y | 634 | CONFIG_ATA_SFF=y |
| 635 | # CONFIG_SATA_SVW is not set | 635 | # CONFIG_SATA_SVW is not set |
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig new file mode 100644 index 000000000000..9bb45b932f04 --- /dev/null +++ b/arch/arm/configs/nhk8815_defconfig | |||
| @@ -0,0 +1,1316 @@ | |||
| 1 | # | ||
| 2 | # Automatically generated make config: don't edit | ||
| 3 | # Linux kernel version: 2.6.30 | ||
| 4 | # Tue Jun 23 22:57:16 2009 | ||
| 5 | # | ||
| 6 | CONFIG_ARM=y | ||
| 7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||
| 8 | CONFIG_GENERIC_GPIO=y | ||
| 9 | CONFIG_GENERIC_TIME=y | ||
| 10 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
| 11 | CONFIG_MMU=y | ||
| 12 | CONFIG_GENERIC_HARDIRQS=y | ||
| 13 | CONFIG_STACKTRACE_SUPPORT=y | ||
| 14 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | ||
| 15 | CONFIG_LOCKDEP_SUPPORT=y | ||
| 16 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
| 17 | CONFIG_HARDIRQS_SW_RESEND=y | ||
| 18 | CONFIG_GENERIC_IRQ_PROBE=y | ||
| 19 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
| 20 | CONFIG_GENERIC_HWEIGHT=y | ||
| 21 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
| 22 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | ||
| 23 | CONFIG_VECTORS_BASE=0xffff0000 | ||
| 24 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
| 25 | CONFIG_CONSTRUCTORS=y | ||
| 26 | |||
| 27 | # | ||
| 28 | # General setup | ||
| 29 | # | ||
| 30 | CONFIG_EXPERIMENTAL=y | ||
| 31 | CONFIG_BROKEN_ON_SMP=y | ||
| 32 | CONFIG_LOCK_KERNEL=y | ||
| 33 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
| 34 | CONFIG_LOCALVERSION="" | ||
| 35 | # CONFIG_LOCALVERSION_AUTO is not set | ||
| 36 | # CONFIG_SWAP is not set | ||
| 37 | CONFIG_SYSVIPC=y | ||
| 38 | CONFIG_SYSVIPC_SYSCTL=y | ||
| 39 | # CONFIG_POSIX_MQUEUE is not set | ||
| 40 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
| 41 | # CONFIG_TASKSTATS is not set | ||
| 42 | # CONFIG_AUDIT is not set | ||
| 43 | |||
| 44 | # | ||
| 45 | # RCU Subsystem | ||
| 46 | # | ||
| 47 | CONFIG_CLASSIC_RCU=y | ||
| 48 | # CONFIG_TREE_RCU is not set | ||
| 49 | # CONFIG_PREEMPT_RCU is not set | ||
| 50 | # CONFIG_TREE_RCU_TRACE is not set | ||
| 51 | # CONFIG_PREEMPT_RCU_TRACE is not set | ||
| 52 | CONFIG_IKCONFIG=y | ||
| 53 | CONFIG_IKCONFIG_PROC=y | ||
| 54 | CONFIG_LOG_BUF_SHIFT=14 | ||
| 55 | # CONFIG_GROUP_SCHED is not set | ||
| 56 | # CONFIG_CGROUPS is not set | ||
| 57 | CONFIG_SYSFS_DEPRECATED=y | ||
| 58 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
| 59 | # CONFIG_RELAY is not set | ||
| 60 | # CONFIG_NAMESPACES is not set | ||
| 61 | CONFIG_BLK_DEV_INITRD=y | ||
| 62 | CONFIG_INITRAMFS_SOURCE="" | ||
| 63 | CONFIG_RD_GZIP=y | ||
| 64 | # CONFIG_RD_BZIP2 is not set | ||
| 65 | # CONFIG_RD_LZMA is not set | ||
| 66 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
| 67 | CONFIG_SYSCTL=y | ||
| 68 | CONFIG_ANON_INODES=y | ||
| 69 | CONFIG_EMBEDDED=y | ||
| 70 | CONFIG_UID16=y | ||
| 71 | CONFIG_SYSCTL_SYSCALL=y | ||
| 72 | CONFIG_KALLSYMS=y | ||
| 73 | CONFIG_KALLSYMS_ALL=y | ||
| 74 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
| 75 | CONFIG_HOTPLUG=y | ||
| 76 | CONFIG_PRINTK=y | ||
| 77 | CONFIG_BUG=y | ||
| 78 | CONFIG_ELF_CORE=y | ||
| 79 | CONFIG_BASE_FULL=y | ||
| 80 | CONFIG_FUTEX=y | ||
| 81 | CONFIG_EPOLL=y | ||
| 82 | CONFIG_SIGNALFD=y | ||
| 83 | CONFIG_TIMERFD=y | ||
| 84 | CONFIG_EVENTFD=y | ||
| 85 | CONFIG_SHMEM=y | ||
| 86 | CONFIG_AIO=y | ||
| 87 | |||
| 88 | # | ||
| 89 | # Performance Counters | ||
| 90 | # | ||
| 91 | CONFIG_VM_EVENT_COUNTERS=y | ||
| 92 | # CONFIG_STRIP_ASM_SYMS is not set | ||
| 93 | CONFIG_COMPAT_BRK=y | ||
| 94 | CONFIG_SLAB=y | ||
| 95 | # CONFIG_SLUB is not set | ||
| 96 | # CONFIG_SLOB is not set | ||
| 97 | # CONFIG_PROFILING is not set | ||
| 98 | # CONFIG_MARKERS is not set | ||
| 99 | CONFIG_HAVE_OPROFILE=y | ||
| 100 | # CONFIG_KPROBES is not set | ||
| 101 | CONFIG_HAVE_KPROBES=y | ||
| 102 | CONFIG_HAVE_KRETPROBES=y | ||
| 103 | CONFIG_HAVE_CLK=y | ||
| 104 | |||
| 105 | # | ||
| 106 | # GCOV-based kernel profiling | ||
| 107 | # | ||
| 108 | # CONFIG_SLOW_WORK is not set | ||
| 109 | CONFIG_HAVE_GENERIC_DMA_COHERENT=y | ||
| 110 | CONFIG_SLABINFO=y | ||
| 111 | CONFIG_RT_MUTEXES=y | ||
| 112 | CONFIG_BASE_SMALL=0 | ||
| 113 | CONFIG_MODULES=y | ||
| 114 | # CONFIG_MODULE_FORCE_LOAD is not set | ||
| 115 | CONFIG_MODULE_UNLOAD=y | ||
| 116 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
| 117 | # CONFIG_MODVERSIONS is not set | ||
| 118 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
| 119 | CONFIG_BLOCK=y | ||
| 120 | CONFIG_LBDAF=y | ||
| 121 | # CONFIG_BLK_DEV_BSG is not set | ||
| 122 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
| 123 | |||
| 124 | # | ||
| 125 | # IO Schedulers | ||
| 126 | # | ||
| 127 | CONFIG_IOSCHED_NOOP=y | ||
| 128 | CONFIG_IOSCHED_AS=y | ||
| 129 | CONFIG_IOSCHED_DEADLINE=y | ||
| 130 | CONFIG_IOSCHED_CFQ=y | ||
| 131 | CONFIG_DEFAULT_AS=y | ||
| 132 | # CONFIG_DEFAULT_DEADLINE is not set | ||
| 133 | # CONFIG_DEFAULT_CFQ is not set | ||
| 134 | # CONFIG_DEFAULT_NOOP is not set | ||
| 135 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
| 136 | CONFIG_FREEZER=y | ||
| 137 | |||
| 138 | # | ||
| 139 | # System Type | ||
| 140 | # | ||
| 141 | # CONFIG_ARCH_AAEC2000 is not set | ||
| 142 | # CONFIG_ARCH_INTEGRATOR is not set | ||
| 143 | # CONFIG_ARCH_REALVIEW is not set | ||
| 144 | # CONFIG_ARCH_VERSATILE is not set | ||
| 145 | # CONFIG_ARCH_AT91 is not set | ||
| 146 | # CONFIG_ARCH_CLPS711X is not set | ||
| 147 | # CONFIG_ARCH_GEMINI is not set | ||
| 148 | # CONFIG_ARCH_EBSA110 is not set | ||
| 149 | # CONFIG_ARCH_EP93XX is not set | ||
| 150 | # CONFIG_ARCH_FOOTBRIDGE is not set | ||
| 151 | # CONFIG_ARCH_MXC is not set | ||
| 152 | # CONFIG_ARCH_STMP3XXX is not set | ||
| 153 | # CONFIG_ARCH_NETX is not set | ||
| 154 | # CONFIG_ARCH_H720X is not set | ||
| 155 | CONFIG_ARCH_NOMADIK=y | ||
| 156 | # CONFIG_ARCH_IOP13XX is not set | ||
| 157 | # CONFIG_ARCH_IOP32X is not set | ||
| 158 | # CONFIG_ARCH_IOP33X is not set | ||
| 159 | # CONFIG_ARCH_IXP23XX is not set | ||
| 160 | # CONFIG_ARCH_IXP2000 is not set | ||
| 161 | # CONFIG_ARCH_IXP4XX is not set | ||
| 162 | # CONFIG_ARCH_L7200 is not set | ||
| 163 | # CONFIG_ARCH_KIRKWOOD is not set | ||
| 164 | # CONFIG_ARCH_LOKI is not set | ||
| 165 | # CONFIG_ARCH_MV78XX0 is not set | ||
| 166 | # CONFIG_ARCH_ORION5X is not set | ||
| 167 | # CONFIG_ARCH_MMP is not set | ||
| 168 | # CONFIG_ARCH_KS8695 is not set | ||
| 169 | # CONFIG_ARCH_NS9XXX is not set | ||
| 170 | # CONFIG_ARCH_W90X900 is not set | ||
| 171 | # CONFIG_ARCH_PNX4008 is not set | ||
| 172 | # CONFIG_ARCH_PXA is not set | ||
| 173 | # CONFIG_ARCH_MSM is not set | ||
| 174 | # CONFIG_ARCH_RPC is not set | ||
| 175 | # CONFIG_ARCH_SA1100 is not set | ||
| 176 | # CONFIG_ARCH_S3C2410 is not set | ||
| 177 | # CONFIG_ARCH_S3C64XX is not set | ||
| 178 | # CONFIG_ARCH_SHARK is not set | ||
| 179 | # CONFIG_ARCH_LH7A40X is not set | ||
| 180 | # CONFIG_ARCH_U300 is not set | ||
| 181 | # CONFIG_ARCH_DAVINCI is not set | ||
| 182 | # CONFIG_ARCH_OMAP is not set | ||
| 183 | |||
| 184 | # | ||
| 185 | # Nomadik boards | ||
| 186 | # | ||
| 187 | CONFIG_MACH_NOMADIK_8815NHK=y | ||
| 188 | CONFIG_NOMADIK_8815=y | ||
| 189 | CONFIG_I2C_BITBANG_8815NHK=y | ||
| 190 | |||
| 191 | # | ||
| 192 | # Processor Type | ||
| 193 | # | ||
| 194 | CONFIG_CPU_32=y | ||
| 195 | CONFIG_CPU_ARM926T=y | ||
| 196 | CONFIG_CPU_32v5=y | ||
| 197 | CONFIG_CPU_ABRT_EV5TJ=y | ||
| 198 | CONFIG_CPU_PABRT_NOIFAR=y | ||
| 199 | CONFIG_CPU_CACHE_VIVT=y | ||
| 200 | CONFIG_CPU_COPY_V4WB=y | ||
| 201 | CONFIG_CPU_TLB_V4WBI=y | ||
| 202 | CONFIG_CPU_CP15=y | ||
| 203 | CONFIG_CPU_CP15_MMU=y | ||
| 204 | |||
| 205 | # | ||
| 206 | # Processor Features | ||
| 207 | # | ||
| 208 | CONFIG_ARM_THUMB=y | ||
| 209 | # CONFIG_CPU_ICACHE_DISABLE is not set | ||
| 210 | # CONFIG_CPU_DCACHE_DISABLE is not set | ||
| 211 | # CONFIG_CPU_DCACHE_WRITETHROUGH is not set | ||
| 212 | # CONFIG_CPU_CACHE_ROUND_ROBIN is not set | ||
| 213 | CONFIG_OUTER_CACHE=y | ||
| 214 | CONFIG_CACHE_L2X0=y | ||
| 215 | CONFIG_ARM_VIC=y | ||
| 216 | CONFIG_ARM_VIC_NR=2 | ||
| 217 | CONFIG_COMMON_CLKDEV=y | ||
| 218 | |||
| 219 | # | ||
| 220 | # Bus support | ||
| 221 | # | ||
| 222 | CONFIG_ARM_AMBA=y | ||
| 223 | # CONFIG_PCI_SYSCALL is not set | ||
| 224 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
| 225 | # CONFIG_PCCARD is not set | ||
| 226 | |||
| 227 | # | ||
| 228 | # Kernel Features | ||
| 229 | # | ||
| 230 | # CONFIG_NO_HZ is not set | ||
| 231 | # CONFIG_HIGH_RES_TIMERS is not set | ||
| 232 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | ||
| 233 | CONFIG_VMSPLIT_3G=y | ||
| 234 | # CONFIG_VMSPLIT_2G is not set | ||
| 235 | # CONFIG_VMSPLIT_1G is not set | ||
| 236 | CONFIG_PAGE_OFFSET=0xC0000000 | ||
| 237 | CONFIG_PREEMPT=y | ||
| 238 | CONFIG_HZ=100 | ||
| 239 | CONFIG_AEABI=y | ||
| 240 | CONFIG_OABI_COMPAT=y | ||
| 241 | # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set | ||
| 242 | # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set | ||
| 243 | # CONFIG_HIGHMEM is not set | ||
| 244 | CONFIG_SELECT_MEMORY_MODEL=y | ||
| 245 | CONFIG_FLATMEM_MANUAL=y | ||
| 246 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
| 247 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
| 248 | CONFIG_FLATMEM=y | ||
| 249 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
| 250 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
| 251 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | ||
| 252 | # CONFIG_PHYS_ADDR_T_64BIT is not set | ||
| 253 | CONFIG_ZONE_DMA_FLAG=0 | ||
| 254 | CONFIG_VIRT_TO_BUS=y | ||
| 255 | CONFIG_HAVE_MLOCK=y | ||
| 256 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | ||
| 257 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
| 258 | CONFIG_ALIGNMENT_TRAP=y | ||
| 259 | # CONFIG_UACCESS_WITH_MEMCPY is not set | ||
| 260 | |||
| 261 | # | ||
| 262 | # Boot options | ||
| 263 | # | ||
| 264 | CONFIG_ZBOOT_ROM_TEXT=0x0 | ||
| 265 | CONFIG_ZBOOT_ROM_BSS=0x0 | ||
| 266 | CONFIG_CMDLINE="" | ||
| 267 | # CONFIG_XIP_KERNEL is not set | ||
| 268 | # CONFIG_KEXEC is not set | ||
| 269 | |||
| 270 | # | ||
| 271 | # CPU Power Management | ||
| 272 | # | ||
| 273 | # CONFIG_CPU_IDLE is not set | ||
| 274 | |||
| 275 | # | ||
| 276 | # Floating point emulation | ||
| 277 | # | ||
| 278 | |||
| 279 | # | ||
| 280 | # At least one emulation must be selected | ||
| 281 | # | ||
| 282 | CONFIG_FPE_NWFPE=y | ||
| 283 | # CONFIG_FPE_NWFPE_XP is not set | ||
| 284 | # CONFIG_FPE_FASTFPE is not set | ||
| 285 | # CONFIG_VFP is not set | ||
| 286 | |||
| 287 | # | ||
| 288 | # Userspace binary formats | ||
| 289 | # | ||
| 290 | CONFIG_BINFMT_ELF=y | ||
| 291 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
| 292 | CONFIG_HAVE_AOUT=y | ||
| 293 | # CONFIG_BINFMT_AOUT is not set | ||
| 294 | # CONFIG_BINFMT_MISC is not set | ||
| 295 | |||
| 296 | # | ||
| 297 | # Power management options | ||
| 298 | # | ||
| 299 | CONFIG_PM=y | ||
| 300 | # CONFIG_PM_DEBUG is not set | ||
| 301 | CONFIG_PM_SLEEP=y | ||
| 302 | CONFIG_SUSPEND=y | ||
| 303 | CONFIG_SUSPEND_FREEZER=y | ||
| 304 | # CONFIG_APM_EMULATION is not set | ||
| 305 | CONFIG_ARCH_SUSPEND_POSSIBLE=y | ||
| 306 | CONFIG_NET=y | ||
| 307 | |||
| 308 | # | ||
| 309 | # Networking options | ||
| 310 | # | ||
| 311 | CONFIG_PACKET=y | ||
| 312 | # CONFIG_PACKET_MMAP is not set | ||
| 313 | CONFIG_UNIX=y | ||
| 314 | CONFIG_XFRM=y | ||
| 315 | # CONFIG_XFRM_USER is not set | ||
| 316 | # CONFIG_XFRM_SUB_POLICY is not set | ||
| 317 | # CONFIG_XFRM_MIGRATE is not set | ||
| 318 | # CONFIG_XFRM_STATISTICS is not set | ||
| 319 | CONFIG_NET_KEY=y | ||
| 320 | # CONFIG_NET_KEY_MIGRATE is not set | ||
| 321 | CONFIG_INET=y | ||
| 322 | CONFIG_IP_MULTICAST=y | ||
| 323 | CONFIG_IP_ADVANCED_ROUTER=y | ||
| 324 | CONFIG_ASK_IP_FIB_HASH=y | ||
| 325 | # CONFIG_IP_FIB_TRIE is not set | ||
| 326 | CONFIG_IP_FIB_HASH=y | ||
| 327 | # CONFIG_IP_MULTIPLE_TABLES is not set | ||
| 328 | # CONFIG_IP_ROUTE_MULTIPATH is not set | ||
| 329 | # CONFIG_IP_ROUTE_VERBOSE is not set | ||
| 330 | CONFIG_IP_PNP=y | ||
| 331 | CONFIG_IP_PNP_DHCP=y | ||
| 332 | CONFIG_IP_PNP_BOOTP=y | ||
| 333 | # CONFIG_IP_PNP_RARP is not set | ||
| 334 | CONFIG_NET_IPIP=y | ||
| 335 | CONFIG_NET_IPGRE=y | ||
| 336 | CONFIG_NET_IPGRE_BROADCAST=y | ||
| 337 | CONFIG_IP_MROUTE=y | ||
| 338 | # CONFIG_IP_PIMSM_V1 is not set | ||
| 339 | # CONFIG_IP_PIMSM_V2 is not set | ||
| 340 | # CONFIG_ARPD is not set | ||
| 341 | # CONFIG_SYN_COOKIES is not set | ||
| 342 | # CONFIG_INET_AH is not set | ||
| 343 | # CONFIG_INET_ESP is not set | ||
| 344 | # CONFIG_INET_IPCOMP is not set | ||
| 345 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
| 346 | CONFIG_INET_TUNNEL=y | ||
| 347 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | ||
| 348 | CONFIG_INET_XFRM_MODE_TUNNEL=y | ||
| 349 | CONFIG_INET_XFRM_MODE_BEET=y | ||
| 350 | # CONFIG_INET_LRO is not set | ||
| 351 | CONFIG_INET_DIAG=y | ||
| 352 | CONFIG_INET_TCP_DIAG=y | ||
| 353 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
| 354 | CONFIG_TCP_CONG_CUBIC=y | ||
| 355 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
| 356 | # CONFIG_TCP_MD5SIG is not set | ||
| 357 | # CONFIG_IPV6 is not set | ||
| 358 | # CONFIG_NETWORK_SECMARK is not set | ||
| 359 | # CONFIG_NETFILTER is not set | ||
| 360 | # CONFIG_IP_DCCP is not set | ||
| 361 | # CONFIG_IP_SCTP is not set | ||
| 362 | # CONFIG_TIPC is not set | ||
| 363 | # CONFIG_ATM is not set | ||
| 364 | # CONFIG_BRIDGE is not set | ||
| 365 | # CONFIG_NET_DSA is not set | ||
| 366 | # CONFIG_VLAN_8021Q is not set | ||
| 367 | # CONFIG_DECNET is not set | ||
| 368 | # CONFIG_LLC2 is not set | ||
| 369 | # CONFIG_IPX is not set | ||
| 370 | # CONFIG_ATALK is not set | ||
| 371 | # CONFIG_X25 is not set | ||
| 372 | # CONFIG_LAPB is not set | ||
| 373 | # CONFIG_ECONET is not set | ||
| 374 | # CONFIG_WAN_ROUTER is not set | ||
| 375 | # CONFIG_PHONET is not set | ||
| 376 | # CONFIG_IEEE802154 is not set | ||
| 377 | # CONFIG_NET_SCHED is not set | ||
| 378 | # CONFIG_DCB is not set | ||
| 379 | |||
| 380 | # | ||
| 381 | # Network testing | ||
| 382 | # | ||
| 383 | # CONFIG_NET_PKTGEN is not set | ||
| 384 | # CONFIG_HAMRADIO is not set | ||
| 385 | # CONFIG_CAN is not set | ||
| 386 | # CONFIG_IRDA is not set | ||
| 387 | CONFIG_BT=m | ||
| 388 | CONFIG_BT_L2CAP=m | ||
| 389 | CONFIG_BT_SCO=m | ||
| 390 | CONFIG_BT_RFCOMM=m | ||
| 391 | CONFIG_BT_RFCOMM_TTY=y | ||
| 392 | CONFIG_BT_BNEP=m | ||
| 393 | CONFIG_BT_BNEP_MC_FILTER=y | ||
| 394 | CONFIG_BT_BNEP_PROTO_FILTER=y | ||
| 395 | CONFIG_BT_HIDP=m | ||
| 396 | |||
| 397 | # | ||
| 398 | # Bluetooth device drivers | ||
| 399 | # | ||
| 400 | CONFIG_BT_HCIUART=m | ||
| 401 | CONFIG_BT_HCIUART_H4=y | ||
| 402 | CONFIG_BT_HCIUART_BCSP=y | ||
| 403 | # CONFIG_BT_HCIUART_LL is not set | ||
| 404 | CONFIG_BT_HCIVHCI=m | ||
| 405 | # CONFIG_AF_RXRPC is not set | ||
| 406 | CONFIG_WIRELESS=y | ||
| 407 | # CONFIG_CFG80211 is not set | ||
| 408 | CONFIG_WIRELESS_OLD_REGULATORY=y | ||
| 409 | # CONFIG_WIRELESS_EXT is not set | ||
| 410 | # CONFIG_LIB80211 is not set | ||
| 411 | |||
| 412 | # | ||
| 413 | # CFG80211 needs to be enabled for MAC80211 | ||
| 414 | # | ||
| 415 | CONFIG_MAC80211_DEFAULT_PS_VALUE=0 | ||
| 416 | # CONFIG_WIMAX is not set | ||
| 417 | # CONFIG_RFKILL is not set | ||
| 418 | # CONFIG_NET_9P is not set | ||
| 419 | |||
| 420 | # | ||
| 421 | # Device Drivers | ||
| 422 | # | ||
| 423 | |||
| 424 | # | ||
| 425 | # Generic Driver Options | ||
| 426 | # | ||
| 427 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
| 428 | CONFIG_STANDALONE=y | ||
| 429 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
| 430 | CONFIG_FW_LOADER=y | ||
| 431 | CONFIG_FIRMWARE_IN_KERNEL=y | ||
| 432 | CONFIG_EXTRA_FIRMWARE="" | ||
| 433 | # CONFIG_DEBUG_DRIVER is not set | ||
| 434 | # CONFIG_DEBUG_DEVRES is not set | ||
| 435 | # CONFIG_SYS_HYPERVISOR is not set | ||
| 436 | # CONFIG_CONNECTOR is not set | ||
| 437 | CONFIG_MTD=y | ||
| 438 | # CONFIG_MTD_DEBUG is not set | ||
| 439 | # CONFIG_MTD_CONCAT is not set | ||
| 440 | CONFIG_MTD_PARTITIONS=y | ||
| 441 | CONFIG_MTD_TESTS=m | ||
| 442 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
| 443 | # CONFIG_MTD_CMDLINE_PARTS is not set | ||
| 444 | # CONFIG_MTD_AFS_PARTS is not set | ||
| 445 | # CONFIG_MTD_AR7_PARTS is not set | ||
| 446 | |||
| 447 | # | ||
| 448 | # User Modules And Translation Layers | ||
| 449 | # | ||
| 450 | CONFIG_MTD_CHAR=y | ||
| 451 | CONFIG_MTD_BLKDEVS=y | ||
| 452 | CONFIG_MTD_BLOCK=y | ||
| 453 | # CONFIG_FTL is not set | ||
| 454 | # CONFIG_NFTL is not set | ||
| 455 | # CONFIG_INFTL is not set | ||
| 456 | # CONFIG_RFD_FTL is not set | ||
| 457 | # CONFIG_SSFDC is not set | ||
| 458 | # CONFIG_MTD_OOPS is not set | ||
| 459 | |||
| 460 | # | ||
| 461 | # RAM/ROM/Flash chip drivers | ||
| 462 | # | ||
| 463 | # CONFIG_MTD_CFI is not set | ||
| 464 | # CONFIG_MTD_JEDECPROBE is not set | ||
| 465 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
| 466 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
| 467 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
| 468 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
| 469 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
| 470 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
| 471 | CONFIG_MTD_CFI_I1=y | ||
| 472 | CONFIG_MTD_CFI_I2=y | ||
| 473 | # CONFIG_MTD_CFI_I4 is not set | ||
| 474 | # CONFIG_MTD_CFI_I8 is not set | ||
| 475 | # CONFIG_MTD_RAM is not set | ||
| 476 | # CONFIG_MTD_ROM is not set | ||
| 477 | # CONFIG_MTD_ABSENT is not set | ||
| 478 | |||
| 479 | # | ||
| 480 | # Mapping drivers for chip access | ||
| 481 | # | ||
| 482 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
| 483 | # CONFIG_MTD_PLATRAM is not set | ||
| 484 | |||
| 485 | # | ||
| 486 | # Self-contained MTD device drivers | ||
| 487 | # | ||
| 488 | # CONFIG_MTD_SLRAM is not set | ||
| 489 | # CONFIG_MTD_PHRAM is not set | ||
| 490 | # CONFIG_MTD_MTDRAM is not set | ||
| 491 | # CONFIG_MTD_BLOCK2MTD is not set | ||
| 492 | |||
| 493 | # | ||
| 494 | # Disk-On-Chip Device Drivers | ||
| 495 | # | ||
| 496 | # CONFIG_MTD_DOC2000 is not set | ||
| 497 | # CONFIG_MTD_DOC2001 is not set | ||
| 498 | # CONFIG_MTD_DOC2001PLUS is not set | ||
| 499 | CONFIG_MTD_NAND=y | ||
| 500 | CONFIG_MTD_NAND_VERIFY_WRITE=y | ||
| 501 | # CONFIG_MTD_NAND_ECC_SMC is not set | ||
| 502 | # CONFIG_MTD_NAND_MUSEUM_IDS is not set | ||
| 503 | # CONFIG_MTD_NAND_GPIO is not set | ||
| 504 | CONFIG_MTD_NAND_IDS=y | ||
| 505 | # CONFIG_MTD_NAND_DISKONCHIP is not set | ||
| 506 | # CONFIG_MTD_NAND_NANDSIM is not set | ||
| 507 | # CONFIG_MTD_NAND_PLATFORM is not set | ||
| 508 | CONFIG_MTD_NAND_NOMADIK=y | ||
| 509 | CONFIG_MTD_ONENAND=y | ||
| 510 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y | ||
| 511 | CONFIG_MTD_ONENAND_GENERIC=y | ||
| 512 | # CONFIG_MTD_ONENAND_OTP is not set | ||
| 513 | # CONFIG_MTD_ONENAND_2X_PROGRAM is not set | ||
| 514 | # CONFIG_MTD_ONENAND_SIM is not set | ||
| 515 | |||
| 516 | # | ||
| 517 | # LPDDR flash memory drivers | ||
| 518 | # | ||
| 519 | # CONFIG_MTD_LPDDR is not set | ||
| 520 | |||
| 521 | # | ||
| 522 | # UBI - Unsorted block images | ||
| 523 | # | ||
| 524 | # CONFIG_MTD_UBI is not set | ||
| 525 | # CONFIG_PARPORT is not set | ||
| 526 | CONFIG_BLK_DEV=y | ||
| 527 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
| 528 | CONFIG_BLK_DEV_LOOP=y | ||
| 529 | CONFIG_BLK_DEV_CRYPTOLOOP=y | ||
| 530 | # CONFIG_BLK_DEV_NBD is not set | ||
| 531 | CONFIG_BLK_DEV_RAM=y | ||
| 532 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
| 533 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
| 534 | # CONFIG_BLK_DEV_XIP is not set | ||
| 535 | # CONFIG_CDROM_PKTCDVD is not set | ||
| 536 | # CONFIG_ATA_OVER_ETH is not set | ||
| 537 | # CONFIG_MG_DISK is not set | ||
| 538 | CONFIG_MISC_DEVICES=y | ||
| 539 | # CONFIG_ICS932S401 is not set | ||
| 540 | # CONFIG_ENCLOSURE_SERVICES is not set | ||
| 541 | # CONFIG_ISL29003 is not set | ||
| 542 | # CONFIG_C2PORT is not set | ||
| 543 | |||
| 544 | # | ||
| 545 | # EEPROM support | ||
| 546 | # | ||
| 547 | # CONFIG_EEPROM_AT24 is not set | ||
| 548 | # CONFIG_EEPROM_LEGACY is not set | ||
| 549 | # CONFIG_EEPROM_MAX6875 is not set | ||
| 550 | # CONFIG_EEPROM_93CX6 is not set | ||
| 551 | CONFIG_HAVE_IDE=y | ||
| 552 | # CONFIG_IDE is not set | ||
| 553 | |||
| 554 | # | ||
| 555 | # SCSI device support | ||
| 556 | # | ||
| 557 | # CONFIG_RAID_ATTRS is not set | ||
| 558 | CONFIG_SCSI=y | ||
| 559 | CONFIG_SCSI_DMA=y | ||
| 560 | # CONFIG_SCSI_TGT is not set | ||
| 561 | # CONFIG_SCSI_NETLINK is not set | ||
| 562 | CONFIG_SCSI_PROC_FS=y | ||
| 563 | |||
| 564 | # | ||
| 565 | # SCSI support type (disk, tape, CD-ROM) | ||
| 566 | # | ||
| 567 | CONFIG_BLK_DEV_SD=y | ||
| 568 | # CONFIG_CHR_DEV_ST is not set | ||
| 569 | # CONFIG_CHR_DEV_OSST is not set | ||
| 570 | # CONFIG_BLK_DEV_SR is not set | ||
| 571 | CONFIG_CHR_DEV_SG=y | ||
| 572 | # CONFIG_CHR_DEV_SCH is not set | ||
| 573 | CONFIG_SCSI_MULTI_LUN=y | ||
| 574 | CONFIG_SCSI_CONSTANTS=y | ||
| 575 | CONFIG_SCSI_LOGGING=y | ||
| 576 | CONFIG_SCSI_SCAN_ASYNC=y | ||
| 577 | CONFIG_SCSI_WAIT_SCAN=m | ||
| 578 | |||
| 579 | # | ||
| 580 | # SCSI Transports | ||
| 581 | # | ||
| 582 | # CONFIG_SCSI_SPI_ATTRS is not set | ||
| 583 | # CONFIG_SCSI_FC_ATTRS is not set | ||
| 584 | # CONFIG_SCSI_ISCSI_ATTRS is not set | ||
| 585 | # CONFIG_SCSI_SAS_LIBSAS is not set | ||
| 586 | # CONFIG_SCSI_SRP_ATTRS is not set | ||
| 587 | CONFIG_SCSI_LOWLEVEL=y | ||
| 588 | # CONFIG_ISCSI_TCP is not set | ||
| 589 | # CONFIG_LIBFC is not set | ||
| 590 | # CONFIG_LIBFCOE is not set | ||
| 591 | # CONFIG_SCSI_DEBUG is not set | ||
| 592 | # CONFIG_SCSI_DH is not set | ||
| 593 | # CONFIG_SCSI_OSD_INITIATOR is not set | ||
| 594 | # CONFIG_ATA is not set | ||
| 595 | # CONFIG_MD is not set | ||
| 596 | CONFIG_NETDEVICES=y | ||
| 597 | # CONFIG_DUMMY is not set | ||
| 598 | # CONFIG_BONDING is not set | ||
| 599 | # CONFIG_MACVLAN is not set | ||
| 600 | # CONFIG_EQUALIZER is not set | ||
| 601 | CONFIG_TUN=y | ||
| 602 | # CONFIG_VETH is not set | ||
| 603 | # CONFIG_PHYLIB is not set | ||
| 604 | CONFIG_NET_ETHERNET=y | ||
| 605 | CONFIG_MII=y | ||
| 606 | # CONFIG_AX88796 is not set | ||
| 607 | CONFIG_SMC91X=y | ||
| 608 | # CONFIG_DM9000 is not set | ||
| 609 | # CONFIG_ETHOC is not set | ||
| 610 | # CONFIG_SMC911X is not set | ||
| 611 | # CONFIG_SMSC911X is not set | ||
| 612 | # CONFIG_DNET is not set | ||
| 613 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
| 614 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
| 615 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
| 616 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
| 617 | # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set | ||
| 618 | # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set | ||
| 619 | # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set | ||
| 620 | # CONFIG_B44 is not set | ||
| 621 | # CONFIG_KS8842 is not set | ||
| 622 | CONFIG_NETDEV_1000=y | ||
| 623 | CONFIG_NETDEV_10000=y | ||
| 624 | |||
| 625 | # | ||
| 626 | # Wireless LAN | ||
| 627 | # | ||
| 628 | # CONFIG_WLAN_PRE80211 is not set | ||
| 629 | # CONFIG_WLAN_80211 is not set | ||
| 630 | |||
| 631 | # | ||
| 632 | # Enable WiMAX (Networking options) to see the WiMAX drivers | ||
| 633 | # | ||
| 634 | # CONFIG_WAN is not set | ||
| 635 | CONFIG_PPP=m | ||
| 636 | # CONFIG_PPP_MULTILINK is not set | ||
| 637 | # CONFIG_PPP_FILTER is not set | ||
| 638 | CONFIG_PPP_ASYNC=m | ||
| 639 | CONFIG_PPP_SYNC_TTY=m | ||
| 640 | CONFIG_PPP_DEFLATE=m | ||
| 641 | CONFIG_PPP_BSDCOMP=m | ||
| 642 | CONFIG_PPP_MPPE=m | ||
| 643 | CONFIG_PPPOE=m | ||
| 644 | # CONFIG_PPPOL2TP is not set | ||
| 645 | # CONFIG_SLIP is not set | ||
| 646 | CONFIG_SLHC=m | ||
| 647 | CONFIG_NETCONSOLE=m | ||
| 648 | # CONFIG_NETCONSOLE_DYNAMIC is not set | ||
| 649 | CONFIG_NETPOLL=y | ||
| 650 | # CONFIG_NETPOLL_TRAP is not set | ||
| 651 | CONFIG_NET_POLL_CONTROLLER=y | ||
| 652 | # CONFIG_ISDN is not set | ||
| 653 | |||
| 654 | # | ||
| 655 | # Input device support | ||
| 656 | # | ||
| 657 | CONFIG_INPUT=y | ||
| 658 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
| 659 | # CONFIG_INPUT_POLLDEV is not set | ||
| 660 | |||
| 661 | # | ||
| 662 | # Userland interfaces | ||
| 663 | # | ||
| 664 | # CONFIG_INPUT_MOUSEDEV is not set | ||
| 665 | # CONFIG_INPUT_JOYDEV is not set | ||
| 666 | CONFIG_INPUT_EVDEV=y | ||
| 667 | # CONFIG_INPUT_EVBUG is not set | ||
| 668 | |||
| 669 | # | ||
| 670 | # Input Device Drivers | ||
| 671 | # | ||
| 672 | CONFIG_INPUT_KEYBOARD=y | ||
| 673 | # CONFIG_KEYBOARD_ATKBD is not set | ||
| 674 | # CONFIG_KEYBOARD_SUNKBD is not set | ||
| 675 | # CONFIG_KEYBOARD_LKKBD is not set | ||
| 676 | # CONFIG_KEYBOARD_XTKBD is not set | ||
| 677 | # CONFIG_KEYBOARD_NEWTON is not set | ||
| 678 | # CONFIG_KEYBOARD_STOWAWAY is not set | ||
| 679 | # CONFIG_KEYBOARD_GPIO is not set | ||
| 680 | CONFIG_INPUT_MOUSE=y | ||
| 681 | # CONFIG_MOUSE_PS2 is not set | ||
| 682 | # CONFIG_MOUSE_SERIAL is not set | ||
| 683 | # CONFIG_MOUSE_APPLETOUCH is not set | ||
| 684 | # CONFIG_MOUSE_BCM5974 is not set | ||
| 685 | # CONFIG_MOUSE_VSXXXAA is not set | ||
| 686 | # CONFIG_MOUSE_GPIO is not set | ||
| 687 | # CONFIG_MOUSE_SYNAPTICS_I2C is not set | ||
| 688 | # CONFIG_INPUT_JOYSTICK is not set | ||
| 689 | # CONFIG_INPUT_TABLET is not set | ||
| 690 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
| 691 | # CONFIG_INPUT_MISC is not set | ||
| 692 | |||
| 693 | # | ||
| 694 | # Hardware I/O ports | ||
| 695 | # | ||
| 696 | # CONFIG_SERIO is not set | ||
| 697 | # CONFIG_GAMEPORT is not set | ||
| 698 | |||
| 699 | # | ||
| 700 | # Character devices | ||
| 701 | # | ||
| 702 | CONFIG_VT=y | ||
| 703 | CONFIG_CONSOLE_TRANSLATIONS=y | ||
| 704 | CONFIG_VT_CONSOLE=y | ||
| 705 | CONFIG_HW_CONSOLE=y | ||
| 706 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | ||
| 707 | CONFIG_DEVKMEM=y | ||
| 708 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
| 709 | |||
| 710 | # | ||
| 711 | # Serial drivers | ||
| 712 | # | ||
| 713 | # CONFIG_SERIAL_8250 is not set | ||
| 714 | |||
| 715 | # | ||
| 716 | # Non-8250 serial port support | ||
| 717 | # | ||
| 718 | # CONFIG_SERIAL_AMBA_PL010 is not set | ||
| 719 | CONFIG_SERIAL_AMBA_PL011=y | ||
| 720 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y | ||
| 721 | CONFIG_SERIAL_CORE=y | ||
| 722 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
| 723 | CONFIG_UNIX98_PTYS=y | ||
| 724 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
| 725 | # CONFIG_LEGACY_PTYS is not set | ||
| 726 | # CONFIG_IPMI_HANDLER is not set | ||
| 727 | # CONFIG_HW_RANDOM is not set | ||
| 728 | # CONFIG_R3964 is not set | ||
| 729 | # CONFIG_RAW_DRIVER is not set | ||
| 730 | # CONFIG_TCG_TPM is not set | ||
| 731 | CONFIG_I2C=y | ||
| 732 | CONFIG_I2C_BOARDINFO=y | ||
| 733 | CONFIG_I2C_CHARDEV=y | ||
| 734 | CONFIG_I2C_HELPER_AUTO=y | ||
| 735 | CONFIG_I2C_ALGOBIT=y | ||
| 736 | |||
| 737 | # | ||
| 738 | # I2C Hardware Bus support | ||
| 739 | # | ||
| 740 | |||
| 741 | # | ||
| 742 | # I2C system bus drivers (mostly embedded / system-on-chip) | ||
| 743 | # | ||
| 744 | CONFIG_I2C_GPIO=y | ||
| 745 | # CONFIG_I2C_OCORES is not set | ||
| 746 | # CONFIG_I2C_SIMTEC is not set | ||
| 747 | |||
| 748 | # | ||
| 749 | # External I2C/SMBus adapter drivers | ||
| 750 | # | ||
| 751 | # CONFIG_I2C_PARPORT_LIGHT is not set | ||
| 752 | # CONFIG_I2C_TAOS_EVM is not set | ||
| 753 | |||
| 754 | # | ||
| 755 | # Other I2C/SMBus bus drivers | ||
| 756 | # | ||
| 757 | # CONFIG_I2C_PCA_PLATFORM is not set | ||
| 758 | # CONFIG_I2C_STUB is not set | ||
| 759 | |||
| 760 | # | ||
| 761 | # Miscellaneous I2C Chip support | ||
| 762 | # | ||
| 763 | # CONFIG_DS1682 is not set | ||
| 764 | # CONFIG_SENSORS_PCF8574 is not set | ||
| 765 | # CONFIG_PCF8575 is not set | ||
| 766 | # CONFIG_SENSORS_PCA9539 is not set | ||
| 767 | # CONFIG_SENSORS_TSL2550 is not set | ||
| 768 | # CONFIG_I2C_DEBUG_CORE is not set | ||
| 769 | # CONFIG_I2C_DEBUG_ALGO is not set | ||
| 770 | # CONFIG_I2C_DEBUG_BUS is not set | ||
| 771 | # CONFIG_I2C_DEBUG_CHIP is not set | ||
| 772 | # CONFIG_SPI is not set | ||
| 773 | CONFIG_ARCH_REQUIRE_GPIOLIB=y | ||
| 774 | CONFIG_GPIOLIB=y | ||
| 775 | CONFIG_DEBUG_GPIO=y | ||
| 776 | # CONFIG_GPIO_SYSFS is not set | ||
| 777 | |||
| 778 | # | ||
| 779 | # Memory mapped GPIO expanders: | ||
| 780 | # | ||
| 781 | # CONFIG_GPIO_PL061 is not set | ||
| 782 | |||
| 783 | # | ||
| 784 | # I2C GPIO expanders: | ||
| 785 | # | ||
| 786 | # CONFIG_GPIO_MAX732X is not set | ||
| 787 | # CONFIG_GPIO_PCA953X is not set | ||
| 788 | # CONFIG_GPIO_PCF857X is not set | ||
| 789 | |||
| 790 | # | ||
| 791 | # PCI GPIO expanders: | ||
| 792 | # | ||
| 793 | |||
| 794 | # | ||
| 795 | # SPI GPIO expanders: | ||
| 796 | # | ||
| 797 | # CONFIG_W1 is not set | ||
| 798 | # CONFIG_POWER_SUPPLY is not set | ||
| 799 | # CONFIG_HWMON is not set | ||
| 800 | # CONFIG_THERMAL is not set | ||
| 801 | # CONFIG_THERMAL_HWMON is not set | ||
| 802 | # CONFIG_WATCHDOG is not set | ||
| 803 | CONFIG_SSB_POSSIBLE=y | ||
| 804 | |||
| 805 | # | ||
| 806 | # Sonics Silicon Backplane | ||
| 807 | # | ||
| 808 | # CONFIG_SSB is not set | ||
| 809 | |||
| 810 | # | ||
| 811 | # Multifunction device drivers | ||
| 812 | # | ||
| 813 | # CONFIG_MFD_CORE is not set | ||
| 814 | # CONFIG_MFD_SM501 is not set | ||
| 815 | # CONFIG_MFD_ASIC3 is not set | ||
| 816 | # CONFIG_HTC_EGPIO is not set | ||
| 817 | # CONFIG_HTC_PASIC3 is not set | ||
| 818 | # CONFIG_TPS65010 is not set | ||
| 819 | # CONFIG_TWL4030_CORE is not set | ||
| 820 | # CONFIG_MFD_TMIO is not set | ||
| 821 | # CONFIG_MFD_T7L66XB is not set | ||
| 822 | # CONFIG_MFD_TC6387XB is not set | ||
| 823 | # CONFIG_MFD_TC6393XB is not set | ||
| 824 | # CONFIG_PMIC_DA903X is not set | ||
| 825 | # CONFIG_MFD_WM8400 is not set | ||
| 826 | # CONFIG_MFD_WM8350_I2C is not set | ||
| 827 | # CONFIG_MFD_PCF50633 is not set | ||
| 828 | # CONFIG_AB3100_CORE is not set | ||
| 829 | # CONFIG_MEDIA_SUPPORT is not set | ||
| 830 | |||
| 831 | # | ||
| 832 | # Graphics support | ||
| 833 | # | ||
| 834 | # CONFIG_VGASTATE is not set | ||
| 835 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
| 836 | # CONFIG_FB is not set | ||
| 837 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
| 838 | |||
| 839 | # | ||
| 840 | # Display device support | ||
| 841 | # | ||
| 842 | # CONFIG_DISPLAY_SUPPORT is not set | ||
| 843 | |||
| 844 | # | ||
| 845 | # Console display driver support | ||
| 846 | # | ||
| 847 | # CONFIG_VGA_CONSOLE is not set | ||
| 848 | CONFIG_DUMMY_CONSOLE=y | ||
| 849 | # CONFIG_SOUND is not set | ||
| 850 | CONFIG_HID_SUPPORT=y | ||
| 851 | CONFIG_HID=y | ||
| 852 | # CONFIG_HID_DEBUG is not set | ||
| 853 | # CONFIG_HIDRAW is not set | ||
| 854 | # CONFIG_HID_PID is not set | ||
| 855 | |||
| 856 | # | ||
| 857 | # Special HID drivers | ||
| 858 | # | ||
| 859 | # CONFIG_HID_APPLE is not set | ||
| 860 | # CONFIG_HID_WACOM is not set | ||
| 861 | CONFIG_USB_SUPPORT=y | ||
| 862 | CONFIG_USB_ARCH_HAS_HCD=y | ||
| 863 | # CONFIG_USB_ARCH_HAS_OHCI is not set | ||
| 864 | # CONFIG_USB_ARCH_HAS_EHCI is not set | ||
| 865 | # CONFIG_USB is not set | ||
| 866 | # CONFIG_USB_OTG_WHITELIST is not set | ||
| 867 | # CONFIG_USB_OTG_BLACKLIST_HUB is not set | ||
| 868 | |||
| 869 | # | ||
| 870 | # Enable Host or Gadget support to see Inventra options | ||
| 871 | # | ||
| 872 | |||
| 873 | # | ||
| 874 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may | ||
| 875 | # | ||
| 876 | # CONFIG_USB_GADGET is not set | ||
| 877 | |||
| 878 | # | ||
| 879 | # OTG and related infrastructure | ||
| 880 | # | ||
| 881 | # CONFIG_MMC is not set | ||
| 882 | # CONFIG_MEMSTICK is not set | ||
| 883 | # CONFIG_ACCESSIBILITY is not set | ||
| 884 | # CONFIG_NEW_LEDS is not set | ||
| 885 | CONFIG_RTC_LIB=y | ||
| 886 | CONFIG_RTC_CLASS=y | ||
| 887 | CONFIG_RTC_HCTOSYS=y | ||
| 888 | CONFIG_RTC_HCTOSYS_DEVICE="rtc0" | ||
| 889 | # CONFIG_RTC_DEBUG is not set | ||
| 890 | |||
| 891 | # | ||
| 892 | # RTC interfaces | ||
| 893 | # | ||
| 894 | CONFIG_RTC_INTF_SYSFS=y | ||
| 895 | CONFIG_RTC_INTF_PROC=y | ||
| 896 | CONFIG_RTC_INTF_DEV=y | ||
| 897 | # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set | ||
| 898 | # CONFIG_RTC_DRV_TEST is not set | ||
| 899 | |||
| 900 | # | ||
| 901 | # I2C RTC drivers | ||
| 902 | # | ||
| 903 | # CONFIG_RTC_DRV_DS1307 is not set | ||
| 904 | # CONFIG_RTC_DRV_DS1374 is not set | ||
| 905 | # CONFIG_RTC_DRV_DS1672 is not set | ||
| 906 | # CONFIG_RTC_DRV_MAX6900 is not set | ||
| 907 | # CONFIG_RTC_DRV_RS5C372 is not set | ||
| 908 | # CONFIG_RTC_DRV_ISL1208 is not set | ||
| 909 | # CONFIG_RTC_DRV_X1205 is not set | ||
| 910 | # CONFIG_RTC_DRV_PCF8563 is not set | ||
| 911 | # CONFIG_RTC_DRV_PCF8583 is not set | ||
| 912 | # CONFIG_RTC_DRV_M41T80 is not set | ||
| 913 | # CONFIG_RTC_DRV_S35390A is not set | ||
| 914 | # CONFIG_RTC_DRV_FM3130 is not set | ||
| 915 | # CONFIG_RTC_DRV_RX8581 is not set | ||
| 916 | # CONFIG_RTC_DRV_RX8025 is not set | ||
| 917 | |||
| 918 | # | ||
| 919 | # SPI RTC drivers | ||
| 920 | # | ||
| 921 | |||
| 922 | # | ||
| 923 | # Platform RTC drivers | ||
| 924 | # | ||
| 925 | # CONFIG_RTC_DRV_CMOS is not set | ||
| 926 | # CONFIG_RTC_DRV_DS1286 is not set | ||
| 927 | # CONFIG_RTC_DRV_DS1511 is not set | ||
| 928 | # CONFIG_RTC_DRV_DS1553 is not set | ||
| 929 | # CONFIG_RTC_DRV_DS1742 is not set | ||
| 930 | # CONFIG_RTC_DRV_STK17TA8 is not set | ||
| 931 | # CONFIG_RTC_DRV_M48T86 is not set | ||
| 932 | # CONFIG_RTC_DRV_M48T35 is not set | ||
| 933 | # CONFIG_RTC_DRV_M48T59 is not set | ||
| 934 | # CONFIG_RTC_DRV_BQ4802 is not set | ||
| 935 | # CONFIG_RTC_DRV_V3020 is not set | ||
| 936 | |||
| 937 | # | ||
| 938 | # on-CPU RTC drivers | ||
| 939 | # | ||
| 940 | # CONFIG_RTC_DRV_PL030 is not set | ||
| 941 | # CONFIG_RTC_DRV_PL031 is not set | ||
| 942 | # CONFIG_DMADEVICES is not set | ||
| 943 | # CONFIG_AUXDISPLAY is not set | ||
| 944 | # CONFIG_REGULATOR is not set | ||
| 945 | # CONFIG_UIO is not set | ||
| 946 | # CONFIG_STAGING is not set | ||
| 947 | |||
| 948 | # | ||
| 949 | # File systems | ||
| 950 | # | ||
| 951 | CONFIG_EXT2_FS=y | ||
| 952 | # CONFIG_EXT2_FS_XATTR is not set | ||
| 953 | # CONFIG_EXT2_FS_XIP is not set | ||
| 954 | CONFIG_EXT3_FS=y | ||
| 955 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
| 956 | CONFIG_EXT3_FS_XATTR=y | ||
| 957 | # CONFIG_EXT3_FS_POSIX_ACL is not set | ||
| 958 | # CONFIG_EXT3_FS_SECURITY is not set | ||
| 959 | # CONFIG_EXT4_FS is not set | ||
| 960 | CONFIG_JBD=y | ||
| 961 | CONFIG_FS_MBCACHE=y | ||
| 962 | # CONFIG_REISERFS_FS is not set | ||
| 963 | # CONFIG_JFS_FS is not set | ||
| 964 | CONFIG_FS_POSIX_ACL=y | ||
| 965 | # CONFIG_XFS_FS is not set | ||
| 966 | # CONFIG_GFS2_FS is not set | ||
| 967 | # CONFIG_OCFS2_FS is not set | ||
| 968 | # CONFIG_BTRFS_FS is not set | ||
| 969 | CONFIG_FILE_LOCKING=y | ||
| 970 | CONFIG_FSNOTIFY=y | ||
| 971 | CONFIG_DNOTIFY=y | ||
| 972 | CONFIG_INOTIFY=y | ||
| 973 | CONFIG_INOTIFY_USER=y | ||
| 974 | # CONFIG_QUOTA is not set | ||
| 975 | # CONFIG_AUTOFS_FS is not set | ||
| 976 | # CONFIG_AUTOFS4_FS is not set | ||
| 977 | CONFIG_FUSE_FS=y | ||
| 978 | # CONFIG_CUSE is not set | ||
| 979 | |||
| 980 | # | ||
| 981 | # Caches | ||
| 982 | # | ||
| 983 | # CONFIG_FSCACHE is not set | ||
| 984 | |||
| 985 | # | ||
| 986 | # CD-ROM/DVD Filesystems | ||
| 987 | # | ||
| 988 | # CONFIG_ISO9660_FS is not set | ||
| 989 | # CONFIG_UDF_FS is not set | ||
| 990 | |||
| 991 | # | ||
| 992 | # DOS/FAT/NT Filesystems | ||
| 993 | # | ||
| 994 | CONFIG_FAT_FS=y | ||
| 995 | CONFIG_MSDOS_FS=y | ||
| 996 | CONFIG_VFAT_FS=y | ||
| 997 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
| 998 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
| 999 | # CONFIG_NTFS_FS is not set | ||
| 1000 | |||
| 1001 | # | ||
| 1002 | # Pseudo filesystems | ||
| 1003 | # | ||
| 1004 | CONFIG_PROC_FS=y | ||
| 1005 | CONFIG_PROC_SYSCTL=y | ||
| 1006 | CONFIG_PROC_PAGE_MONITOR=y | ||
| 1007 | CONFIG_SYSFS=y | ||
| 1008 | CONFIG_TMPFS=y | ||
| 1009 | # CONFIG_TMPFS_POSIX_ACL is not set | ||
| 1010 | # CONFIG_HUGETLB_PAGE is not set | ||
| 1011 | # CONFIG_CONFIGFS_FS is not set | ||
| 1012 | CONFIG_MISC_FILESYSTEMS=y | ||
| 1013 | # CONFIG_ADFS_FS is not set | ||
| 1014 | # CONFIG_AFFS_FS is not set | ||
| 1015 | # CONFIG_HFS_FS is not set | ||
| 1016 | # CONFIG_HFSPLUS_FS is not set | ||
| 1017 | # CONFIG_BEFS_FS is not set | ||
| 1018 | # CONFIG_BFS_FS is not set | ||
| 1019 | # CONFIG_EFS_FS is not set | ||
| 1020 | CONFIG_JFFS2_FS=y | ||
| 1021 | CONFIG_JFFS2_FS_DEBUG=0 | ||
| 1022 | CONFIG_JFFS2_FS_WRITEBUFFER=y | ||
| 1023 | # CONFIG_JFFS2_FS_WBUF_VERIFY is not set | ||
| 1024 | # CONFIG_JFFS2_SUMMARY is not set | ||
| 1025 | # CONFIG_JFFS2_FS_XATTR is not set | ||
| 1026 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | ||
| 1027 | CONFIG_JFFS2_ZLIB=y | ||
| 1028 | # CONFIG_JFFS2_LZO is not set | ||
| 1029 | CONFIG_JFFS2_RTIME=y | ||
| 1030 | # CONFIG_JFFS2_RUBIN is not set | ||
| 1031 | # CONFIG_CRAMFS is not set | ||
| 1032 | # CONFIG_SQUASHFS is not set | ||
| 1033 | # CONFIG_VXFS_FS is not set | ||
| 1034 | # CONFIG_MINIX_FS is not set | ||
| 1035 | # CONFIG_OMFS_FS is not set | ||
| 1036 | # CONFIG_HPFS_FS is not set | ||
| 1037 | # CONFIG_QNX4FS_FS is not set | ||
| 1038 | # CONFIG_ROMFS_FS is not set | ||
| 1039 | # CONFIG_SYSV_FS is not set | ||
| 1040 | # CONFIG_UFS_FS is not set | ||
| 1041 | # CONFIG_NILFS2_FS is not set | ||
| 1042 | CONFIG_NETWORK_FILESYSTEMS=y | ||
| 1043 | CONFIG_NFS_FS=y | ||
| 1044 | CONFIG_NFS_V3=y | ||
| 1045 | CONFIG_NFS_V3_ACL=y | ||
| 1046 | # CONFIG_NFS_V4 is not set | ||
| 1047 | CONFIG_ROOT_NFS=y | ||
| 1048 | # CONFIG_NFSD is not set | ||
| 1049 | CONFIG_LOCKD=y | ||
| 1050 | CONFIG_LOCKD_V4=y | ||
| 1051 | CONFIG_NFS_ACL_SUPPORT=y | ||
| 1052 | CONFIG_NFS_COMMON=y | ||
| 1053 | CONFIG_SUNRPC=y | ||
| 1054 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
| 1055 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
| 1056 | CONFIG_SMB_FS=m | ||
| 1057 | # CONFIG_SMB_NLS_DEFAULT is not set | ||
| 1058 | CONFIG_CIFS=m | ||
| 1059 | # CONFIG_CIFS_STATS is not set | ||
| 1060 | CONFIG_CIFS_WEAK_PW_HASH=y | ||
| 1061 | # CONFIG_CIFS_XATTR is not set | ||
| 1062 | # CONFIG_CIFS_DEBUG2 is not set | ||
| 1063 | # CONFIG_CIFS_EXPERIMENTAL is not set | ||
| 1064 | # CONFIG_NCP_FS is not set | ||
| 1065 | # CONFIG_CODA_FS is not set | ||
| 1066 | # CONFIG_AFS_FS is not set | ||
| 1067 | |||
| 1068 | # | ||
| 1069 | # Partition Types | ||
| 1070 | # | ||
| 1071 | # CONFIG_PARTITION_ADVANCED is not set | ||
| 1072 | CONFIG_MSDOS_PARTITION=y | ||
| 1073 | CONFIG_NLS=y | ||
| 1074 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
| 1075 | CONFIG_NLS_CODEPAGE_437=y | ||
| 1076 | # CONFIG_NLS_CODEPAGE_737 is not set | ||
| 1077 | # CONFIG_NLS_CODEPAGE_775 is not set | ||
| 1078 | # CONFIG_NLS_CODEPAGE_850 is not set | ||
| 1079 | # CONFIG_NLS_CODEPAGE_852 is not set | ||
| 1080 | # CONFIG_NLS_CODEPAGE_855 is not set | ||
| 1081 | # CONFIG_NLS_CODEPAGE_857 is not set | ||
| 1082 | # CONFIG_NLS_CODEPAGE_860 is not set | ||
| 1083 | # CONFIG_NLS_CODEPAGE_861 is not set | ||
| 1084 | # CONFIG_NLS_CODEPAGE_862 is not set | ||
| 1085 | # CONFIG_NLS_CODEPAGE_863 is not set | ||
| 1086 | # CONFIG_NLS_CODEPAGE_864 is not set | ||
| 1087 | # CONFIG_NLS_CODEPAGE_865 is not set | ||
| 1088 | # CONFIG_NLS_CODEPAGE_866 is not set | ||
| 1089 | # CONFIG_NLS_CODEPAGE_869 is not set | ||
| 1090 | # CONFIG_NLS_CODEPAGE_936 is not set | ||
| 1091 | # CONFIG_NLS_CODEPAGE_950 is not set | ||
| 1092 | # CONFIG_NLS_CODEPAGE_932 is not set | ||
| 1093 | # CONFIG_NLS_CODEPAGE_949 is not set | ||
| 1094 | # CONFIG_NLS_CODEPAGE_874 is not set | ||
| 1095 | # CONFIG_NLS_ISO8859_8 is not set | ||
| 1096 | # CONFIG_NLS_CODEPAGE_1250 is not set | ||
| 1097 | # CONFIG_NLS_CODEPAGE_1251 is not set | ||
| 1098 | CONFIG_NLS_ASCII=y | ||
| 1099 | CONFIG_NLS_ISO8859_1=y | ||
| 1100 | # CONFIG_NLS_ISO8859_2 is not set | ||
| 1101 | # CONFIG_NLS_ISO8859_3 is not set | ||
| 1102 | # CONFIG_NLS_ISO8859_4 is not set | ||
| 1103 | # CONFIG_NLS_ISO8859_5 is not set | ||
| 1104 | # CONFIG_NLS_ISO8859_6 is not set | ||
| 1105 | # CONFIG_NLS_ISO8859_7 is not set | ||
| 1106 | # CONFIG_NLS_ISO8859_9 is not set | ||
| 1107 | # CONFIG_NLS_ISO8859_13 is not set | ||
| 1108 | # CONFIG_NLS_ISO8859_14 is not set | ||
| 1109 | CONFIG_NLS_ISO8859_15=y | ||
| 1110 | # CONFIG_NLS_KOI8_R is not set | ||
| 1111 | # CONFIG_NLS_KOI8_U is not set | ||
| 1112 | # CONFIG_NLS_UTF8 is not set | ||
| 1113 | # CONFIG_DLM is not set | ||
| 1114 | |||
| 1115 | # | ||
| 1116 | # Kernel hacking | ||
| 1117 | # | ||
| 1118 | # CONFIG_PRINTK_TIME is not set | ||
| 1119 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
| 1120 | # CONFIG_ENABLE_MUST_CHECK is not set | ||
| 1121 | CONFIG_FRAME_WARN=1024 | ||
| 1122 | # CONFIG_MAGIC_SYSRQ is not set | ||
| 1123 | # CONFIG_UNUSED_SYMBOLS is not set | ||
| 1124 | # CONFIG_DEBUG_FS is not set | ||
| 1125 | # CONFIG_HEADERS_CHECK is not set | ||
| 1126 | CONFIG_DEBUG_KERNEL=y | ||
| 1127 | # CONFIG_DEBUG_SHIRQ is not set | ||
| 1128 | CONFIG_DETECT_SOFTLOCKUP=y | ||
| 1129 | # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set | ||
| 1130 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 | ||
| 1131 | CONFIG_DETECT_HUNG_TASK=y | ||
| 1132 | # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set | ||
| 1133 | CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 | ||
| 1134 | # CONFIG_SCHED_DEBUG is not set | ||
| 1135 | # CONFIG_SCHEDSTATS is not set | ||
| 1136 | # CONFIG_TIMER_STATS is not set | ||
| 1137 | # CONFIG_DEBUG_OBJECTS is not set | ||
| 1138 | # CONFIG_DEBUG_SLAB is not set | ||
| 1139 | # CONFIG_DEBUG_KMEMLEAK is not set | ||
| 1140 | # CONFIG_DEBUG_PREEMPT is not set | ||
| 1141 | # CONFIG_DEBUG_RT_MUTEXES is not set | ||
| 1142 | # CONFIG_RT_MUTEX_TESTER is not set | ||
| 1143 | # CONFIG_DEBUG_SPINLOCK is not set | ||
| 1144 | # CONFIG_DEBUG_MUTEXES is not set | ||
| 1145 | # CONFIG_DEBUG_LOCK_ALLOC is not set | ||
| 1146 | # CONFIG_PROVE_LOCKING is not set | ||
| 1147 | # CONFIG_LOCK_STAT is not set | ||
| 1148 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | ||
| 1149 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | ||
| 1150 | # CONFIG_DEBUG_KOBJECT is not set | ||
| 1151 | # CONFIG_DEBUG_BUGVERBOSE is not set | ||
| 1152 | CONFIG_DEBUG_INFO=y | ||
| 1153 | # CONFIG_DEBUG_VM is not set | ||
| 1154 | # CONFIG_DEBUG_WRITECOUNT is not set | ||
| 1155 | # CONFIG_DEBUG_MEMORY_INIT is not set | ||
| 1156 | # CONFIG_DEBUG_LIST is not set | ||
| 1157 | # CONFIG_DEBUG_SG is not set | ||
| 1158 | # CONFIG_DEBUG_NOTIFIERS is not set | ||
| 1159 | # CONFIG_BOOT_PRINTK_DELAY is not set | ||
| 1160 | # CONFIG_RCU_TORTURE_TEST is not set | ||
| 1161 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
| 1162 | # CONFIG_BACKTRACE_SELF_TEST is not set | ||
| 1163 | # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set | ||
| 1164 | # CONFIG_FAULT_INJECTION is not set | ||
| 1165 | # CONFIG_LATENCYTOP is not set | ||
| 1166 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set | ||
| 1167 | # CONFIG_PAGE_POISONING is not set | ||
| 1168 | CONFIG_HAVE_FUNCTION_TRACER=y | ||
| 1169 | CONFIG_TRACING_SUPPORT=y | ||
| 1170 | CONFIG_FTRACE=y | ||
| 1171 | # CONFIG_FUNCTION_TRACER is not set | ||
| 1172 | # CONFIG_IRQSOFF_TRACER is not set | ||
| 1173 | # CONFIG_PREEMPT_TRACER is not set | ||
| 1174 | # CONFIG_SCHED_TRACER is not set | ||
| 1175 | # CONFIG_ENABLE_DEFAULT_TRACERS is not set | ||
| 1176 | # CONFIG_BOOT_TRACER is not set | ||
| 1177 | CONFIG_BRANCH_PROFILE_NONE=y | ||
| 1178 | # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set | ||
| 1179 | # CONFIG_PROFILE_ALL_BRANCHES is not set | ||
| 1180 | # CONFIG_STACK_TRACER is not set | ||
| 1181 | # CONFIG_KMEMTRACE is not set | ||
| 1182 | # CONFIG_WORKQUEUE_TRACER is not set | ||
| 1183 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
| 1184 | # CONFIG_SAMPLES is not set | ||
| 1185 | CONFIG_HAVE_ARCH_KGDB=y | ||
| 1186 | # CONFIG_KGDB is not set | ||
| 1187 | CONFIG_ARM_UNWIND=y | ||
| 1188 | # CONFIG_DEBUG_USER is not set | ||
| 1189 | # CONFIG_DEBUG_ERRORS is not set | ||
| 1190 | # CONFIG_DEBUG_STACK_USAGE is not set | ||
| 1191 | # CONFIG_DEBUG_LL is not set | ||
| 1192 | |||
| 1193 | # | ||
| 1194 | # Security options | ||
| 1195 | # | ||
| 1196 | # CONFIG_KEYS is not set | ||
| 1197 | # CONFIG_SECURITY is not set | ||
| 1198 | # CONFIG_SECURITYFS is not set | ||
| 1199 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
| 1200 | CONFIG_CRYPTO=y | ||
| 1201 | |||
| 1202 | # | ||
| 1203 | # Crypto core or helper | ||
| 1204 | # | ||
| 1205 | # CONFIG_CRYPTO_FIPS is not set | ||
| 1206 | CONFIG_CRYPTO_ALGAPI=y | ||
| 1207 | CONFIG_CRYPTO_ALGAPI2=y | ||
| 1208 | CONFIG_CRYPTO_AEAD2=y | ||
| 1209 | CONFIG_CRYPTO_BLKCIPHER=y | ||
| 1210 | CONFIG_CRYPTO_BLKCIPHER2=y | ||
| 1211 | CONFIG_CRYPTO_HASH=y | ||
| 1212 | CONFIG_CRYPTO_HASH2=y | ||
| 1213 | CONFIG_CRYPTO_RNG2=y | ||
| 1214 | CONFIG_CRYPTO_PCOMP=y | ||
| 1215 | CONFIG_CRYPTO_MANAGER=y | ||
| 1216 | CONFIG_CRYPTO_MANAGER2=y | ||
| 1217 | # CONFIG_CRYPTO_GF128MUL is not set | ||
| 1218 | # CONFIG_CRYPTO_NULL is not set | ||
| 1219 | CONFIG_CRYPTO_WORKQUEUE=y | ||
| 1220 | # CONFIG_CRYPTO_CRYPTD is not set | ||
| 1221 | # CONFIG_CRYPTO_AUTHENC is not set | ||
| 1222 | # CONFIG_CRYPTO_TEST is not set | ||
| 1223 | |||
| 1224 | # | ||
| 1225 | # Authenticated Encryption with Associated Data | ||
| 1226 | # | ||
| 1227 | # CONFIG_CRYPTO_CCM is not set | ||
| 1228 | # CONFIG_CRYPTO_GCM is not set | ||
| 1229 | # CONFIG_CRYPTO_SEQIV is not set | ||
| 1230 | |||
| 1231 | # | ||
| 1232 | # Block modes | ||
| 1233 | # | ||
| 1234 | CONFIG_CRYPTO_CBC=y | ||
| 1235 | # CONFIG_CRYPTO_CTR is not set | ||
| 1236 | # CONFIG_CRYPTO_CTS is not set | ||
| 1237 | CONFIG_CRYPTO_ECB=m | ||
| 1238 | # CONFIG_CRYPTO_LRW is not set | ||
| 1239 | # CONFIG_CRYPTO_PCBC is not set | ||
| 1240 | # CONFIG_CRYPTO_XTS is not set | ||
| 1241 | |||
| 1242 | # | ||
| 1243 | # Hash modes | ||
| 1244 | # | ||
| 1245 | # CONFIG_CRYPTO_HMAC is not set | ||
| 1246 | # CONFIG_CRYPTO_XCBC is not set | ||
| 1247 | |||
| 1248 | # | ||
| 1249 | # Digest | ||
| 1250 | # | ||
| 1251 | # CONFIG_CRYPTO_CRC32C is not set | ||
| 1252 | # CONFIG_CRYPTO_MD4 is not set | ||
| 1253 | CONFIG_CRYPTO_MD5=y | ||
| 1254 | # CONFIG_CRYPTO_MICHAEL_MIC is not set | ||
| 1255 | # CONFIG_CRYPTO_RMD128 is not set | ||
| 1256 | # CONFIG_CRYPTO_RMD160 is not set | ||
| 1257 | # CONFIG_CRYPTO_RMD256 is not set | ||
| 1258 | # CONFIG_CRYPTO_RMD320 is not set | ||
| 1259 | CONFIG_CRYPTO_SHA1=y | ||
| 1260 | # CONFIG_CRYPTO_SHA256 is not set | ||
| 1261 | # CONFIG_CRYPTO_SHA512 is not set | ||
| 1262 | # CONFIG_CRYPTO_TGR192 is not set | ||
| 1263 | # CONFIG_CRYPTO_WP512 is not set | ||
| 1264 | |||
| 1265 | # | ||
| 1266 | # Ciphers | ||
| 1267 | # | ||
| 1268 | # CONFIG_CRYPTO_AES is not set | ||
| 1269 | # CONFIG_CRYPTO_ANUBIS is not set | ||
| 1270 | CONFIG_CRYPTO_ARC4=m | ||
| 1271 | # CONFIG_CRYPTO_BLOWFISH is not set | ||
| 1272 | # CONFIG_CRYPTO_CAMELLIA is not set | ||
| 1273 | # CONFIG_CRYPTO_CAST5 is not set | ||
| 1274 | # CONFIG_CRYPTO_CAST6 is not set | ||
| 1275 | CONFIG_CRYPTO_DES=y | ||
| 1276 | # CONFIG_CRYPTO_FCRYPT is not set | ||
| 1277 | # CONFIG_CRYPTO_KHAZAD is not set | ||
| 1278 | # CONFIG_CRYPTO_SALSA20 is not set | ||
| 1279 | # CONFIG_CRYPTO_SEED is not set | ||
| 1280 | # CONFIG_CRYPTO_SERPENT is not set | ||
| 1281 | # CONFIG_CRYPTO_TEA is not set | ||
| 1282 | # CONFIG_CRYPTO_TWOFISH is not set | ||
| 1283 | |||
| 1284 | # | ||
| 1285 | # Compression | ||
| 1286 | # | ||
| 1287 | # CONFIG_CRYPTO_DEFLATE is not set | ||
| 1288 | # CONFIG_CRYPTO_ZLIB is not set | ||
| 1289 | # CONFIG_CRYPTO_LZO is not set | ||
| 1290 | |||
| 1291 | # | ||
| 1292 | # Random Number Generation | ||
| 1293 | # | ||
| 1294 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
| 1295 | CONFIG_CRYPTO_HW=y | ||
| 1296 | # CONFIG_BINARY_PRINTF is not set | ||
| 1297 | |||
| 1298 | # | ||
| 1299 | # Library routines | ||
| 1300 | # | ||
| 1301 | CONFIG_BITREVERSE=y | ||
| 1302 | CONFIG_GENERIC_FIND_LAST_BIT=y | ||
| 1303 | CONFIG_CRC_CCITT=m | ||
| 1304 | # CONFIG_CRC16 is not set | ||
| 1305 | # CONFIG_CRC_T10DIF is not set | ||
| 1306 | # CONFIG_CRC_ITU_T is not set | ||
| 1307 | CONFIG_CRC32=y | ||
| 1308 | # CONFIG_CRC7 is not set | ||
| 1309 | # CONFIG_LIBCRC32C is not set | ||
| 1310 | CONFIG_ZLIB_INFLATE=y | ||
| 1311 | CONFIG_ZLIB_DEFLATE=y | ||
| 1312 | CONFIG_DECOMPRESS_GZIP=y | ||
| 1313 | CONFIG_HAS_IOMEM=y | ||
| 1314 | CONFIG_HAS_IOPORT=y | ||
| 1315 | CONFIG_HAS_DMA=y | ||
| 1316 | CONFIG_NLATTR=y | ||
diff --git a/arch/arm/configs/s5pc100_defconfig b/arch/arm/configs/s5pc100_defconfig new file mode 100644 index 000000000000..b0d7d3d3a5e3 --- /dev/null +++ b/arch/arm/configs/s5pc100_defconfig | |||
| @@ -0,0 +1,892 @@ | |||
| 1 | # | ||
| 2 | # Automatically generated make config: don't edit | ||
| 3 | # Linux kernel version: 2.6.30 | ||
| 4 | # Wed Jul 1 15:53:07 2009 | ||
| 5 | # | ||
| 6 | CONFIG_ARM=y | ||
| 7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||
| 8 | CONFIG_GENERIC_GPIO=y | ||
| 9 | CONFIG_MMU=y | ||
| 10 | CONFIG_NO_IOPORT=y | ||
| 11 | CONFIG_GENERIC_HARDIRQS=y | ||
| 12 | CONFIG_STACKTRACE_SUPPORT=y | ||
| 13 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | ||
| 14 | CONFIG_LOCKDEP_SUPPORT=y | ||
| 15 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
| 16 | CONFIG_HARDIRQS_SW_RESEND=y | ||
| 17 | CONFIG_GENERIC_IRQ_PROBE=y | ||
| 18 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
| 19 | CONFIG_GENERIC_HWEIGHT=y | ||
| 20 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
| 21 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | ||
| 22 | CONFIG_VECTORS_BASE=0xffff0000 | ||
| 23 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
| 24 | CONFIG_CONSTRUCTORS=y | ||
| 25 | |||
| 26 | # | ||
| 27 | # General setup | ||
| 28 | # | ||
| 29 | CONFIG_EXPERIMENTAL=y | ||
| 30 | CONFIG_BROKEN_ON_SMP=y | ||
| 31 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
| 32 | CONFIG_LOCALVERSION="" | ||
| 33 | CONFIG_LOCALVERSION_AUTO=y | ||
| 34 | CONFIG_SWAP=y | ||
| 35 | # CONFIG_SYSVIPC is not set | ||
| 36 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
| 37 | |||
| 38 | # | ||
| 39 | # RCU Subsystem | ||
| 40 | # | ||
| 41 | CONFIG_CLASSIC_RCU=y | ||
| 42 | # CONFIG_TREE_RCU is not set | ||
| 43 | # CONFIG_PREEMPT_RCU is not set | ||
| 44 | # CONFIG_TREE_RCU_TRACE is not set | ||
| 45 | # CONFIG_PREEMPT_RCU_TRACE is not set | ||
| 46 | # CONFIG_IKCONFIG is not set | ||
| 47 | CONFIG_LOG_BUF_SHIFT=17 | ||
| 48 | # CONFIG_GROUP_SCHED is not set | ||
| 49 | # CONFIG_CGROUPS is not set | ||
| 50 | CONFIG_SYSFS_DEPRECATED=y | ||
| 51 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
| 52 | # CONFIG_RELAY is not set | ||
| 53 | CONFIG_NAMESPACES=y | ||
| 54 | # CONFIG_UTS_NS is not set | ||
| 55 | # CONFIG_USER_NS is not set | ||
| 56 | # CONFIG_PID_NS is not set | ||
| 57 | CONFIG_BLK_DEV_INITRD=y | ||
| 58 | CONFIG_INITRAMFS_SOURCE="" | ||
| 59 | CONFIG_RD_GZIP=y | ||
| 60 | CONFIG_RD_BZIP2=y | ||
| 61 | CONFIG_RD_LZMA=y | ||
| 62 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
| 63 | CONFIG_SYSCTL=y | ||
| 64 | CONFIG_ANON_INODES=y | ||
| 65 | # CONFIG_EMBEDDED is not set | ||
| 66 | CONFIG_UID16=y | ||
| 67 | CONFIG_SYSCTL_SYSCALL=y | ||
| 68 | CONFIG_KALLSYMS=y | ||
| 69 | CONFIG_KALLSYMS_ALL=y | ||
| 70 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
| 71 | CONFIG_HOTPLUG=y | ||
| 72 | CONFIG_PRINTK=y | ||
| 73 | CONFIG_BUG=y | ||
| 74 | CONFIG_ELF_CORE=y | ||
| 75 | CONFIG_BASE_FULL=y | ||
| 76 | CONFIG_FUTEX=y | ||
| 77 | CONFIG_EPOLL=y | ||
| 78 | CONFIG_SIGNALFD=y | ||
| 79 | CONFIG_TIMERFD=y | ||
| 80 | CONFIG_EVENTFD=y | ||
| 81 | CONFIG_SHMEM=y | ||
| 82 | CONFIG_AIO=y | ||
| 83 | |||
| 84 | # | ||
| 85 | # Performance Counters | ||
| 86 | # | ||
| 87 | CONFIG_VM_EVENT_COUNTERS=y | ||
| 88 | CONFIG_SLUB_DEBUG=y | ||
| 89 | # CONFIG_STRIP_ASM_SYMS is not set | ||
| 90 | CONFIG_COMPAT_BRK=y | ||
| 91 | # CONFIG_SLAB is not set | ||
| 92 | CONFIG_SLUB=y | ||
| 93 | # CONFIG_SLOB is not set | ||
| 94 | # CONFIG_PROFILING is not set | ||
| 95 | # CONFIG_MARKERS is not set | ||
| 96 | CONFIG_HAVE_OPROFILE=y | ||
| 97 | # CONFIG_KPROBES is not set | ||
| 98 | CONFIG_HAVE_KPROBES=y | ||
| 99 | CONFIG_HAVE_KRETPROBES=y | ||
| 100 | CONFIG_HAVE_CLK=y | ||
| 101 | |||
| 102 | # | ||
| 103 | # GCOV-based kernel profiling | ||
| 104 | # | ||
| 105 | # CONFIG_SLOW_WORK is not set | ||
| 106 | CONFIG_HAVE_GENERIC_DMA_COHERENT=y | ||
| 107 | CONFIG_SLABINFO=y | ||
| 108 | CONFIG_RT_MUTEXES=y | ||
| 109 | CONFIG_BASE_SMALL=0 | ||
| 110 | CONFIG_MODULES=y | ||
| 111 | # CONFIG_MODULE_FORCE_LOAD is not set | ||
| 112 | CONFIG_MODULE_UNLOAD=y | ||
| 113 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
| 114 | # CONFIG_MODVERSIONS is not set | ||
| 115 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
| 116 | CONFIG_BLOCK=y | ||
| 117 | CONFIG_LBDAF=y | ||
| 118 | # CONFIG_BLK_DEV_BSG is not set | ||
| 119 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
| 120 | |||
| 121 | # | ||
| 122 | # IO Schedulers | ||
| 123 | # | ||
| 124 | CONFIG_IOSCHED_NOOP=y | ||
| 125 | CONFIG_IOSCHED_AS=y | ||
| 126 | CONFIG_IOSCHED_DEADLINE=y | ||
| 127 | CONFIG_IOSCHED_CFQ=y | ||
| 128 | # CONFIG_DEFAULT_AS is not set | ||
| 129 | # CONFIG_DEFAULT_DEADLINE is not set | ||
| 130 | CONFIG_DEFAULT_CFQ=y | ||
| 131 | # CONFIG_DEFAULT_NOOP is not set | ||
| 132 | CONFIG_DEFAULT_IOSCHED="cfq" | ||
| 133 | # CONFIG_FREEZER is not set | ||
| 134 | |||
| 135 | # | ||
| 136 | # System Type | ||
| 137 | # | ||
| 138 | # CONFIG_ARCH_AAEC2000 is not set | ||
| 139 | # CONFIG_ARCH_INTEGRATOR is not set | ||
| 140 | # CONFIG_ARCH_REALVIEW is not set | ||
| 141 | # CONFIG_ARCH_VERSATILE is not set | ||
| 142 | # CONFIG_ARCH_AT91 is not set | ||
| 143 | # CONFIG_ARCH_CLPS711X is not set | ||
| 144 | # CONFIG_ARCH_GEMINI is not set | ||
| 145 | # CONFIG_ARCH_EBSA110 is not set | ||
| 146 | # CONFIG_ARCH_EP93XX is not set | ||
| 147 | # CONFIG_ARCH_FOOTBRIDGE is not set | ||
| 148 | # CONFIG_ARCH_MXC is not set | ||
| 149 | # CONFIG_ARCH_STMP3XXX is not set | ||
| 150 | # CONFIG_ARCH_NETX is not set | ||
| 151 | # CONFIG_ARCH_H720X is not set | ||
| 152 | # CONFIG_ARCH_IOP13XX is not set | ||
| 153 | # CONFIG_ARCH_IOP32X is not set | ||
| 154 | # CONFIG_ARCH_IOP33X is not set | ||
| 155 | # CONFIG_ARCH_IXP23XX is not set | ||
| 156 | # CONFIG_ARCH_IXP2000 is not set | ||
| 157 | # CONFIG_ARCH_IXP4XX is not set | ||
| 158 | # CONFIG_ARCH_L7200 is not set | ||
| 159 | # CONFIG_ARCH_KIRKWOOD is not set | ||
| 160 | # CONFIG_ARCH_LOKI is not set | ||
| 161 | # CONFIG_ARCH_MV78XX0 is not set | ||
| 162 | # CONFIG_ARCH_ORION5X is not set | ||
| 163 | # CONFIG_ARCH_MMP is not set | ||
| 164 | # CONFIG_ARCH_KS8695 is not set | ||
| 165 | # CONFIG_ARCH_NS9XXX is not set | ||
| 166 | # CONFIG_ARCH_W90X900 is not set | ||
| 167 | # CONFIG_ARCH_PNX4008 is not set | ||
| 168 | # CONFIG_ARCH_PXA is not set | ||
| 169 | # CONFIG_ARCH_MSM is not set | ||
| 170 | # CONFIG_ARCH_RPC is not set | ||
| 171 | # CONFIG_ARCH_SA1100 is not set | ||
| 172 | # CONFIG_ARCH_S3C2410 is not set | ||
| 173 | # CONFIG_ARCH_S3C64XX is not set | ||
| 174 | CONFIG_ARCH_S5PC1XX=y | ||
| 175 | # CONFIG_ARCH_SHARK is not set | ||
| 176 | # CONFIG_ARCH_LH7A40X is not set | ||
| 177 | # CONFIG_ARCH_U300 is not set | ||
| 178 | # CONFIG_ARCH_DAVINCI is not set | ||
| 179 | # CONFIG_ARCH_OMAP is not set | ||
| 180 | CONFIG_PLAT_S3C=y | ||
| 181 | |||
| 182 | # | ||
| 183 | # Boot options | ||
| 184 | # | ||
| 185 | # CONFIG_S3C_BOOT_ERROR_RESET is not set | ||
| 186 | CONFIG_S3C_BOOT_UART_FORCE_FIFO=y | ||
| 187 | |||
| 188 | # | ||
| 189 | # Power management | ||
| 190 | # | ||
| 191 | CONFIG_S3C_LOWLEVEL_UART_PORT=0 | ||
| 192 | CONFIG_S3C_GPIO_SPACE=0 | ||
| 193 | CONFIG_S3C_GPIO_TRACK=y | ||
| 194 | CONFIG_S3C_GPIO_PULL_UPDOWN=y | ||
| 195 | CONFIG_PLAT_S5PC1XX=y | ||
| 196 | CONFIG_CPU_S5PC100_INIT=y | ||
| 197 | CONFIG_CPU_S5PC100_CLOCK=y | ||
| 198 | CONFIG_S5PC100_SETUP_I2C0=y | ||
| 199 | CONFIG_CPU_S5PC100=y | ||
| 200 | CONFIG_MACH_SMDKC100=y | ||
| 201 | |||
| 202 | # | ||
| 203 | # Processor Type | ||
| 204 | # | ||
| 205 | CONFIG_CPU_32=y | ||
| 206 | CONFIG_CPU_32v6K=y | ||
| 207 | CONFIG_CPU_V7=y | ||
| 208 | CONFIG_CPU_32v7=y | ||
| 209 | CONFIG_CPU_ABRT_EV7=y | ||
| 210 | CONFIG_CPU_PABRT_IFAR=y | ||
| 211 | CONFIG_CPU_CACHE_V7=y | ||
| 212 | CONFIG_CPU_CACHE_VIPT=y | ||
| 213 | CONFIG_CPU_COPY_V6=y | ||
| 214 | CONFIG_CPU_TLB_V7=y | ||
| 215 | CONFIG_CPU_HAS_ASID=y | ||
| 216 | CONFIG_CPU_CP15=y | ||
| 217 | CONFIG_CPU_CP15_MMU=y | ||
| 218 | |||
| 219 | # | ||
| 220 | # Processor Features | ||
| 221 | # | ||
| 222 | CONFIG_ARM_THUMB=y | ||
| 223 | # CONFIG_ARM_THUMBEE is not set | ||
| 224 | # CONFIG_CPU_ICACHE_DISABLE is not set | ||
| 225 | # CONFIG_CPU_DCACHE_DISABLE is not set | ||
| 226 | # CONFIG_CPU_BPREDICT_DISABLE is not set | ||
| 227 | CONFIG_HAS_TLS_REG=y | ||
| 228 | # CONFIG_ARM_ERRATA_430973 is not set | ||
| 229 | # CONFIG_ARM_ERRATA_458693 is not set | ||
| 230 | # CONFIG_ARM_ERRATA_460075 is not set | ||
| 231 | CONFIG_ARM_VIC=y | ||
| 232 | CONFIG_ARM_VIC_NR=2 | ||
| 233 | |||
| 234 | # | ||
| 235 | # Bus support | ||
| 236 | # | ||
| 237 | # CONFIG_PCI_SYSCALL is not set | ||
| 238 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
| 239 | # CONFIG_PCCARD is not set | ||
| 240 | |||
| 241 | # | ||
| 242 | # Kernel Features | ||
| 243 | # | ||
| 244 | CONFIG_VMSPLIT_3G=y | ||
| 245 | # CONFIG_VMSPLIT_2G is not set | ||
| 246 | # CONFIG_VMSPLIT_1G is not set | ||
| 247 | CONFIG_PAGE_OFFSET=0xC0000000 | ||
| 248 | # CONFIG_PREEMPT is not set | ||
| 249 | CONFIG_HZ=100 | ||
| 250 | CONFIG_AEABI=y | ||
| 251 | CONFIG_OABI_COMPAT=y | ||
| 252 | # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set | ||
| 253 | # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set | ||
| 254 | # CONFIG_HIGHMEM is not set | ||
| 255 | CONFIG_SELECT_MEMORY_MODEL=y | ||
| 256 | CONFIG_FLATMEM_MANUAL=y | ||
| 257 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
| 258 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
| 259 | CONFIG_FLATMEM=y | ||
| 260 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
| 261 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
| 262 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
| 263 | # CONFIG_PHYS_ADDR_T_64BIT is not set | ||
| 264 | CONFIG_ZONE_DMA_FLAG=0 | ||
| 265 | CONFIG_VIRT_TO_BUS=y | ||
| 266 | CONFIG_HAVE_MLOCK=y | ||
| 267 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | ||
| 268 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
| 269 | CONFIG_ALIGNMENT_TRAP=y | ||
| 270 | # CONFIG_UACCESS_WITH_MEMCPY is not set | ||
| 271 | |||
| 272 | # | ||
| 273 | # Boot options | ||
| 274 | # | ||
| 275 | CONFIG_ZBOOT_ROM_TEXT=0 | ||
| 276 | CONFIG_ZBOOT_ROM_BSS=0 | ||
| 277 | CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=cramfs init=/linuxrc console=ttySAC2,115200 mem=128M" | ||
| 278 | # CONFIG_XIP_KERNEL is not set | ||
| 279 | # CONFIG_KEXEC is not set | ||
| 280 | |||
| 281 | # | ||
| 282 | # CPU Power Management | ||
| 283 | # | ||
| 284 | # CONFIG_CPU_IDLE is not set | ||
| 285 | |||
| 286 | # | ||
| 287 | # Floating point emulation | ||
| 288 | # | ||
| 289 | |||
| 290 | # | ||
| 291 | # At least one emulation must be selected | ||
| 292 | # | ||
| 293 | # CONFIG_FPE_NWFPE is not set | ||
| 294 | # CONFIG_FPE_FASTFPE is not set | ||
| 295 | # CONFIG_VFP is not set | ||
| 296 | |||
| 297 | # | ||
| 298 | # Userspace binary formats | ||
| 299 | # | ||
| 300 | CONFIG_BINFMT_ELF=y | ||
| 301 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
| 302 | CONFIG_HAVE_AOUT=y | ||
| 303 | # CONFIG_BINFMT_AOUT is not set | ||
| 304 | # CONFIG_BINFMT_MISC is not set | ||
| 305 | |||
| 306 | # | ||
| 307 | # Power management options | ||
| 308 | # | ||
| 309 | # CONFIG_PM is not set | ||
| 310 | CONFIG_ARCH_SUSPEND_POSSIBLE=y | ||
| 311 | # CONFIG_NET is not set | ||
| 312 | |||
| 313 | # | ||
| 314 | # Device Drivers | ||
| 315 | # | ||
| 316 | |||
| 317 | # | ||
| 318 | # Generic Driver Options | ||
| 319 | # | ||
| 320 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
| 321 | CONFIG_STANDALONE=y | ||
| 322 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
| 323 | CONFIG_FW_LOADER=y | ||
| 324 | CONFIG_FIRMWARE_IN_KERNEL=y | ||
| 325 | CONFIG_EXTRA_FIRMWARE="" | ||
| 326 | # CONFIG_DEBUG_DRIVER is not set | ||
| 327 | # CONFIG_DEBUG_DEVRES is not set | ||
| 328 | # CONFIG_SYS_HYPERVISOR is not set | ||
| 329 | # CONFIG_MTD is not set | ||
| 330 | # CONFIG_PARPORT is not set | ||
| 331 | CONFIG_BLK_DEV=y | ||
| 332 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
| 333 | CONFIG_BLK_DEV_LOOP=y | ||
| 334 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
| 335 | CONFIG_BLK_DEV_RAM=y | ||
| 336 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
| 337 | CONFIG_BLK_DEV_RAM_SIZE=8192 | ||
| 338 | # CONFIG_BLK_DEV_XIP is not set | ||
| 339 | # CONFIG_CDROM_PKTCDVD is not set | ||
| 340 | # CONFIG_MG_DISK is not set | ||
| 341 | CONFIG_MISC_DEVICES=y | ||
| 342 | # CONFIG_ICS932S401 is not set | ||
| 343 | # CONFIG_ENCLOSURE_SERVICES is not set | ||
| 344 | # CONFIG_ISL29003 is not set | ||
| 345 | # CONFIG_C2PORT is not set | ||
| 346 | |||
| 347 | # | ||
| 348 | # EEPROM support | ||
| 349 | # | ||
| 350 | CONFIG_EEPROM_AT24=y | ||
| 351 | # CONFIG_EEPROM_LEGACY is not set | ||
| 352 | # CONFIG_EEPROM_MAX6875 is not set | ||
| 353 | # CONFIG_EEPROM_93CX6 is not set | ||
| 354 | CONFIG_HAVE_IDE=y | ||
| 355 | # CONFIG_IDE is not set | ||
| 356 | |||
| 357 | # | ||
| 358 | # SCSI device support | ||
| 359 | # | ||
| 360 | # CONFIG_RAID_ATTRS is not set | ||
| 361 | # CONFIG_SCSI is not set | ||
| 362 | # CONFIG_SCSI_DMA is not set | ||
| 363 | # CONFIG_SCSI_NETLINK is not set | ||
| 364 | # CONFIG_ATA is not set | ||
| 365 | # CONFIG_MD is not set | ||
| 366 | |||
| 367 | # | ||
| 368 | # Input device support | ||
| 369 | # | ||
| 370 | CONFIG_INPUT=y | ||
| 371 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
| 372 | # CONFIG_INPUT_POLLDEV is not set | ||
| 373 | |||
| 374 | # | ||
| 375 | # Userland interfaces | ||
| 376 | # | ||
| 377 | CONFIG_INPUT_MOUSEDEV=y | ||
| 378 | CONFIG_INPUT_MOUSEDEV_PSAUX=y | ||
| 379 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
| 380 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
| 381 | # CONFIG_INPUT_JOYDEV is not set | ||
| 382 | # CONFIG_INPUT_EVDEV is not set | ||
| 383 | # CONFIG_INPUT_EVBUG is not set | ||
| 384 | |||
| 385 | # | ||
| 386 | # Input Device Drivers | ||
| 387 | # | ||
| 388 | CONFIG_INPUT_KEYBOARD=y | ||
| 389 | CONFIG_KEYBOARD_ATKBD=y | ||
| 390 | # CONFIG_KEYBOARD_SUNKBD is not set | ||
| 391 | # CONFIG_KEYBOARD_LKKBD is not set | ||
| 392 | # CONFIG_KEYBOARD_XTKBD is not set | ||
| 393 | # CONFIG_KEYBOARD_NEWTON is not set | ||
| 394 | # CONFIG_KEYBOARD_STOWAWAY is not set | ||
| 395 | # CONFIG_KEYBOARD_GPIO is not set | ||
| 396 | CONFIG_INPUT_MOUSE=y | ||
| 397 | CONFIG_MOUSE_PS2=y | ||
| 398 | CONFIG_MOUSE_PS2_ALPS=y | ||
| 399 | CONFIG_MOUSE_PS2_LOGIPS2PP=y | ||
| 400 | CONFIG_MOUSE_PS2_SYNAPTICS=y | ||
| 401 | CONFIG_MOUSE_PS2_TRACKPOINT=y | ||
| 402 | # CONFIG_MOUSE_PS2_ELANTECH is not set | ||
| 403 | # CONFIG_MOUSE_PS2_TOUCHKIT is not set | ||
| 404 | # CONFIG_MOUSE_SERIAL is not set | ||
| 405 | # CONFIG_MOUSE_APPLETOUCH is not set | ||
| 406 | # CONFIG_MOUSE_BCM5974 is not set | ||
| 407 | # CONFIG_MOUSE_VSXXXAA is not set | ||
| 408 | # CONFIG_MOUSE_GPIO is not set | ||
| 409 | # CONFIG_MOUSE_SYNAPTICS_I2C is not set | ||
| 410 | # CONFIG_INPUT_JOYSTICK is not set | ||
| 411 | # CONFIG_INPUT_TABLET is not set | ||
| 412 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
| 413 | # CONFIG_INPUT_MISC is not set | ||
| 414 | |||
| 415 | # | ||
| 416 | # Hardware I/O ports | ||
| 417 | # | ||
| 418 | CONFIG_SERIO=y | ||
| 419 | CONFIG_SERIO_SERPORT=y | ||
| 420 | CONFIG_SERIO_LIBPS2=y | ||
| 421 | # CONFIG_SERIO_RAW is not set | ||
| 422 | # CONFIG_GAMEPORT is not set | ||
| 423 | |||
| 424 | # | ||
| 425 | # Character devices | ||
| 426 | # | ||
| 427 | CONFIG_VT=y | ||
| 428 | CONFIG_CONSOLE_TRANSLATIONS=y | ||
| 429 | CONFIG_VT_CONSOLE=y | ||
| 430 | CONFIG_HW_CONSOLE=y | ||
| 431 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | ||
| 432 | CONFIG_DEVKMEM=y | ||
| 433 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
| 434 | |||
| 435 | # | ||
| 436 | # Serial drivers | ||
| 437 | # | ||
| 438 | CONFIG_SERIAL_8250=y | ||
| 439 | # CONFIG_SERIAL_8250_CONSOLE is not set | ||
| 440 | CONFIG_SERIAL_8250_NR_UARTS=4 | ||
| 441 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | ||
| 442 | # CONFIG_SERIAL_8250_EXTENDED is not set | ||
| 443 | |||
| 444 | # | ||
| 445 | # Non-8250 serial port support | ||
| 446 | # | ||
| 447 | CONFIG_SERIAL_SAMSUNG=y | ||
| 448 | CONFIG_SERIAL_SAMSUNG_UARTS=3 | ||
| 449 | # CONFIG_SERIAL_SAMSUNG_DEBUG is not set | ||
| 450 | CONFIG_SERIAL_SAMSUNG_CONSOLE=y | ||
| 451 | CONFIG_SERIAL_CORE=y | ||
| 452 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
| 453 | CONFIG_UNIX98_PTYS=y | ||
| 454 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
| 455 | CONFIG_LEGACY_PTYS=y | ||
| 456 | CONFIG_LEGACY_PTY_COUNT=256 | ||
| 457 | # CONFIG_IPMI_HANDLER is not set | ||
| 458 | CONFIG_HW_RANDOM=y | ||
| 459 | # CONFIG_HW_RANDOM_TIMERIOMEM is not set | ||
| 460 | # CONFIG_R3964 is not set | ||
| 461 | # CONFIG_RAW_DRIVER is not set | ||
| 462 | # CONFIG_TCG_TPM is not set | ||
| 463 | CONFIG_I2C=y | ||
| 464 | CONFIG_I2C_BOARDINFO=y | ||
| 465 | CONFIG_I2C_CHARDEV=y | ||
| 466 | CONFIG_I2C_HELPER_AUTO=y | ||
| 467 | |||
| 468 | # | ||
| 469 | # I2C Hardware Bus support | ||
| 470 | # | ||
| 471 | |||
| 472 | # | ||
| 473 | # I2C system bus drivers (mostly embedded / system-on-chip) | ||
| 474 | # | ||
| 475 | # CONFIG_I2C_GPIO is not set | ||
| 476 | # CONFIG_I2C_OCORES is not set | ||
| 477 | # CONFIG_I2C_SIMTEC is not set | ||
| 478 | |||
| 479 | # | ||
| 480 | # External I2C/SMBus adapter drivers | ||
| 481 | # | ||
| 482 | # CONFIG_I2C_PARPORT_LIGHT is not set | ||
| 483 | # CONFIG_I2C_TAOS_EVM is not set | ||
| 484 | |||
| 485 | # | ||
| 486 | # Other I2C/SMBus bus drivers | ||
| 487 | # | ||
| 488 | # CONFIG_I2C_PCA_PLATFORM is not set | ||
| 489 | # CONFIG_I2C_STUB is not set | ||
| 490 | |||
| 491 | # | ||
| 492 | # Miscellaneous I2C Chip support | ||
| 493 | # | ||
| 494 | # CONFIG_DS1682 is not set | ||
| 495 | # CONFIG_SENSORS_PCF8574 is not set | ||
| 496 | # CONFIG_PCF8575 is not set | ||
| 497 | # CONFIG_SENSORS_PCA9539 is not set | ||
| 498 | # CONFIG_SENSORS_TSL2550 is not set | ||
| 499 | # CONFIG_I2C_DEBUG_CORE is not set | ||
| 500 | # CONFIG_I2C_DEBUG_ALGO is not set | ||
| 501 | # CONFIG_I2C_DEBUG_BUS is not set | ||
| 502 | # CONFIG_I2C_DEBUG_CHIP is not set | ||
| 503 | # CONFIG_SPI is not set | ||
| 504 | CONFIG_ARCH_REQUIRE_GPIOLIB=y | ||
| 505 | CONFIG_GPIOLIB=y | ||
| 506 | # CONFIG_DEBUG_GPIO is not set | ||
| 507 | # CONFIG_GPIO_SYSFS is not set | ||
| 508 | |||
| 509 | # | ||
| 510 | # Memory mapped GPIO expanders: | ||
| 511 | # | ||
| 512 | |||
| 513 | # | ||
| 514 | # I2C GPIO expanders: | ||
| 515 | # | ||
| 516 | # CONFIG_GPIO_MAX732X is not set | ||
| 517 | # CONFIG_GPIO_PCA953X is not set | ||
| 518 | # CONFIG_GPIO_PCF857X is not set | ||
| 519 | |||
| 520 | # | ||
| 521 | # PCI GPIO expanders: | ||
| 522 | # | ||
| 523 | |||
| 524 | # | ||
| 525 | # SPI GPIO expanders: | ||
| 526 | # | ||
| 527 | # CONFIG_W1 is not set | ||
| 528 | # CONFIG_POWER_SUPPLY is not set | ||
| 529 | CONFIG_HWMON=y | ||
| 530 | # CONFIG_HWMON_VID is not set | ||
| 531 | # CONFIG_SENSORS_AD7414 is not set | ||
| 532 | # CONFIG_SENSORS_AD7418 is not set | ||
| 533 | # CONFIG_SENSORS_ADM1021 is not set | ||
| 534 | # CONFIG_SENSORS_ADM1025 is not set | ||
| 535 | # CONFIG_SENSORS_ADM1026 is not set | ||
| 536 | # CONFIG_SENSORS_ADM1029 is not set | ||
| 537 | # CONFIG_SENSORS_ADM1031 is not set | ||
| 538 | # CONFIG_SENSORS_ADM9240 is not set | ||
| 539 | # CONFIG_SENSORS_ADT7462 is not set | ||
| 540 | # CONFIG_SENSORS_ADT7470 is not set | ||
| 541 | # CONFIG_SENSORS_ADT7473 is not set | ||
| 542 | # CONFIG_SENSORS_ADT7475 is not set | ||
| 543 | # CONFIG_SENSORS_ATXP1 is not set | ||
| 544 | # CONFIG_SENSORS_DS1621 is not set | ||
| 545 | # CONFIG_SENSORS_F71805F is not set | ||
| 546 | # CONFIG_SENSORS_F71882FG is not set | ||
| 547 | # CONFIG_SENSORS_F75375S is not set | ||
| 548 | # CONFIG_SENSORS_G760A is not set | ||
| 549 | # CONFIG_SENSORS_GL518SM is not set | ||
| 550 | # CONFIG_SENSORS_GL520SM is not set | ||
| 551 | # CONFIG_SENSORS_IT87 is not set | ||
| 552 | # CONFIG_SENSORS_LM63 is not set | ||
| 553 | # CONFIG_SENSORS_LM75 is not set | ||
| 554 | # CONFIG_SENSORS_LM77 is not set | ||
| 555 | # CONFIG_SENSORS_LM78 is not set | ||
| 556 | # CONFIG_SENSORS_LM80 is not set | ||
| 557 | # CONFIG_SENSORS_LM83 is not set | ||
| 558 | # CONFIG_SENSORS_LM85 is not set | ||
| 559 | # CONFIG_SENSORS_LM87 is not set | ||
| 560 | # CONFIG_SENSORS_LM90 is not set | ||
| 561 | # CONFIG_SENSORS_LM92 is not set | ||
| 562 | # CONFIG_SENSORS_LM93 is not set | ||
| 563 | # CONFIG_SENSORS_LTC4215 is not set | ||
| 564 | # CONFIG_SENSORS_LTC4245 is not set | ||
| 565 | # CONFIG_SENSORS_LM95241 is not set | ||
| 566 | # CONFIG_SENSORS_MAX1619 is not set | ||
| 567 | # CONFIG_SENSORS_MAX6650 is not set | ||
| 568 | # CONFIG_SENSORS_PC87360 is not set | ||
| 569 | # CONFIG_SENSORS_PC87427 is not set | ||
| 570 | # CONFIG_SENSORS_PCF8591 is not set | ||
| 571 | # CONFIG_SENSORS_SHT15 is not set | ||
| 572 | # CONFIG_SENSORS_DME1737 is not set | ||
| 573 | # CONFIG_SENSORS_SMSC47M1 is not set | ||
| 574 | # CONFIG_SENSORS_SMSC47M192 is not set | ||
| 575 | # CONFIG_SENSORS_SMSC47B397 is not set | ||
| 576 | # CONFIG_SENSORS_ADS7828 is not set | ||
| 577 | # CONFIG_SENSORS_THMC50 is not set | ||
| 578 | # CONFIG_SENSORS_TMP401 is not set | ||
| 579 | # CONFIG_SENSORS_VT1211 is not set | ||
| 580 | # CONFIG_SENSORS_W83781D is not set | ||
| 581 | # CONFIG_SENSORS_W83791D is not set | ||
| 582 | # CONFIG_SENSORS_W83792D is not set | ||
| 583 | # CONFIG_SENSORS_W83793 is not set | ||
| 584 | # CONFIG_SENSORS_W83L785TS is not set | ||
| 585 | # CONFIG_SENSORS_W83L786NG is not set | ||
| 586 | # CONFIG_SENSORS_W83627HF is not set | ||
| 587 | # CONFIG_SENSORS_W83627EHF is not set | ||
| 588 | # CONFIG_HWMON_DEBUG_CHIP is not set | ||
| 589 | # CONFIG_THERMAL is not set | ||
| 590 | # CONFIG_THERMAL_HWMON is not set | ||
| 591 | # CONFIG_WATCHDOG is not set | ||
| 592 | CONFIG_SSB_POSSIBLE=y | ||
| 593 | |||
| 594 | # | ||
| 595 | # Sonics Silicon Backplane | ||
| 596 | # | ||
| 597 | # CONFIG_SSB is not set | ||
| 598 | |||
| 599 | # | ||
| 600 | # Multifunction device drivers | ||
| 601 | # | ||
| 602 | # CONFIG_MFD_CORE is not set | ||
| 603 | # CONFIG_MFD_SM501 is not set | ||
| 604 | # CONFIG_MFD_ASIC3 is not set | ||
| 605 | # CONFIG_HTC_EGPIO is not set | ||
| 606 | # CONFIG_HTC_PASIC3 is not set | ||
| 607 | # CONFIG_TPS65010 is not set | ||
| 608 | # CONFIG_TWL4030_CORE is not set | ||
| 609 | # CONFIG_MFD_TMIO is not set | ||
| 610 | # CONFIG_MFD_T7L66XB is not set | ||
| 611 | # CONFIG_MFD_TC6387XB is not set | ||
| 612 | # CONFIG_MFD_TC6393XB is not set | ||
| 613 | # CONFIG_PMIC_DA903X is not set | ||
| 614 | # CONFIG_MFD_WM8400 is not set | ||
| 615 | # CONFIG_MFD_WM8350_I2C is not set | ||
| 616 | # CONFIG_MFD_PCF50633 is not set | ||
| 617 | # CONFIG_AB3100_CORE is not set | ||
| 618 | # CONFIG_MEDIA_SUPPORT is not set | ||
| 619 | |||
| 620 | # | ||
| 621 | # Graphics support | ||
| 622 | # | ||
| 623 | # CONFIG_VGASTATE is not set | ||
| 624 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
| 625 | # CONFIG_FB is not set | ||
| 626 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
| 627 | |||
| 628 | # | ||
| 629 | # Display device support | ||
| 630 | # | ||
| 631 | # CONFIG_DISPLAY_SUPPORT is not set | ||
| 632 | |||
| 633 | # | ||
| 634 | # Console display driver support | ||
| 635 | # | ||
| 636 | # CONFIG_VGA_CONSOLE is not set | ||
| 637 | CONFIG_DUMMY_CONSOLE=y | ||
| 638 | # CONFIG_SOUND is not set | ||
| 639 | CONFIG_HID_SUPPORT=y | ||
| 640 | CONFIG_HID=y | ||
| 641 | CONFIG_HID_DEBUG=y | ||
| 642 | # CONFIG_HIDRAW is not set | ||
| 643 | # CONFIG_HID_PID is not set | ||
| 644 | |||
| 645 | # | ||
| 646 | # Special HID drivers | ||
| 647 | # | ||
| 648 | CONFIG_USB_SUPPORT=y | ||
| 649 | CONFIG_USB_ARCH_HAS_HCD=y | ||
| 650 | # CONFIG_USB_ARCH_HAS_OHCI is not set | ||
| 651 | # CONFIG_USB_ARCH_HAS_EHCI is not set | ||
| 652 | # CONFIG_USB is not set | ||
| 653 | |||
| 654 | # | ||
| 655 | # Enable Host or Gadget support to see Inventra options | ||
| 656 | # | ||
| 657 | |||
| 658 | # | ||
| 659 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may | ||
| 660 | # | ||
| 661 | # CONFIG_USB_GADGET is not set | ||
| 662 | |||
| 663 | # | ||
| 664 | # OTG and related infrastructure | ||
| 665 | # | ||
| 666 | CONFIG_MMC=y | ||
| 667 | CONFIG_MMC_DEBUG=y | ||
| 668 | CONFIG_MMC_UNSAFE_RESUME=y | ||
| 669 | |||
| 670 | # | ||
| 671 | # MMC/SD/SDIO Card Drivers | ||
| 672 | # | ||
| 673 | CONFIG_MMC_BLOCK=y | ||
| 674 | CONFIG_MMC_BLOCK_BOUNCE=y | ||
| 675 | CONFIG_SDIO_UART=y | ||
| 676 | # CONFIG_MMC_TEST is not set | ||
| 677 | |||
| 678 | # | ||
| 679 | # MMC/SD/SDIO Host Controller Drivers | ||
| 680 | # | ||
| 681 | CONFIG_MMC_SDHCI=y | ||
| 682 | # CONFIG_MMC_SDHCI_PLTFM is not set | ||
| 683 | # CONFIG_MEMSTICK is not set | ||
| 684 | # CONFIG_ACCESSIBILITY is not set | ||
| 685 | # CONFIG_NEW_LEDS is not set | ||
| 686 | CONFIG_RTC_LIB=y | ||
| 687 | # CONFIG_RTC_CLASS is not set | ||
| 688 | # CONFIG_DMADEVICES is not set | ||
| 689 | # CONFIG_AUXDISPLAY is not set | ||
| 690 | # CONFIG_REGULATOR is not set | ||
| 691 | # CONFIG_UIO is not set | ||
| 692 | # CONFIG_STAGING is not set | ||
| 693 | |||
| 694 | # | ||
| 695 | # File systems | ||
| 696 | # | ||
| 697 | CONFIG_EXT2_FS=y | ||
| 698 | # CONFIG_EXT2_FS_XATTR is not set | ||
| 699 | # CONFIG_EXT2_FS_XIP is not set | ||
| 700 | CONFIG_EXT3_FS=y | ||
| 701 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
| 702 | CONFIG_EXT3_FS_XATTR=y | ||
| 703 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
| 704 | CONFIG_EXT3_FS_SECURITY=y | ||
| 705 | # CONFIG_EXT4_FS is not set | ||
| 706 | CONFIG_JBD=y | ||
| 707 | CONFIG_FS_MBCACHE=y | ||
| 708 | # CONFIG_REISERFS_FS is not set | ||
| 709 | # CONFIG_JFS_FS is not set | ||
| 710 | CONFIG_FS_POSIX_ACL=y | ||
| 711 | # CONFIG_XFS_FS is not set | ||
| 712 | # CONFIG_GFS2_FS is not set | ||
| 713 | # CONFIG_BTRFS_FS is not set | ||
| 714 | CONFIG_FILE_LOCKING=y | ||
| 715 | CONFIG_FSNOTIFY=y | ||
| 716 | CONFIG_DNOTIFY=y | ||
| 717 | CONFIG_INOTIFY=y | ||
| 718 | CONFIG_INOTIFY_USER=y | ||
| 719 | # CONFIG_QUOTA is not set | ||
| 720 | # CONFIG_AUTOFS_FS is not set | ||
| 721 | # CONFIG_AUTOFS4_FS is not set | ||
| 722 | # CONFIG_FUSE_FS is not set | ||
| 723 | CONFIG_GENERIC_ACL=y | ||
| 724 | |||
| 725 | # | ||
| 726 | # Caches | ||
| 727 | # | ||
| 728 | # CONFIG_FSCACHE is not set | ||
| 729 | |||
| 730 | # | ||
| 731 | # CD-ROM/DVD Filesystems | ||
| 732 | # | ||
| 733 | # CONFIG_ISO9660_FS is not set | ||
| 734 | # CONFIG_UDF_FS is not set | ||
| 735 | |||
| 736 | # | ||
| 737 | # DOS/FAT/NT Filesystems | ||
| 738 | # | ||
| 739 | # CONFIG_MSDOS_FS is not set | ||
| 740 | # CONFIG_VFAT_FS is not set | ||
| 741 | # CONFIG_NTFS_FS is not set | ||
| 742 | |||
| 743 | # | ||
| 744 | # Pseudo filesystems | ||
| 745 | # | ||
| 746 | CONFIG_PROC_FS=y | ||
| 747 | CONFIG_PROC_SYSCTL=y | ||
| 748 | CONFIG_PROC_PAGE_MONITOR=y | ||
| 749 | CONFIG_SYSFS=y | ||
| 750 | CONFIG_TMPFS=y | ||
| 751 | CONFIG_TMPFS_POSIX_ACL=y | ||
| 752 | # CONFIG_HUGETLB_PAGE is not set | ||
| 753 | # CONFIG_CONFIGFS_FS is not set | ||
| 754 | CONFIG_MISC_FILESYSTEMS=y | ||
| 755 | # CONFIG_ADFS_FS is not set | ||
| 756 | # CONFIG_AFFS_FS is not set | ||
| 757 | # CONFIG_HFS_FS is not set | ||
| 758 | # CONFIG_HFSPLUS_FS is not set | ||
| 759 | # CONFIG_BEFS_FS is not set | ||
| 760 | # CONFIG_BFS_FS is not set | ||
| 761 | # CONFIG_EFS_FS is not set | ||
| 762 | CONFIG_CRAMFS=y | ||
| 763 | # CONFIG_SQUASHFS is not set | ||
| 764 | # CONFIG_VXFS_FS is not set | ||
| 765 | # CONFIG_MINIX_FS is not set | ||
| 766 | # CONFIG_OMFS_FS is not set | ||
| 767 | # CONFIG_HPFS_FS is not set | ||
| 768 | # CONFIG_QNX4FS_FS is not set | ||
| 769 | CONFIG_ROMFS_FS=y | ||
| 770 | CONFIG_ROMFS_BACKED_BY_BLOCK=y | ||
| 771 | # CONFIG_ROMFS_BACKED_BY_MTD is not set | ||
| 772 | # CONFIG_ROMFS_BACKED_BY_BOTH is not set | ||
| 773 | CONFIG_ROMFS_ON_BLOCK=y | ||
| 774 | # CONFIG_SYSV_FS is not set | ||
| 775 | # CONFIG_UFS_FS is not set | ||
| 776 | # CONFIG_NILFS2_FS is not set | ||
| 777 | |||
| 778 | # | ||
| 779 | # Partition Types | ||
| 780 | # | ||
| 781 | # CONFIG_PARTITION_ADVANCED is not set | ||
| 782 | CONFIG_MSDOS_PARTITION=y | ||
| 783 | # CONFIG_NLS is not set | ||
| 784 | |||
| 785 | # | ||
| 786 | # Kernel hacking | ||
| 787 | # | ||
| 788 | # CONFIG_PRINTK_TIME is not set | ||
| 789 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
| 790 | CONFIG_ENABLE_MUST_CHECK=y | ||
| 791 | CONFIG_FRAME_WARN=1024 | ||
| 792 | CONFIG_MAGIC_SYSRQ=y | ||
| 793 | # CONFIG_UNUSED_SYMBOLS is not set | ||
| 794 | # CONFIG_DEBUG_FS is not set | ||
| 795 | # CONFIG_HEADERS_CHECK is not set | ||
| 796 | CONFIG_DEBUG_KERNEL=y | ||
| 797 | # CONFIG_DEBUG_SHIRQ is not set | ||
| 798 | CONFIG_DETECT_SOFTLOCKUP=y | ||
| 799 | # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set | ||
| 800 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 | ||
| 801 | CONFIG_DETECT_HUNG_TASK=y | ||
| 802 | # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set | ||
| 803 | CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 | ||
| 804 | CONFIG_SCHED_DEBUG=y | ||
| 805 | # CONFIG_SCHEDSTATS is not set | ||
| 806 | # CONFIG_TIMER_STATS is not set | ||
| 807 | # CONFIG_DEBUG_OBJECTS is not set | ||
| 808 | # CONFIG_SLUB_DEBUG_ON is not set | ||
| 809 | # CONFIG_SLUB_STATS is not set | ||
| 810 | # CONFIG_DEBUG_KMEMLEAK is not set | ||
| 811 | CONFIG_DEBUG_RT_MUTEXES=y | ||
| 812 | CONFIG_DEBUG_PI_LIST=y | ||
| 813 | # CONFIG_RT_MUTEX_TESTER is not set | ||
| 814 | CONFIG_DEBUG_SPINLOCK=y | ||
| 815 | CONFIG_DEBUG_MUTEXES=y | ||
| 816 | # CONFIG_DEBUG_LOCK_ALLOC is not set | ||
| 817 | # CONFIG_PROVE_LOCKING is not set | ||
| 818 | # CONFIG_LOCK_STAT is not set | ||
| 819 | CONFIG_DEBUG_SPINLOCK_SLEEP=y | ||
| 820 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | ||
| 821 | # CONFIG_DEBUG_KOBJECT is not set | ||
| 822 | CONFIG_DEBUG_BUGVERBOSE=y | ||
| 823 | CONFIG_DEBUG_INFO=y | ||
| 824 | # CONFIG_DEBUG_VM is not set | ||
| 825 | # CONFIG_DEBUG_WRITECOUNT is not set | ||
| 826 | CONFIG_DEBUG_MEMORY_INIT=y | ||
| 827 | # CONFIG_DEBUG_LIST is not set | ||
| 828 | # CONFIG_DEBUG_SG is not set | ||
| 829 | # CONFIG_DEBUG_NOTIFIERS is not set | ||
| 830 | # CONFIG_BOOT_PRINTK_DELAY is not set | ||
| 831 | # CONFIG_RCU_TORTURE_TEST is not set | ||
| 832 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
| 833 | # CONFIG_BACKTRACE_SELF_TEST is not set | ||
| 834 | # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set | ||
| 835 | # CONFIG_FAULT_INJECTION is not set | ||
| 836 | # CONFIG_LATENCYTOP is not set | ||
| 837 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
| 838 | # CONFIG_PAGE_POISONING is not set | ||
| 839 | CONFIG_HAVE_FUNCTION_TRACER=y | ||
| 840 | CONFIG_TRACING_SUPPORT=y | ||
| 841 | CONFIG_FTRACE=y | ||
| 842 | # CONFIG_FUNCTION_TRACER is not set | ||
| 843 | # CONFIG_SCHED_TRACER is not set | ||
| 844 | # CONFIG_ENABLE_DEFAULT_TRACERS is not set | ||
| 845 | # CONFIG_BOOT_TRACER is not set | ||
| 846 | CONFIG_BRANCH_PROFILE_NONE=y | ||
| 847 | # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set | ||
| 848 | # CONFIG_PROFILE_ALL_BRANCHES is not set | ||
| 849 | # CONFIG_STACK_TRACER is not set | ||
| 850 | # CONFIG_KMEMTRACE is not set | ||
| 851 | # CONFIG_WORKQUEUE_TRACER is not set | ||
| 852 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
| 853 | # CONFIG_SAMPLES is not set | ||
| 854 | CONFIG_HAVE_ARCH_KGDB=y | ||
| 855 | # CONFIG_KGDB is not set | ||
| 856 | CONFIG_ARM_UNWIND=y | ||
| 857 | CONFIG_DEBUG_USER=y | ||
| 858 | CONFIG_DEBUG_ERRORS=y | ||
| 859 | # CONFIG_DEBUG_STACK_USAGE is not set | ||
| 860 | CONFIG_DEBUG_LL=y | ||
| 861 | # CONFIG_DEBUG_ICEDCC is not set | ||
| 862 | CONFIG_DEBUG_S3C_PORT=y | ||
| 863 | CONFIG_DEBUG_S3C_UART=0 | ||
| 864 | |||
| 865 | # | ||
| 866 | # Security options | ||
| 867 | # | ||
| 868 | # CONFIG_KEYS is not set | ||
| 869 | # CONFIG_SECURITY is not set | ||
| 870 | # CONFIG_SECURITYFS is not set | ||
| 871 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
| 872 | # CONFIG_CRYPTO is not set | ||
| 873 | # CONFIG_BINARY_PRINTF is not set | ||
| 874 | |||
| 875 | # | ||
| 876 | # Library routines | ||
| 877 | # | ||
| 878 | CONFIG_BITREVERSE=y | ||
| 879 | CONFIG_GENERIC_FIND_LAST_BIT=y | ||
| 880 | # CONFIG_CRC_CCITT is not set | ||
| 881 | # CONFIG_CRC16 is not set | ||
| 882 | # CONFIG_CRC_T10DIF is not set | ||
| 883 | # CONFIG_CRC_ITU_T is not set | ||
| 884 | CONFIG_CRC32=y | ||
| 885 | # CONFIG_CRC7 is not set | ||
| 886 | # CONFIG_LIBCRC32C is not set | ||
| 887 | CONFIG_ZLIB_INFLATE=y | ||
| 888 | CONFIG_DECOMPRESS_GZIP=y | ||
| 889 | CONFIG_DECOMPRESS_BZIP2=y | ||
| 890 | CONFIG_DECOMPRESS_LZMA=y | ||
| 891 | CONFIG_HAS_IOMEM=y | ||
| 892 | CONFIG_HAS_DMA=y | ||
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 15f8a092b700..00f46d9ce299 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h | |||
| @@ -74,23 +74,56 @@ | |||
| 74 | * Enable and disable interrupts | 74 | * Enable and disable interrupts |
| 75 | */ | 75 | */ |
| 76 | #if __LINUX_ARM_ARCH__ >= 6 | 76 | #if __LINUX_ARM_ARCH__ >= 6 |
| 77 | .macro disable_irq | 77 | .macro disable_irq_notrace |
| 78 | cpsid i | 78 | cpsid i |
| 79 | .endm | 79 | .endm |
| 80 | 80 | ||
| 81 | .macro enable_irq | 81 | .macro enable_irq_notrace |
| 82 | cpsie i | 82 | cpsie i |
| 83 | .endm | 83 | .endm |
| 84 | #else | 84 | #else |
| 85 | .macro disable_irq | 85 | .macro disable_irq_notrace |
| 86 | msr cpsr_c, #PSR_I_BIT | SVC_MODE | 86 | msr cpsr_c, #PSR_I_BIT | SVC_MODE |
| 87 | .endm | 87 | .endm |
| 88 | 88 | ||
| 89 | .macro enable_irq | 89 | .macro enable_irq_notrace |
| 90 | msr cpsr_c, #SVC_MODE | 90 | msr cpsr_c, #SVC_MODE |
| 91 | .endm | 91 | .endm |
| 92 | #endif | 92 | #endif |
| 93 | 93 | ||
| 94 | .macro asm_trace_hardirqs_off | ||
| 95 | #if defined(CONFIG_TRACE_IRQFLAGS) | ||
| 96 | stmdb sp!, {r0-r3, ip, lr} | ||
| 97 | bl trace_hardirqs_off | ||
| 98 | ldmia sp!, {r0-r3, ip, lr} | ||
| 99 | #endif | ||
| 100 | .endm | ||
| 101 | |||
| 102 | .macro asm_trace_hardirqs_on_cond, cond | ||
| 103 | #if defined(CONFIG_TRACE_IRQFLAGS) | ||
| 104 | /* | ||
| 105 | * actually the registers should be pushed and pop'd conditionally, but | ||
| 106 | * after bl the flags are certainly clobbered | ||
| 107 | */ | ||
| 108 | stmdb sp!, {r0-r3, ip, lr} | ||
| 109 | bl\cond trace_hardirqs_on | ||
| 110 | ldmia sp!, {r0-r3, ip, lr} | ||
| 111 | #endif | ||
| 112 | .endm | ||
| 113 | |||
| 114 | .macro asm_trace_hardirqs_on | ||
| 115 | asm_trace_hardirqs_on_cond al | ||
| 116 | .endm | ||
| 117 | |||
| 118 | .macro disable_irq | ||
| 119 | disable_irq_notrace | ||
| 120 | asm_trace_hardirqs_off | ||
| 121 | .endm | ||
| 122 | |||
| 123 | .macro enable_irq | ||
| 124 | asm_trace_hardirqs_on | ||
| 125 | enable_irq_notrace | ||
| 126 | .endm | ||
| 94 | /* | 127 | /* |
| 95 | * Save the current IRQ state and disable IRQs. Note that this macro | 128 | * Save the current IRQ state and disable IRQs. Note that this macro |
| 96 | * assumes FIQs are enabled, and that the processor is in SVC mode. | 129 | * assumes FIQs are enabled, and that the processor is in SVC mode. |
| @@ -104,10 +137,16 @@ | |||
| 104 | * Restore interrupt state previously stored in a register. We don't | 137 | * Restore interrupt state previously stored in a register. We don't |
| 105 | * guarantee that this will preserve the flags. | 138 | * guarantee that this will preserve the flags. |
| 106 | */ | 139 | */ |
| 107 | .macro restore_irqs, oldcpsr | 140 | .macro restore_irqs_notrace, oldcpsr |
| 108 | msr cpsr_c, \oldcpsr | 141 | msr cpsr_c, \oldcpsr |
| 109 | .endm | 142 | .endm |
| 110 | 143 | ||
| 144 | .macro restore_irqs, oldcpsr | ||
| 145 | tst \oldcpsr, #PSR_I_BIT | ||
| 146 | asm_trace_hardirqs_on_cond eq | ||
| 147 | restore_irqs_notrace \oldcpsr | ||
| 148 | .endm | ||
| 149 | |||
| 111 | #define USER(x...) \ | 150 | #define USER(x...) \ |
| 112 | 9999: x; \ | 151 | 9999: x; \ |
| 113 | .section __ex_table,"a"; \ | 152 | .section __ex_table,"a"; \ |
| @@ -127,3 +166,87 @@ | |||
| 127 | #endif | 166 | #endif |
| 128 | #endif | 167 | #endif |
| 129 | .endm | 168 | .endm |
| 169 | |||
| 170 | #ifdef CONFIG_THUMB2_KERNEL | ||
| 171 | .macro setmode, mode, reg | ||
| 172 | mov \reg, #\mode | ||
| 173 | msr cpsr_c, \reg | ||
| 174 | .endm | ||
| 175 | #else | ||
| 176 | .macro setmode, mode, reg | ||
| 177 | msr cpsr_c, #\mode | ||
| 178 | .endm | ||
| 179 | #endif | ||
| 180 | |||
| 181 | /* | ||
| 182 | * STRT/LDRT access macros with ARM and Thumb-2 variants | ||
| 183 | */ | ||
| 184 | #ifdef CONFIG_THUMB2_KERNEL | ||
| 185 | |||
| 186 | .macro usraccoff, instr, reg, ptr, inc, off, cond, abort | ||
| 187 | 9999: | ||
| 188 | .if \inc == 1 | ||
| 189 | \instr\cond\()bt \reg, [\ptr, #\off] | ||
| 190 | .elseif \inc == 4 | ||
| 191 | \instr\cond\()t \reg, [\ptr, #\off] | ||
| 192 | .else | ||
| 193 | .error "Unsupported inc macro argument" | ||
| 194 | .endif | ||
| 195 | |||
| 196 | .section __ex_table,"a" | ||
| 197 | .align 3 | ||
| 198 | .long 9999b, \abort | ||
| 199 | .previous | ||
| 200 | .endm | ||
| 201 | |||
| 202 | .macro usracc, instr, reg, ptr, inc, cond, rept, abort | ||
| 203 | @ explicit IT instruction needed because of the label | ||
| 204 | @ introduced by the USER macro | ||
| 205 | .ifnc \cond,al | ||
| 206 | .if \rept == 1 | ||
| 207 | itt \cond | ||
| 208 | .elseif \rept == 2 | ||
| 209 | ittt \cond | ||
| 210 | .else | ||
| 211 | .error "Unsupported rept macro argument" | ||
| 212 | .endif | ||
| 213 | .endif | ||
| 214 | |||
| 215 | @ Slightly optimised to avoid incrementing the pointer twice | ||
| 216 | usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort | ||
| 217 | .if \rept == 2 | ||
| 218 | usraccoff \instr, \reg, \ptr, \inc, 4, \cond, \abort | ||
| 219 | .endif | ||
| 220 | |||
| 221 | add\cond \ptr, #\rept * \inc | ||
| 222 | .endm | ||
| 223 | |||
| 224 | #else /* !CONFIG_THUMB2_KERNEL */ | ||
| 225 | |||
| 226 | .macro usracc, instr, reg, ptr, inc, cond, rept, abort | ||
| 227 | .rept \rept | ||
| 228 | 9999: | ||
| 229 | .if \inc == 1 | ||
| 230 | \instr\cond\()bt \reg, [\ptr], #\inc | ||
| 231 | .elseif \inc == 4 | ||
| 232 | \instr\cond\()t \reg, [\ptr], #\inc | ||
| 233 | .else | ||
| 234 | .error "Unsupported inc macro argument" | ||
| 235 | .endif | ||
| 236 | |||
| 237 | .section __ex_table,"a" | ||
| 238 | .align 3 | ||
| 239 | .long 9999b, \abort | ||
| 240 | .previous | ||
| 241 | .endr | ||
| 242 | .endm | ||
| 243 | |||
| 244 | #endif /* CONFIG_THUMB2_KERNEL */ | ||
| 245 | |||
| 246 | .macro strusr, reg, ptr, inc, cond=al, rept=1, abort=9001f | ||
| 247 | usracc str, \reg, \ptr, \inc, \cond, \rept, \abort | ||
| 248 | .endm | ||
| 249 | |||
| 250 | .macro ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f | ||
| 251 | usracc ldr, \reg, \ptr, \inc, \cond, \rept, \abort | ||
| 252 | .endm | ||
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index c207504de84d..c3b911ee9151 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h | |||
| @@ -55,6 +55,9 @@ typedef struct user_fp elf_fpregset_t; | |||
| 55 | #define R_ARM_MOVW_ABS_NC 43 | 55 | #define R_ARM_MOVW_ABS_NC 43 |
| 56 | #define R_ARM_MOVT_ABS 44 | 56 | #define R_ARM_MOVT_ABS 44 |
| 57 | 57 | ||
| 58 | #define R_ARM_THM_CALL 10 | ||
| 59 | #define R_ARM_THM_JUMP24 30 | ||
| 60 | |||
| 58 | /* | 61 | /* |
| 59 | * These are used to set parameters in the core dumps. | 62 | * These are used to set parameters in the core dumps. |
| 60 | */ | 63 | */ |
diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h index 39c8bc1a006a..103f7ee97313 100644 --- a/arch/arm/include/asm/ftrace.h +++ b/arch/arm/include/asm/ftrace.h | |||
| @@ -7,8 +7,43 @@ | |||
| 7 | 7 | ||
| 8 | #ifndef __ASSEMBLY__ | 8 | #ifndef __ASSEMBLY__ |
| 9 | extern void mcount(void); | 9 | extern void mcount(void); |
| 10 | extern void __gnu_mcount_nc(void); | ||
| 10 | #endif | 11 | #endif |
| 11 | 12 | ||
| 12 | #endif | 13 | #endif |
| 13 | 14 | ||
| 15 | #ifndef __ASSEMBLY__ | ||
| 16 | |||
| 17 | #if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) | ||
| 18 | /* | ||
| 19 | * return_address uses walk_stackframe to do it's work. If both | ||
| 20 | * CONFIG_FRAME_POINTER=y and CONFIG_ARM_UNWIND=y walk_stackframe uses unwind | ||
| 21 | * information. For this to work in the function tracer many functions would | ||
| 22 | * have to be marked with __notrace. So for now just depend on | ||
| 23 | * !CONFIG_ARM_UNWIND. | ||
| 24 | */ | ||
| 25 | |||
| 26 | void *return_address(unsigned int); | ||
| 27 | |||
| 28 | #else | ||
| 29 | |||
| 30 | extern inline void *return_address(unsigned int level) | ||
| 31 | { | ||
| 32 | return NULL; | ||
| 33 | } | ||
| 34 | |||
| 35 | #endif | ||
| 36 | |||
| 37 | #define HAVE_ARCH_CALLER_ADDR | ||
| 38 | |||
| 39 | #define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) | ||
| 40 | #define CALLER_ADDR1 ((unsigned long)return_address(1)) | ||
| 41 | #define CALLER_ADDR2 ((unsigned long)return_address(2)) | ||
| 42 | #define CALLER_ADDR3 ((unsigned long)return_address(3)) | ||
| 43 | #define CALLER_ADDR4 ((unsigned long)return_address(4)) | ||
| 44 | #define CALLER_ADDR5 ((unsigned long)return_address(5)) | ||
| 45 | #define CALLER_ADDR6 ((unsigned long)return_address(6)) | ||
| 46 | |||
| 47 | #endif /* ifndef __ASSEMBLY__ */ | ||
| 48 | |||
| 14 | #endif /* _ASM_ARM_FTRACE */ | 49 | #endif /* _ASM_ARM_FTRACE */ |
diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h index 9ee743b95de8..bfcc15929a7f 100644 --- a/arch/arm/include/asm/futex.h +++ b/arch/arm/include/asm/futex.h | |||
| @@ -99,6 +99,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) | |||
| 99 | __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" | 99 | __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" |
| 100 | "1: ldrt %0, [%3]\n" | 100 | "1: ldrt %0, [%3]\n" |
| 101 | " teq %0, %1\n" | 101 | " teq %0, %1\n" |
| 102 | " it eq @ explicit IT needed for the 2b label\n" | ||
| 102 | "2: streqt %2, [%3]\n" | 103 | "2: streqt %2, [%3]\n" |
| 103 | "3:\n" | 104 | "3:\n" |
| 104 | " .section __ex_table,\"a\"\n" | 105 | " .section __ex_table,\"a\"\n" |
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h index 4da332b03144..b490ecc79def 100644 --- a/arch/arm/include/asm/mach/mmc.h +++ b/arch/arm/include/asm/mach/mmc.h | |||
| @@ -10,6 +10,8 @@ struct mmc_platform_data { | |||
| 10 | unsigned int ocr_mask; /* available voltages */ | 10 | unsigned int ocr_mask; /* available voltages */ |
| 11 | u32 (*translate_vdd)(struct device *, unsigned int); | 11 | u32 (*translate_vdd)(struct device *, unsigned int); |
| 12 | unsigned int (*status)(struct device *); | 12 | unsigned int (*status)(struct device *); |
| 13 | int gpio_wp; | ||
| 14 | int gpio_cd; | ||
| 13 | }; | 15 | }; |
| 14 | 16 | ||
| 15 | #endif | 17 | #endif |
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 85763db87449..cefedf062138 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h | |||
| @@ -44,7 +44,13 @@ | |||
| 44 | * The module space lives between the addresses given by TASK_SIZE | 44 | * The module space lives between the addresses given by TASK_SIZE |
| 45 | * and PAGE_OFFSET - it must be within 32MB of the kernel text. | 45 | * and PAGE_OFFSET - it must be within 32MB of the kernel text. |
| 46 | */ | 46 | */ |
| 47 | #ifndef CONFIG_THUMB2_KERNEL | ||
| 47 | #define MODULES_VADDR (PAGE_OFFSET - 16*1024*1024) | 48 | #define MODULES_VADDR (PAGE_OFFSET - 16*1024*1024) |
| 49 | #else | ||
| 50 | /* smaller range for Thumb-2 symbols relocation (2^24)*/ | ||
| 51 | #define MODULES_VADDR (PAGE_OFFSET - 8*1024*1024) | ||
| 52 | #endif | ||
| 53 | |||
| 48 | #if TASK_SIZE > MODULES_VADDR | 54 | #if TASK_SIZE > MODULES_VADDR |
| 49 | #error Top of user space clashes with start of module space | 55 | #error Top of user space clashes with start of module space |
| 50 | #endif | 56 | #endif |
| @@ -212,7 +218,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x) | |||
| 212 | * | 218 | * |
| 213 | * page_to_pfn(page) convert a struct page * to a PFN number | 219 | * page_to_pfn(page) convert a struct page * to a PFN number |
| 214 | * pfn_to_page(pfn) convert a _valid_ PFN number to struct page * | 220 | * pfn_to_page(pfn) convert a _valid_ PFN number to struct page * |
| 215 | * pfn_valid(pfn) indicates whether a PFN number is valid | ||
| 216 | * | 221 | * |
| 217 | * virt_to_page(k) convert a _valid_ virtual address to struct page * | 222 | * virt_to_page(k) convert a _valid_ virtual address to struct page * |
| 218 | * virt_addr_valid(k) indicates whether a virtual address is valid | 223 | * virt_addr_valid(k) indicates whether a virtual address is valid |
| @@ -221,10 +226,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x) | |||
| 221 | 226 | ||
| 222 | #define ARCH_PFN_OFFSET PHYS_PFN_OFFSET | 227 | #define ARCH_PFN_OFFSET PHYS_PFN_OFFSET |
| 223 | 228 | ||
| 224 | #ifndef CONFIG_SPARSEMEM | ||
| 225 | #define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr)) | ||
| 226 | #endif | ||
| 227 | |||
| 228 | #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) | 229 | #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) |
| 229 | #define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) | 230 | #define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) |
| 230 | 231 | ||
| @@ -241,18 +242,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x) | |||
| 241 | #define arch_pfn_to_nid(pfn) PFN_TO_NID(pfn) | 242 | #define arch_pfn_to_nid(pfn) PFN_TO_NID(pfn) |
| 242 | #define arch_local_page_offset(pfn, nid) LOCAL_MAP_NR((pfn) << PAGE_SHIFT) | 243 | #define arch_local_page_offset(pfn, nid) LOCAL_MAP_NR((pfn) << PAGE_SHIFT) |
| 243 | 244 | ||
| 244 | #define pfn_valid(pfn) \ | ||
| 245 | ({ \ | ||
| 246 | unsigned int nid = PFN_TO_NID(pfn); \ | ||
| 247 | int valid = nid < MAX_NUMNODES; \ | ||
| 248 | if (valid) { \ | ||
| 249 | pg_data_t *node = NODE_DATA(nid); \ | ||
| 250 | valid = (pfn - node->node_start_pfn) < \ | ||
| 251 | node->node_spanned_pages; \ | ||
| 252 | } \ | ||
| 253 | valid; \ | ||
| 254 | }) | ||
| 255 | |||
| 256 | #define virt_to_page(kaddr) \ | 245 | #define virt_to_page(kaddr) \ |
| 257 | (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)) | 246 | (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)) |
| 258 | 247 | ||
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h index 263fed05ea33..bcdb9291ef0c 100644 --- a/arch/arm/include/asm/mmu_context.h +++ b/arch/arm/include/asm/mmu_context.h | |||
| @@ -62,8 +62,10 @@ static inline void check_context(struct mm_struct *mm) | |||
| 62 | 62 | ||
| 63 | static inline void check_context(struct mm_struct *mm) | 63 | static inline void check_context(struct mm_struct *mm) |
| 64 | { | 64 | { |
| 65 | #ifdef CONFIG_MMU | ||
| 65 | if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq)) | 66 | if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq)) |
| 66 | __check_kvm_seq(mm); | 67 | __check_kvm_seq(mm); |
| 68 | #endif | ||
| 67 | } | 69 | } |
| 68 | 70 | ||
| 69 | #define init_new_context(tsk,mm) 0 | 71 | #define init_new_context(tsk,mm) 0 |
diff --git a/arch/arm/include/asm/page-nommu.h b/arch/arm/include/asm/page-nommu.h index 3574c0deb37f..d1b162a18dcb 100644 --- a/arch/arm/include/asm/page-nommu.h +++ b/arch/arm/include/asm/page-nommu.h | |||
| @@ -43,7 +43,4 @@ typedef unsigned long pgprot_t; | |||
| 43 | #define __pmd(x) (x) | 43 | #define __pmd(x) (x) |
| 44 | #define __pgprot(x) (x) | 44 | #define __pgprot(x) (x) |
| 45 | 45 | ||
| 46 | extern unsigned long memory_start; | ||
| 47 | extern unsigned long memory_end; | ||
| 48 | |||
| 49 | #endif | 46 | #endif |
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h index 9c746af1bf6e..3a32af4cce30 100644 --- a/arch/arm/include/asm/page.h +++ b/arch/arm/include/asm/page.h | |||
| @@ -194,6 +194,10 @@ typedef unsigned long pgprot_t; | |||
| 194 | 194 | ||
| 195 | typedef struct page *pgtable_t; | 195 | typedef struct page *pgtable_t; |
| 196 | 196 | ||
| 197 | #ifndef CONFIG_SPARSEMEM | ||
| 198 | extern int pfn_valid(unsigned long); | ||
| 199 | #endif | ||
| 200 | |||
| 197 | #include <asm/memory.h> | 201 | #include <asm/memory.h> |
| 198 | 202 | ||
| 199 | #endif /* !__ASSEMBLY__ */ | 203 | #endif /* !__ASSEMBLY__ */ |
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h index 3dcd64bf1824..b12cc98bbe04 100644 --- a/arch/arm/include/asm/pgalloc.h +++ b/arch/arm/include/asm/pgalloc.h | |||
| @@ -36,6 +36,8 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd); | |||
| 36 | #define pgd_alloc(mm) get_pgd_slow(mm) | 36 | #define pgd_alloc(mm) get_pgd_slow(mm) |
| 37 | #define pgd_free(mm, pgd) free_pgd_slow(mm, pgd) | 37 | #define pgd_free(mm, pgd) free_pgd_slow(mm, pgd) |
| 38 | 38 | ||
| 39 | #define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO) | ||
| 40 | |||
| 39 | /* | 41 | /* |
| 40 | * Allocate one PTE table. | 42 | * Allocate one PTE table. |
| 41 | * | 43 | * |
| @@ -57,7 +59,7 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) | |||
| 57 | { | 59 | { |
| 58 | pte_t *pte; | 60 | pte_t *pte; |
| 59 | 61 | ||
| 60 | pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); | 62 | pte = (pte_t *)__get_free_page(PGALLOC_GFP); |
| 61 | if (pte) { | 63 | if (pte) { |
| 62 | clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE); | 64 | clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE); |
| 63 | pte += PTRS_PER_PTE; | 65 | pte += PTRS_PER_PTE; |
| @@ -71,10 +73,16 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr) | |||
| 71 | { | 73 | { |
| 72 | struct page *pte; | 74 | struct page *pte; |
| 73 | 75 | ||
| 74 | pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); | 76 | #ifdef CONFIG_HIGHPTE |
| 77 | pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0); | ||
| 78 | #else | ||
| 79 | pte = alloc_pages(PGALLOC_GFP, 0); | ||
| 80 | #endif | ||
| 75 | if (pte) { | 81 | if (pte) { |
| 76 | void *page = page_address(pte); | 82 | if (!PageHighMem(pte)) { |
| 77 | clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE); | 83 | void *page = page_address(pte); |
| 84 | clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE); | ||
| 85 | } | ||
| 78 | pgtable_page_ctor(pte); | 86 | pgtable_page_ctor(pte); |
| 79 | } | 87 | } |
| 80 | 88 | ||
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index c433c6c73112..201ccaa11f61 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
| @@ -162,10 +162,8 @@ extern void __pgd_error(const char *file, int line, unsigned long val); | |||
| 162 | * entries are stored 1024 bytes below. | 162 | * entries are stored 1024 bytes below. |
| 163 | */ | 163 | */ |
| 164 | #define L_PTE_PRESENT (1 << 0) | 164 | #define L_PTE_PRESENT (1 << 0) |
| 165 | #define L_PTE_FILE (1 << 1) /* only when !PRESENT */ | ||
| 166 | #define L_PTE_YOUNG (1 << 1) | 165 | #define L_PTE_YOUNG (1 << 1) |
| 167 | #define L_PTE_BUFFERABLE (1 << 2) /* obsolete, matches PTE */ | 166 | #define L_PTE_FILE (1 << 2) /* only when !PRESENT */ |
| 168 | #define L_PTE_CACHEABLE (1 << 3) /* obsolete, matches PTE */ | ||
| 169 | #define L_PTE_DIRTY (1 << 6) | 167 | #define L_PTE_DIRTY (1 << 6) |
| 170 | #define L_PTE_WRITE (1 << 7) | 168 | #define L_PTE_WRITE (1 << 7) |
| 171 | #define L_PTE_USER (1 << 8) | 169 | #define L_PTE_USER (1 << 8) |
| @@ -264,10 +262,19 @@ extern struct page *empty_zero_page; | |||
| 264 | #define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) | 262 | #define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) |
| 265 | #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) | 263 | #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) |
| 266 | #define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) | 264 | #define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) |
| 267 | #define pte_offset_map(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) | 265 | |
| 268 | #define pte_offset_map_nested(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) | 266 | #define pte_offset_map(dir,addr) (__pte_map(dir, KM_PTE0) + __pte_index(addr)) |
| 269 | #define pte_unmap(pte) do { } while (0) | 267 | #define pte_offset_map_nested(dir,addr) (__pte_map(dir, KM_PTE1) + __pte_index(addr)) |
| 270 | #define pte_unmap_nested(pte) do { } while (0) | 268 | #define pte_unmap(pte) __pte_unmap(pte, KM_PTE0) |
| 269 | #define pte_unmap_nested(pte) __pte_unmap(pte, KM_PTE1) | ||
| 270 | |||
| 271 | #ifndef CONFIG_HIGHPTE | ||
| 272 | #define __pte_map(dir,km) pmd_page_vaddr(*(dir)) | ||
| 273 | #define __pte_unmap(pte,km) do { } while (0) | ||
| 274 | #else | ||
| 275 | #define __pte_map(dir,km) ((pte_t *)kmap_atomic(pmd_page(*(dir)), km) + PTRS_PER_PTE) | ||
| 276 | #define __pte_unmap(pte,km) kunmap_atomic((pte - PTRS_PER_PTE), km) | ||
| 277 | #endif | ||
| 271 | 278 | ||
| 272 | #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) | 279 | #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) |
| 273 | 280 | ||
| @@ -381,13 +388,13 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; | |||
| 381 | * | 388 | * |
| 382 | * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 | 389 | * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 |
| 383 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | 390 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 |
| 384 | * <--------------- offset --------------------> <--- type --> 0 0 | 391 | * <--------------- offset --------------------> <- type --> 0 0 0 |
| 385 | * | 392 | * |
| 386 | * This gives us up to 127 swap files and 32GB per swap file. Note that | 393 | * This gives us up to 63 swap files and 32GB per swap file. Note that |
| 387 | * the offset field is always non-zero. | 394 | * the offset field is always non-zero. |
| 388 | */ | 395 | */ |
| 389 | #define __SWP_TYPE_SHIFT 2 | 396 | #define __SWP_TYPE_SHIFT 3 |
| 390 | #define __SWP_TYPE_BITS 7 | 397 | #define __SWP_TYPE_BITS 6 |
| 391 | #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) | 398 | #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) |
| 392 | #define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) | 399 | #define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) |
| 393 | 400 | ||
| @@ -411,13 +418,13 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; | |||
| 411 | * | 418 | * |
| 412 | * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 | 419 | * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 |
| 413 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | 420 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 |
| 414 | * <------------------------ offset -------------------------> 1 0 | 421 | * <----------------------- offset ------------------------> 1 0 0 |
| 415 | */ | 422 | */ |
| 416 | #define pte_file(pte) (pte_val(pte) & L_PTE_FILE) | 423 | #define pte_file(pte) (pte_val(pte) & L_PTE_FILE) |
| 417 | #define pte_to_pgoff(x) (pte_val(x) >> 2) | 424 | #define pte_to_pgoff(x) (pte_val(x) >> 3) |
| 418 | #define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE) | 425 | #define pgoff_to_pte(x) __pte(((x) << 3) | L_PTE_FILE) |
| 419 | 426 | ||
| 420 | #define PTE_FILE_MAX_BITS 30 | 427 | #define PTE_FILE_MAX_BITS 29 |
| 421 | 428 | ||
| 422 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ | 429 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ |
| 423 | /* FIXME: this is not correct */ | 430 | /* FIXME: this is not correct */ |
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 67b833c9b6b9..bbecccda76d0 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h | |||
| @@ -82,6 +82,14 @@ | |||
| 82 | #define PSR_ENDSTATE 0 | 82 | #define PSR_ENDSTATE 0 |
| 83 | #endif | 83 | #endif |
| 84 | 84 | ||
| 85 | /* | ||
| 86 | * These are 'magic' values for PTRACE_PEEKUSR that return info about where a | ||
| 87 | * process is located in memory. | ||
| 88 | */ | ||
| 89 | #define PT_TEXT_ADDR 0x10000 | ||
| 90 | #define PT_DATA_ADDR 0x10004 | ||
| 91 | #define PT_TEXT_END_ADDR 0x10008 | ||
| 92 | |||
| 85 | #ifndef __ASSEMBLY__ | 93 | #ifndef __ASSEMBLY__ |
| 86 | 94 | ||
| 87 | /* | 95 | /* |
diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h index 537de4e0ef50..92ac61d294fd 100644 --- a/arch/arm/include/asm/socket.h +++ b/arch/arm/include/asm/socket.h | |||
| @@ -57,4 +57,7 @@ | |||
| 57 | #define SO_TIMESTAMPING 37 | 57 | #define SO_TIMESTAMPING 37 |
| 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING | 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING |
| 59 | 59 | ||
| 60 | #define SO_PROTOCOL 38 | ||
| 61 | #define SO_DOMAIN 39 | ||
| 62 | |||
| 60 | #endif /* _ASM_SOCKET_H */ | 63 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index 73394e50cbca..2dfb7d7a66e9 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h | |||
| @@ -130,23 +130,28 @@ extern void vfp_sync_state(struct thread_info *thread); | |||
| 130 | * TIF_SYSCALL_TRACE - syscall trace active | 130 | * TIF_SYSCALL_TRACE - syscall trace active |
| 131 | * TIF_SIGPENDING - signal pending | 131 | * TIF_SIGPENDING - signal pending |
| 132 | * TIF_NEED_RESCHED - rescheduling necessary | 132 | * TIF_NEED_RESCHED - rescheduling necessary |
| 133 | * TIF_NOTIFY_RESUME - callback before returning to user | ||
| 133 | * TIF_USEDFPU - FPU was used by this task this quantum (SMP) | 134 | * TIF_USEDFPU - FPU was used by this task this quantum (SMP) |
| 134 | * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED | 135 | * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED |
| 135 | */ | 136 | */ |
| 136 | #define TIF_SIGPENDING 0 | 137 | #define TIF_SIGPENDING 0 |
| 137 | #define TIF_NEED_RESCHED 1 | 138 | #define TIF_NEED_RESCHED 1 |
| 139 | #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ | ||
| 138 | #define TIF_SYSCALL_TRACE 8 | 140 | #define TIF_SYSCALL_TRACE 8 |
| 139 | #define TIF_POLLING_NRFLAG 16 | 141 | #define TIF_POLLING_NRFLAG 16 |
| 140 | #define TIF_USING_IWMMXT 17 | 142 | #define TIF_USING_IWMMXT 17 |
| 141 | #define TIF_MEMDIE 18 | 143 | #define TIF_MEMDIE 18 |
| 142 | #define TIF_FREEZE 19 | 144 | #define TIF_FREEZE 19 |
| 145 | #define TIF_RESTORE_SIGMASK 20 | ||
| 143 | 146 | ||
| 144 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) | 147 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) |
| 145 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) | 148 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) |
| 149 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) | ||
| 146 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) | 150 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) |
| 147 | #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) | 151 | #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) |
| 148 | #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) | 152 | #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) |
| 149 | #define _TIF_FREEZE (1 << TIF_FREEZE) | 153 | #define _TIF_FREEZE (1 << TIF_FREEZE) |
| 154 | #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) | ||
| 150 | 155 | ||
| 151 | /* | 156 | /* |
| 152 | * Change these and you break ASM code in entry-common.S | 157 | * Change these and you break ASM code in entry-common.S |
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 0da9bc9b3b1d..1d6bd40a4322 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <asm/memory.h> | 17 | #include <asm/memory.h> |
| 18 | #include <asm/domain.h> | 18 | #include <asm/domain.h> |
| 19 | #include <asm/system.h> | 19 | #include <asm/system.h> |
| 20 | #include <asm/unified.h> | ||
| 20 | 21 | ||
| 21 | #define VERIFY_READ 0 | 22 | #define VERIFY_READ 0 |
| 22 | #define VERIFY_WRITE 1 | 23 | #define VERIFY_WRITE 1 |
| @@ -365,8 +366,10 @@ do { \ | |||
| 365 | 366 | ||
| 366 | #define __put_user_asm_dword(x,__pu_addr,err) \ | 367 | #define __put_user_asm_dword(x,__pu_addr,err) \ |
| 367 | __asm__ __volatile__( \ | 368 | __asm__ __volatile__( \ |
| 368 | "1: strt " __reg_oper1 ", [%1], #4\n" \ | 369 | ARM( "1: strt " __reg_oper1 ", [%1], #4\n" ) \ |
| 369 | "2: strt " __reg_oper0 ", [%1]\n" \ | 370 | ARM( "2: strt " __reg_oper0 ", [%1]\n" ) \ |
| 371 | THUMB( "1: strt " __reg_oper1 ", [%1]\n" ) \ | ||
| 372 | THUMB( "2: strt " __reg_oper0 ", [%1, #4]\n" ) \ | ||
| 370 | "3:\n" \ | 373 | "3:\n" \ |
| 371 | " .section .fixup,\"ax\"\n" \ | 374 | " .section .fixup,\"ax\"\n" \ |
| 372 | " .align 2\n" \ | 375 | " .align 2\n" \ |
diff --git a/arch/arm/include/asm/unified.h b/arch/arm/include/asm/unified.h new file mode 100644 index 000000000000..073e85b9b961 --- /dev/null +++ b/arch/arm/include/asm/unified.h | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | /* | ||
| 2 | * include/asm-arm/unified.h - Unified Assembler Syntax helper macros | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 ARM Limited | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef __ASM_UNIFIED_H | ||
| 21 | #define __ASM_UNIFIED_H | ||
| 22 | |||
| 23 | #if defined(__ASSEMBLY__) && defined(CONFIG_ARM_ASM_UNIFIED) | ||
| 24 | .syntax unified | ||
| 25 | #endif | ||
| 26 | |||
| 27 | #ifdef CONFIG_THUMB2_KERNEL | ||
| 28 | |||
| 29 | #if __GNUC__ < 4 | ||
| 30 | #error Thumb-2 kernel requires gcc >= 4 | ||
| 31 | #endif | ||
| 32 | |||
| 33 | /* The CPSR bit describing the instruction set (Thumb) */ | ||
| 34 | #define PSR_ISETSTATE PSR_T_BIT | ||
| 35 | |||
| 36 | #define ARM(x...) | ||
| 37 | #define THUMB(x...) x | ||
| 38 | #define W(instr) instr.w | ||
| 39 | #define BSYM(sym) sym + 1 | ||
| 40 | |||
| 41 | #else /* !CONFIG_THUMB2_KERNEL */ | ||
| 42 | |||
| 43 | /* The CPSR bit describing the instruction set (ARM) */ | ||
| 44 | #define PSR_ISETSTATE 0 | ||
| 45 | |||
| 46 | #define ARM(x...) x | ||
| 47 | #define THUMB(x...) | ||
| 48 | #define W(instr) instr | ||
| 49 | #define BSYM(sym) sym | ||
| 50 | |||
| 51 | #endif /* CONFIG_THUMB2_KERNEL */ | ||
| 52 | |||
| 53 | #ifndef CONFIG_ARM_ASM_UNIFIED | ||
| 54 | |||
| 55 | /* | ||
| 56 | * If the unified assembly syntax isn't used (in ARM mode), these | ||
| 57 | * macros expand to an empty string | ||
| 58 | */ | ||
| 59 | #ifdef __ASSEMBLY__ | ||
| 60 | .macro it, cond | ||
| 61 | .endm | ||
| 62 | .macro itt, cond | ||
| 63 | .endm | ||
| 64 | .macro ite, cond | ||
| 65 | .endm | ||
| 66 | .macro ittt, cond | ||
| 67 | .endm | ||
| 68 | .macro itte, cond | ||
| 69 | .endm | ||
| 70 | .macro itet, cond | ||
| 71 | .endm | ||
| 72 | .macro itee, cond | ||
| 73 | .endm | ||
| 74 | .macro itttt, cond | ||
| 75 | .endm | ||
| 76 | .macro ittte, cond | ||
| 77 | .endm | ||
| 78 | .macro ittet, cond | ||
| 79 | .endm | ||
| 80 | .macro ittee, cond | ||
| 81 | .endm | ||
| 82 | .macro itett, cond | ||
| 83 | .endm | ||
| 84 | .macro itete, cond | ||
| 85 | .endm | ||
| 86 | .macro iteet, cond | ||
| 87 | .endm | ||
| 88 | .macro iteee, cond | ||
| 89 | .endm | ||
| 90 | #else /* !__ASSEMBLY__ */ | ||
| 91 | __asm__( | ||
| 92 | " .macro it, cond\n" | ||
| 93 | " .endm\n" | ||
| 94 | " .macro itt, cond\n" | ||
| 95 | " .endm\n" | ||
| 96 | " .macro ite, cond\n" | ||
| 97 | " .endm\n" | ||
| 98 | " .macro ittt, cond\n" | ||
| 99 | " .endm\n" | ||
| 100 | " .macro itte, cond\n" | ||
| 101 | " .endm\n" | ||
| 102 | " .macro itet, cond\n" | ||
| 103 | " .endm\n" | ||
| 104 | " .macro itee, cond\n" | ||
| 105 | " .endm\n" | ||
| 106 | " .macro itttt, cond\n" | ||
| 107 | " .endm\n" | ||
| 108 | " .macro ittte, cond\n" | ||
| 109 | " .endm\n" | ||
| 110 | " .macro ittet, cond\n" | ||
| 111 | " .endm\n" | ||
| 112 | " .macro ittee, cond\n" | ||
| 113 | " .endm\n" | ||
| 114 | " .macro itett, cond\n" | ||
| 115 | " .endm\n" | ||
| 116 | " .macro itete, cond\n" | ||
| 117 | " .endm\n" | ||
| 118 | " .macro iteet, cond\n" | ||
| 119 | " .endm\n" | ||
| 120 | " .macro iteee, cond\n" | ||
| 121 | " .endm\n"); | ||
| 122 | #endif /* __ASSEMBLY__ */ | ||
| 123 | |||
| 124 | #endif /* CONFIG_ARM_ASM_UNIFIED */ | ||
| 125 | |||
| 126 | #endif /* !__ASM_UNIFIED_H */ | ||
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 0e97b8cb77d5..9122c9ee18fb 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h | |||
| @@ -360,8 +360,8 @@ | |||
| 360 | #define __NR_readlinkat (__NR_SYSCALL_BASE+332) | 360 | #define __NR_readlinkat (__NR_SYSCALL_BASE+332) |
| 361 | #define __NR_fchmodat (__NR_SYSCALL_BASE+333) | 361 | #define __NR_fchmodat (__NR_SYSCALL_BASE+333) |
| 362 | #define __NR_faccessat (__NR_SYSCALL_BASE+334) | 362 | #define __NR_faccessat (__NR_SYSCALL_BASE+334) |
| 363 | /* 335 for pselect6 */ | 363 | #define __NR_pselect6 (__NR_SYSCALL_BASE+335) |
| 364 | /* 336 for ppoll */ | 364 | #define __NR_ppoll (__NR_SYSCALL_BASE+336) |
| 365 | #define __NR_unshare (__NR_SYSCALL_BASE+337) | 365 | #define __NR_unshare (__NR_SYSCALL_BASE+337) |
| 366 | #define __NR_set_robust_list (__NR_SYSCALL_BASE+338) | 366 | #define __NR_set_robust_list (__NR_SYSCALL_BASE+338) |
| 367 | #define __NR_get_robust_list (__NR_SYSCALL_BASE+339) | 367 | #define __NR_get_robust_list (__NR_SYSCALL_BASE+339) |
| @@ -372,7 +372,7 @@ | |||
| 372 | #define __NR_vmsplice (__NR_SYSCALL_BASE+343) | 372 | #define __NR_vmsplice (__NR_SYSCALL_BASE+343) |
| 373 | #define __NR_move_pages (__NR_SYSCALL_BASE+344) | 373 | #define __NR_move_pages (__NR_SYSCALL_BASE+344) |
| 374 | #define __NR_getcpu (__NR_SYSCALL_BASE+345) | 374 | #define __NR_getcpu (__NR_SYSCALL_BASE+345) |
| 375 | /* 346 for epoll_pwait */ | 375 | #define __NR_epoll_pwait (__NR_SYSCALL_BASE+346) |
| 376 | #define __NR_kexec_load (__NR_SYSCALL_BASE+347) | 376 | #define __NR_kexec_load (__NR_SYSCALL_BASE+347) |
| 377 | #define __NR_utimensat (__NR_SYSCALL_BASE+348) | 377 | #define __NR_utimensat (__NR_SYSCALL_BASE+348) |
| 378 | #define __NR_signalfd (__NR_SYSCALL_BASE+349) | 378 | #define __NR_signalfd (__NR_SYSCALL_BASE+349) |
| @@ -432,6 +432,7 @@ | |||
| 432 | #define __ARCH_WANT_SYS_SIGPENDING | 432 | #define __ARCH_WANT_SYS_SIGPENDING |
| 433 | #define __ARCH_WANT_SYS_SIGPROCMASK | 433 | #define __ARCH_WANT_SYS_SIGPROCMASK |
| 434 | #define __ARCH_WANT_SYS_RT_SIGACTION | 434 | #define __ARCH_WANT_SYS_RT_SIGACTION |
| 435 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | ||
| 435 | 436 | ||
| 436 | #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT) | 437 | #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT) |
| 437 | #define __ARCH_WANT_SYS_TIME | 438 | #define __ARCH_WANT_SYS_TIME |
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index ff89d0b3abc5..3213c9382b17 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
| @@ -8,10 +8,12 @@ ifdef CONFIG_DYNAMIC_FTRACE | |||
| 8 | CFLAGS_REMOVE_ftrace.o = -pg | 8 | CFLAGS_REMOVE_ftrace.o = -pg |
| 9 | endif | 9 | endif |
| 10 | 10 | ||
| 11 | CFLAGS_REMOVE_return_address.o = -pg | ||
| 12 | |||
| 11 | # Object file lists. | 13 | # Object file lists. |
| 12 | 14 | ||
| 13 | obj-y := compat.o elf.o entry-armv.o entry-common.o irq.o \ | 15 | obj-y := compat.o elf.o entry-armv.o entry-common.o irq.o \ |
| 14 | process.o ptrace.o setup.o signal.o \ | 16 | process.o ptrace.o return_address.o setup.o signal.o \ |
| 15 | sys_arm.o stacktrace.o time.o traps.o | 17 | sys_arm.o stacktrace.o time.o traps.o |
| 16 | 18 | ||
| 17 | obj-$(CONFIG_ISA_DMA_API) += dma.o | 19 | obj-$(CONFIG_ISA_DMA_API) += dma.o |
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 531e1860e546..0e627705f746 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c | |||
| @@ -186,4 +186,5 @@ EXPORT_SYMBOL(_find_next_bit_be); | |||
| 186 | 186 | ||
| 187 | #ifdef CONFIG_FUNCTION_TRACER | 187 | #ifdef CONFIG_FUNCTION_TRACER |
| 188 | EXPORT_SYMBOL(mcount); | 188 | EXPORT_SYMBOL(mcount); |
| 189 | EXPORT_SYMBOL(__gnu_mcount_nc); | ||
| 189 | #endif | 190 | #endif |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index f776e72a4cb8..ecfa98954d1d 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
| @@ -81,7 +81,7 @@ | |||
| 81 | CALL(sys_ni_syscall) /* was sys_ssetmask */ | 81 | CALL(sys_ni_syscall) /* was sys_ssetmask */ |
| 82 | /* 70 */ CALL(sys_setreuid16) | 82 | /* 70 */ CALL(sys_setreuid16) |
| 83 | CALL(sys_setregid16) | 83 | CALL(sys_setregid16) |
| 84 | CALL(sys_sigsuspend_wrapper) | 84 | CALL(sys_sigsuspend) |
| 85 | CALL(sys_sigpending) | 85 | CALL(sys_sigpending) |
| 86 | CALL(sys_sethostname) | 86 | CALL(sys_sethostname) |
| 87 | /* 75 */ CALL(sys_setrlimit) | 87 | /* 75 */ CALL(sys_setrlimit) |
| @@ -188,7 +188,7 @@ | |||
| 188 | CALL(sys_rt_sigpending) | 188 | CALL(sys_rt_sigpending) |
| 189 | CALL(sys_rt_sigtimedwait) | 189 | CALL(sys_rt_sigtimedwait) |
| 190 | CALL(sys_rt_sigqueueinfo) | 190 | CALL(sys_rt_sigqueueinfo) |
| 191 | CALL(sys_rt_sigsuspend_wrapper) | 191 | CALL(sys_rt_sigsuspend) |
| 192 | /* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64)) | 192 | /* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64)) |
| 193 | CALL(ABI(sys_pwrite64, sys_oabi_pwrite64)) | 193 | CALL(ABI(sys_pwrite64, sys_oabi_pwrite64)) |
| 194 | CALL(sys_chown16) | 194 | CALL(sys_chown16) |
| @@ -344,8 +344,8 @@ | |||
| 344 | CALL(sys_readlinkat) | 344 | CALL(sys_readlinkat) |
| 345 | CALL(sys_fchmodat) | 345 | CALL(sys_fchmodat) |
| 346 | CALL(sys_faccessat) | 346 | CALL(sys_faccessat) |
| 347 | /* 335 */ CALL(sys_ni_syscall) /* eventually pselect6 */ | 347 | /* 335 */ CALL(sys_pselect6) |
| 348 | CALL(sys_ni_syscall) /* eventually ppoll */ | 348 | CALL(sys_ppoll) |
| 349 | CALL(sys_unshare) | 349 | CALL(sys_unshare) |
| 350 | CALL(sys_set_robust_list) | 350 | CALL(sys_set_robust_list) |
| 351 | CALL(sys_get_robust_list) | 351 | CALL(sys_get_robust_list) |
| @@ -355,7 +355,7 @@ | |||
| 355 | CALL(sys_vmsplice) | 355 | CALL(sys_vmsplice) |
| 356 | CALL(sys_move_pages) | 356 | CALL(sys_move_pages) |
| 357 | /* 345 */ CALL(sys_getcpu) | 357 | /* 345 */ CALL(sys_getcpu) |
| 358 | CALL(sys_ni_syscall) /* eventually epoll_pwait */ | 358 | CALL(sys_epoll_pwait) |
| 359 | CALL(sys_kexec_load) | 359 | CALL(sys_kexec_load) |
| 360 | CALL(sys_utimensat) | 360 | CALL(sys_utimensat) |
| 361 | CALL(sys_signalfd) | 361 | CALL(sys_signalfd) |
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c index 99995c2b2312..769abe15cf91 100644 --- a/arch/arm/kernel/crunch.c +++ b/arch/arm/kernel/crunch.c | |||
| @@ -31,7 +31,7 @@ void crunch_task_release(struct thread_info *thread) | |||
| 31 | 31 | ||
| 32 | static int crunch_enabled(u32 devcfg) | 32 | static int crunch_enabled(u32 devcfg) |
| 33 | { | 33 | { |
| 34 | return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE); | 34 | return !!(devcfg & EP93XX_SYSCON_DEVCFG_CPENA); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) | 37 | static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) |
| @@ -56,11 +56,16 @@ static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) | |||
| 56 | break; | 56 | break; |
| 57 | 57 | ||
| 58 | case THREAD_NOTIFY_SWITCH: | 58 | case THREAD_NOTIFY_SWITCH: |
| 59 | devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); | 59 | devcfg = __raw_readl(EP93XX_SYSCON_DEVCFG); |
| 60 | if (crunch_enabled(devcfg) || crunch_owner == crunch_state) { | 60 | if (crunch_enabled(devcfg) || crunch_owner == crunch_state) { |
| 61 | devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; | 61 | /* |
| 62 | * We don't use ep93xx_syscon_swlocked_write() here | ||
| 63 | * because we are on the context switch path and | ||
| 64 | * preemption is already disabled. | ||
| 65 | */ | ||
| 66 | devcfg ^= EP93XX_SYSCON_DEVCFG_CPENA; | ||
| 62 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | 67 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); |
| 63 | __raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG); | 68 | __raw_writel(devcfg, EP93XX_SYSCON_DEVCFG); |
| 64 | } | 69 | } |
| 65 | break; | 70 | break; |
| 66 | } | 71 | } |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index fc8af43c5000..3d727a8a23bc 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | @ | 34 | @ |
| 35 | @ routine called with r0 = irq number, r1 = struct pt_regs * | 35 | @ routine called with r0 = irq number, r1 = struct pt_regs * |
| 36 | @ | 36 | @ |
| 37 | adrne lr, 1b | 37 | adrne lr, BSYM(1b) |
| 38 | bne asm_do_IRQ | 38 | bne asm_do_IRQ |
| 39 | 39 | ||
| 40 | #ifdef CONFIG_SMP | 40 | #ifdef CONFIG_SMP |
| @@ -46,13 +46,13 @@ | |||
| 46 | */ | 46 | */ |
| 47 | test_for_ipi r0, r6, r5, lr | 47 | test_for_ipi r0, r6, r5, lr |
| 48 | movne r0, sp | 48 | movne r0, sp |
| 49 | adrne lr, 1b | 49 | adrne lr, BSYM(1b) |
| 50 | bne do_IPI | 50 | bne do_IPI |
| 51 | 51 | ||
| 52 | #ifdef CONFIG_LOCAL_TIMERS | 52 | #ifdef CONFIG_LOCAL_TIMERS |
| 53 | test_for_ltirq r0, r6, r5, lr | 53 | test_for_ltirq r0, r6, r5, lr |
| 54 | movne r0, sp | 54 | movne r0, sp |
| 55 | adrne lr, 1b | 55 | adrne lr, BSYM(1b) |
| 56 | bne do_local_timer | 56 | bne do_local_timer |
| 57 | #endif | 57 | #endif |
| 58 | #endif | 58 | #endif |
| @@ -70,7 +70,10 @@ | |||
| 70 | */ | 70 | */ |
| 71 | .macro inv_entry, reason | 71 | .macro inv_entry, reason |
| 72 | sub sp, sp, #S_FRAME_SIZE | 72 | sub sp, sp, #S_FRAME_SIZE |
| 73 | stmib sp, {r1 - lr} | 73 | ARM( stmib sp, {r1 - lr} ) |
| 74 | THUMB( stmia sp, {r0 - r12} ) | ||
| 75 | THUMB( str sp, [sp, #S_SP] ) | ||
| 76 | THUMB( str lr, [sp, #S_LR] ) | ||
| 74 | mov r1, #\reason | 77 | mov r1, #\reason |
| 75 | .endm | 78 | .endm |
| 76 | 79 | ||
| @@ -126,17 +129,24 @@ ENDPROC(__und_invalid) | |||
| 126 | .macro svc_entry, stack_hole=0 | 129 | .macro svc_entry, stack_hole=0 |
| 127 | UNWIND(.fnstart ) | 130 | UNWIND(.fnstart ) |
| 128 | UNWIND(.save {r0 - pc} ) | 131 | UNWIND(.save {r0 - pc} ) |
| 129 | sub sp, sp, #(S_FRAME_SIZE + \stack_hole) | 132 | sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4) |
| 133 | #ifdef CONFIG_THUMB2_KERNEL | ||
| 134 | SPFIX( str r0, [sp] ) @ temporarily saved | ||
| 135 | SPFIX( mov r0, sp ) | ||
| 136 | SPFIX( tst r0, #4 ) @ test original stack alignment | ||
| 137 | SPFIX( ldr r0, [sp] ) @ restored | ||
| 138 | #else | ||
| 130 | SPFIX( tst sp, #4 ) | 139 | SPFIX( tst sp, #4 ) |
| 131 | SPFIX( bicne sp, sp, #4 ) | 140 | #endif |
| 132 | stmib sp, {r1 - r12} | 141 | SPFIX( subeq sp, sp, #4 ) |
| 142 | stmia sp, {r1 - r12} | ||
| 133 | 143 | ||
| 134 | ldmia r0, {r1 - r3} | 144 | ldmia r0, {r1 - r3} |
| 135 | add r5, sp, #S_SP @ here for interlock avoidance | 145 | add r5, sp, #S_SP - 4 @ here for interlock avoidance |
| 136 | mov r4, #-1 @ "" "" "" "" | 146 | mov r4, #-1 @ "" "" "" "" |
| 137 | add r0, sp, #(S_FRAME_SIZE + \stack_hole) | 147 | add r0, sp, #(S_FRAME_SIZE + \stack_hole - 4) |
| 138 | SPFIX( addne r0, r0, #4 ) | 148 | SPFIX( addeq r0, r0, #4 ) |
| 139 | str r1, [sp] @ save the "real" r0 copied | 149 | str r1, [sp, #-4]! @ save the "real" r0 copied |
| 140 | @ from the exception stack | 150 | @ from the exception stack |
| 141 | 151 | ||
| 142 | mov r1, lr | 152 | mov r1, lr |
| @@ -151,6 +161,8 @@ ENDPROC(__und_invalid) | |||
| 151 | @ r4 - orig_r0 (see pt_regs definition in ptrace.h) | 161 | @ r4 - orig_r0 (see pt_regs definition in ptrace.h) |
| 152 | @ | 162 | @ |
| 153 | stmia r5, {r0 - r4} | 163 | stmia r5, {r0 - r4} |
| 164 | |||
| 165 | asm_trace_hardirqs_off | ||
| 154 | .endm | 166 | .endm |
| 155 | 167 | ||
| 156 | .align 5 | 168 | .align 5 |
| @@ -196,9 +208,8 @@ __dabt_svc: | |||
| 196 | @ | 208 | @ |
| 197 | @ restore SPSR and restart the instruction | 209 | @ restore SPSR and restart the instruction |
| 198 | @ | 210 | @ |
| 199 | ldr r0, [sp, #S_PSR] | 211 | ldr r2, [sp, #S_PSR] |
| 200 | msr spsr_cxsf, r0 | 212 | svc_exit r2 @ return from exception |
| 201 | ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr | ||
| 202 | UNWIND(.fnend ) | 213 | UNWIND(.fnend ) |
| 203 | ENDPROC(__dabt_svc) | 214 | ENDPROC(__dabt_svc) |
| 204 | 215 | ||
| @@ -206,9 +217,6 @@ ENDPROC(__dabt_svc) | |||
| 206 | __irq_svc: | 217 | __irq_svc: |
| 207 | svc_entry | 218 | svc_entry |
| 208 | 219 | ||
| 209 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
| 210 | bl trace_hardirqs_off | ||
| 211 | #endif | ||
| 212 | #ifdef CONFIG_PREEMPT | 220 | #ifdef CONFIG_PREEMPT |
| 213 | get_thread_info tsk | 221 | get_thread_info tsk |
| 214 | ldr r8, [tsk, #TI_PREEMPT] @ get preempt count | 222 | ldr r8, [tsk, #TI_PREEMPT] @ get preempt count |
| @@ -225,13 +233,12 @@ __irq_svc: | |||
| 225 | tst r0, #_TIF_NEED_RESCHED | 233 | tst r0, #_TIF_NEED_RESCHED |
| 226 | blne svc_preempt | 234 | blne svc_preempt |
| 227 | #endif | 235 | #endif |
| 228 | ldr r0, [sp, #S_PSR] @ irqs are already disabled | 236 | ldr r4, [sp, #S_PSR] @ irqs are already disabled |
| 229 | msr spsr_cxsf, r0 | ||
| 230 | #ifdef CONFIG_TRACE_IRQFLAGS | 237 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 231 | tst r0, #PSR_I_BIT | 238 | tst r4, #PSR_I_BIT |
| 232 | bleq trace_hardirqs_on | 239 | bleq trace_hardirqs_on |
| 233 | #endif | 240 | #endif |
| 234 | ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr | 241 | svc_exit r4 @ return from exception |
| 235 | UNWIND(.fnend ) | 242 | UNWIND(.fnend ) |
| 236 | ENDPROC(__irq_svc) | 243 | ENDPROC(__irq_svc) |
| 237 | 244 | ||
| @@ -266,7 +273,7 @@ __und_svc: | |||
| 266 | @ r0 - instruction | 273 | @ r0 - instruction |
| 267 | @ | 274 | @ |
| 268 | ldr r0, [r2, #-4] | 275 | ldr r0, [r2, #-4] |
| 269 | adr r9, 1f | 276 | adr r9, BSYM(1f) |
| 270 | bl call_fpe | 277 | bl call_fpe |
| 271 | 278 | ||
| 272 | mov r0, sp @ struct pt_regs *regs | 279 | mov r0, sp @ struct pt_regs *regs |
| @@ -280,9 +287,8 @@ __und_svc: | |||
| 280 | @ | 287 | @ |
| 281 | @ restore SPSR and restart the instruction | 288 | @ restore SPSR and restart the instruction |
| 282 | @ | 289 | @ |
| 283 | ldr lr, [sp, #S_PSR] @ Get SVC cpsr | 290 | ldr r2, [sp, #S_PSR] @ Get SVC cpsr |
| 284 | msr spsr_cxsf, lr | 291 | svc_exit r2 @ return from exception |
| 285 | ldmia sp, {r0 - pc}^ @ Restore SVC registers | ||
| 286 | UNWIND(.fnend ) | 292 | UNWIND(.fnend ) |
| 287 | ENDPROC(__und_svc) | 293 | ENDPROC(__und_svc) |
| 288 | 294 | ||
| @@ -323,9 +329,8 @@ __pabt_svc: | |||
| 323 | @ | 329 | @ |
| 324 | @ restore SPSR and restart the instruction | 330 | @ restore SPSR and restart the instruction |
| 325 | @ | 331 | @ |
| 326 | ldr r0, [sp, #S_PSR] | 332 | ldr r2, [sp, #S_PSR] |
| 327 | msr spsr_cxsf, r0 | 333 | svc_exit r2 @ return from exception |
| 328 | ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr | ||
| 329 | UNWIND(.fnend ) | 334 | UNWIND(.fnend ) |
| 330 | ENDPROC(__pabt_svc) | 335 | ENDPROC(__pabt_svc) |
| 331 | 336 | ||
| @@ -353,7 +358,8 @@ ENDPROC(__pabt_svc) | |||
| 353 | UNWIND(.fnstart ) | 358 | UNWIND(.fnstart ) |
| 354 | UNWIND(.cantunwind ) @ don't unwind the user space | 359 | UNWIND(.cantunwind ) @ don't unwind the user space |
| 355 | sub sp, sp, #S_FRAME_SIZE | 360 | sub sp, sp, #S_FRAME_SIZE |
| 356 | stmib sp, {r1 - r12} | 361 | ARM( stmib sp, {r1 - r12} ) |
| 362 | THUMB( stmia sp, {r0 - r12} ) | ||
| 357 | 363 | ||
| 358 | ldmia r0, {r1 - r3} | 364 | ldmia r0, {r1 - r3} |
| 359 | add r0, sp, #S_PC @ here for interlock avoidance | 365 | add r0, sp, #S_PC @ here for interlock avoidance |
| @@ -372,7 +378,8 @@ ENDPROC(__pabt_svc) | |||
| 372 | @ Also, separately save sp_usr and lr_usr | 378 | @ Also, separately save sp_usr and lr_usr |
| 373 | @ | 379 | @ |
| 374 | stmia r0, {r2 - r4} | 380 | stmia r0, {r2 - r4} |
| 375 | stmdb r0, {sp, lr}^ | 381 | ARM( stmdb r0, {sp, lr}^ ) |
| 382 | THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) | ||
| 376 | 383 | ||
| 377 | @ | 384 | @ |
| 378 | @ Enable the alignment trap while in kernel mode | 385 | @ Enable the alignment trap while in kernel mode |
| @@ -383,6 +390,8 @@ ENDPROC(__pabt_svc) | |||
| 383 | @ Clear FP to mark the first stack frame | 390 | @ Clear FP to mark the first stack frame |
| 384 | @ | 391 | @ |
| 385 | zero_fp | 392 | zero_fp |
| 393 | |||
| 394 | asm_trace_hardirqs_off | ||
| 386 | .endm | 395 | .endm |
| 387 | 396 | ||
| 388 | .macro kuser_cmpxchg_check | 397 | .macro kuser_cmpxchg_check |
| @@ -427,7 +436,7 @@ __dabt_usr: | |||
| 427 | @ | 436 | @ |
| 428 | enable_irq | 437 | enable_irq |
| 429 | mov r2, sp | 438 | mov r2, sp |
| 430 | adr lr, ret_from_exception | 439 | adr lr, BSYM(ret_from_exception) |
| 431 | b do_DataAbort | 440 | b do_DataAbort |
| 432 | UNWIND(.fnend ) | 441 | UNWIND(.fnend ) |
| 433 | ENDPROC(__dabt_usr) | 442 | ENDPROC(__dabt_usr) |
| @@ -437,9 +446,6 @@ __irq_usr: | |||
| 437 | usr_entry | 446 | usr_entry |
| 438 | kuser_cmpxchg_check | 447 | kuser_cmpxchg_check |
| 439 | 448 | ||
| 440 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
| 441 | bl trace_hardirqs_off | ||
| 442 | #endif | ||
| 443 | get_thread_info tsk | 449 | get_thread_info tsk |
| 444 | #ifdef CONFIG_PREEMPT | 450 | #ifdef CONFIG_PREEMPT |
| 445 | ldr r8, [tsk, #TI_PREEMPT] @ get preempt count | 451 | ldr r8, [tsk, #TI_PREEMPT] @ get preempt count |
| @@ -452,7 +458,9 @@ __irq_usr: | |||
| 452 | ldr r0, [tsk, #TI_PREEMPT] | 458 | ldr r0, [tsk, #TI_PREEMPT] |
| 453 | str r8, [tsk, #TI_PREEMPT] | 459 | str r8, [tsk, #TI_PREEMPT] |
| 454 | teq r0, r7 | 460 | teq r0, r7 |
| 455 | strne r0, [r0, -r0] | 461 | ARM( strne r0, [r0, -r0] ) |
| 462 | THUMB( movne r0, #0 ) | ||
| 463 | THUMB( strne r0, [r0] ) | ||
| 456 | #endif | 464 | #endif |
| 457 | #ifdef CONFIG_TRACE_IRQFLAGS | 465 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 458 | bl trace_hardirqs_on | 466 | bl trace_hardirqs_on |
| @@ -476,9 +484,10 @@ __und_usr: | |||
| 476 | @ | 484 | @ |
| 477 | @ r0 - instruction | 485 | @ r0 - instruction |
| 478 | @ | 486 | @ |
| 479 | adr r9, ret_from_exception | 487 | adr r9, BSYM(ret_from_exception) |
| 480 | adr lr, __und_usr_unknown | 488 | adr lr, BSYM(__und_usr_unknown) |
| 481 | tst r3, #PSR_T_BIT @ Thumb mode? | 489 | tst r3, #PSR_T_BIT @ Thumb mode? |
| 490 | itet eq @ explicit IT needed for the 1f label | ||
| 482 | subeq r4, r2, #4 @ ARM instr at LR - 4 | 491 | subeq r4, r2, #4 @ ARM instr at LR - 4 |
| 483 | subne r4, r2, #2 @ Thumb instr at LR - 2 | 492 | subne r4, r2, #2 @ Thumb instr at LR - 2 |
| 484 | 1: ldreqt r0, [r4] | 493 | 1: ldreqt r0, [r4] |
| @@ -488,7 +497,10 @@ __und_usr: | |||
| 488 | beq call_fpe | 497 | beq call_fpe |
| 489 | @ Thumb instruction | 498 | @ Thumb instruction |
| 490 | #if __LINUX_ARM_ARCH__ >= 7 | 499 | #if __LINUX_ARM_ARCH__ >= 7 |
| 491 | 2: ldrht r5, [r4], #2 | 500 | 2: |
| 501 | ARM( ldrht r5, [r4], #2 ) | ||
| 502 | THUMB( ldrht r5, [r4] ) | ||
| 503 | THUMB( add r4, r4, #2 ) | ||
| 492 | and r0, r5, #0xf800 @ mask bits 111x x... .... .... | 504 | and r0, r5, #0xf800 @ mask bits 111x x... .... .... |
| 493 | cmp r0, #0xe800 @ 32bit instruction if xx != 0 | 505 | cmp r0, #0xe800 @ 32bit instruction if xx != 0 |
| 494 | blo __und_usr_unknown | 506 | blo __und_usr_unknown |
| @@ -577,9 +589,11 @@ call_fpe: | |||
| 577 | moveq pc, lr | 589 | moveq pc, lr |
| 578 | get_thread_info r10 @ get current thread | 590 | get_thread_info r10 @ get current thread |
| 579 | and r8, r0, #0x00000f00 @ mask out CP number | 591 | and r8, r0, #0x00000f00 @ mask out CP number |
| 592 | THUMB( lsr r8, r8, #8 ) | ||
| 580 | mov r7, #1 | 593 | mov r7, #1 |
| 581 | add r6, r10, #TI_USED_CP | 594 | add r6, r10, #TI_USED_CP |
| 582 | strb r7, [r6, r8, lsr #8] @ set appropriate used_cp[] | 595 | ARM( strb r7, [r6, r8, lsr #8] ) @ set appropriate used_cp[] |
| 596 | THUMB( strb r7, [r6, r8] ) @ set appropriate used_cp[] | ||
| 583 | #ifdef CONFIG_IWMMXT | 597 | #ifdef CONFIG_IWMMXT |
| 584 | @ Test if we need to give access to iWMMXt coprocessors | 598 | @ Test if we need to give access to iWMMXt coprocessors |
| 585 | ldr r5, [r10, #TI_FLAGS] | 599 | ldr r5, [r10, #TI_FLAGS] |
| @@ -587,36 +601,38 @@ call_fpe: | |||
| 587 | movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1) | 601 | movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1) |
| 588 | bcs iwmmxt_task_enable | 602 | bcs iwmmxt_task_enable |
| 589 | #endif | 603 | #endif |
| 590 | add pc, pc, r8, lsr #6 | 604 | ARM( add pc, pc, r8, lsr #6 ) |
| 591 | mov r0, r0 | 605 | THUMB( lsl r8, r8, #2 ) |
| 592 | 606 | THUMB( add pc, r8 ) | |
| 593 | mov pc, lr @ CP#0 | 607 | nop |
| 594 | b do_fpe @ CP#1 (FPE) | 608 | |
| 595 | b do_fpe @ CP#2 (FPE) | 609 | W(mov) pc, lr @ CP#0 |
| 596 | mov pc, lr @ CP#3 | 610 | W(b) do_fpe @ CP#1 (FPE) |
| 611 | W(b) do_fpe @ CP#2 (FPE) | ||
| 612 | W(mov) pc, lr @ CP#3 | ||
| 597 | #ifdef CONFIG_CRUNCH | 613 | #ifdef CONFIG_CRUNCH |
| 598 | b crunch_task_enable @ CP#4 (MaverickCrunch) | 614 | b crunch_task_enable @ CP#4 (MaverickCrunch) |
| 599 | b crunch_task_enable @ CP#5 (MaverickCrunch) | 615 | b crunch_task_enable @ CP#5 (MaverickCrunch) |
| 600 | b crunch_task_enable @ CP#6 (MaverickCrunch) | 616 | b crunch_task_enable @ CP#6 (MaverickCrunch) |
| 601 | #else | 617 | #else |
| 602 | mov pc, lr @ CP#4 | 618 | W(mov) pc, lr @ CP#4 |
| 603 | mov pc, lr @ CP#5 | 619 | W(mov) pc, lr @ CP#5 |
| 604 | mov pc, lr @ CP#6 | 620 | W(mov) pc, lr @ CP#6 |
| 605 | #endif | 621 | #endif |
| 606 | mov pc, lr @ CP#7 | 622 | W(mov) pc, lr @ CP#7 |
| 607 | mov pc, lr @ CP#8 | 623 | W(mov) pc, lr @ CP#8 |
| 608 | mov pc, lr @ CP#9 | 624 | W(mov) pc, lr @ CP#9 |
| 609 | #ifdef CONFIG_VFP | 625 | #ifdef CONFIG_VFP |
| 610 | b do_vfp @ CP#10 (VFP) | 626 | W(b) do_vfp @ CP#10 (VFP) |
| 611 | b do_vfp @ CP#11 (VFP) | 627 | W(b) do_vfp @ CP#11 (VFP) |
| 612 | #else | 628 | #else |
| 613 | mov pc, lr @ CP#10 (VFP) | 629 | W(mov) pc, lr @ CP#10 (VFP) |
| 614 | mov pc, lr @ CP#11 (VFP) | 630 | W(mov) pc, lr @ CP#11 (VFP) |
| 615 | #endif | 631 | #endif |
| 616 | mov pc, lr @ CP#12 | 632 | W(mov) pc, lr @ CP#12 |
| 617 | mov pc, lr @ CP#13 | 633 | W(mov) pc, lr @ CP#13 |
| 618 | mov pc, lr @ CP#14 (Debug) | 634 | W(mov) pc, lr @ CP#14 (Debug) |
| 619 | mov pc, lr @ CP#15 (Control) | 635 | W(mov) pc, lr @ CP#15 (Control) |
| 620 | 636 | ||
| 621 | #ifdef CONFIG_NEON | 637 | #ifdef CONFIG_NEON |
| 622 | .align 6 | 638 | .align 6 |
| @@ -667,7 +683,7 @@ no_fp: mov pc, lr | |||
| 667 | __und_usr_unknown: | 683 | __und_usr_unknown: |
| 668 | enable_irq | 684 | enable_irq |
| 669 | mov r0, sp | 685 | mov r0, sp |
| 670 | adr lr, ret_from_exception | 686 | adr lr, BSYM(ret_from_exception) |
| 671 | b do_undefinstr | 687 | b do_undefinstr |
| 672 | ENDPROC(__und_usr_unknown) | 688 | ENDPROC(__und_usr_unknown) |
| 673 | 689 | ||
| @@ -711,7 +727,10 @@ ENTRY(__switch_to) | |||
| 711 | UNWIND(.cantunwind ) | 727 | UNWIND(.cantunwind ) |
| 712 | add ip, r1, #TI_CPU_SAVE | 728 | add ip, r1, #TI_CPU_SAVE |
| 713 | ldr r3, [r2, #TI_TP_VALUE] | 729 | ldr r3, [r2, #TI_TP_VALUE] |
| 714 | stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack | 730 | ARM( stmia ip!, {r4 - sl, fp, sp, lr} ) @ Store most regs on stack |
| 731 | THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack | ||
| 732 | THUMB( str sp, [ip], #4 ) | ||
| 733 | THUMB( str lr, [ip], #4 ) | ||
| 715 | #ifdef CONFIG_MMU | 734 | #ifdef CONFIG_MMU |
| 716 | ldr r6, [r2, #TI_CPU_DOMAIN] | 735 | ldr r6, [r2, #TI_CPU_DOMAIN] |
| 717 | #endif | 736 | #endif |
| @@ -736,8 +755,12 @@ ENTRY(__switch_to) | |||
| 736 | ldr r0, =thread_notify_head | 755 | ldr r0, =thread_notify_head |
| 737 | mov r1, #THREAD_NOTIFY_SWITCH | 756 | mov r1, #THREAD_NOTIFY_SWITCH |
| 738 | bl atomic_notifier_call_chain | 757 | bl atomic_notifier_call_chain |
| 758 | THUMB( mov ip, r4 ) | ||
| 739 | mov r0, r5 | 759 | mov r0, r5 |
| 740 | ldmia r4, {r4 - sl, fp, sp, pc} @ Load all regs saved previously | 760 | ARM( ldmia r4, {r4 - sl, fp, sp, pc} ) @ Load all regs saved previously |
| 761 | THUMB( ldmia ip!, {r4 - sl, fp} ) @ Load all regs saved previously | ||
| 762 | THUMB( ldr sp, [ip], #4 ) | ||
| 763 | THUMB( ldr pc, [ip] ) | ||
| 741 | UNWIND(.fnend ) | 764 | UNWIND(.fnend ) |
| 742 | ENDPROC(__switch_to) | 765 | ENDPROC(__switch_to) |
| 743 | 766 | ||
| @@ -772,6 +795,7 @@ ENDPROC(__switch_to) | |||
| 772 | * if your compiled code is not going to use the new instructions for other | 795 | * if your compiled code is not going to use the new instructions for other |
| 773 | * purpose. | 796 | * purpose. |
| 774 | */ | 797 | */ |
| 798 | THUMB( .arm ) | ||
| 775 | 799 | ||
| 776 | .macro usr_ret, reg | 800 | .macro usr_ret, reg |
| 777 | #ifdef CONFIG_ARM_THUMB | 801 | #ifdef CONFIG_ARM_THUMB |
| @@ -1020,6 +1044,7 @@ __kuser_helper_version: @ 0xffff0ffc | |||
| 1020 | .globl __kuser_helper_end | 1044 | .globl __kuser_helper_end |
| 1021 | __kuser_helper_end: | 1045 | __kuser_helper_end: |
| 1022 | 1046 | ||
| 1047 | THUMB( .thumb ) | ||
| 1023 | 1048 | ||
| 1024 | /* | 1049 | /* |
| 1025 | * Vector stubs. | 1050 | * Vector stubs. |
| @@ -1054,17 +1079,23 @@ vector_\name: | |||
| 1054 | @ Prepare for SVC32 mode. IRQs remain disabled. | 1079 | @ Prepare for SVC32 mode. IRQs remain disabled. |
| 1055 | @ | 1080 | @ |
| 1056 | mrs r0, cpsr | 1081 | mrs r0, cpsr |
| 1057 | eor r0, r0, #(\mode ^ SVC_MODE) | 1082 | eor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE) |
| 1058 | msr spsr_cxsf, r0 | 1083 | msr spsr_cxsf, r0 |
| 1059 | 1084 | ||
| 1060 | @ | 1085 | @ |
| 1061 | @ the branch table must immediately follow this code | 1086 | @ the branch table must immediately follow this code |
| 1062 | @ | 1087 | @ |
| 1063 | and lr, lr, #0x0f | 1088 | and lr, lr, #0x0f |
| 1089 | THUMB( adr r0, 1f ) | ||
| 1090 | THUMB( ldr lr, [r0, lr, lsl #2] ) | ||
| 1064 | mov r0, sp | 1091 | mov r0, sp |
| 1065 | ldr lr, [pc, lr, lsl #2] | 1092 | ARM( ldr lr, [pc, lr, lsl #2] ) |
| 1066 | movs pc, lr @ branch to handler in SVC mode | 1093 | movs pc, lr @ branch to handler in SVC mode |
| 1067 | ENDPROC(vector_\name) | 1094 | ENDPROC(vector_\name) |
| 1095 | |||
| 1096 | .align 2 | ||
| 1097 | @ handler addresses follow this label | ||
| 1098 | 1: | ||
| 1068 | .endm | 1099 | .endm |
| 1069 | 1100 | ||
| 1070 | .globl __stubs_start | 1101 | .globl __stubs_start |
| @@ -1202,14 +1233,16 @@ __stubs_end: | |||
| 1202 | 1233 | ||
| 1203 | .globl __vectors_start | 1234 | .globl __vectors_start |
| 1204 | __vectors_start: | 1235 | __vectors_start: |
| 1205 | swi SYS_ERROR0 | 1236 | ARM( swi SYS_ERROR0 ) |
| 1206 | b vector_und + stubs_offset | 1237 | THUMB( svc #0 ) |
| 1207 | ldr pc, .LCvswi + stubs_offset | 1238 | THUMB( nop ) |
| 1208 | b vector_pabt + stubs_offset | 1239 | W(b) vector_und + stubs_offset |
| 1209 | b vector_dabt + stubs_offset | 1240 | W(ldr) pc, .LCvswi + stubs_offset |
| 1210 | b vector_addrexcptn + stubs_offset | 1241 | W(b) vector_pabt + stubs_offset |
| 1211 | b vector_irq + stubs_offset | 1242 | W(b) vector_dabt + stubs_offset |
| 1212 | b vector_fiq + stubs_offset | 1243 | W(b) vector_addrexcptn + stubs_offset |
| 1244 | W(b) vector_irq + stubs_offset | ||
| 1245 | W(b) vector_fiq + stubs_offset | ||
| 1213 | 1246 | ||
| 1214 | .globl __vectors_end | 1247 | .globl __vectors_end |
| 1215 | __vectors_end: | 1248 | __vectors_end: |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 8c3de1a350b5..807cfebb0f44 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
| @@ -33,14 +33,7 @@ ret_fast_syscall: | |||
| 33 | /* perform architecture specific actions before user return */ | 33 | /* perform architecture specific actions before user return */ |
| 34 | arch_ret_to_user r1, lr | 34 | arch_ret_to_user r1, lr |
| 35 | 35 | ||
| 36 | @ fast_restore_user_regs | 36 | restore_user_regs fast = 1, offset = S_OFF |
| 37 | ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr | ||
| 38 | ldr lr, [sp, #S_OFF + S_PC]! @ get pc | ||
| 39 | msr spsr_cxsf, r1 @ save in spsr_svc | ||
| 40 | ldmdb sp, {r1 - lr}^ @ get calling r1 - lr | ||
| 41 | mov r0, r0 | ||
| 42 | add sp, sp, #S_FRAME_SIZE - S_PC | ||
| 43 | movs pc, lr @ return & move spsr_svc into cpsr | ||
| 44 | UNWIND(.fnend ) | 37 | UNWIND(.fnend ) |
| 45 | 38 | ||
| 46 | /* | 39 | /* |
| @@ -51,7 +44,7 @@ fast_work_pending: | |||
| 51 | work_pending: | 44 | work_pending: |
| 52 | tst r1, #_TIF_NEED_RESCHED | 45 | tst r1, #_TIF_NEED_RESCHED |
| 53 | bne work_resched | 46 | bne work_resched |
| 54 | tst r1, #_TIF_SIGPENDING | 47 | tst r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME |
| 55 | beq no_work_pending | 48 | beq no_work_pending |
| 56 | mov r0, sp @ 'regs' | 49 | mov r0, sp @ 'regs' |
| 57 | mov r2, why @ 'syscall' | 50 | mov r2, why @ 'syscall' |
| @@ -73,14 +66,7 @@ no_work_pending: | |||
| 73 | /* perform architecture specific actions before user return */ | 66 | /* perform architecture specific actions before user return */ |
| 74 | arch_ret_to_user r1, lr | 67 | arch_ret_to_user r1, lr |
| 75 | 68 | ||
| 76 | @ slow_restore_user_regs | 69 | restore_user_regs fast = 0, offset = 0 |
| 77 | ldr r1, [sp, #S_PSR] @ get calling cpsr | ||
| 78 | ldr lr, [sp, #S_PC]! @ get pc | ||
| 79 | msr spsr_cxsf, r1 @ save in spsr_svc | ||
| 80 | ldmdb sp, {r0 - lr}^ @ get calling r0 - lr | ||
| 81 | mov r0, r0 | ||
| 82 | add sp, sp, #S_FRAME_SIZE - S_PC | ||
| 83 | movs pc, lr @ return & move spsr_svc into cpsr | ||
| 84 | ENDPROC(ret_to_user) | 70 | ENDPROC(ret_to_user) |
| 85 | 71 | ||
| 86 | /* | 72 | /* |
| @@ -132,6 +118,25 @@ ftrace_call: | |||
| 132 | 118 | ||
| 133 | #else | 119 | #else |
| 134 | 120 | ||
| 121 | ENTRY(__gnu_mcount_nc) | ||
| 122 | stmdb sp!, {r0-r3, lr} | ||
| 123 | ldr r0, =ftrace_trace_function | ||
| 124 | ldr r2, [r0] | ||
| 125 | adr r0, ftrace_stub | ||
| 126 | cmp r0, r2 | ||
| 127 | bne gnu_trace | ||
| 128 | ldmia sp!, {r0-r3, ip, lr} | ||
| 129 | bx ip | ||
| 130 | |||
| 131 | gnu_trace: | ||
| 132 | ldr r1, [sp, #20] @ lr of instrumented routine | ||
| 133 | mov r0, lr | ||
| 134 | sub r0, r0, #MCOUNT_INSN_SIZE | ||
| 135 | mov lr, pc | ||
| 136 | mov pc, r2 | ||
| 137 | ldmia sp!, {r0-r3, ip, lr} | ||
| 138 | bx ip | ||
| 139 | |||
| 135 | ENTRY(mcount) | 140 | ENTRY(mcount) |
| 136 | stmdb sp!, {r0-r3, lr} | 141 | stmdb sp!, {r0-r3, lr} |
| 137 | ldr r0, =ftrace_trace_function | 142 | ldr r0, =ftrace_trace_function |
| @@ -182,8 +187,10 @@ ftrace_stub: | |||
| 182 | ENTRY(vector_swi) | 187 | ENTRY(vector_swi) |
| 183 | sub sp, sp, #S_FRAME_SIZE | 188 | sub sp, sp, #S_FRAME_SIZE |
| 184 | stmia sp, {r0 - r12} @ Calling r0 - r12 | 189 | stmia sp, {r0 - r12} @ Calling r0 - r12 |
| 185 | add r8, sp, #S_PC | 190 | ARM( add r8, sp, #S_PC ) |
| 186 | stmdb r8, {sp, lr}^ @ Calling sp, lr | 191 | ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr |
| 192 | THUMB( mov r8, sp ) | ||
| 193 | THUMB( store_user_sp_lr r8, r10, S_SP ) @ calling sp, lr | ||
| 187 | mrs r8, spsr @ called from non-FIQ mode, so ok. | 194 | mrs r8, spsr @ called from non-FIQ mode, so ok. |
| 188 | str lr, [sp, #S_PC] @ Save calling PC | 195 | str lr, [sp, #S_PC] @ Save calling PC |
| 189 | str r8, [sp, #S_PSR] @ Save CPSR | 196 | str r8, [sp, #S_PSR] @ Save CPSR |
| @@ -272,7 +279,7 @@ ENTRY(vector_swi) | |||
| 272 | bne __sys_trace | 279 | bne __sys_trace |
| 273 | 280 | ||
| 274 | cmp scno, #NR_syscalls @ check upper syscall limit | 281 | cmp scno, #NR_syscalls @ check upper syscall limit |
| 275 | adr lr, ret_fast_syscall @ return address | 282 | adr lr, BSYM(ret_fast_syscall) @ return address |
| 276 | ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine | 283 | ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine |
| 277 | 284 | ||
| 278 | add r1, sp, #S_OFF | 285 | add r1, sp, #S_OFF |
| @@ -293,7 +300,7 @@ __sys_trace: | |||
| 293 | mov r0, #0 @ trace entry [IP = 0] | 300 | mov r0, #0 @ trace entry [IP = 0] |
| 294 | bl syscall_trace | 301 | bl syscall_trace |
| 295 | 302 | ||
| 296 | adr lr, __sys_trace_return @ return address | 303 | adr lr, BSYM(__sys_trace_return) @ return address |
| 297 | mov scno, r0 @ syscall number (possibly new) | 304 | mov scno, r0 @ syscall number (possibly new) |
| 298 | add r1, sp, #S_R0 + S_OFF @ pointer to regs | 305 | add r1, sp, #S_R0 + S_OFF @ pointer to regs |
| 299 | cmp scno, #NR_syscalls @ check upper syscall limit | 306 | cmp scno, #NR_syscalls @ check upper syscall limit |
| @@ -373,16 +380,6 @@ sys_clone_wrapper: | |||
| 373 | b sys_clone | 380 | b sys_clone |
| 374 | ENDPROC(sys_clone_wrapper) | 381 | ENDPROC(sys_clone_wrapper) |
| 375 | 382 | ||
| 376 | sys_sigsuspend_wrapper: | ||
| 377 | add r3, sp, #S_OFF | ||
| 378 | b sys_sigsuspend | ||
| 379 | ENDPROC(sys_sigsuspend_wrapper) | ||
| 380 | |||
| 381 | sys_rt_sigsuspend_wrapper: | ||
| 382 | add r2, sp, #S_OFF | ||
| 383 | b sys_rt_sigsuspend | ||
| 384 | ENDPROC(sys_rt_sigsuspend_wrapper) | ||
| 385 | |||
| 386 | sys_sigreturn_wrapper: | 383 | sys_sigreturn_wrapper: |
| 387 | add r0, sp, #S_OFF | 384 | add r0, sp, #S_OFF |
| 388 | b sys_sigreturn | 385 | b sys_sigreturn |
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 87ab4e157997..a4eaf4f920c5 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S | |||
| @@ -36,11 +36,6 @@ | |||
| 36 | #endif | 36 | #endif |
| 37 | .endm | 37 | .endm |
| 38 | 38 | ||
| 39 | .macro get_thread_info, rd | ||
| 40 | mov \rd, sp, lsr #13 | ||
| 41 | mov \rd, \rd, lsl #13 | ||
| 42 | .endm | ||
| 43 | |||
| 44 | .macro alignment_trap, rtemp | 39 | .macro alignment_trap, rtemp |
| 45 | #ifdef CONFIG_ALIGNMENT_TRAP | 40 | #ifdef CONFIG_ALIGNMENT_TRAP |
| 46 | ldr \rtemp, .LCcralign | 41 | ldr \rtemp, .LCcralign |
| @@ -49,6 +44,93 @@ | |||
| 49 | #endif | 44 | #endif |
| 50 | .endm | 45 | .endm |
| 51 | 46 | ||
| 47 | @ | ||
| 48 | @ Store/load the USER SP and LR registers by switching to the SYS | ||
| 49 | @ mode. Useful in Thumb-2 mode where "stm/ldm rd, {sp, lr}^" is not | ||
| 50 | @ available. Should only be called from SVC mode | ||
| 51 | @ | ||
| 52 | .macro store_user_sp_lr, rd, rtemp, offset = 0 | ||
| 53 | mrs \rtemp, cpsr | ||
| 54 | eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE) | ||
| 55 | msr cpsr_c, \rtemp @ switch to the SYS mode | ||
| 56 | |||
| 57 | str sp, [\rd, #\offset] @ save sp_usr | ||
| 58 | str lr, [\rd, #\offset + 4] @ save lr_usr | ||
| 59 | |||
| 60 | eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE) | ||
| 61 | msr cpsr_c, \rtemp @ switch back to the SVC mode | ||
| 62 | .endm | ||
| 63 | |||
| 64 | .macro load_user_sp_lr, rd, rtemp, offset = 0 | ||
| 65 | mrs \rtemp, cpsr | ||
| 66 | eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE) | ||
| 67 | msr cpsr_c, \rtemp @ switch to the SYS mode | ||
| 68 | |||
| 69 | ldr sp, [\rd, #\offset] @ load sp_usr | ||
| 70 | ldr lr, [\rd, #\offset + 4] @ load lr_usr | ||
| 71 | |||
| 72 | eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE) | ||
| 73 | msr cpsr_c, \rtemp @ switch back to the SVC mode | ||
| 74 | .endm | ||
| 75 | |||
| 76 | #ifndef CONFIG_THUMB2_KERNEL | ||
| 77 | .macro svc_exit, rpsr | ||
| 78 | msr spsr_cxsf, \rpsr | ||
| 79 | ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr | ||
| 80 | .endm | ||
| 81 | |||
| 82 | .macro restore_user_regs, fast = 0, offset = 0 | ||
| 83 | ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr | ||
| 84 | ldr lr, [sp, #\offset + S_PC]! @ get pc | ||
| 85 | msr spsr_cxsf, r1 @ save in spsr_svc | ||
| 86 | .if \fast | ||
| 87 | ldmdb sp, {r1 - lr}^ @ get calling r1 - lr | ||
| 88 | .else | ||
| 89 | ldmdb sp, {r0 - lr}^ @ get calling r0 - lr | ||
| 90 | .endif | ||
| 91 | add sp, sp, #S_FRAME_SIZE - S_PC | ||
| 92 | movs pc, lr @ return & move spsr_svc into cpsr | ||
| 93 | .endm | ||
| 94 | |||
| 95 | .macro get_thread_info, rd | ||
| 96 | mov \rd, sp, lsr #13 | ||
| 97 | mov \rd, \rd, lsl #13 | ||
| 98 | .endm | ||
| 99 | #else /* CONFIG_THUMB2_KERNEL */ | ||
| 100 | .macro svc_exit, rpsr | ||
| 101 | ldr r0, [sp, #S_SP] @ top of the stack | ||
| 102 | ldr r1, [sp, #S_PC] @ return address | ||
| 103 | tst r0, #4 @ orig stack 8-byte aligned? | ||
| 104 | stmdb r0, {r1, \rpsr} @ rfe context | ||
| 105 | ldmia sp, {r0 - r12} | ||
| 106 | ldr lr, [sp, #S_LR] | ||
| 107 | addeq sp, sp, #S_FRAME_SIZE - 8 @ aligned | ||
| 108 | addne sp, sp, #S_FRAME_SIZE - 4 @ not aligned | ||
| 109 | rfeia sp! | ||
| 110 | .endm | ||
| 111 | |||
| 112 | .macro restore_user_regs, fast = 0, offset = 0 | ||
| 113 | mov r2, sp | ||
| 114 | load_user_sp_lr r2, r3, \offset + S_SP @ calling sp, lr | ||
| 115 | ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr | ||
| 116 | ldr lr, [sp, #\offset + S_PC] @ get pc | ||
| 117 | add sp, sp, #\offset + S_SP | ||
| 118 | msr spsr_cxsf, r1 @ save in spsr_svc | ||
| 119 | .if \fast | ||
| 120 | ldmdb sp, {r1 - r12} @ get calling r1 - r12 | ||
| 121 | .else | ||
| 122 | ldmdb sp, {r0 - r12} @ get calling r0 - r12 | ||
| 123 | .endif | ||
| 124 | add sp, sp, #S_FRAME_SIZE - S_SP | ||
| 125 | movs pc, lr @ return & move spsr_svc into cpsr | ||
| 126 | .endm | ||
| 127 | |||
| 128 | .macro get_thread_info, rd | ||
| 129 | mov \rd, sp | ||
| 130 | lsr \rd, \rd, #13 | ||
| 131 | mov \rd, \rd, lsl #13 | ||
| 132 | .endm | ||
| 133 | #endif /* !CONFIG_THUMB2_KERNEL */ | ||
| 52 | 134 | ||
| 53 | /* | 135 | /* |
| 54 | * These are the registers used in the syscall handler, and allow us to | 136 | * These are the registers used in the syscall handler, and allow us to |
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 991952c644d1..93ad576b2d74 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #define ATAG_CORE 0x54410001 | 14 | #define ATAG_CORE 0x54410001 |
| 15 | #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) | 15 | #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) |
| 16 | 16 | ||
| 17 | .align 2 | ||
| 17 | .type __switch_data, %object | 18 | .type __switch_data, %object |
| 18 | __switch_data: | 19 | __switch_data: |
| 19 | .long __mmap_switched | 20 | .long __mmap_switched |
| @@ -51,7 +52,9 @@ __mmap_switched: | |||
| 51 | strcc fp, [r6],#4 | 52 | strcc fp, [r6],#4 |
| 52 | bcc 1b | 53 | bcc 1b |
| 53 | 54 | ||
| 54 | ldmia r3, {r4, r5, r6, r7, sp} | 55 | ARM( ldmia r3, {r4, r5, r6, r7, sp}) |
| 56 | THUMB( ldmia r3, {r4, r5, r6, r7} ) | ||
| 57 | THUMB( ldr sp, [r3, #16] ) | ||
| 55 | str r9, [r4] @ Save processor ID | 58 | str r9, [r4] @ Save processor ID |
| 56 | str r1, [r5] @ Save machine type | 59 | str r1, [r5] @ Save machine type |
| 57 | str r2, [r6] @ Save atags pointer | 60 | str r2, [r6] @ Save atags pointer |
| @@ -155,7 +158,8 @@ ENDPROC(__error) | |||
| 155 | */ | 158 | */ |
| 156 | __lookup_processor_type: | 159 | __lookup_processor_type: |
| 157 | adr r3, 3f | 160 | adr r3, 3f |
| 158 | ldmda r3, {r5 - r7} | 161 | ldmia r3, {r5 - r7} |
| 162 | add r3, r3, #8 | ||
| 159 | sub r3, r3, r7 @ get offset between virt&phys | 163 | sub r3, r3, r7 @ get offset between virt&phys |
| 160 | add r5, r5, r3 @ convert virt addresses to | 164 | add r5, r5, r3 @ convert virt addresses to |
| 161 | add r6, r6, r3 @ physical address space | 165 | add r6, r6, r3 @ physical address space |
| @@ -185,9 +189,10 @@ ENDPROC(lookup_processor_type) | |||
| 185 | * Look in <asm/procinfo.h> and arch/arm/kernel/arch.[ch] for | 189 | * Look in <asm/procinfo.h> and arch/arm/kernel/arch.[ch] for |
| 186 | * more information about the __proc_info and __arch_info structures. | 190 | * more information about the __proc_info and __arch_info structures. |
| 187 | */ | 191 | */ |
| 188 | .long __proc_info_begin | 192 | .align 2 |
| 193 | 3: .long __proc_info_begin | ||
| 189 | .long __proc_info_end | 194 | .long __proc_info_end |
| 190 | 3: .long . | 195 | 4: .long . |
| 191 | .long __arch_info_begin | 196 | .long __arch_info_begin |
| 192 | .long __arch_info_end | 197 | .long __arch_info_end |
| 193 | 198 | ||
| @@ -203,7 +208,7 @@ ENDPROC(lookup_processor_type) | |||
| 203 | * r5 = mach_info pointer in physical address space | 208 | * r5 = mach_info pointer in physical address space |
| 204 | */ | 209 | */ |
| 205 | __lookup_machine_type: | 210 | __lookup_machine_type: |
| 206 | adr r3, 3b | 211 | adr r3, 4b |
| 207 | ldmia r3, {r4, r5, r6} | 212 | ldmia r3, {r4, r5, r6} |
| 208 | sub r3, r3, r4 @ get offset between virt&phys | 213 | sub r3, r3, r4 @ get offset between virt&phys |
| 209 | add r5, r5, r3 @ convert virt addresses to | 214 | add r5, r5, r3 @ convert virt addresses to |
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index cc87e1765ed2..e5dfc2895e24 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | */ | 34 | */ |
| 35 | .section ".text.head", "ax" | 35 | .section ".text.head", "ax" |
| 36 | ENTRY(stext) | 36 | ENTRY(stext) |
| 37 | msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode | 37 | setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode |
| 38 | @ and irqs disabled | 38 | @ and irqs disabled |
| 39 | #ifndef CONFIG_CPU_CP15 | 39 | #ifndef CONFIG_CPU_CP15 |
| 40 | ldr r9, =CONFIG_PROCESSOR_ID | 40 | ldr r9, =CONFIG_PROCESSOR_ID |
| @@ -50,8 +50,10 @@ ENTRY(stext) | |||
| 50 | 50 | ||
| 51 | ldr r13, __switch_data @ address to jump to after | 51 | ldr r13, __switch_data @ address to jump to after |
| 52 | @ the initialization is done | 52 | @ the initialization is done |
| 53 | adr lr, __after_proc_init @ return (PIC) address | 53 | adr lr, BSYM(__after_proc_init) @ return (PIC) address |
| 54 | add pc, r10, #PROCINFO_INITFUNC | 54 | ARM( add pc, r10, #PROCINFO_INITFUNC ) |
| 55 | THUMB( add r12, r10, #PROCINFO_INITFUNC ) | ||
| 56 | THUMB( mov pc, r12 ) | ||
| 55 | ENDPROC(stext) | 57 | ENDPROC(stext) |
| 56 | 58 | ||
| 57 | /* | 59 | /* |
| @@ -59,7 +61,10 @@ ENDPROC(stext) | |||
| 59 | */ | 61 | */ |
| 60 | __after_proc_init: | 62 | __after_proc_init: |
| 61 | #ifdef CONFIG_CPU_CP15 | 63 | #ifdef CONFIG_CPU_CP15 |
| 62 | mrc p15, 0, r0, c1, c0, 0 @ read control reg | 64 | /* |
| 65 | * CP15 system control register value returned in r0 from | ||
| 66 | * the CPU init function. | ||
| 67 | */ | ||
| 63 | #ifdef CONFIG_ALIGNMENT_TRAP | 68 | #ifdef CONFIG_ALIGNMENT_TRAP |
| 64 | orr r0, r0, #CR_A | 69 | orr r0, r0, #CR_A |
| 65 | #else | 70 | #else |
| @@ -82,7 +87,8 @@ __after_proc_init: | |||
| 82 | mcr p15, 0, r0, c1, c0, 0 @ write control reg | 87 | mcr p15, 0, r0, c1, c0, 0 @ write control reg |
| 83 | #endif /* CONFIG_CPU_CP15 */ | 88 | #endif /* CONFIG_CPU_CP15 */ |
| 84 | 89 | ||
| 85 | mov pc, r13 @ clear the BSS and jump | 90 | mov r3, r13 |
| 91 | mov pc, r3 @ clear the BSS and jump | ||
| 86 | @ to start_kernel | 92 | @ to start_kernel |
| 87 | ENDPROC(__after_proc_init) | 93 | ENDPROC(__after_proc_init) |
| 88 | .ltorg | 94 | .ltorg |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 21e17dc94cb5..38ccbe1d3b2c 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
| @@ -76,7 +76,7 @@ | |||
| 76 | */ | 76 | */ |
| 77 | .section ".text.head", "ax" | 77 | .section ".text.head", "ax" |
| 78 | ENTRY(stext) | 78 | ENTRY(stext) |
| 79 | msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode | 79 | setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode |
| 80 | @ and irqs disabled | 80 | @ and irqs disabled |
| 81 | mrc p15, 0, r9, c0, c0 @ get processor id | 81 | mrc p15, 0, r9, c0, c0 @ get processor id |
| 82 | bl __lookup_processor_type @ r5=procinfo r9=cpuid | 82 | bl __lookup_processor_type @ r5=procinfo r9=cpuid |
| @@ -97,8 +97,10 @@ ENTRY(stext) | |||
| 97 | */ | 97 | */ |
| 98 | ldr r13, __switch_data @ address to jump to after | 98 | ldr r13, __switch_data @ address to jump to after |
| 99 | @ mmu has been enabled | 99 | @ mmu has been enabled |
| 100 | adr lr, __enable_mmu @ return (PIC) address | 100 | adr lr, BSYM(__enable_mmu) @ return (PIC) address |
| 101 | add pc, r10, #PROCINFO_INITFUNC | 101 | ARM( add pc, r10, #PROCINFO_INITFUNC ) |
| 102 | THUMB( add r12, r10, #PROCINFO_INITFUNC ) | ||
| 103 | THUMB( mov pc, r12 ) | ||
| 102 | ENDPROC(stext) | 104 | ENDPROC(stext) |
| 103 | 105 | ||
| 104 | #if defined(CONFIG_SMP) | 106 | #if defined(CONFIG_SMP) |
| @@ -110,7 +112,7 @@ ENTRY(secondary_startup) | |||
| 110 | * the processor type - there is no need to check the machine type | 112 | * the processor type - there is no need to check the machine type |
| 111 | * as it has already been validated by the primary processor. | 113 | * as it has already been validated by the primary processor. |
| 112 | */ | 114 | */ |
| 113 | msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE | 115 | setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 |
| 114 | mrc p15, 0, r9, c0, c0 @ get processor id | 116 | mrc p15, 0, r9, c0, c0 @ get processor id |
| 115 | bl __lookup_processor_type | 117 | bl __lookup_processor_type |
| 116 | movs r10, r5 @ invalid processor? | 118 | movs r10, r5 @ invalid processor? |
| @@ -121,12 +123,15 @@ ENTRY(secondary_startup) | |||
| 121 | * Use the page tables supplied from __cpu_up. | 123 | * Use the page tables supplied from __cpu_up. |
| 122 | */ | 124 | */ |
| 123 | adr r4, __secondary_data | 125 | adr r4, __secondary_data |
| 124 | ldmia r4, {r5, r7, r13} @ address to jump to after | 126 | ldmia r4, {r5, r7, r12} @ address to jump to after |
| 125 | sub r4, r4, r5 @ mmu has been enabled | 127 | sub r4, r4, r5 @ mmu has been enabled |
| 126 | ldr r4, [r7, r4] @ get secondary_data.pgdir | 128 | ldr r4, [r7, r4] @ get secondary_data.pgdir |
| 127 | adr lr, __enable_mmu @ return address | 129 | adr lr, BSYM(__enable_mmu) @ return address |
| 128 | add pc, r10, #PROCINFO_INITFUNC @ initialise processor | 130 | mov r13, r12 @ __secondary_switched address |
| 129 | @ (return control reg) | 131 | ARM( add pc, r10, #PROCINFO_INITFUNC ) @ initialise processor |
| 132 | @ (return control reg) | ||
| 133 | THUMB( add r12, r10, #PROCINFO_INITFUNC ) | ||
| 134 | THUMB( mov pc, r12 ) | ||
| 130 | ENDPROC(secondary_startup) | 135 | ENDPROC(secondary_startup) |
| 131 | 136 | ||
| 132 | /* | 137 | /* |
| @@ -193,8 +198,8 @@ __turn_mmu_on: | |||
| 193 | mcr p15, 0, r0, c1, c0, 0 @ write control reg | 198 | mcr p15, 0, r0, c1, c0, 0 @ write control reg |
| 194 | mrc p15, 0, r3, c0, c0, 0 @ read id reg | 199 | mrc p15, 0, r3, c0, c0, 0 @ read id reg |
| 195 | mov r3, r3 | 200 | mov r3, r3 |
| 196 | mov r3, r3 | 201 | mov r3, r13 |
| 197 | mov pc, r13 | 202 | mov pc, r3 |
| 198 | ENDPROC(__turn_mmu_on) | 203 | ENDPROC(__turn_mmu_on) |
| 199 | 204 | ||
| 200 | 205 | ||
| @@ -235,7 +240,8 @@ __create_page_tables: | |||
| 235 | * will be removed by paging_init(). We use our current program | 240 | * will be removed by paging_init(). We use our current program |
| 236 | * counter to determine corresponding section base address. | 241 | * counter to determine corresponding section base address. |
| 237 | */ | 242 | */ |
| 238 | mov r6, pc, lsr #20 @ start of kernel section | 243 | mov r6, pc |
| 244 | mov r6, r6, lsr #20 @ start of kernel section | ||
| 239 | orr r3, r7, r6, lsl #20 @ flags + kernel base | 245 | orr r3, r7, r6, lsl #20 @ flags + kernel base |
| 240 | str r3, [r4, r6, lsl #2] @ identity mapping | 246 | str r3, [r4, r6, lsl #2] @ identity mapping |
| 241 | 247 | ||
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index b7c3490eaa24..c9a8619f3856 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c | |||
| @@ -86,7 +86,7 @@ int show_interrupts(struct seq_file *p, void *v) | |||
| 86 | unlock: | 86 | unlock: |
| 87 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | 87 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); |
| 88 | } else if (i == NR_IRQS) { | 88 | } else if (i == NR_IRQS) { |
| 89 | #ifdef CONFIG_ARCH_ACORN | 89 | #ifdef CONFIG_FIQ |
| 90 | show_fiq_list(p, v); | 90 | show_fiq_list(p, v); |
| 91 | #endif | 91 | #endif |
| 92 | #ifdef CONFIG_SMP | 92 | #ifdef CONFIG_SMP |
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index bac03c81489d..f28c5e9c51ea 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c | |||
| @@ -102,6 +102,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, | |||
| 102 | unsigned long loc; | 102 | unsigned long loc; |
| 103 | Elf32_Sym *sym; | 103 | Elf32_Sym *sym; |
| 104 | s32 offset; | 104 | s32 offset; |
| 105 | u32 upper, lower, sign, j1, j2; | ||
| 105 | 106 | ||
| 106 | offset = ELF32_R_SYM(rel->r_info); | 107 | offset = ELF32_R_SYM(rel->r_info); |
| 107 | if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { | 108 | if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { |
| @@ -184,6 +185,58 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, | |||
| 184 | (offset & 0x0fff); | 185 | (offset & 0x0fff); |
| 185 | break; | 186 | break; |
| 186 | 187 | ||
| 188 | case R_ARM_THM_CALL: | ||
| 189 | case R_ARM_THM_JUMP24: | ||
| 190 | upper = *(u16 *)loc; | ||
| 191 | lower = *(u16 *)(loc + 2); | ||
| 192 | |||
| 193 | /* | ||
| 194 | * 25 bit signed address range (Thumb-2 BL and B.W | ||
| 195 | * instructions): | ||
| 196 | * S:I1:I2:imm10:imm11:0 | ||
| 197 | * where: | ||
| 198 | * S = upper[10] = offset[24] | ||
| 199 | * I1 = ~(J1 ^ S) = offset[23] | ||
| 200 | * I2 = ~(J2 ^ S) = offset[22] | ||
| 201 | * imm10 = upper[9:0] = offset[21:12] | ||
| 202 | * imm11 = lower[10:0] = offset[11:1] | ||
| 203 | * J1 = lower[13] | ||
| 204 | * J2 = lower[11] | ||
| 205 | */ | ||
| 206 | sign = (upper >> 10) & 1; | ||
| 207 | j1 = (lower >> 13) & 1; | ||
| 208 | j2 = (lower >> 11) & 1; | ||
| 209 | offset = (sign << 24) | ((~(j1 ^ sign) & 1) << 23) | | ||
| 210 | ((~(j2 ^ sign) & 1) << 22) | | ||
| 211 | ((upper & 0x03ff) << 12) | | ||
| 212 | ((lower & 0x07ff) << 1); | ||
| 213 | if (offset & 0x01000000) | ||
| 214 | offset -= 0x02000000; | ||
| 215 | offset += sym->st_value - loc; | ||
| 216 | |||
| 217 | /* only Thumb addresses allowed (no interworking) */ | ||
| 218 | if (!(offset & 1) || | ||
| 219 | offset <= (s32)0xff000000 || | ||
| 220 | offset >= (s32)0x01000000) { | ||
| 221 | printk(KERN_ERR | ||
| 222 | "%s: relocation out of range, section " | ||
| 223 | "%d reloc %d sym '%s'\n", module->name, | ||
| 224 | relindex, i, strtab + sym->st_name); | ||
| 225 | return -ENOEXEC; | ||
| 226 | } | ||
| 227 | |||
| 228 | sign = (offset >> 24) & 1; | ||
| 229 | j1 = sign ^ (~(offset >> 23) & 1); | ||
| 230 | j2 = sign ^ (~(offset >> 22) & 1); | ||
| 231 | *(u16 *)loc = (u16)((upper & 0xf800) | (sign << 10) | | ||
| 232 | ((offset >> 12) & 0x03ff)); | ||
| 233 | *(u16 *)(loc + 2) = (u16)((lower & 0xd000) | | ||
| 234 | (j1 << 13) | (j2 << 11) | | ||
| 235 | ((offset >> 1) & 0x07ff)); | ||
| 236 | upper = *(u16 *)loc; | ||
| 237 | lower = *(u16 *)(loc + 2); | ||
| 238 | break; | ||
| 239 | |||
| 187 | default: | 240 | default: |
| 188 | printk(KERN_ERR "%s: unknown relocation: %u\n", | 241 | printk(KERN_ERR "%s: unknown relocation: %u\n", |
| 189 | module->name, ELF32_R_TYPE(rel->r_info)); | 242 | module->name, ELF32_R_TYPE(rel->r_info)); |
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 39196dff478c..790fbee92ec5 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
| @@ -388,7 +388,7 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | |||
| 388 | regs.ARM_r2 = (unsigned long)fn; | 388 | regs.ARM_r2 = (unsigned long)fn; |
| 389 | regs.ARM_r3 = (unsigned long)kernel_thread_exit; | 389 | regs.ARM_r3 = (unsigned long)kernel_thread_exit; |
| 390 | regs.ARM_pc = (unsigned long)kernel_thread_helper; | 390 | regs.ARM_pc = (unsigned long)kernel_thread_helper; |
| 391 | regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE; | 391 | regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE; |
| 392 | 392 | ||
| 393 | return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | 393 | return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); |
| 394 | } | 394 | } |
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 89882a1d0187..a2ea3854cb3c 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
| @@ -521,7 +521,13 @@ static int ptrace_read_user(struct task_struct *tsk, unsigned long off, | |||
| 521 | return -EIO; | 521 | return -EIO; |
| 522 | 522 | ||
| 523 | tmp = 0; | 523 | tmp = 0; |
| 524 | if (off < sizeof(struct pt_regs)) | 524 | if (off == PT_TEXT_ADDR) |
| 525 | tmp = tsk->mm->start_code; | ||
| 526 | else if (off == PT_DATA_ADDR) | ||
| 527 | tmp = tsk->mm->start_data; | ||
| 528 | else if (off == PT_TEXT_END_ADDR) | ||
| 529 | tmp = tsk->mm->end_code; | ||
| 530 | else if (off < sizeof(struct pt_regs)) | ||
| 525 | tmp = get_user_reg(tsk, off >> 2); | 531 | tmp = get_user_reg(tsk, off >> 2); |
| 526 | 532 | ||
| 527 | return put_user(tmp, ret); | 533 | return put_user(tmp, ret); |
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c new file mode 100644 index 000000000000..df246da4ceca --- /dev/null +++ b/arch/arm/kernel/return_address.c | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/kernel/return_address.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> | ||
| 5 | * for Pengutronix | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License version 2 as published by | ||
| 9 | * the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | #include <linux/module.h> | ||
| 12 | |||
| 13 | #if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) | ||
| 14 | #include <linux/sched.h> | ||
| 15 | |||
| 16 | #include <asm/stacktrace.h> | ||
| 17 | |||
| 18 | struct return_address_data { | ||
| 19 | unsigned int level; | ||
| 20 | void *addr; | ||
| 21 | }; | ||
| 22 | |||
| 23 | static int save_return_addr(struct stackframe *frame, void *d) | ||
| 24 | { | ||
| 25 | struct return_address_data *data = d; | ||
| 26 | |||
| 27 | if (!data->level) { | ||
| 28 | data->addr = (void *)frame->lr; | ||
| 29 | |||
| 30 | return 1; | ||
| 31 | } else { | ||
| 32 | --data->level; | ||
| 33 | return 0; | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 37 | void *return_address(unsigned int level) | ||
| 38 | { | ||
| 39 | struct return_address_data data; | ||
| 40 | struct stackframe frame; | ||
| 41 | register unsigned long current_sp asm ("sp"); | ||
| 42 | |||
| 43 | data.level = level + 1; | ||
| 44 | |||
| 45 | frame.fp = (unsigned long)__builtin_frame_address(0); | ||
| 46 | frame.sp = current_sp; | ||
| 47 | frame.lr = (unsigned long)__builtin_return_address(0); | ||
| 48 | frame.pc = (unsigned long)return_address; | ||
| 49 | |||
| 50 | walk_stackframe(&frame, save_return_addr, &data); | ||
| 51 | |||
| 52 | if (!data.level) | ||
| 53 | return data.addr; | ||
| 54 | else | ||
| 55 | return NULL; | ||
| 56 | } | ||
| 57 | |||
| 58 | #else /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */ | ||
| 59 | |||
| 60 | #if defined(CONFIG_ARM_UNWIND) | ||
| 61 | #warning "TODO: return_address should use unwind tables" | ||
| 62 | #endif | ||
| 63 | |||
| 64 | void *return_address(unsigned int level) | ||
| 65 | { | ||
| 66 | return NULL; | ||
| 67 | } | ||
| 68 | |||
| 69 | #endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) / else */ | ||
| 70 | |||
| 71 | EXPORT_SYMBOL_GPL(return_address); | ||
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index bc5e4128f9f3..d4d4f77c91b2 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/smp.h> | 25 | #include <linux/smp.h> |
| 26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
| 27 | 27 | ||
| 28 | #include <asm/unified.h> | ||
| 28 | #include <asm/cpu.h> | 29 | #include <asm/cpu.h> |
| 29 | #include <asm/cputype.h> | 30 | #include <asm/cputype.h> |
| 30 | #include <asm/elf.h> | 31 | #include <asm/elf.h> |
| @@ -327,25 +328,38 @@ void cpu_init(void) | |||
| 327 | } | 328 | } |
| 328 | 329 | ||
| 329 | /* | 330 | /* |
| 331 | * Define the placement constraint for the inline asm directive below. | ||
| 332 | * In Thumb-2, msr with an immediate value is not allowed. | ||
| 333 | */ | ||
| 334 | #ifdef CONFIG_THUMB2_KERNEL | ||
| 335 | #define PLC "r" | ||
| 336 | #else | ||
| 337 | #define PLC "I" | ||
| 338 | #endif | ||
| 339 | |||
| 340 | /* | ||
| 330 | * setup stacks for re-entrant exception handlers | 341 | * setup stacks for re-entrant exception handlers |
| 331 | */ | 342 | */ |
| 332 | __asm__ ( | 343 | __asm__ ( |
| 333 | "msr cpsr_c, %1\n\t" | 344 | "msr cpsr_c, %1\n\t" |
| 334 | "add sp, %0, %2\n\t" | 345 | "add r14, %0, %2\n\t" |
| 346 | "mov sp, r14\n\t" | ||
| 335 | "msr cpsr_c, %3\n\t" | 347 | "msr cpsr_c, %3\n\t" |
| 336 | "add sp, %0, %4\n\t" | 348 | "add r14, %0, %4\n\t" |
| 349 | "mov sp, r14\n\t" | ||
| 337 | "msr cpsr_c, %5\n\t" | 350 | "msr cpsr_c, %5\n\t" |
| 338 | "add sp, %0, %6\n\t" | 351 | "add r14, %0, %6\n\t" |
| 352 | "mov sp, r14\n\t" | ||
| 339 | "msr cpsr_c, %7" | 353 | "msr cpsr_c, %7" |
| 340 | : | 354 | : |
| 341 | : "r" (stk), | 355 | : "r" (stk), |
| 342 | "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE), | 356 | PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE), |
| 343 | "I" (offsetof(struct stack, irq[0])), | 357 | "I" (offsetof(struct stack, irq[0])), |
| 344 | "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE), | 358 | PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE), |
| 345 | "I" (offsetof(struct stack, abt[0])), | 359 | "I" (offsetof(struct stack, abt[0])), |
| 346 | "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE), | 360 | PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE), |
| 347 | "I" (offsetof(struct stack, und[0])), | 361 | "I" (offsetof(struct stack, und[0])), |
| 348 | "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE) | 362 | PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE) |
| 349 | : "r14"); | 363 | : "r14"); |
| 350 | } | 364 | } |
| 351 | 365 | ||
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index f6bc5d442782..1423a3419789 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/personality.h> | 12 | #include <linux/personality.h> |
| 13 | #include <linux/freezer.h> | 13 | #include <linux/freezer.h> |
| 14 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
| 15 | #include <linux/tracehook.h> | ||
| 15 | 16 | ||
| 16 | #include <asm/elf.h> | 17 | #include <asm/elf.h> |
| 17 | #include <asm/cacheflush.h> | 18 | #include <asm/cacheflush.h> |
| @@ -47,57 +48,22 @@ const unsigned long sigreturn_codes[7] = { | |||
| 47 | MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, | 48 | MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, |
| 48 | }; | 49 | }; |
| 49 | 50 | ||
| 50 | static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall); | ||
| 51 | |||
| 52 | /* | 51 | /* |
| 53 | * atomically swap in the new signal mask, and wait for a signal. | 52 | * atomically swap in the new signal mask, and wait for a signal. |
| 54 | */ | 53 | */ |
| 55 | asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs) | 54 | asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) |
| 56 | { | 55 | { |
| 57 | sigset_t saveset; | ||
| 58 | |||
| 59 | mask &= _BLOCKABLE; | 56 | mask &= _BLOCKABLE; |
| 60 | spin_lock_irq(¤t->sighand->siglock); | 57 | spin_lock_irq(¤t->sighand->siglock); |
| 61 | saveset = current->blocked; | 58 | current->saved_sigmask = current->blocked; |
| 62 | siginitset(¤t->blocked, mask); | 59 | siginitset(¤t->blocked, mask); |
| 63 | recalc_sigpending(); | 60 | recalc_sigpending(); |
| 64 | spin_unlock_irq(¤t->sighand->siglock); | 61 | spin_unlock_irq(¤t->sighand->siglock); |
| 65 | regs->ARM_r0 = -EINTR; | ||
| 66 | 62 | ||
| 67 | while (1) { | 63 | current->state = TASK_INTERRUPTIBLE; |
| 68 | current->state = TASK_INTERRUPTIBLE; | 64 | schedule(); |
| 69 | schedule(); | 65 | set_restore_sigmask(); |
| 70 | if (do_signal(&saveset, regs, 0)) | 66 | return -ERESTARTNOHAND; |
| 71 | return regs->ARM_r0; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | asmlinkage int | ||
| 76 | sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs) | ||
| 77 | { | ||
| 78 | sigset_t saveset, newset; | ||
| 79 | |||
| 80 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
| 81 | if (sigsetsize != sizeof(sigset_t)) | ||
| 82 | return -EINVAL; | ||
| 83 | |||
| 84 | if (copy_from_user(&newset, unewset, sizeof(newset))) | ||
| 85 | return -EFAULT; | ||
| 86 | sigdelsetmask(&newset, ~_BLOCKABLE); | ||
| 87 | |||
| 88 | spin_lock_irq(¤t->sighand->siglock); | ||
| 89 | saveset = current->blocked; | ||
| 90 | current->blocked = newset; | ||
| 91 | recalc_sigpending(); | ||
| 92 | spin_unlock_irq(¤t->sighand->siglock); | ||
| 93 | regs->ARM_r0 = -EINTR; | ||
| 94 | |||
| 95 | while (1) { | ||
| 96 | current->state = TASK_INTERRUPTIBLE; | ||
| 97 | schedule(); | ||
| 98 | if (do_signal(&saveset, regs, 0)) | ||
| 99 | return regs->ARM_r0; | ||
| 100 | } | ||
| 101 | } | 67 | } |
| 102 | 68 | ||
| 103 | asmlinkage int | 69 | asmlinkage int |
| @@ -545,7 +511,7 @@ static inline void setup_syscall_restart(struct pt_regs *regs) | |||
| 545 | /* | 511 | /* |
| 546 | * OK, we're invoking a handler | 512 | * OK, we're invoking a handler |
| 547 | */ | 513 | */ |
| 548 | static void | 514 | static int |
| 549 | handle_signal(unsigned long sig, struct k_sigaction *ka, | 515 | handle_signal(unsigned long sig, struct k_sigaction *ka, |
| 550 | siginfo_t *info, sigset_t *oldset, | 516 | siginfo_t *info, sigset_t *oldset, |
| 551 | struct pt_regs * regs, int syscall) | 517 | struct pt_regs * regs, int syscall) |
| @@ -596,7 +562,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
| 596 | 562 | ||
| 597 | if (ret != 0) { | 563 | if (ret != 0) { |
| 598 | force_sigsegv(sig, tsk); | 564 | force_sigsegv(sig, tsk); |
| 599 | return; | 565 | return ret; |
| 600 | } | 566 | } |
| 601 | 567 | ||
| 602 | /* | 568 | /* |
| @@ -610,6 +576,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
| 610 | recalc_sigpending(); | 576 | recalc_sigpending(); |
| 611 | spin_unlock_irq(&tsk->sighand->siglock); | 577 | spin_unlock_irq(&tsk->sighand->siglock); |
| 612 | 578 | ||
| 579 | return 0; | ||
| 613 | } | 580 | } |
| 614 | 581 | ||
| 615 | /* | 582 | /* |
| @@ -621,7 +588,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
| 621 | * the kernel can handle, and then we build all the user-level signal handling | 588 | * the kernel can handle, and then we build all the user-level signal handling |
| 622 | * stack-frames in one go after that. | 589 | * stack-frames in one go after that. |
| 623 | */ | 590 | */ |
| 624 | static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) | 591 | static void do_signal(struct pt_regs *regs, int syscall) |
| 625 | { | 592 | { |
| 626 | struct k_sigaction ka; | 593 | struct k_sigaction ka; |
| 627 | siginfo_t info; | 594 | siginfo_t info; |
| @@ -634,7 +601,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) | |||
| 634 | * if so. | 601 | * if so. |
| 635 | */ | 602 | */ |
| 636 | if (!user_mode(regs)) | 603 | if (!user_mode(regs)) |
| 637 | return 0; | 604 | return; |
| 638 | 605 | ||
| 639 | if (try_to_freeze()) | 606 | if (try_to_freeze()) |
| 640 | goto no_signal; | 607 | goto no_signal; |
| @@ -643,9 +610,24 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) | |||
| 643 | 610 | ||
| 644 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 611 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
| 645 | if (signr > 0) { | 612 | if (signr > 0) { |
| 646 | handle_signal(signr, &ka, &info, oldset, regs, syscall); | 613 | sigset_t *oldset; |
| 614 | |||
| 615 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
| 616 | oldset = ¤t->saved_sigmask; | ||
| 617 | else | ||
| 618 | oldset = ¤t->blocked; | ||
| 619 | if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) { | ||
| 620 | /* | ||
| 621 | * A signal was successfully delivered; the saved | ||
| 622 | * sigmask will have been stored in the signal frame, | ||
| 623 | * and will be restored by sigreturn, so we can simply | ||
| 624 | * clear the TIF_RESTORE_SIGMASK flag. | ||
| 625 | */ | ||
| 626 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
| 627 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 628 | } | ||
| 647 | single_step_set(current); | 629 | single_step_set(current); |
| 648 | return 1; | 630 | return; |
| 649 | } | 631 | } |
| 650 | 632 | ||
| 651 | no_signal: | 633 | no_signal: |
| @@ -697,14 +679,28 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) | |||
| 697 | regs->ARM_r0 == -ERESTARTNOINTR) { | 679 | regs->ARM_r0 == -ERESTARTNOINTR) { |
| 698 | setup_syscall_restart(regs); | 680 | setup_syscall_restart(regs); |
| 699 | } | 681 | } |
| 682 | |||
| 683 | /* If there's no signal to deliver, we just put the saved sigmask | ||
| 684 | * back. | ||
| 685 | */ | ||
| 686 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
| 687 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 688 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
| 689 | } | ||
| 700 | } | 690 | } |
| 701 | single_step_set(current); | 691 | single_step_set(current); |
| 702 | return 0; | ||
| 703 | } | 692 | } |
| 704 | 693 | ||
| 705 | asmlinkage void | 694 | asmlinkage void |
| 706 | do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) | 695 | do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) |
| 707 | { | 696 | { |
| 708 | if (thread_flags & _TIF_SIGPENDING) | 697 | if (thread_flags & _TIF_SIGPENDING) |
| 709 | do_signal(¤t->blocked, regs, syscall); | 698 | do_signal(regs, syscall); |
| 699 | |||
| 700 | if (thread_flags & _TIF_NOTIFY_RESUME) { | ||
| 701 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
| 702 | tracehook_notify_resume(regs); | ||
| 703 | if (current->replacement_session_keyring) | ||
| 704 | key_replace_session_keyring(); | ||
| 705 | } | ||
| 710 | } | 706 | } |
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index 9f444e5cc165..20b7411e47fd 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | * Note that with framepointer enabled, even the leaf functions have the same | 21 | * Note that with framepointer enabled, even the leaf functions have the same |
| 22 | * prologue and epilogue, therefore we can ignore the LR value in this case. | 22 | * prologue and epilogue, therefore we can ignore the LR value in this case. |
| 23 | */ | 23 | */ |
| 24 | int unwind_frame(struct stackframe *frame) | 24 | int notrace unwind_frame(struct stackframe *frame) |
| 25 | { | 25 | { |
| 26 | unsigned long high, low; | 26 | unsigned long high, low; |
| 27 | unsigned long fp = frame->fp; | 27 | unsigned long fp = frame->fp; |
| @@ -43,7 +43,7 @@ int unwind_frame(struct stackframe *frame) | |||
| 43 | } | 43 | } |
| 44 | #endif | 44 | #endif |
| 45 | 45 | ||
| 46 | void walk_stackframe(struct stackframe *frame, | 46 | void notrace walk_stackframe(struct stackframe *frame, |
| 47 | int (*fn)(struct stackframe *, void *), void *data) | 47 | int (*fn)(struct stackframe *, void *), void *data) |
| 48 | { | 48 | { |
| 49 | while (1) { | 49 | while (1) { |
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index dd56e11f339a..39baf1128bfa 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c | |||
| @@ -62,7 +62,11 @@ struct unwind_ctrl_block { | |||
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | enum regs { | 64 | enum regs { |
| 65 | #ifdef CONFIG_THUMB2_KERNEL | ||
| 66 | FP = 7, | ||
| 67 | #else | ||
| 65 | FP = 11, | 68 | FP = 11, |
| 69 | #endif | ||
| 66 | SP = 13, | 70 | SP = 13, |
| 67 | LR = 14, | 71 | LR = 14, |
| 68 | PC = 15 | 72 | PC = 15 |
diff --git a/arch/arm/lib/ashldi3.S b/arch/arm/lib/ashldi3.S index 1154d924080b..638deb13da1c 100644 --- a/arch/arm/lib/ashldi3.S +++ b/arch/arm/lib/ashldi3.S | |||
| @@ -43,7 +43,9 @@ ENTRY(__aeabi_llsl) | |||
| 43 | rsb ip, r2, #32 | 43 | rsb ip, r2, #32 |
| 44 | movmi ah, ah, lsl r2 | 44 | movmi ah, ah, lsl r2 |
| 45 | movpl ah, al, lsl r3 | 45 | movpl ah, al, lsl r3 |
| 46 | orrmi ah, ah, al, lsr ip | 46 | ARM( orrmi ah, ah, al, lsr ip ) |
| 47 | THUMB( lsrmi r3, al, ip ) | ||
| 48 | THUMB( orrmi ah, ah, r3 ) | ||
| 47 | mov al, al, lsl r2 | 49 | mov al, al, lsl r2 |
| 48 | mov pc, lr | 50 | mov pc, lr |
| 49 | 51 | ||
diff --git a/arch/arm/lib/ashrdi3.S b/arch/arm/lib/ashrdi3.S index 9f8b35572f8c..015e8aa5a1d1 100644 --- a/arch/arm/lib/ashrdi3.S +++ b/arch/arm/lib/ashrdi3.S | |||
| @@ -43,7 +43,9 @@ ENTRY(__aeabi_lasr) | |||
| 43 | rsb ip, r2, #32 | 43 | rsb ip, r2, #32 |
| 44 | movmi al, al, lsr r2 | 44 | movmi al, al, lsr r2 |
| 45 | movpl al, ah, asr r3 | 45 | movpl al, ah, asr r3 |
| 46 | orrmi al, al, ah, lsl ip | 46 | ARM( orrmi al, al, ah, lsl ip ) |
| 47 | THUMB( lslmi r3, ah, ip ) | ||
| 48 | THUMB( orrmi al, al, r3 ) | ||
| 47 | mov ah, ah, asr r2 | 49 | mov ah, ah, asr r2 |
| 48 | mov pc, lr | 50 | mov pc, lr |
| 49 | 51 | ||
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S index b0951d0e8b2c..aaf7220d9e30 100644 --- a/arch/arm/lib/backtrace.S +++ b/arch/arm/lib/backtrace.S | |||
| @@ -38,7 +38,9 @@ ENDPROC(c_backtrace) | |||
| 38 | beq no_frame @ we have no stack frames | 38 | beq no_frame @ we have no stack frames |
| 39 | 39 | ||
| 40 | tst r1, #0x10 @ 26 or 32-bit mode? | 40 | tst r1, #0x10 @ 26 or 32-bit mode? |
| 41 | moveq mask, #0xfc000003 @ mask for 26-bit | 41 | ARM( moveq mask, #0xfc000003 ) |
| 42 | THUMB( moveq mask, #0xfc000000 ) | ||
| 43 | THUMB( orreq mask, #0x03 ) | ||
| 42 | movne mask, #0 @ mask for 32-bit | 44 | movne mask, #0 @ mask for 32-bit |
| 43 | 45 | ||
| 44 | 1: stmfd sp!, {pc} @ calculate offset of PC stored | 46 | 1: stmfd sp!, {pc} @ calculate offset of PC stored |
| @@ -126,7 +128,9 @@ ENDPROC(c_backtrace) | |||
| 126 | mov reg, #10 | 128 | mov reg, #10 |
| 127 | mov r7, #0 | 129 | mov r7, #0 |
| 128 | 1: mov r3, #1 | 130 | 1: mov r3, #1 |
| 129 | tst instr, r3, lsl reg | 131 | ARM( tst instr, r3, lsl reg ) |
| 132 | THUMB( lsl r3, reg ) | ||
| 133 | THUMB( tst instr, r3 ) | ||
| 130 | beq 2f | 134 | beq 2f |
| 131 | add r7, r7, #1 | 135 | add r7, r7, #1 |
| 132 | teq r7, #6 | 136 | teq r7, #6 |
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h index c7f2627385e7..d42252918bfb 100644 --- a/arch/arm/lib/bitops.h +++ b/arch/arm/lib/bitops.h | |||
| @@ -60,8 +60,8 @@ | |||
| 60 | tst r2, r0, lsl r3 | 60 | tst r2, r0, lsl r3 |
| 61 | \instr r2, r2, r0, lsl r3 | 61 | \instr r2, r2, r0, lsl r3 |
| 62 | \store r2, [r1] | 62 | \store r2, [r1] |
| 63 | restore_irqs ip | ||
| 64 | moveq r0, #0 | 63 | moveq r0, #0 |
| 64 | restore_irqs ip | ||
| 65 | mov pc, lr | 65 | mov pc, lr |
| 66 | .endm | 66 | .endm |
| 67 | #endif | 67 | #endif |
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S index 844f56785ebc..1279abd8b886 100644 --- a/arch/arm/lib/clear_user.S +++ b/arch/arm/lib/clear_user.S | |||
| @@ -27,21 +27,20 @@ WEAK(__clear_user) | |||
| 27 | ands ip, r0, #3 | 27 | ands ip, r0, #3 |
| 28 | beq 1f | 28 | beq 1f |
| 29 | cmp ip, #2 | 29 | cmp ip, #2 |
| 30 | USER( strbt r2, [r0], #1) | 30 | strusr r2, r0, 1 |
| 31 | USER( strlebt r2, [r0], #1) | 31 | strusr r2, r0, 1, le |
| 32 | USER( strltbt r2, [r0], #1) | 32 | strusr r2, r0, 1, lt |
| 33 | rsb ip, ip, #4 | 33 | rsb ip, ip, #4 |
| 34 | sub r1, r1, ip @ 7 6 5 4 3 2 1 | 34 | sub r1, r1, ip @ 7 6 5 4 3 2 1 |
| 35 | 1: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7 | 35 | 1: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7 |
| 36 | USER( strplt r2, [r0], #4) | 36 | strusr r2, r0, 4, pl, rept=2 |
| 37 | USER( strplt r2, [r0], #4) | ||
| 38 | bpl 1b | 37 | bpl 1b |
| 39 | adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3 | 38 | adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3 |
| 40 | USER( strplt r2, [r0], #4) | 39 | strusr r2, r0, 4, pl |
| 41 | 2: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x | 40 | 2: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x |
| 42 | USER( strnebt r2, [r0], #1) | 41 | strusr r2, r0, 1, ne, rept=2 |
| 43 | USER( strnebt r2, [r0], #1) | ||
| 44 | tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1 | 42 | tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1 |
| 43 | it ne @ explicit IT needed for the label | ||
| 45 | USER( strnebt r2, [r0]) | 44 | USER( strnebt r2, [r0]) |
| 46 | mov r0, #0 | 45 | mov r0, #0 |
| 47 | ldmfd sp!, {r1, pc} | 46 | ldmfd sp!, {r1, pc} |
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S index 56799a165cc4..e4fe124acedc 100644 --- a/arch/arm/lib/copy_from_user.S +++ b/arch/arm/lib/copy_from_user.S | |||
| @@ -33,11 +33,15 @@ | |||
| 33 | * Number of bytes NOT copied. | 33 | * Number of bytes NOT copied. |
| 34 | */ | 34 | */ |
| 35 | 35 | ||
| 36 | #ifndef CONFIG_THUMB2_KERNEL | ||
| 37 | #define LDR1W_SHIFT 0 | ||
| 38 | #else | ||
| 39 | #define LDR1W_SHIFT 1 | ||
| 40 | #endif | ||
| 41 | #define STR1W_SHIFT 0 | ||
| 42 | |||
| 36 | .macro ldr1w ptr reg abort | 43 | .macro ldr1w ptr reg abort |
| 37 | 100: ldrt \reg, [\ptr], #4 | 44 | ldrusr \reg, \ptr, 4, abort=\abort |
| 38 | .section __ex_table, "a" | ||
| 39 | .long 100b, \abort | ||
| 40 | .previous | ||
| 41 | .endm | 45 | .endm |
| 42 | 46 | ||
| 43 | .macro ldr4w ptr reg1 reg2 reg3 reg4 abort | 47 | .macro ldr4w ptr reg1 reg2 reg3 reg4 abort |
| @@ -53,14 +57,11 @@ | |||
| 53 | .endm | 57 | .endm |
| 54 | 58 | ||
| 55 | .macro ldr1b ptr reg cond=al abort | 59 | .macro ldr1b ptr reg cond=al abort |
| 56 | 100: ldr\cond\()bt \reg, [\ptr], #1 | 60 | ldrusr \reg, \ptr, 1, \cond, abort=\abort |
| 57 | .section __ex_table, "a" | ||
| 58 | .long 100b, \abort | ||
| 59 | .previous | ||
| 60 | .endm | 61 | .endm |
| 61 | 62 | ||
| 62 | .macro str1w ptr reg abort | 63 | .macro str1w ptr reg abort |
| 63 | str \reg, [\ptr], #4 | 64 | W(str) \reg, [\ptr], #4 |
| 64 | .endm | 65 | .endm |
| 65 | 66 | ||
| 66 | .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort | 67 | .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort |
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S index 139cce646055..805e3f8fb007 100644 --- a/arch/arm/lib/copy_template.S +++ b/arch/arm/lib/copy_template.S | |||
| @@ -57,6 +57,13 @@ | |||
| 57 | * | 57 | * |
| 58 | * Restore registers with the values previously saved with the | 58 | * Restore registers with the values previously saved with the |
| 59 | * 'preserv' macro. Called upon code termination. | 59 | * 'preserv' macro. Called upon code termination. |
| 60 | * | ||
| 61 | * LDR1W_SHIFT | ||
| 62 | * STR1W_SHIFT | ||
| 63 | * | ||
| 64 | * Correction to be applied to the "ip" register when branching into | ||
| 65 | * the ldr1w or str1w instructions (some of these macros may expand to | ||
| 66 | * than one 32bit instruction in Thumb-2) | ||
| 60 | */ | 67 | */ |
| 61 | 68 | ||
| 62 | 69 | ||
| @@ -99,9 +106,15 @@ | |||
| 99 | 106 | ||
| 100 | 5: ands ip, r2, #28 | 107 | 5: ands ip, r2, #28 |
| 101 | rsb ip, ip, #32 | 108 | rsb ip, ip, #32 |
| 109 | #if LDR1W_SHIFT > 0 | ||
| 110 | lsl ip, ip, #LDR1W_SHIFT | ||
| 111 | #endif | ||
| 102 | addne pc, pc, ip @ C is always clear here | 112 | addne pc, pc, ip @ C is always clear here |
| 103 | b 7f | 113 | b 7f |
| 104 | 6: nop | 114 | 6: |
| 115 | .rept (1 << LDR1W_SHIFT) | ||
| 116 | W(nop) | ||
| 117 | .endr | ||
| 105 | ldr1w r1, r3, abort=20f | 118 | ldr1w r1, r3, abort=20f |
| 106 | ldr1w r1, r4, abort=20f | 119 | ldr1w r1, r4, abort=20f |
| 107 | ldr1w r1, r5, abort=20f | 120 | ldr1w r1, r5, abort=20f |
| @@ -110,9 +123,16 @@ | |||
| 110 | ldr1w r1, r8, abort=20f | 123 | ldr1w r1, r8, abort=20f |
| 111 | ldr1w r1, lr, abort=20f | 124 | ldr1w r1, lr, abort=20f |
| 112 | 125 | ||
| 126 | #if LDR1W_SHIFT < STR1W_SHIFT | ||
| 127 | lsl ip, ip, #STR1W_SHIFT - LDR1W_SHIFT | ||
| 128 | #elif LDR1W_SHIFT > STR1W_SHIFT | ||
| 129 | lsr ip, ip, #LDR1W_SHIFT - STR1W_SHIFT | ||
| 130 | #endif | ||
| 113 | add pc, pc, ip | 131 | add pc, pc, ip |
| 114 | nop | 132 | nop |
| 115 | nop | 133 | .rept (1 << STR1W_SHIFT) |
| 134 | W(nop) | ||
| 135 | .endr | ||
| 116 | str1w r0, r3, abort=20f | 136 | str1w r0, r3, abort=20f |
| 117 | str1w r0, r4, abort=20f | 137 | str1w r0, r4, abort=20f |
| 118 | str1w r0, r5, abort=20f | 138 | str1w r0, r5, abort=20f |
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S index 878820f0a320..1a71e1584442 100644 --- a/arch/arm/lib/copy_to_user.S +++ b/arch/arm/lib/copy_to_user.S | |||
| @@ -33,8 +33,15 @@ | |||
| 33 | * Number of bytes NOT copied. | 33 | * Number of bytes NOT copied. |
| 34 | */ | 34 | */ |
| 35 | 35 | ||
| 36 | #define LDR1W_SHIFT 0 | ||
| 37 | #ifndef CONFIG_THUMB2_KERNEL | ||
| 38 | #define STR1W_SHIFT 0 | ||
| 39 | #else | ||
| 40 | #define STR1W_SHIFT 1 | ||
| 41 | #endif | ||
| 42 | |||
| 36 | .macro ldr1w ptr reg abort | 43 | .macro ldr1w ptr reg abort |
| 37 | ldr \reg, [\ptr], #4 | 44 | W(ldr) \reg, [\ptr], #4 |
| 38 | .endm | 45 | .endm |
| 39 | 46 | ||
| 40 | .macro ldr4w ptr reg1 reg2 reg3 reg4 abort | 47 | .macro ldr4w ptr reg1 reg2 reg3 reg4 abort |
| @@ -50,10 +57,7 @@ | |||
| 50 | .endm | 57 | .endm |
| 51 | 58 | ||
| 52 | .macro str1w ptr reg abort | 59 | .macro str1w ptr reg abort |
| 53 | 100: strt \reg, [\ptr], #4 | 60 | strusr \reg, \ptr, 4, abort=\abort |
| 54 | .section __ex_table, "a" | ||
| 55 | .long 100b, \abort | ||
| 56 | .previous | ||
| 57 | .endm | 61 | .endm |
| 58 | 62 | ||
| 59 | .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort | 63 | .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort |
| @@ -68,10 +72,7 @@ | |||
| 68 | .endm | 72 | .endm |
| 69 | 73 | ||
| 70 | .macro str1b ptr reg cond=al abort | 74 | .macro str1b ptr reg cond=al abort |
| 71 | 100: str\cond\()bt \reg, [\ptr], #1 | 75 | strusr \reg, \ptr, 1, \cond, abort=\abort |
| 72 | .section __ex_table, "a" | ||
| 73 | .long 100b, \abort | ||
| 74 | .previous | ||
| 75 | .endm | 76 | .endm |
| 76 | 77 | ||
| 77 | .macro enter reg1 reg2 | 78 | .macro enter reg1 reg2 |
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S index 14677fb4b0c4..fd0e9dcd9fdc 100644 --- a/arch/arm/lib/csumpartialcopyuser.S +++ b/arch/arm/lib/csumpartialcopyuser.S | |||
| @@ -26,50 +26,28 @@ | |||
| 26 | .endm | 26 | .endm |
| 27 | 27 | ||
| 28 | .macro load1b, reg1 | 28 | .macro load1b, reg1 |
| 29 | 9999: ldrbt \reg1, [r0], $1 | 29 | ldrusr \reg1, r0, 1 |
| 30 | .section __ex_table, "a" | ||
| 31 | .align 3 | ||
| 32 | .long 9999b, 6001f | ||
| 33 | .previous | ||
| 34 | .endm | 30 | .endm |
| 35 | 31 | ||
| 36 | .macro load2b, reg1, reg2 | 32 | .macro load2b, reg1, reg2 |
| 37 | 9999: ldrbt \reg1, [r0], $1 | 33 | ldrusr \reg1, r0, 1 |
| 38 | 9998: ldrbt \reg2, [r0], $1 | 34 | ldrusr \reg2, r0, 1 |
| 39 | .section __ex_table, "a" | ||
| 40 | .long 9999b, 6001f | ||
| 41 | .long 9998b, 6001f | ||
| 42 | .previous | ||
| 43 | .endm | 35 | .endm |
| 44 | 36 | ||
| 45 | .macro load1l, reg1 | 37 | .macro load1l, reg1 |
| 46 | 9999: ldrt \reg1, [r0], $4 | 38 | ldrusr \reg1, r0, 4 |
| 47 | .section __ex_table, "a" | ||
| 48 | .align 3 | ||
| 49 | .long 9999b, 6001f | ||
| 50 | .previous | ||
| 51 | .endm | 39 | .endm |
| 52 | 40 | ||
| 53 | .macro load2l, reg1, reg2 | 41 | .macro load2l, reg1, reg2 |
| 54 | 9999: ldrt \reg1, [r0], $4 | 42 | ldrusr \reg1, r0, 4 |
| 55 | 9998: ldrt \reg2, [r0], $4 | 43 | ldrusr \reg2, r0, 4 |
| 56 | .section __ex_table, "a" | ||
| 57 | .long 9999b, 6001f | ||
| 58 | .long 9998b, 6001f | ||
| 59 | .previous | ||
| 60 | .endm | 44 | .endm |
| 61 | 45 | ||
| 62 | .macro load4l, reg1, reg2, reg3, reg4 | 46 | .macro load4l, reg1, reg2, reg3, reg4 |
| 63 | 9999: ldrt \reg1, [r0], $4 | 47 | ldrusr \reg1, r0, 4 |
| 64 | 9998: ldrt \reg2, [r0], $4 | 48 | ldrusr \reg2, r0, 4 |
| 65 | 9997: ldrt \reg3, [r0], $4 | 49 | ldrusr \reg3, r0, 4 |
| 66 | 9996: ldrt \reg4, [r0], $4 | 50 | ldrusr \reg4, r0, 4 |
| 67 | .section __ex_table, "a" | ||
| 68 | .long 9999b, 6001f | ||
| 69 | .long 9998b, 6001f | ||
| 70 | .long 9997b, 6001f | ||
| 71 | .long 9996b, 6001f | ||
| 72 | .previous | ||
| 73 | .endm | 51 | .endm |
| 74 | 52 | ||
| 75 | /* | 53 | /* |
| @@ -92,14 +70,14 @@ | |||
| 92 | */ | 70 | */ |
| 93 | .section .fixup,"ax" | 71 | .section .fixup,"ax" |
| 94 | .align 4 | 72 | .align 4 |
| 95 | 6001: mov r4, #-EFAULT | 73 | 9001: mov r4, #-EFAULT |
| 96 | ldr r5, [fp, #4] @ *err_ptr | 74 | ldr r5, [fp, #4] @ *err_ptr |
| 97 | str r4, [r5] | 75 | str r4, [r5] |
| 98 | ldmia sp, {r1, r2} @ retrieve dst, len | 76 | ldmia sp, {r1, r2} @ retrieve dst, len |
| 99 | add r2, r2, r1 | 77 | add r2, r2, r1 |
| 100 | mov r0, #0 @ zero the buffer | 78 | mov r0, #0 @ zero the buffer |
| 101 | 6002: teq r2, r1 | 79 | 9002: teq r2, r1 |
| 102 | strneb r0, [r1], #1 | 80 | strneb r0, [r1], #1 |
| 103 | bne 6002b | 81 | bne 9002b |
| 104 | load_regs | 82 | load_regs |
| 105 | .previous | 83 | .previous |
diff --git a/arch/arm/lib/div64.S b/arch/arm/lib/div64.S index 1425e789ba86..faa7748142da 100644 --- a/arch/arm/lib/div64.S +++ b/arch/arm/lib/div64.S | |||
| @@ -177,7 +177,9 @@ ENTRY(__do_div64) | |||
| 177 | mov yh, xh, lsr ip | 177 | mov yh, xh, lsr ip |
| 178 | mov yl, xl, lsr ip | 178 | mov yl, xl, lsr ip |
| 179 | rsb ip, ip, #32 | 179 | rsb ip, ip, #32 |
| 180 | orr yl, yl, xh, lsl ip | 180 | ARM( orr yl, yl, xh, lsl ip ) |
| 181 | THUMB( lsl xh, xh, ip ) | ||
| 182 | THUMB( orr yl, yl, xh ) | ||
| 181 | mov xh, xl, lsl ip | 183 | mov xh, xl, lsl ip |
| 182 | mov xh, xh, lsr ip | 184 | mov xh, xh, lsr ip |
| 183 | mov pc, lr | 185 | mov pc, lr |
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S index 8c4defc4f3c4..1e4cbd4e7be9 100644 --- a/arch/arm/lib/findbit.S +++ b/arch/arm/lib/findbit.S | |||
| @@ -25,7 +25,10 @@ ENTRY(_find_first_zero_bit_le) | |||
| 25 | teq r1, #0 | 25 | teq r1, #0 |
| 26 | beq 3f | 26 | beq 3f |
| 27 | mov r2, #0 | 27 | mov r2, #0 |
| 28 | 1: ldrb r3, [r0, r2, lsr #3] | 28 | 1: |
| 29 | ARM( ldrb r3, [r0, r2, lsr #3] ) | ||
| 30 | THUMB( lsr r3, r2, #3 ) | ||
| 31 | THUMB( ldrb r3, [r0, r3] ) | ||
| 29 | eors r3, r3, #0xff @ invert bits | 32 | eors r3, r3, #0xff @ invert bits |
| 30 | bne .L_found @ any now set - found zero bit | 33 | bne .L_found @ any now set - found zero bit |
| 31 | add r2, r2, #8 @ next bit pointer | 34 | add r2, r2, #8 @ next bit pointer |
| @@ -44,7 +47,9 @@ ENTRY(_find_next_zero_bit_le) | |||
| 44 | beq 3b | 47 | beq 3b |
| 45 | ands ip, r2, #7 | 48 | ands ip, r2, #7 |
| 46 | beq 1b @ If new byte, goto old routine | 49 | beq 1b @ If new byte, goto old routine |
| 47 | ldrb r3, [r0, r2, lsr #3] | 50 | ARM( ldrb r3, [r0, r2, lsr #3] ) |
| 51 | THUMB( lsr r3, r2, #3 ) | ||
| 52 | THUMB( ldrb r3, [r0, r3] ) | ||
| 48 | eor r3, r3, #0xff @ now looking for a 1 bit | 53 | eor r3, r3, #0xff @ now looking for a 1 bit |
| 49 | movs r3, r3, lsr ip @ shift off unused bits | 54 | movs r3, r3, lsr ip @ shift off unused bits |
| 50 | bne .L_found | 55 | bne .L_found |
| @@ -61,7 +66,10 @@ ENTRY(_find_first_bit_le) | |||
| 61 | teq r1, #0 | 66 | teq r1, #0 |
| 62 | beq 3f | 67 | beq 3f |
| 63 | mov r2, #0 | 68 | mov r2, #0 |
| 64 | 1: ldrb r3, [r0, r2, lsr #3] | 69 | 1: |
| 70 | ARM( ldrb r3, [r0, r2, lsr #3] ) | ||
| 71 | THUMB( lsr r3, r2, #3 ) | ||
| 72 | THUMB( ldrb r3, [r0, r3] ) | ||
| 65 | movs r3, r3 | 73 | movs r3, r3 |
| 66 | bne .L_found @ any now set - found zero bit | 74 | bne .L_found @ any now set - found zero bit |
| 67 | add r2, r2, #8 @ next bit pointer | 75 | add r2, r2, #8 @ next bit pointer |
| @@ -80,7 +88,9 @@ ENTRY(_find_next_bit_le) | |||
| 80 | beq 3b | 88 | beq 3b |
| 81 | ands ip, r2, #7 | 89 | ands ip, r2, #7 |
| 82 | beq 1b @ If new byte, goto old routine | 90 | beq 1b @ If new byte, goto old routine |
| 83 | ldrb r3, [r0, r2, lsr #3] | 91 | ARM( ldrb r3, [r0, r2, lsr #3] ) |
| 92 | THUMB( lsr r3, r2, #3 ) | ||
| 93 | THUMB( ldrb r3, [r0, r3] ) | ||
| 84 | movs r3, r3, lsr ip @ shift off unused bits | 94 | movs r3, r3, lsr ip @ shift off unused bits |
| 85 | bne .L_found | 95 | bne .L_found |
| 86 | orr r2, r2, #7 @ if zero, then no bits here | 96 | orr r2, r2, #7 @ if zero, then no bits here |
| @@ -95,7 +105,9 @@ ENTRY(_find_first_zero_bit_be) | |||
| 95 | beq 3f | 105 | beq 3f |
| 96 | mov r2, #0 | 106 | mov r2, #0 |
| 97 | 1: eor r3, r2, #0x18 @ big endian byte ordering | 107 | 1: eor r3, r2, #0x18 @ big endian byte ordering |
| 98 | ldrb r3, [r0, r3, lsr #3] | 108 | ARM( ldrb r3, [r0, r3, lsr #3] ) |
| 109 | THUMB( lsr r3, #3 ) | ||
| 110 | THUMB( ldrb r3, [r0, r3] ) | ||
| 99 | eors r3, r3, #0xff @ invert bits | 111 | eors r3, r3, #0xff @ invert bits |
| 100 | bne .L_found @ any now set - found zero bit | 112 | bne .L_found @ any now set - found zero bit |
| 101 | add r2, r2, #8 @ next bit pointer | 113 | add r2, r2, #8 @ next bit pointer |
| @@ -111,7 +123,9 @@ ENTRY(_find_next_zero_bit_be) | |||
| 111 | ands ip, r2, #7 | 123 | ands ip, r2, #7 |
| 112 | beq 1b @ If new byte, goto old routine | 124 | beq 1b @ If new byte, goto old routine |
| 113 | eor r3, r2, #0x18 @ big endian byte ordering | 125 | eor r3, r2, #0x18 @ big endian byte ordering |
| 114 | ldrb r3, [r0, r3, lsr #3] | 126 | ARM( ldrb r3, [r0, r3, lsr #3] ) |
| 127 | THUMB( lsr r3, #3 ) | ||
| 128 | THUMB( ldrb r3, [r0, r3] ) | ||
| 115 | eor r3, r3, #0xff @ now looking for a 1 bit | 129 | eor r3, r3, #0xff @ now looking for a 1 bit |
| 116 | movs r3, r3, lsr ip @ shift off unused bits | 130 | movs r3, r3, lsr ip @ shift off unused bits |
| 117 | bne .L_found | 131 | bne .L_found |
| @@ -125,7 +139,9 @@ ENTRY(_find_first_bit_be) | |||
| 125 | beq 3f | 139 | beq 3f |
| 126 | mov r2, #0 | 140 | mov r2, #0 |
| 127 | 1: eor r3, r2, #0x18 @ big endian byte ordering | 141 | 1: eor r3, r2, #0x18 @ big endian byte ordering |
| 128 | ldrb r3, [r0, r3, lsr #3] | 142 | ARM( ldrb r3, [r0, r3, lsr #3] ) |
| 143 | THUMB( lsr r3, #3 ) | ||
| 144 | THUMB( ldrb r3, [r0, r3] ) | ||
| 129 | movs r3, r3 | 145 | movs r3, r3 |
| 130 | bne .L_found @ any now set - found zero bit | 146 | bne .L_found @ any now set - found zero bit |
| 131 | add r2, r2, #8 @ next bit pointer | 147 | add r2, r2, #8 @ next bit pointer |
| @@ -141,7 +157,9 @@ ENTRY(_find_next_bit_be) | |||
| 141 | ands ip, r2, #7 | 157 | ands ip, r2, #7 |
| 142 | beq 1b @ If new byte, goto old routine | 158 | beq 1b @ If new byte, goto old routine |
| 143 | eor r3, r2, #0x18 @ big endian byte ordering | 159 | eor r3, r2, #0x18 @ big endian byte ordering |
| 144 | ldrb r3, [r0, r3, lsr #3] | 160 | ARM( ldrb r3, [r0, r3, lsr #3] ) |
| 161 | THUMB( lsr r3, #3 ) | ||
| 162 | THUMB( ldrb r3, [r0, r3] ) | ||
| 145 | movs r3, r3, lsr ip @ shift off unused bits | 163 | movs r3, r3, lsr ip @ shift off unused bits |
| 146 | bne .L_found | 164 | bne .L_found |
| 147 | orr r2, r2, #7 @ if zero, then no bits here | 165 | orr r2, r2, #7 @ if zero, then no bits here |
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S index 6763088b7607..a1814d927122 100644 --- a/arch/arm/lib/getuser.S +++ b/arch/arm/lib/getuser.S | |||
| @@ -36,8 +36,13 @@ ENTRY(__get_user_1) | |||
| 36 | ENDPROC(__get_user_1) | 36 | ENDPROC(__get_user_1) |
| 37 | 37 | ||
| 38 | ENTRY(__get_user_2) | 38 | ENTRY(__get_user_2) |
| 39 | #ifdef CONFIG_THUMB2_KERNEL | ||
| 40 | 2: ldrbt r2, [r0] | ||
| 41 | 3: ldrbt r3, [r0, #1] | ||
| 42 | #else | ||
| 39 | 2: ldrbt r2, [r0], #1 | 43 | 2: ldrbt r2, [r0], #1 |
| 40 | 3: ldrbt r3, [r0] | 44 | 3: ldrbt r3, [r0] |
| 45 | #endif | ||
| 41 | #ifndef __ARMEB__ | 46 | #ifndef __ARMEB__ |
| 42 | orr r2, r2, r3, lsl #8 | 47 | orr r2, r2, r3, lsl #8 |
| 43 | #else | 48 | #else |
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S index d6585612c86b..ff4f71b579ee 100644 --- a/arch/arm/lib/io-writesw-armv4.S +++ b/arch/arm/lib/io-writesw-armv4.S | |||
| @@ -75,7 +75,10 @@ ENTRY(__raw_writesw) | |||
| 75 | #endif | 75 | #endif |
| 76 | 76 | ||
| 77 | .Loutsw_noalign: | 77 | .Loutsw_noalign: |
| 78 | ldr r3, [r1, -r3]! | 78 | ARM( ldr r3, [r1, -r3]! ) |
| 79 | THUMB( rsb r3, r3, #0 ) | ||
| 80 | THUMB( ldr r3, [r1, r3] ) | ||
| 81 | THUMB( sub r1, r3 ) | ||
| 79 | subcs r2, r2, #1 | 82 | subcs r2, r2, #1 |
| 80 | bcs 2f | 83 | bcs 2f |
| 81 | subs r2, r2, #2 | 84 | subs r2, r2, #2 |
diff --git a/arch/arm/lib/lshrdi3.S b/arch/arm/lib/lshrdi3.S index 99ea338bf87c..f83d449141f7 100644 --- a/arch/arm/lib/lshrdi3.S +++ b/arch/arm/lib/lshrdi3.S | |||
| @@ -43,7 +43,9 @@ ENTRY(__aeabi_llsr) | |||
| 43 | rsb ip, r2, #32 | 43 | rsb ip, r2, #32 |
| 44 | movmi al, al, lsr r2 | 44 | movmi al, al, lsr r2 |
| 45 | movpl al, ah, lsr r3 | 45 | movpl al, ah, lsr r3 |
| 46 | orrmi al, al, ah, lsl ip | 46 | ARM( orrmi al, al, ah, lsl ip ) |
| 47 | THUMB( lslmi r3, ah, ip ) | ||
| 48 | THUMB( orrmi al, al, r3 ) | ||
| 47 | mov ah, ah, lsr r2 | 49 | mov ah, ah, lsr r2 |
| 48 | mov pc, lr | 50 | mov pc, lr |
| 49 | 51 | ||
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S index e0d002641d3f..a9b9e2287a09 100644 --- a/arch/arm/lib/memcpy.S +++ b/arch/arm/lib/memcpy.S | |||
| @@ -13,8 +13,11 @@ | |||
| 13 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
| 14 | #include <asm/assembler.h> | 14 | #include <asm/assembler.h> |
| 15 | 15 | ||
| 16 | #define LDR1W_SHIFT 0 | ||
| 17 | #define STR1W_SHIFT 0 | ||
| 18 | |||
| 16 | .macro ldr1w ptr reg abort | 19 | .macro ldr1w ptr reg abort |
| 17 | ldr \reg, [\ptr], #4 | 20 | W(ldr) \reg, [\ptr], #4 |
| 18 | .endm | 21 | .endm |
| 19 | 22 | ||
| 20 | .macro ldr4w ptr reg1 reg2 reg3 reg4 abort | 23 | .macro ldr4w ptr reg1 reg2 reg3 reg4 abort |
| @@ -30,7 +33,7 @@ | |||
| 30 | .endm | 33 | .endm |
| 31 | 34 | ||
| 32 | .macro str1w ptr reg abort | 35 | .macro str1w ptr reg abort |
| 33 | str \reg, [\ptr], #4 | 36 | W(str) \reg, [\ptr], #4 |
| 34 | .endm | 37 | .endm |
| 35 | 38 | ||
| 36 | .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort | 39 | .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort |
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S index 12549187088c..5025c863713d 100644 --- a/arch/arm/lib/memmove.S +++ b/arch/arm/lib/memmove.S | |||
| @@ -75,24 +75,24 @@ ENTRY(memmove) | |||
| 75 | addne pc, pc, ip @ C is always clear here | 75 | addne pc, pc, ip @ C is always clear here |
| 76 | b 7f | 76 | b 7f |
| 77 | 6: nop | 77 | 6: nop |
| 78 | ldr r3, [r1, #-4]! | 78 | W(ldr) r3, [r1, #-4]! |
| 79 | ldr r4, [r1, #-4]! | 79 | W(ldr) r4, [r1, #-4]! |
| 80 | ldr r5, [r1, #-4]! | 80 | W(ldr) r5, [r1, #-4]! |
| 81 | ldr r6, [r1, #-4]! | 81 | W(ldr) r6, [r1, #-4]! |
| 82 | ldr r7, [r1, #-4]! | 82 | W(ldr) r7, [r1, #-4]! |
| 83 | ldr r8, [r1, #-4]! | 83 | W(ldr) r8, [r1, #-4]! |
| 84 | ldr lr, [r1, #-4]! | 84 | W(ldr) lr, [r1, #-4]! |
| 85 | 85 | ||
| 86 | add pc, pc, ip | 86 | add pc, pc, ip |
| 87 | nop | 87 | nop |
| 88 | nop | 88 | nop |
| 89 | str r3, [r0, #-4]! | 89 | W(str) r3, [r0, #-4]! |
| 90 | str r4, [r0, #-4]! | 90 | W(str) r4, [r0, #-4]! |
| 91 | str r5, [r0, #-4]! | 91 | W(str) r5, [r0, #-4]! |
| 92 | str r6, [r0, #-4]! | 92 | W(str) r6, [r0, #-4]! |
| 93 | str r7, [r0, #-4]! | 93 | W(str) r7, [r0, #-4]! |
| 94 | str r8, [r0, #-4]! | 94 | W(str) r8, [r0, #-4]! |
| 95 | str lr, [r0, #-4]! | 95 | W(str) lr, [r0, #-4]! |
| 96 | 96 | ||
| 97 | CALGN( bcs 2b ) | 97 | CALGN( bcs 2b ) |
| 98 | 98 | ||
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S index 864f3c1c4f18..02fedbf07c0d 100644 --- a/arch/arm/lib/putuser.S +++ b/arch/arm/lib/putuser.S | |||
| @@ -37,6 +37,15 @@ ENDPROC(__put_user_1) | |||
| 37 | 37 | ||
| 38 | ENTRY(__put_user_2) | 38 | ENTRY(__put_user_2) |
| 39 | mov ip, r2, lsr #8 | 39 | mov ip, r2, lsr #8 |
| 40 | #ifdef CONFIG_THUMB2_KERNEL | ||
| 41 | #ifndef __ARMEB__ | ||
| 42 | 2: strbt r2, [r0] | ||
| 43 | 3: strbt ip, [r0, #1] | ||
| 44 | #else | ||
| 45 | 2: strbt ip, [r0] | ||
| 46 | 3: strbt r2, [r0, #1] | ||
| 47 | #endif | ||
| 48 | #else /* !CONFIG_THUMB2_KERNEL */ | ||
| 40 | #ifndef __ARMEB__ | 49 | #ifndef __ARMEB__ |
| 41 | 2: strbt r2, [r0], #1 | 50 | 2: strbt r2, [r0], #1 |
| 42 | 3: strbt ip, [r0] | 51 | 3: strbt ip, [r0] |
| @@ -44,6 +53,7 @@ ENTRY(__put_user_2) | |||
| 44 | 2: strbt ip, [r0], #1 | 53 | 2: strbt ip, [r0], #1 |
| 45 | 3: strbt r2, [r0] | 54 | 3: strbt r2, [r0] |
| 46 | #endif | 55 | #endif |
| 56 | #endif /* CONFIG_THUMB2_KERNEL */ | ||
| 47 | mov r0, #0 | 57 | mov r0, #0 |
| 48 | mov pc, lr | 58 | mov pc, lr |
| 49 | ENDPROC(__put_user_2) | 59 | ENDPROC(__put_user_2) |
| @@ -55,8 +65,13 @@ ENTRY(__put_user_4) | |||
| 55 | ENDPROC(__put_user_4) | 65 | ENDPROC(__put_user_4) |
| 56 | 66 | ||
| 57 | ENTRY(__put_user_8) | 67 | ENTRY(__put_user_8) |
| 68 | #ifdef CONFIG_THUMB2_KERNEL | ||
| 69 | 5: strt r2, [r0] | ||
| 70 | 6: strt r3, [r0, #4] | ||
| 71 | #else | ||
| 58 | 5: strt r2, [r0], #4 | 72 | 5: strt r2, [r0], #4 |
| 59 | 6: strt r3, [r0] | 73 | 6: strt r3, [r0] |
| 74 | #endif | ||
| 60 | mov r0, #0 | 75 | mov r0, #0 |
| 61 | mov pc, lr | 76 | mov pc, lr |
| 62 | ENDPROC(__put_user_8) | 77 | ENDPROC(__put_user_8) |
diff --git a/arch/arm/lib/sha1.S b/arch/arm/lib/sha1.S index a16fb208c841..09b548cac1a4 100644 --- a/arch/arm/lib/sha1.S +++ b/arch/arm/lib/sha1.S | |||
| @@ -187,6 +187,7 @@ ENTRY(sha_transform) | |||
| 187 | 187 | ||
| 188 | ENDPROC(sha_transform) | 188 | ENDPROC(sha_transform) |
| 189 | 189 | ||
| 190 | .align 2 | ||
| 190 | .L_sha_K: | 191 | .L_sha_K: |
| 191 | .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 | 192 | .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 |
| 192 | 193 | ||
| @@ -195,6 +196,7 @@ ENDPROC(sha_transform) | |||
| 195 | * void sha_init(__u32 *buf) | 196 | * void sha_init(__u32 *buf) |
| 196 | */ | 197 | */ |
| 197 | 198 | ||
| 199 | .align 2 | ||
| 198 | .L_sha_initial_digest: | 200 | .L_sha_initial_digest: |
| 199 | .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 | 201 | .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 |
| 200 | 202 | ||
diff --git a/arch/arm/lib/strncpy_from_user.S b/arch/arm/lib/strncpy_from_user.S index 330373c26dd9..1c9814f346c6 100644 --- a/arch/arm/lib/strncpy_from_user.S +++ b/arch/arm/lib/strncpy_from_user.S | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | ENTRY(__strncpy_from_user) | 23 | ENTRY(__strncpy_from_user) |
| 24 | mov ip, r1 | 24 | mov ip, r1 |
| 25 | 1: subs r2, r2, #1 | 25 | 1: subs r2, r2, #1 |
| 26 | USER( ldrplbt r3, [r1], #1) | 26 | ldrusr r3, r1, 1, pl |
| 27 | bmi 2f | 27 | bmi 2f |
| 28 | strb r3, [r0], #1 | 28 | strb r3, [r0], #1 |
| 29 | teq r3, #0 | 29 | teq r3, #0 |
diff --git a/arch/arm/lib/strnlen_user.S b/arch/arm/lib/strnlen_user.S index 90bb9d020836..7855b2906659 100644 --- a/arch/arm/lib/strnlen_user.S +++ b/arch/arm/lib/strnlen_user.S | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | ENTRY(__strnlen_user) | 23 | ENTRY(__strnlen_user) |
| 24 | mov r2, r0 | 24 | mov r2, r0 |
| 25 | 1: | 25 | 1: |
| 26 | USER( ldrbt r3, [r0], #1) | 26 | ldrusr r3, r0, 1 |
| 27 | teq r3, #0 | 27 | teq r3, #0 |
| 28 | beq 2f | 28 | beq 2f |
| 29 | subs r1, r1, #1 | 29 | subs r1, r1, #1 |
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 323b47f2b52f..a24d824c428b 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
| @@ -23,6 +23,12 @@ config ARCH_AT91SAM9261 | |||
| 23 | select GENERIC_TIME | 23 | select GENERIC_TIME |
| 24 | select GENERIC_CLOCKEVENTS | 24 | select GENERIC_CLOCKEVENTS |
| 25 | 25 | ||
| 26 | config ARCH_AT91SAM9G10 | ||
| 27 | bool "AT91SAM9G10" | ||
| 28 | select CPU_ARM926T | ||
| 29 | select GENERIC_TIME | ||
| 30 | select GENERIC_CLOCKEVENTS | ||
| 31 | |||
| 26 | config ARCH_AT91SAM9263 | 32 | config ARCH_AT91SAM9263 |
| 27 | bool "AT91SAM9263" | 33 | bool "AT91SAM9263" |
| 28 | select CPU_ARM926T | 34 | select CPU_ARM926T |
| @@ -41,6 +47,12 @@ config ARCH_AT91SAM9G20 | |||
| 41 | select GENERIC_TIME | 47 | select GENERIC_TIME |
| 42 | select GENERIC_CLOCKEVENTS | 48 | select GENERIC_CLOCKEVENTS |
| 43 | 49 | ||
| 50 | config ARCH_AT91SAM9G45 | ||
| 51 | bool "AT91SAM9G45" | ||
| 52 | select CPU_ARM926T | ||
| 53 | select GENERIC_TIME | ||
| 54 | select GENERIC_CLOCKEVENTS | ||
| 55 | |||
| 44 | config ARCH_AT91CAP9 | 56 | config ARCH_AT91CAP9 |
| 45 | bool "AT91CAP9" | 57 | bool "AT91CAP9" |
| 46 | select CPU_ARM926T | 58 | select CPU_ARM926T |
| @@ -144,6 +156,13 @@ config MACH_YL9200 | |||
| 144 | help | 156 | help |
| 145 | Select this if you are using the ucDragon YL-9200 board. | 157 | Select this if you are using the ucDragon YL-9200 board. |
| 146 | 158 | ||
| 159 | config MACH_CPUAT91 | ||
| 160 | bool "Eukrea CPUAT91" | ||
| 161 | depends on ARCH_AT91RM9200 | ||
| 162 | help | ||
| 163 | Select this if you are using the Eukrea Electromatique's | ||
| 164 | CPUAT91 board <http://www.eukrea.com/>. | ||
| 165 | |||
| 147 | endif | 166 | endif |
| 148 | 167 | ||
| 149 | # ---------------------------------------------------------- | 168 | # ---------------------------------------------------------- |
| @@ -205,6 +224,13 @@ config MACH_QIL_A9260 | |||
| 205 | Select this if you are using a Calao Systems QIL-A9260 Board. | 224 | Select this if you are using a Calao Systems QIL-A9260 Board. |
| 206 | <http://www.calao-systems.com> | 225 | <http://www.calao-systems.com> |
| 207 | 226 | ||
| 227 | config MACH_CPU9260 | ||
| 228 | bool "Eukrea CPU9260 board" | ||
| 229 | depends on ARCH_AT91SAM9260 | ||
| 230 | help | ||
| 231 | Select this if you are using a Eukrea Electromatique's | ||
| 232 | CPU9260 Board <http://www.eukrea.com/> | ||
| 233 | |||
| 208 | endif | 234 | endif |
| 209 | 235 | ||
| 210 | # ---------------------------------------------------------- | 236 | # ---------------------------------------------------------- |
| @@ -224,6 +250,21 @@ endif | |||
| 224 | 250 | ||
| 225 | # ---------------------------------------------------------- | 251 | # ---------------------------------------------------------- |
| 226 | 252 | ||
| 253 | if ARCH_AT91SAM9G10 | ||
| 254 | |||
| 255 | comment "AT91SAM9G10 Board Type" | ||
| 256 | |||
| 257 | config MACH_AT91SAM9G10EK | ||
| 258 | bool "Atmel AT91SAM9G10-EK Evaluation Kit" | ||
| 259 | depends on ARCH_AT91SAM9G10 | ||
| 260 | help | ||
| 261 | Select this if you are using Atmel's AT91SAM9G10-EK Evaluation Kit. | ||
| 262 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4588> | ||
| 263 | |||
| 264 | endif | ||
| 265 | |||
| 266 | # ---------------------------------------------------------- | ||
| 267 | |||
| 227 | if ARCH_AT91SAM9263 | 268 | if ARCH_AT91SAM9263 |
| 228 | 269 | ||
| 229 | comment "AT91SAM9263 Board Type" | 270 | comment "AT91SAM9263 Board Type" |
| @@ -276,6 +317,29 @@ config MACH_AT91SAM9G20EK | |||
| 276 | help | 317 | help |
| 277 | Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit. | 318 | Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit. |
| 278 | 319 | ||
| 320 | config MACH_CPU9G20 | ||
| 321 | bool "Eukrea CPU9G20 board" | ||
| 322 | depends on ARCH_AT91SAM9G20 | ||
| 323 | help | ||
| 324 | Select this if you are using a Eukrea Electromatique's | ||
| 325 | CPU9G20 Board <http://www.eukrea.com/> | ||
| 326 | |||
| 327 | endif | ||
| 328 | |||
| 329 | # ---------------------------------------------------------- | ||
| 330 | |||
| 331 | if ARCH_AT91SAM9G45 | ||
| 332 | |||
| 333 | comment "AT91SAM9G45 Board Type" | ||
| 334 | |||
| 335 | config MACH_AT91SAM9G45EKES | ||
| 336 | bool "Atmel AT91SAM9G45-EKES Evaluation Kit" | ||
| 337 | depends on ARCH_AT91SAM9G45 | ||
| 338 | help | ||
| 339 | Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit. | ||
| 340 | "ES" at the end of the name means that this board is an | ||
| 341 | Engineering Sample. | ||
| 342 | |||
| 279 | endif | 343 | endif |
| 280 | 344 | ||
| 281 | # ---------------------------------------------------------- | 345 | # ---------------------------------------------------------- |
| @@ -315,13 +379,13 @@ comment "AT91 Board Options" | |||
| 315 | 379 | ||
| 316 | config MTD_AT91_DATAFLASH_CARD | 380 | config MTD_AT91_DATAFLASH_CARD |
| 317 | bool "Enable DataFlash Card support" | 381 | bool "Enable DataFlash Card support" |
| 318 | depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK || MACH_NEOCORE926) | 382 | depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK || MACH_NEOCORE926) |
| 319 | help | 383 | help |
| 320 | Enable support for the DataFlash card. | 384 | Enable support for the DataFlash card. |
| 321 | 385 | ||
| 322 | config MTD_NAND_ATMEL_BUSWIDTH_16 | 386 | config MTD_NAND_ATMEL_BUSWIDTH_16 |
| 323 | bool "Enable 16-bit data bus interface to NAND flash" | 387 | bool "Enable 16-bit data bus interface to NAND flash" |
| 324 | depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91CAP9ADK) | 388 | depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK) |
| 325 | help | 389 | help |
| 326 | On AT91SAM926x boards both types of NAND flash can be present | 390 | On AT91SAM926x boards both types of NAND flash can be present |
| 327 | (8 and 16 bit data bus width). | 391 | (8 and 16 bit data bus width). |
| @@ -383,7 +447,7 @@ config AT91_EARLY_USART2 | |||
| 383 | 447 | ||
| 384 | config AT91_EARLY_USART3 | 448 | config AT91_EARLY_USART3 |
| 385 | bool "USART3" | 449 | bool "USART3" |
| 386 | depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20) | 450 | depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45) |
| 387 | 451 | ||
| 388 | config AT91_EARLY_USART4 | 452 | config AT91_EARLY_USART4 |
| 389 | bool "USART4" | 453 | bool "USART4" |
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index c69ff237fd14..a6ed015d82ed 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile | |||
| @@ -13,9 +13,11 @@ obj-$(CONFIG_AT91_PMC_UNIT) += clock.o | |||
| 13 | obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o | 13 | obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o |
| 14 | obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o | 14 | obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o |
| 15 | obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o | 15 | obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o |
| 16 | obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o | ||
| 16 | obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o | 17 | obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o |
| 17 | obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o | 18 | obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o |
| 18 | obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o | 19 | obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o |
| 20 | obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o | ||
| 19 | obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o | 21 | obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o |
| 20 | obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o | 22 | obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o |
| 21 | 23 | ||
| @@ -32,6 +34,7 @@ obj-$(CONFIG_MACH_KAFA) += board-kafa.o | |||
| 32 | obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o | 34 | obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o |
| 33 | obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o | 35 | obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o |
| 34 | obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o | 36 | obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o |
| 37 | obj-$(CONFIG_MACH_CPUAT91) += board-cpuat91.o | ||
| 35 | 38 | ||
| 36 | # AT91SAM9260 board-specific support | 39 | # AT91SAM9260 board-specific support |
| 37 | obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o | 40 | obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o |
| @@ -40,9 +43,11 @@ obj-$(CONFIG_MACH_SAM9_L9260) += board-sam9-l9260.o | |||
| 40 | obj-$(CONFIG_MACH_USB_A9260) += board-usb-a9260.o | 43 | obj-$(CONFIG_MACH_USB_A9260) += board-usb-a9260.o |
| 41 | obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o | 44 | obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o |
| 42 | obj-$(CONFIG_MACH_AFEB9260) += board-afeb-9260v1.o | 45 | obj-$(CONFIG_MACH_AFEB9260) += board-afeb-9260v1.o |
| 46 | obj-$(CONFIG_MACH_CPU9260) += board-cpu9krea.o | ||
| 43 | 47 | ||
| 44 | # AT91SAM9261 board-specific support | 48 | # AT91SAM9261 board-specific support |
| 45 | obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o | 49 | obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o |
| 50 | obj-$(CONFIG_MACH_AT91SAM9G10EK) += board-sam9261ek.o | ||
| 46 | 51 | ||
| 47 | # AT91SAM9263 board-specific support | 52 | # AT91SAM9263 board-specific support |
| 48 | obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o | 53 | obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o |
| @@ -54,6 +59,10 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o | |||
| 54 | 59 | ||
| 55 | # AT91SAM9G20 board-specific support | 60 | # AT91SAM9G20 board-specific support |
| 56 | obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o | 61 | obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o |
| 62 | obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o | ||
| 63 | |||
| 64 | # AT91SAM9G45 board-specific support | ||
| 65 | obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o | ||
| 57 | 66 | ||
| 58 | # AT91CAP9 board-specific support | 67 | # AT91CAP9 board-specific support |
| 59 | obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o | 68 | obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o |
diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot index 071a2506a69f..3462b815054a 100644 --- a/arch/arm/mach-at91/Makefile.boot +++ b/arch/arm/mach-at91/Makefile.boot | |||
| @@ -7,6 +7,10 @@ ifeq ($(CONFIG_ARCH_AT91CAP9),y) | |||
| 7 | zreladdr-y := 0x70008000 | 7 | zreladdr-y := 0x70008000 |
| 8 | params_phys-y := 0x70000100 | 8 | params_phys-y := 0x70000100 |
| 9 | initrd_phys-y := 0x70410000 | 9 | initrd_phys-y := 0x70410000 |
| 10 | else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y) | ||
| 11 | zreladdr-y := 0x70008000 | ||
| 12 | params_phys-y := 0x70000100 | ||
| 13 | initrd_phys-y := 0x70410000 | ||
| 10 | else | 14 | else |
| 11 | zreladdr-y := 0x20008000 | 15 | zreladdr-y := 0x20008000 |
| 12 | params_phys-y := 0x20000100 | 16 | params_phys-y := 0x20000100 |
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index d74c9ac007e7..ee4ea0e720cf 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c | |||
| @@ -1113,6 +1113,122 @@ void __init at91_set_serial_console(unsigned portnr) {} | |||
| 1113 | void __init at91_add_device_serial(void) {} | 1113 | void __init at91_add_device_serial(void) {} |
| 1114 | #endif | 1114 | #endif |
| 1115 | 1115 | ||
| 1116 | /* -------------------------------------------------------------------- | ||
| 1117 | * CF/IDE | ||
| 1118 | * -------------------------------------------------------------------- */ | ||
| 1119 | |||
| 1120 | #if defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) || \ | ||
| 1121 | defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \ | ||
| 1122 | defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) | ||
| 1123 | |||
| 1124 | static struct at91_cf_data cf0_data; | ||
| 1125 | |||
| 1126 | static struct resource cf0_resources[] = { | ||
| 1127 | [0] = { | ||
| 1128 | .start = AT91_CHIPSELECT_4, | ||
| 1129 | .end = AT91_CHIPSELECT_4 + SZ_256M - 1, | ||
| 1130 | .flags = IORESOURCE_MEM, | ||
| 1131 | } | ||
| 1132 | }; | ||
| 1133 | |||
| 1134 | static struct platform_device cf0_device = { | ||
| 1135 | .id = 0, | ||
| 1136 | .dev = { | ||
| 1137 | .platform_data = &cf0_data, | ||
| 1138 | }, | ||
| 1139 | .resource = cf0_resources, | ||
| 1140 | .num_resources = ARRAY_SIZE(cf0_resources), | ||
| 1141 | }; | ||
| 1142 | |||
| 1143 | static struct at91_cf_data cf1_data; | ||
| 1144 | |||
| 1145 | static struct resource cf1_resources[] = { | ||
| 1146 | [0] = { | ||
| 1147 | .start = AT91_CHIPSELECT_5, | ||
| 1148 | .end = AT91_CHIPSELECT_5 + SZ_256M - 1, | ||
| 1149 | .flags = IORESOURCE_MEM, | ||
| 1150 | } | ||
| 1151 | }; | ||
| 1152 | |||
| 1153 | static struct platform_device cf1_device = { | ||
| 1154 | .id = 1, | ||
| 1155 | .dev = { | ||
| 1156 | .platform_data = &cf1_data, | ||
| 1157 | }, | ||
| 1158 | .resource = cf1_resources, | ||
| 1159 | .num_resources = ARRAY_SIZE(cf1_resources), | ||
| 1160 | }; | ||
| 1161 | |||
| 1162 | void __init at91_add_device_cf(struct at91_cf_data *data) | ||
| 1163 | { | ||
| 1164 | struct platform_device *pdev; | ||
| 1165 | unsigned long csa; | ||
| 1166 | |||
| 1167 | if (!data) | ||
| 1168 | return; | ||
| 1169 | |||
| 1170 | csa = at91_sys_read(AT91_MATRIX_EBICSA); | ||
| 1171 | |||
| 1172 | switch (data->chipselect) { | ||
| 1173 | case 4: | ||
| 1174 | at91_set_multi_drive(AT91_PIN_PC8, 0); | ||
| 1175 | at91_set_A_periph(AT91_PIN_PC8, 0); | ||
| 1176 | csa |= AT91_MATRIX_CS4A_SMC_CF1; | ||
| 1177 | cf0_data = *data; | ||
| 1178 | pdev = &cf0_device; | ||
| 1179 | break; | ||
| 1180 | case 5: | ||
| 1181 | at91_set_multi_drive(AT91_PIN_PC9, 0); | ||
| 1182 | at91_set_A_periph(AT91_PIN_PC9, 0); | ||
| 1183 | csa |= AT91_MATRIX_CS5A_SMC_CF2; | ||
| 1184 | cf1_data = *data; | ||
| 1185 | pdev = &cf1_device; | ||
| 1186 | break; | ||
| 1187 | default: | ||
| 1188 | printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n", | ||
| 1189 | data->chipselect); | ||
| 1190 | return; | ||
| 1191 | } | ||
| 1192 | |||
| 1193 | at91_sys_write(AT91_MATRIX_EBICSA, csa); | ||
| 1194 | |||
| 1195 | if (data->rst_pin) { | ||
| 1196 | at91_set_multi_drive(data->rst_pin, 0); | ||
| 1197 | at91_set_gpio_output(data->rst_pin, 1); | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | if (data->irq_pin) { | ||
| 1201 | at91_set_gpio_input(data->irq_pin, 0); | ||
| 1202 | at91_set_deglitch(data->irq_pin, 1); | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | if (data->det_pin) { | ||
| 1206 | at91_set_gpio_input(data->det_pin, 0); | ||
| 1207 | at91_set_deglitch(data->det_pin, 1); | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | at91_set_B_periph(AT91_PIN_PC6, 0); /* CFCE1 */ | ||
| 1211 | at91_set_B_periph(AT91_PIN_PC7, 0); /* CFCE2 */ | ||
| 1212 | at91_set_A_periph(AT91_PIN_PC10, 0); /* CFRNW */ | ||
| 1213 | at91_set_A_periph(AT91_PIN_PC15, 1); /* NWAIT */ | ||
| 1214 | |||
| 1215 | if (data->flags & AT91_CF_TRUE_IDE) | ||
| 1216 | #if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) | ||
| 1217 | pdev->name = "pata_at91"; | ||
| 1218 | #elif defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) | ||
| 1219 | pdev->name = "at91_ide"; | ||
| 1220 | #else | ||
| 1221 | #warning "board requires AT91_CF_TRUE_IDE: enable either at91_ide or pata_at91" | ||
| 1222 | #endif | ||
| 1223 | else | ||
| 1224 | pdev->name = "at91_cf"; | ||
| 1225 | |||
| 1226 | platform_device_register(pdev); | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | #else | ||
| 1230 | void __init at91_add_device_cf(struct at91_cf_data * data) {} | ||
| 1231 | #endif | ||
| 1116 | 1232 | ||
| 1117 | /* -------------------------------------------------------------------- */ | 1233 | /* -------------------------------------------------------------------- */ |
| 1118 | /* | 1234 | /* |
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 3acd7d7e6a42..4ecf37996c77 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <asm/irq.h> | 16 | #include <asm/irq.h> |
| 17 | #include <asm/mach/arch.h> | 17 | #include <asm/mach/arch.h> |
| 18 | #include <asm/mach/map.h> | 18 | #include <asm/mach/map.h> |
| 19 | #include <mach/cpu.h> | ||
| 19 | #include <mach/at91sam9261.h> | 20 | #include <mach/at91sam9261.h> |
| 20 | #include <mach/at91_pmc.h> | 21 | #include <mach/at91_pmc.h> |
| 21 | #include <mach/at91_rstc.h> | 22 | #include <mach/at91_rstc.h> |
| @@ -30,7 +31,11 @@ static struct map_desc at91sam9261_io_desc[] __initdata = { | |||
| 30 | .pfn = __phys_to_pfn(AT91_BASE_SYS), | 31 | .pfn = __phys_to_pfn(AT91_BASE_SYS), |
| 31 | .length = SZ_16K, | 32 | .length = SZ_16K, |
| 32 | .type = MT_DEVICE, | 33 | .type = MT_DEVICE, |
| 33 | }, { | 34 | }, |
| 35 | }; | ||
| 36 | |||
| 37 | static struct map_desc at91sam9261_sram_desc[] __initdata = { | ||
| 38 | { | ||
| 34 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE, | 39 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE, |
| 35 | .pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE), | 40 | .pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE), |
| 36 | .length = AT91SAM9261_SRAM_SIZE, | 41 | .length = AT91SAM9261_SRAM_SIZE, |
| @@ -38,6 +43,15 @@ static struct map_desc at91sam9261_io_desc[] __initdata = { | |||
| 38 | }, | 43 | }, |
| 39 | }; | 44 | }; |
| 40 | 45 | ||
| 46 | static struct map_desc at91sam9g10_sram_desc[] __initdata = { | ||
| 47 | { | ||
| 48 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9G10_SRAM_SIZE, | ||
| 49 | .pfn = __phys_to_pfn(AT91SAM9G10_SRAM_BASE), | ||
| 50 | .length = AT91SAM9G10_SRAM_SIZE, | ||
| 51 | .type = MT_DEVICE, | ||
| 52 | }, | ||
| 53 | }; | ||
| 54 | |||
| 41 | /* -------------------------------------------------------------------- | 55 | /* -------------------------------------------------------------------- |
| 42 | * Clocks | 56 | * Clocks |
| 43 | * -------------------------------------------------------------------- */ | 57 | * -------------------------------------------------------------------- */ |
| @@ -263,6 +277,12 @@ void __init at91sam9261_initialize(unsigned long main_clock) | |||
| 263 | /* Map peripherals */ | 277 | /* Map peripherals */ |
| 264 | iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc)); | 278 | iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc)); |
| 265 | 279 | ||
| 280 | if (cpu_is_at91sam9g10()) | ||
| 281 | iotable_init(at91sam9g10_sram_desc, ARRAY_SIZE(at91sam9g10_sram_desc)); | ||
| 282 | else | ||
| 283 | iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc)); | ||
| 284 | |||
| 285 | |||
| 266 | at91_arch_reset = at91sam9261_reset; | 286 | at91_arch_reset = at91sam9261_reset; |
| 267 | pm_power_off = at91sam9261_poweroff; | 287 | pm_power_off = at91sam9261_poweroff; |
| 268 | at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) | 288 | at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) |
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index b7f233242315..55719a974276 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c | |||
| @@ -707,9 +707,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | |||
| 707 | * AC97 | 707 | * AC97 |
| 708 | * -------------------------------------------------------------------- */ | 708 | * -------------------------------------------------------------------- */ |
| 709 | 709 | ||
| 710 | #if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE) | 710 | #if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE) |
| 711 | static u64 ac97_dmamask = DMA_BIT_MASK(32); | 711 | static u64 ac97_dmamask = DMA_BIT_MASK(32); |
| 712 | static struct atmel_ac97_data ac97_data; | 712 | static struct ac97c_platform_data ac97_data; |
| 713 | 713 | ||
| 714 | static struct resource ac97_resources[] = { | 714 | static struct resource ac97_resources[] = { |
| 715 | [0] = { | 715 | [0] = { |
| @@ -725,8 +725,8 @@ static struct resource ac97_resources[] = { | |||
| 725 | }; | 725 | }; |
| 726 | 726 | ||
| 727 | static struct platform_device at91sam9263_ac97_device = { | 727 | static struct platform_device at91sam9263_ac97_device = { |
| 728 | .name = "ac97c", | 728 | .name = "atmel_ac97c", |
| 729 | .id = 1, | 729 | .id = 0, |
| 730 | .dev = { | 730 | .dev = { |
| 731 | .dma_mask = &ac97_dmamask, | 731 | .dma_mask = &ac97_dmamask, |
| 732 | .coherent_dma_mask = DMA_BIT_MASK(32), | 732 | .coherent_dma_mask = DMA_BIT_MASK(32), |
| @@ -736,7 +736,7 @@ static struct platform_device at91sam9263_ac97_device = { | |||
| 736 | .num_resources = ARRAY_SIZE(ac97_resources), | 736 | .num_resources = ARRAY_SIZE(ac97_resources), |
| 737 | }; | 737 | }; |
| 738 | 738 | ||
| 739 | void __init at91_add_device_ac97(struct atmel_ac97_data *data) | 739 | void __init at91_add_device_ac97(struct ac97c_platform_data *data) |
| 740 | { | 740 | { |
| 741 | if (!data) | 741 | if (!data) |
| 742 | return; | 742 | return; |
| @@ -750,11 +750,11 @@ void __init at91_add_device_ac97(struct atmel_ac97_data *data) | |||
| 750 | if (data->reset_pin) | 750 | if (data->reset_pin) |
| 751 | at91_set_gpio_output(data->reset_pin, 0); | 751 | at91_set_gpio_output(data->reset_pin, 0); |
| 752 | 752 | ||
| 753 | ac97_data = *ek_data; | 753 | ac97_data = *data; |
| 754 | platform_device_register(&at91sam9263_ac97_device); | 754 | platform_device_register(&at91sam9263_ac97_device); |
| 755 | } | 755 | } |
| 756 | #else | 756 | #else |
| 757 | void __init at91_add_device_ac97(struct atmel_ac97_data *data) {} | 757 | void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} |
| 758 | #endif | 758 | #endif |
| 759 | 759 | ||
| 760 | 760 | ||
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c new file mode 100644 index 000000000000..85166b7e69a1 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9g45.c | |||
| @@ -0,0 +1,360 @@ | |||
| 1 | /* | ||
| 2 | * Chip-specific setup code for the AT91SAM9G45 family | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 Atmel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/pm.h> | ||
| 15 | |||
| 16 | #include <asm/irq.h> | ||
| 17 | #include <asm/mach/arch.h> | ||
| 18 | #include <asm/mach/map.h> | ||
| 19 | #include <mach/at91sam9g45.h> | ||
| 20 | #include <mach/at91_pmc.h> | ||
| 21 | #include <mach/at91_rstc.h> | ||
| 22 | #include <mach/at91_shdwc.h> | ||
| 23 | |||
| 24 | #include "generic.h" | ||
| 25 | #include "clock.h" | ||
| 26 | |||
| 27 | static struct map_desc at91sam9g45_io_desc[] __initdata = { | ||
| 28 | { | ||
| 29 | .virtual = AT91_VA_BASE_SYS, | ||
| 30 | .pfn = __phys_to_pfn(AT91_BASE_SYS), | ||
| 31 | .length = SZ_16K, | ||
| 32 | .type = MT_DEVICE, | ||
| 33 | }, { | ||
| 34 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9G45_SRAM_SIZE, | ||
| 35 | .pfn = __phys_to_pfn(AT91SAM9G45_SRAM_BASE), | ||
| 36 | .length = AT91SAM9G45_SRAM_SIZE, | ||
| 37 | .type = MT_DEVICE, | ||
| 38 | } | ||
| 39 | }; | ||
| 40 | |||
| 41 | /* -------------------------------------------------------------------- | ||
| 42 | * Clocks | ||
| 43 | * -------------------------------------------------------------------- */ | ||
| 44 | |||
| 45 | /* | ||
| 46 | * The peripheral clocks. | ||
| 47 | */ | ||
| 48 | static struct clk pioA_clk = { | ||
| 49 | .name = "pioA_clk", | ||
| 50 | .pmc_mask = 1 << AT91SAM9G45_ID_PIOA, | ||
| 51 | .type = CLK_TYPE_PERIPHERAL, | ||
| 52 | }; | ||
| 53 | static struct clk pioB_clk = { | ||
| 54 | .name = "pioB_clk", | ||
| 55 | .pmc_mask = 1 << AT91SAM9G45_ID_PIOB, | ||
| 56 | .type = CLK_TYPE_PERIPHERAL, | ||
| 57 | }; | ||
| 58 | static struct clk pioC_clk = { | ||
| 59 | .name = "pioC_clk", | ||
| 60 | .pmc_mask = 1 << AT91SAM9G45_ID_PIOC, | ||
| 61 | .type = CLK_TYPE_PERIPHERAL, | ||
| 62 | }; | ||
| 63 | static struct clk pioDE_clk = { | ||
| 64 | .name = "pioDE_clk", | ||
| 65 | .pmc_mask = 1 << AT91SAM9G45_ID_PIODE, | ||
| 66 | .type = CLK_TYPE_PERIPHERAL, | ||
| 67 | }; | ||
| 68 | static struct clk usart0_clk = { | ||
| 69 | .name = "usart0_clk", | ||
| 70 | .pmc_mask = 1 << AT91SAM9G45_ID_US0, | ||
| 71 | .type = CLK_TYPE_PERIPHERAL, | ||
| 72 | }; | ||
| 73 | static struct clk usart1_clk = { | ||
| 74 | .name = "usart1_clk", | ||
| 75 | .pmc_mask = 1 << AT91SAM9G45_ID_US1, | ||
| 76 | .type = CLK_TYPE_PERIPHERAL, | ||
| 77 | }; | ||
| 78 | static struct clk usart2_clk = { | ||
| 79 | .name = "usart2_clk", | ||
| 80 | .pmc_mask = 1 << AT91SAM9G45_ID_US2, | ||
| 81 | .type = CLK_TYPE_PERIPHERAL, | ||
| 82 | }; | ||
| 83 | static struct clk usart3_clk = { | ||
| 84 | .name = "usart3_clk", | ||
| 85 | .pmc_mask = 1 << AT91SAM9G45_ID_US3, | ||
| 86 | .type = CLK_TYPE_PERIPHERAL, | ||
| 87 | }; | ||
| 88 | static struct clk mmc0_clk = { | ||
| 89 | .name = "mci0_clk", | ||
| 90 | .pmc_mask = 1 << AT91SAM9G45_ID_MCI0, | ||
| 91 | .type = CLK_TYPE_PERIPHERAL, | ||
| 92 | }; | ||
| 93 | static struct clk twi0_clk = { | ||
| 94 | .name = "twi0_clk", | ||
| 95 | .pmc_mask = 1 << AT91SAM9G45_ID_TWI0, | ||
| 96 | .type = CLK_TYPE_PERIPHERAL, | ||
| 97 | }; | ||
| 98 | static struct clk twi1_clk = { | ||
| 99 | .name = "twi1_clk", | ||
| 100 | .pmc_mask = 1 << AT91SAM9G45_ID_TWI1, | ||
| 101 | .type = CLK_TYPE_PERIPHERAL, | ||
| 102 | }; | ||
| 103 | static struct clk spi0_clk = { | ||
| 104 | .name = "spi0_clk", | ||
| 105 | .pmc_mask = 1 << AT91SAM9G45_ID_SPI0, | ||
| 106 | .type = CLK_TYPE_PERIPHERAL, | ||
| 107 | }; | ||
| 108 | static struct clk spi1_clk = { | ||
| 109 | .name = "spi1_clk", | ||
| 110 | .pmc_mask = 1 << AT91SAM9G45_ID_SPI1, | ||
| 111 | .type = CLK_TYPE_PERIPHERAL, | ||
| 112 | }; | ||
| 113 | static struct clk ssc0_clk = { | ||
| 114 | .name = "ssc0_clk", | ||
| 115 | .pmc_mask = 1 << AT91SAM9G45_ID_SSC0, | ||
| 116 | .type = CLK_TYPE_PERIPHERAL, | ||
| 117 | }; | ||
| 118 | static struct clk ssc1_clk = { | ||
| 119 | .name = "ssc1_clk", | ||
| 120 | .pmc_mask = 1 << AT91SAM9G45_ID_SSC1, | ||
| 121 | .type = CLK_TYPE_PERIPHERAL, | ||
| 122 | }; | ||
| 123 | static struct clk tcb_clk = { | ||
| 124 | .name = "tcb_clk", | ||
| 125 | .pmc_mask = 1 << AT91SAM9G45_ID_TCB, | ||
| 126 | .type = CLK_TYPE_PERIPHERAL, | ||
| 127 | }; | ||
| 128 | static struct clk pwm_clk = { | ||
| 129 | .name = "pwm_clk", | ||
| 130 | .pmc_mask = 1 << AT91SAM9G45_ID_PWMC, | ||
| 131 | .type = CLK_TYPE_PERIPHERAL, | ||
| 132 | }; | ||
| 133 | static struct clk tsc_clk = { | ||
| 134 | .name = "tsc_clk", | ||
| 135 | .pmc_mask = 1 << AT91SAM9G45_ID_TSC, | ||
| 136 | .type = CLK_TYPE_PERIPHERAL, | ||
| 137 | }; | ||
| 138 | static struct clk dma_clk = { | ||
| 139 | .name = "dma_clk", | ||
| 140 | .pmc_mask = 1 << AT91SAM9G45_ID_DMA, | ||
| 141 | .type = CLK_TYPE_PERIPHERAL, | ||
| 142 | }; | ||
| 143 | static struct clk uhphs_clk = { | ||
| 144 | .name = "uhphs_clk", | ||
| 145 | .pmc_mask = 1 << AT91SAM9G45_ID_UHPHS, | ||
| 146 | .type = CLK_TYPE_PERIPHERAL, | ||
| 147 | }; | ||
| 148 | static struct clk lcdc_clk = { | ||
| 149 | .name = "lcdc_clk", | ||
| 150 | .pmc_mask = 1 << AT91SAM9G45_ID_LCDC, | ||
| 151 | .type = CLK_TYPE_PERIPHERAL, | ||
| 152 | }; | ||
| 153 | static struct clk ac97_clk = { | ||
| 154 | .name = "ac97_clk", | ||
| 155 | .pmc_mask = 1 << AT91SAM9G45_ID_AC97C, | ||
| 156 | .type = CLK_TYPE_PERIPHERAL, | ||
| 157 | }; | ||
| 158 | static struct clk macb_clk = { | ||
| 159 | .name = "macb_clk", | ||
| 160 | .pmc_mask = 1 << AT91SAM9G45_ID_EMAC, | ||
| 161 | .type = CLK_TYPE_PERIPHERAL, | ||
| 162 | }; | ||
| 163 | static struct clk isi_clk = { | ||
| 164 | .name = "isi_clk", | ||
| 165 | .pmc_mask = 1 << AT91SAM9G45_ID_ISI, | ||
| 166 | .type = CLK_TYPE_PERIPHERAL, | ||
| 167 | }; | ||
| 168 | static struct clk udphs_clk = { | ||
| 169 | .name = "udphs_clk", | ||
| 170 | .pmc_mask = 1 << AT91SAM9G45_ID_UDPHS, | ||
| 171 | .type = CLK_TYPE_PERIPHERAL, | ||
| 172 | }; | ||
| 173 | static struct clk mmc1_clk = { | ||
| 174 | .name = "mci1_clk", | ||
| 175 | .pmc_mask = 1 << AT91SAM9G45_ID_MCI1, | ||
| 176 | .type = CLK_TYPE_PERIPHERAL, | ||
| 177 | }; | ||
| 178 | |||
| 179 | /* One additional fake clock for ohci */ | ||
| 180 | static struct clk ohci_clk = { | ||
| 181 | .name = "ohci_clk", | ||
| 182 | .pmc_mask = 0, | ||
| 183 | .type = CLK_TYPE_PERIPHERAL, | ||
| 184 | .parent = &uhphs_clk, | ||
| 185 | }; | ||
| 186 | |||
| 187 | static struct clk *periph_clocks[] __initdata = { | ||
| 188 | &pioA_clk, | ||
| 189 | &pioB_clk, | ||
| 190 | &pioC_clk, | ||
| 191 | &pioDE_clk, | ||
| 192 | &usart0_clk, | ||
| 193 | &usart1_clk, | ||
| 194 | &usart2_clk, | ||
| 195 | &usart3_clk, | ||
| 196 | &mmc0_clk, | ||
| 197 | &twi0_clk, | ||
| 198 | &twi1_clk, | ||
| 199 | &spi0_clk, | ||
| 200 | &spi1_clk, | ||
| 201 | &ssc0_clk, | ||
| 202 | &ssc1_clk, | ||
| 203 | &tcb_clk, | ||
| 204 | &pwm_clk, | ||
| 205 | &tsc_clk, | ||
| 206 | &dma_clk, | ||
| 207 | &uhphs_clk, | ||
| 208 | &lcdc_clk, | ||
| 209 | &ac97_clk, | ||
| 210 | &macb_clk, | ||
| 211 | &isi_clk, | ||
| 212 | &udphs_clk, | ||
| 213 | &mmc1_clk, | ||
| 214 | // irq0 | ||
| 215 | &ohci_clk, | ||
| 216 | }; | ||
| 217 | |||
| 218 | /* | ||
| 219 | * The two programmable clocks. | ||
| 220 | * You must configure pin multiplexing to bring these signals out. | ||
| 221 | */ | ||
| 222 | static struct clk pck0 = { | ||
| 223 | .name = "pck0", | ||
| 224 | .pmc_mask = AT91_PMC_PCK0, | ||
| 225 | .type = CLK_TYPE_PROGRAMMABLE, | ||
| 226 | .id = 0, | ||
| 227 | }; | ||
| 228 | static struct clk pck1 = { | ||
| 229 | .name = "pck1", | ||
| 230 | .pmc_mask = AT91_PMC_PCK1, | ||
| 231 | .type = CLK_TYPE_PROGRAMMABLE, | ||
| 232 | .id = 1, | ||
| 233 | }; | ||
| 234 | |||
| 235 | static void __init at91sam9g45_register_clocks(void) | ||
| 236 | { | ||
| 237 | int i; | ||
| 238 | |||
| 239 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | ||
| 240 | clk_register(periph_clocks[i]); | ||
| 241 | |||
| 242 | clk_register(&pck0); | ||
| 243 | clk_register(&pck1); | ||
| 244 | } | ||
| 245 | |||
| 246 | /* -------------------------------------------------------------------- | ||
| 247 | * GPIO | ||
| 248 | * -------------------------------------------------------------------- */ | ||
| 249 | |||
| 250 | static struct at91_gpio_bank at91sam9g45_gpio[] = { | ||
| 251 | { | ||
| 252 | .id = AT91SAM9G45_ID_PIOA, | ||
| 253 | .offset = AT91_PIOA, | ||
| 254 | .clock = &pioA_clk, | ||
| 255 | }, { | ||
| 256 | .id = AT91SAM9G45_ID_PIOB, | ||
| 257 | .offset = AT91_PIOB, | ||
| 258 | .clock = &pioB_clk, | ||
| 259 | }, { | ||
| 260 | .id = AT91SAM9G45_ID_PIOC, | ||
| 261 | .offset = AT91_PIOC, | ||
| 262 | .clock = &pioC_clk, | ||
| 263 | }, { | ||
| 264 | .id = AT91SAM9G45_ID_PIODE, | ||
| 265 | .offset = AT91_PIOD, | ||
| 266 | .clock = &pioDE_clk, | ||
| 267 | }, { | ||
| 268 | .id = AT91SAM9G45_ID_PIODE, | ||
| 269 | .offset = AT91_PIOE, | ||
| 270 | .clock = &pioDE_clk, | ||
| 271 | } | ||
| 272 | }; | ||
| 273 | |||
| 274 | static void at91sam9g45_reset(void) | ||
| 275 | { | ||
| 276 | at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); | ||
| 277 | } | ||
| 278 | |||
| 279 | static void at91sam9g45_poweroff(void) | ||
| 280 | { | ||
| 281 | at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); | ||
| 282 | } | ||
| 283 | |||
| 284 | |||
| 285 | /* -------------------------------------------------------------------- | ||
| 286 | * AT91SAM9G45 processor initialization | ||
| 287 | * -------------------------------------------------------------------- */ | ||
| 288 | |||
| 289 | void __init at91sam9g45_initialize(unsigned long main_clock) | ||
| 290 | { | ||
| 291 | /* Map peripherals */ | ||
| 292 | iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc)); | ||
| 293 | |||
| 294 | at91_arch_reset = at91sam9g45_reset; | ||
| 295 | pm_power_off = at91sam9g45_poweroff; | ||
| 296 | at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0); | ||
| 297 | |||
| 298 | /* Init clock subsystem */ | ||
| 299 | at91_clock_init(main_clock); | ||
| 300 | |||
| 301 | /* Register the processor-specific clocks */ | ||
| 302 | at91sam9g45_register_clocks(); | ||
| 303 | |||
| 304 | /* Register GPIO subsystem */ | ||
| 305 | at91_gpio_init(at91sam9g45_gpio, 5); | ||
| 306 | } | ||
| 307 | |||
| 308 | /* -------------------------------------------------------------------- | ||
| 309 | * Interrupt initialization | ||
| 310 | * -------------------------------------------------------------------- */ | ||
| 311 | |||
| 312 | /* | ||
| 313 | * The default interrupt priority levels (0 = lowest, 7 = highest). | ||
| 314 | */ | ||
| 315 | static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { | ||
| 316 | 7, /* Advanced Interrupt Controller (FIQ) */ | ||
| 317 | 7, /* System Peripherals */ | ||
| 318 | 1, /* Parallel IO Controller A */ | ||
| 319 | 1, /* Parallel IO Controller B */ | ||
| 320 | 1, /* Parallel IO Controller C */ | ||
| 321 | 1, /* Parallel IO Controller D and E */ | ||
| 322 | 0, | ||
| 323 | 5, /* USART 0 */ | ||
| 324 | 5, /* USART 1 */ | ||
| 325 | 5, /* USART 2 */ | ||
| 326 | 5, /* USART 3 */ | ||
| 327 | 0, /* Multimedia Card Interface 0 */ | ||
| 328 | 6, /* Two-Wire Interface 0 */ | ||
| 329 | 6, /* Two-Wire Interface 1 */ | ||
| 330 | 5, /* Serial Peripheral Interface 0 */ | ||
| 331 | 5, /* Serial Peripheral Interface 1 */ | ||
| 332 | 4, /* Serial Synchronous Controller 0 */ | ||
| 333 | 4, /* Serial Synchronous Controller 1 */ | ||
| 334 | 0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */ | ||
| 335 | 0, /* Pulse Width Modulation Controller */ | ||
| 336 | 0, /* Touch Screen Controller */ | ||
| 337 | 0, /* DMA Controller */ | ||
| 338 | 2, /* USB Host High Speed port */ | ||
| 339 | 3, /* LDC Controller */ | ||
| 340 | 5, /* AC97 Controller */ | ||
| 341 | 3, /* Ethernet */ | ||
| 342 | 0, /* Image Sensor Interface */ | ||
| 343 | 2, /* USB Device High speed port */ | ||
| 344 | 0, | ||
| 345 | 0, /* Multimedia Card Interface 1 */ | ||
| 346 | 0, | ||
| 347 | 0, /* Advanced Interrupt Controller (IRQ0) */ | ||
| 348 | }; | ||
| 349 | |||
| 350 | void __init at91sam9g45_init_interrupts(unsigned int priority[NR_AIC_IRQS]) | ||
| 351 | { | ||
| 352 | if (!priority) | ||
| 353 | priority = at91sam9g45_default_irq_priority; | ||
| 354 | |||
| 355 | /* Initialize the AIC interrupt controller */ | ||
| 356 | at91_aic_init(priority); | ||
| 357 | |||
| 358 | /* Enable GPIO interrupts */ | ||
| 359 | at91_gpio_irq_setup(); | ||
| 360 | } | ||
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c new file mode 100644 index 000000000000..d746e8621bc2 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
| @@ -0,0 +1,1230 @@ | |||
| 1 | /* | ||
| 2 | * On-Chip devices setup code for the AT91SAM9G45 family | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 Atmel Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | */ | ||
| 12 | #include <asm/mach/arch.h> | ||
| 13 | #include <asm/mach/map.h> | ||
| 14 | |||
| 15 | #include <linux/dma-mapping.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/i2c-gpio.h> | ||
| 18 | |||
| 19 | #include <linux/fb.h> | ||
| 20 | #include <video/atmel_lcdc.h> | ||
| 21 | |||
| 22 | #include <mach/board.h> | ||
| 23 | #include <mach/gpio.h> | ||
| 24 | #include <mach/at91sam9g45.h> | ||
| 25 | #include <mach/at91sam9g45_matrix.h> | ||
| 26 | #include <mach/at91sam9_smc.h> | ||
| 27 | |||
| 28 | #include "generic.h" | ||
| 29 | |||
| 30 | |||
| 31 | /* -------------------------------------------------------------------- | ||
| 32 | * USB Host (OHCI) | ||
| 33 | * -------------------------------------------------------------------- */ | ||
| 34 | |||
| 35 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | ||
| 36 | static u64 ohci_dmamask = DMA_BIT_MASK(32); | ||
| 37 | static struct at91_usbh_data usbh_ohci_data; | ||
| 38 | |||
| 39 | static struct resource usbh_ohci_resources[] = { | ||
| 40 | [0] = { | ||
| 41 | .start = AT91SAM9G45_OHCI_BASE, | ||
| 42 | .end = AT91SAM9G45_OHCI_BASE + SZ_1M - 1, | ||
| 43 | .flags = IORESOURCE_MEM, | ||
| 44 | }, | ||
| 45 | [1] = { | ||
| 46 | .start = AT91SAM9G45_ID_UHPHS, | ||
| 47 | .end = AT91SAM9G45_ID_UHPHS, | ||
| 48 | .flags = IORESOURCE_IRQ, | ||
| 49 | }, | ||
| 50 | }; | ||
| 51 | |||
| 52 | static struct platform_device at91_usbh_ohci_device = { | ||
| 53 | .name = "at91_ohci", | ||
| 54 | .id = -1, | ||
| 55 | .dev = { | ||
| 56 | .dma_mask = &ohci_dmamask, | ||
| 57 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 58 | .platform_data = &usbh_ohci_data, | ||
| 59 | }, | ||
| 60 | .resource = usbh_ohci_resources, | ||
| 61 | .num_resources = ARRAY_SIZE(usbh_ohci_resources), | ||
| 62 | }; | ||
| 63 | |||
| 64 | void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) | ||
| 65 | { | ||
| 66 | int i; | ||
| 67 | |||
| 68 | if (!data) | ||
| 69 | return; | ||
| 70 | |||
| 71 | /* Enable VBus control for UHP ports */ | ||
| 72 | for (i = 0; i < data->ports; i++) { | ||
| 73 | if (data->vbus_pin[i]) | ||
| 74 | at91_set_gpio_output(data->vbus_pin[i], 0); | ||
| 75 | } | ||
| 76 | |||
| 77 | usbh_ohci_data = *data; | ||
| 78 | platform_device_register(&at91_usbh_ohci_device); | ||
| 79 | } | ||
| 80 | #else | ||
| 81 | void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {} | ||
| 82 | #endif | ||
| 83 | |||
| 84 | |||
| 85 | /* -------------------------------------------------------------------- | ||
| 86 | * USB HS Device (Gadget) | ||
| 87 | * -------------------------------------------------------------------- */ | ||
| 88 | |||
| 89 | #if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE) | ||
| 90 | static struct resource usba_udc_resources[] = { | ||
| 91 | [0] = { | ||
| 92 | .start = AT91SAM9G45_UDPHS_FIFO, | ||
| 93 | .end = AT91SAM9G45_UDPHS_FIFO + SZ_512K - 1, | ||
| 94 | .flags = IORESOURCE_MEM, | ||
| 95 | }, | ||
| 96 | [1] = { | ||
| 97 | .start = AT91SAM9G45_BASE_UDPHS, | ||
| 98 | .end = AT91SAM9G45_BASE_UDPHS + SZ_1K - 1, | ||
| 99 | .flags = IORESOURCE_MEM, | ||
| 100 | }, | ||
| 101 | [2] = { | ||
| 102 | .start = AT91SAM9G45_ID_UDPHS, | ||
| 103 | .end = AT91SAM9G45_ID_UDPHS, | ||
| 104 | .flags = IORESOURCE_IRQ, | ||
| 105 | }, | ||
| 106 | }; | ||
| 107 | |||
| 108 | #define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ | ||
| 109 | [idx] = { \ | ||
| 110 | .name = nam, \ | ||
| 111 | .index = idx, \ | ||
| 112 | .fifo_size = maxpkt, \ | ||
| 113 | .nr_banks = maxbk, \ | ||
| 114 | .can_dma = dma, \ | ||
| 115 | .can_isoc = isoc, \ | ||
| 116 | } | ||
| 117 | |||
| 118 | static struct usba_ep_data usba_udc_ep[] __initdata = { | ||
| 119 | EP("ep0", 0, 64, 1, 0, 0), | ||
| 120 | EP("ep1", 1, 1024, 2, 1, 1), | ||
| 121 | EP("ep2", 2, 1024, 2, 1, 1), | ||
| 122 | EP("ep3", 3, 1024, 3, 1, 0), | ||
| 123 | EP("ep4", 4, 1024, 3, 1, 0), | ||
| 124 | EP("ep5", 5, 1024, 3, 1, 1), | ||
| 125 | EP("ep6", 6, 1024, 3, 1, 1), | ||
| 126 | }; | ||
| 127 | |||
| 128 | #undef EP | ||
| 129 | |||
| 130 | /* | ||
| 131 | * pdata doesn't have room for any endpoints, so we need to | ||
| 132 | * append room for the ones we need right after it. | ||
| 133 | */ | ||
| 134 | static struct { | ||
| 135 | struct usba_platform_data pdata; | ||
| 136 | struct usba_ep_data ep[7]; | ||
| 137 | } usba_udc_data; | ||
| 138 | |||
| 139 | static struct platform_device at91_usba_udc_device = { | ||
| 140 | .name = "atmel_usba_udc", | ||
| 141 | .id = -1, | ||
| 142 | .dev = { | ||
| 143 | .platform_data = &usba_udc_data.pdata, | ||
| 144 | }, | ||
| 145 | .resource = usba_udc_resources, | ||
| 146 | .num_resources = ARRAY_SIZE(usba_udc_resources), | ||
| 147 | }; | ||
| 148 | |||
| 149 | void __init at91_add_device_usba(struct usba_platform_data *data) | ||
| 150 | { | ||
| 151 | usba_udc_data.pdata.vbus_pin = -EINVAL; | ||
| 152 | usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); | ||
| 153 | memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));; | ||
| 154 | |||
| 155 | if (data && data->vbus_pin > 0) { | ||
| 156 | at91_set_gpio_input(data->vbus_pin, 0); | ||
| 157 | at91_set_deglitch(data->vbus_pin, 1); | ||
| 158 | usba_udc_data.pdata.vbus_pin = data->vbus_pin; | ||
| 159 | } | ||
| 160 | |||
| 161 | /* Pullup pin is handled internally by USB device peripheral */ | ||
| 162 | |||
| 163 | /* Clocks */ | ||
| 164 | at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk"); | ||
| 165 | at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk"); | ||
| 166 | |||
| 167 | platform_device_register(&at91_usba_udc_device); | ||
| 168 | } | ||
| 169 | #else | ||
| 170 | void __init at91_add_device_usba(struct usba_platform_data *data) {} | ||
| 171 | #endif | ||
| 172 | |||
| 173 | |||
| 174 | /* -------------------------------------------------------------------- | ||
| 175 | * Ethernet | ||
| 176 | * -------------------------------------------------------------------- */ | ||
| 177 | |||
| 178 | #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) | ||
| 179 | static u64 eth_dmamask = DMA_BIT_MASK(32); | ||
| 180 | static struct at91_eth_data eth_data; | ||
| 181 | |||
| 182 | static struct resource eth_resources[] = { | ||
| 183 | [0] = { | ||
| 184 | .start = AT91SAM9G45_BASE_EMAC, | ||
| 185 | .end = AT91SAM9G45_BASE_EMAC + SZ_16K - 1, | ||
| 186 | .flags = IORESOURCE_MEM, | ||
| 187 | }, | ||
| 188 | [1] = { | ||
| 189 | .start = AT91SAM9G45_ID_EMAC, | ||
| 190 | .end = AT91SAM9G45_ID_EMAC, | ||
| 191 | .flags = IORESOURCE_IRQ, | ||
| 192 | }, | ||
| 193 | }; | ||
| 194 | |||
| 195 | static struct platform_device at91sam9g45_eth_device = { | ||
| 196 | .name = "macb", | ||
| 197 | .id = -1, | ||
| 198 | .dev = { | ||
| 199 | .dma_mask = ð_dmamask, | ||
| 200 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 201 | .platform_data = ð_data, | ||
| 202 | }, | ||
| 203 | .resource = eth_resources, | ||
| 204 | .num_resources = ARRAY_SIZE(eth_resources), | ||
| 205 | }; | ||
| 206 | |||
| 207 | void __init at91_add_device_eth(struct at91_eth_data *data) | ||
| 208 | { | ||
| 209 | if (!data) | ||
| 210 | return; | ||
| 211 | |||
| 212 | if (data->phy_irq_pin) { | ||
| 213 | at91_set_gpio_input(data->phy_irq_pin, 0); | ||
| 214 | at91_set_deglitch(data->phy_irq_pin, 1); | ||
| 215 | } | ||
| 216 | |||
| 217 | /* Pins used for MII and RMII */ | ||
| 218 | at91_set_A_periph(AT91_PIN_PA17, 0); /* ETXCK_EREFCK */ | ||
| 219 | at91_set_A_periph(AT91_PIN_PA15, 0); /* ERXDV */ | ||
| 220 | at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */ | ||
| 221 | at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */ | ||
| 222 | at91_set_A_periph(AT91_PIN_PA16, 0); /* ERXER */ | ||
| 223 | at91_set_A_periph(AT91_PIN_PA14, 0); /* ETXEN */ | ||
| 224 | at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX0 */ | ||
| 225 | at91_set_A_periph(AT91_PIN_PA11, 0); /* ETX1 */ | ||
| 226 | at91_set_A_periph(AT91_PIN_PA19, 0); /* EMDIO */ | ||
| 227 | at91_set_A_periph(AT91_PIN_PA18, 0); /* EMDC */ | ||
| 228 | |||
| 229 | if (!data->is_rmii) { | ||
| 230 | at91_set_B_periph(AT91_PIN_PA29, 0); /* ECRS */ | ||
| 231 | at91_set_B_periph(AT91_PIN_PA30, 0); /* ECOL */ | ||
| 232 | at91_set_B_periph(AT91_PIN_PA8, 0); /* ERX2 */ | ||
| 233 | at91_set_B_periph(AT91_PIN_PA9, 0); /* ERX3 */ | ||
| 234 | at91_set_B_periph(AT91_PIN_PA28, 0); /* ERXCK */ | ||
| 235 | at91_set_B_periph(AT91_PIN_PA6, 0); /* ETX2 */ | ||
| 236 | at91_set_B_periph(AT91_PIN_PA7, 0); /* ETX3 */ | ||
| 237 | at91_set_B_periph(AT91_PIN_PA27, 0); /* ETXER */ | ||
| 238 | } | ||
| 239 | |||
| 240 | eth_data = *data; | ||
| 241 | platform_device_register(&at91sam9g45_eth_device); | ||
| 242 | } | ||
| 243 | #else | ||
| 244 | void __init at91_add_device_eth(struct at91_eth_data *data) {} | ||
| 245 | #endif | ||
| 246 | |||
| 247 | |||
| 248 | /* -------------------------------------------------------------------- | ||
| 249 | * NAND / SmartMedia | ||
| 250 | * -------------------------------------------------------------------- */ | ||
| 251 | |||
| 252 | #if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE) | ||
| 253 | static struct atmel_nand_data nand_data; | ||
| 254 | |||
| 255 | #define NAND_BASE AT91_CHIPSELECT_3 | ||
| 256 | |||
| 257 | static struct resource nand_resources[] = { | ||
| 258 | [0] = { | ||
| 259 | .start = NAND_BASE, | ||
| 260 | .end = NAND_BASE + SZ_256M - 1, | ||
| 261 | .flags = IORESOURCE_MEM, | ||
| 262 | }, | ||
| 263 | [1] = { | ||
| 264 | .start = AT91_BASE_SYS + AT91_ECC, | ||
| 265 | .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, | ||
| 266 | .flags = IORESOURCE_MEM, | ||
| 267 | } | ||
| 268 | }; | ||
| 269 | |||
| 270 | static struct platform_device at91sam9g45_nand_device = { | ||
| 271 | .name = "atmel_nand", | ||
| 272 | .id = -1, | ||
| 273 | .dev = { | ||
| 274 | .platform_data = &nand_data, | ||
| 275 | }, | ||
| 276 | .resource = nand_resources, | ||
| 277 | .num_resources = ARRAY_SIZE(nand_resources), | ||
| 278 | }; | ||
| 279 | |||
| 280 | void __init at91_add_device_nand(struct atmel_nand_data *data) | ||
| 281 | { | ||
| 282 | unsigned long csa; | ||
| 283 | |||
| 284 | if (!data) | ||
| 285 | return; | ||
| 286 | |||
| 287 | csa = at91_sys_read(AT91_MATRIX_EBICSA); | ||
| 288 | at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); | ||
| 289 | |||
| 290 | /* enable pin */ | ||
| 291 | if (data->enable_pin) | ||
| 292 | at91_set_gpio_output(data->enable_pin, 1); | ||
| 293 | |||
| 294 | /* ready/busy pin */ | ||
| 295 | if (data->rdy_pin) | ||
| 296 | at91_set_gpio_input(data->rdy_pin, 1); | ||
| 297 | |||
| 298 | /* card detect pin */ | ||
| 299 | if (data->det_pin) | ||
| 300 | at91_set_gpio_input(data->det_pin, 1); | ||
| 301 | |||
| 302 | nand_data = *data; | ||
| 303 | platform_device_register(&at91sam9g45_nand_device); | ||
| 304 | } | ||
| 305 | #else | ||
| 306 | void __init at91_add_device_nand(struct atmel_nand_data *data) {} | ||
| 307 | #endif | ||
| 308 | |||
| 309 | |||
| 310 | /* -------------------------------------------------------------------- | ||
| 311 | * TWI (i2c) | ||
| 312 | * -------------------------------------------------------------------- */ | ||
| 313 | |||
| 314 | /* | ||
| 315 | * Prefer the GPIO code since the TWI controller isn't robust | ||
| 316 | * (gets overruns and underruns under load) and can only issue | ||
| 317 | * repeated STARTs in one scenario (the driver doesn't yet handle them). | ||
| 318 | */ | ||
| 319 | #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) | ||
| 320 | static struct i2c_gpio_platform_data pdata_i2c0 = { | ||
| 321 | .sda_pin = AT91_PIN_PA20, | ||
| 322 | .sda_is_open_drain = 1, | ||
| 323 | .scl_pin = AT91_PIN_PA21, | ||
| 324 | .scl_is_open_drain = 1, | ||
| 325 | .udelay = 2, /* ~100 kHz */ | ||
| 326 | }; | ||
| 327 | |||
| 328 | static struct platform_device at91sam9g45_twi0_device = { | ||
| 329 | .name = "i2c-gpio", | ||
| 330 | .id = 0, | ||
| 331 | .dev.platform_data = &pdata_i2c0, | ||
| 332 | }; | ||
| 333 | |||
| 334 | static struct i2c_gpio_platform_data pdata_i2c1 = { | ||
| 335 | .sda_pin = AT91_PIN_PB10, | ||
| 336 | .sda_is_open_drain = 1, | ||
| 337 | .scl_pin = AT91_PIN_PB11, | ||
| 338 | .scl_is_open_drain = 1, | ||
| 339 | .udelay = 2, /* ~100 kHz */ | ||
| 340 | }; | ||
| 341 | |||
| 342 | static struct platform_device at91sam9g45_twi1_device = { | ||
| 343 | .name = "i2c-gpio", | ||
| 344 | .id = 1, | ||
| 345 | .dev.platform_data = &pdata_i2c1, | ||
| 346 | }; | ||
| 347 | |||
| 348 | void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) | ||
| 349 | { | ||
| 350 | i2c_register_board_info(i2c_id, devices, nr_devices); | ||
| 351 | |||
| 352 | if (i2c_id == 0) { | ||
| 353 | at91_set_GPIO_periph(AT91_PIN_PA20, 1); /* TWD (SDA) */ | ||
| 354 | at91_set_multi_drive(AT91_PIN_PA20, 1); | ||
| 355 | |||
| 356 | at91_set_GPIO_periph(AT91_PIN_PA21, 1); /* TWCK (SCL) */ | ||
| 357 | at91_set_multi_drive(AT91_PIN_PA21, 1); | ||
| 358 | |||
| 359 | platform_device_register(&at91sam9g45_twi0_device); | ||
| 360 | } else { | ||
| 361 | at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* TWD (SDA) */ | ||
| 362 | at91_set_multi_drive(AT91_PIN_PB10, 1); | ||
| 363 | |||
| 364 | at91_set_GPIO_periph(AT91_PIN_PB11, 1); /* TWCK (SCL) */ | ||
| 365 | at91_set_multi_drive(AT91_PIN_PB11, 1); | ||
| 366 | |||
| 367 | platform_device_register(&at91sam9g45_twi1_device); | ||
| 368 | } | ||
| 369 | } | ||
| 370 | |||
| 371 | #elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) | ||
| 372 | static struct resource twi0_resources[] = { | ||
| 373 | [0] = { | ||
| 374 | .start = AT91SAM9G45_BASE_TWI0, | ||
| 375 | .end = AT91SAM9G45_BASE_TWI0 + SZ_16K - 1, | ||
| 376 | .flags = IORESOURCE_MEM, | ||
| 377 | }, | ||
| 378 | [1] = { | ||
| 379 | .start = AT91SAM9G45_ID_TWI0, | ||
| 380 | .end = AT91SAM9G45_ID_TWI0, | ||
| 381 | .flags = IORESOURCE_IRQ, | ||
| 382 | }, | ||
| 383 | }; | ||
| 384 | |||
| 385 | static struct platform_device at91sam9g45_twi0_device = { | ||
| 386 | .name = "at91_i2c", | ||
| 387 | .id = 0, | ||
| 388 | .resource = twi0_resources, | ||
| 389 | .num_resources = ARRAY_SIZE(twi0_resources), | ||
| 390 | }; | ||
| 391 | |||
| 392 | static struct resource twi1_resources[] = { | ||
| 393 | [0] = { | ||
| 394 | .start = AT91SAM9G45_BASE_TWI1, | ||
| 395 | .end = AT91SAM9G45_BASE_TWI1 + SZ_16K - 1, | ||
| 396 | .flags = IORESOURCE_MEM, | ||
| 397 | }, | ||
| 398 | [1] = { | ||
| 399 | .start = AT91SAM9G45_ID_TWI1, | ||
| 400 | .end = AT91SAM9G45_ID_TWI1, | ||
| 401 | .flags = IORESOURCE_IRQ, | ||
| 402 | }, | ||
| 403 | }; | ||
| 404 | |||
| 405 | static struct platform_device at91sam9g45_twi1_device = { | ||
| 406 | .name = "at91_i2c", | ||
| 407 | .id = 1, | ||
| 408 | .resource = twi1_resources, | ||
| 409 | .num_resources = ARRAY_SIZE(twi1_resources), | ||
| 410 | }; | ||
| 411 | |||
| 412 | void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) | ||
| 413 | { | ||
| 414 | i2c_register_board_info(i2c_id, devices, nr_devices); | ||
| 415 | |||
| 416 | /* pins used for TWI interface */ | ||
| 417 | if (i2c_id == 0) { | ||
| 418 | at91_set_A_periph(AT91_PIN_PA20, 0); /* TWD */ | ||
| 419 | at91_set_multi_drive(AT91_PIN_PA20, 1); | ||
| 420 | |||
| 421 | at91_set_A_periph(AT91_PIN_PA21, 0); /* TWCK */ | ||
| 422 | at91_set_multi_drive(AT91_PIN_PA21, 1); | ||
| 423 | |||
| 424 | platform_device_register(&at91sam9g45_twi0_device); | ||
| 425 | } else { | ||
| 426 | at91_set_A_periph(AT91_PIN_PB10, 0); /* TWD */ | ||
| 427 | at91_set_multi_drive(AT91_PIN_PB10, 1); | ||
| 428 | |||
| 429 | at91_set_A_periph(AT91_PIN_PB11, 0); /* TWCK */ | ||
| 430 | at91_set_multi_drive(AT91_PIN_PB11, 1); | ||
| 431 | |||
| 432 | platform_device_register(&at91sam9g45_twi1_device); | ||
| 433 | } | ||
| 434 | } | ||
| 435 | #else | ||
| 436 | void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) {} | ||
| 437 | #endif | ||
| 438 | |||
| 439 | |||
| 440 | /* -------------------------------------------------------------------- | ||
| 441 | * SPI | ||
| 442 | * -------------------------------------------------------------------- */ | ||
| 443 | |||
| 444 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | ||
| 445 | static u64 spi_dmamask = DMA_BIT_MASK(32); | ||
| 446 | |||
| 447 | static struct resource spi0_resources[] = { | ||
| 448 | [0] = { | ||
| 449 | .start = AT91SAM9G45_BASE_SPI0, | ||
| 450 | .end = AT91SAM9G45_BASE_SPI0 + SZ_16K - 1, | ||
| 451 | .flags = IORESOURCE_MEM, | ||
| 452 | }, | ||
| 453 | [1] = { | ||
| 454 | .start = AT91SAM9G45_ID_SPI0, | ||
| 455 | .end = AT91SAM9G45_ID_SPI0, | ||
| 456 | .flags = IORESOURCE_IRQ, | ||
| 457 | }, | ||
| 458 | }; | ||
| 459 | |||
| 460 | static struct platform_device at91sam9g45_spi0_device = { | ||
| 461 | .name = "atmel_spi", | ||
| 462 | .id = 0, | ||
| 463 | .dev = { | ||
| 464 | .dma_mask = &spi_dmamask, | ||
| 465 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 466 | }, | ||
| 467 | .resource = spi0_resources, | ||
| 468 | .num_resources = ARRAY_SIZE(spi0_resources), | ||
| 469 | }; | ||
| 470 | |||
| 471 | static const unsigned spi0_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PB18, AT91_PIN_PB19, AT91_PIN_PD27 }; | ||
| 472 | |||
| 473 | static struct resource spi1_resources[] = { | ||
| 474 | [0] = { | ||
| 475 | .start = AT91SAM9G45_BASE_SPI1, | ||
| 476 | .end = AT91SAM9G45_BASE_SPI1 + SZ_16K - 1, | ||
| 477 | .flags = IORESOURCE_MEM, | ||
| 478 | }, | ||
| 479 | [1] = { | ||
| 480 | .start = AT91SAM9G45_ID_SPI1, | ||
| 481 | .end = AT91SAM9G45_ID_SPI1, | ||
| 482 | .flags = IORESOURCE_IRQ, | ||
| 483 | }, | ||
| 484 | }; | ||
| 485 | |||
| 486 | static struct platform_device at91sam9g45_spi1_device = { | ||
| 487 | .name = "atmel_spi", | ||
| 488 | .id = 1, | ||
| 489 | .dev = { | ||
| 490 | .dma_mask = &spi_dmamask, | ||
| 491 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 492 | }, | ||
| 493 | .resource = spi1_resources, | ||
| 494 | .num_resources = ARRAY_SIZE(spi1_resources), | ||
| 495 | }; | ||
| 496 | |||
| 497 | static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB17, AT91_PIN_PD28, AT91_PIN_PD18, AT91_PIN_PD19 }; | ||
| 498 | |||
| 499 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | ||
| 500 | { | ||
| 501 | int i; | ||
| 502 | unsigned long cs_pin; | ||
| 503 | short enable_spi0 = 0; | ||
| 504 | short enable_spi1 = 0; | ||
| 505 | |||
| 506 | /* Choose SPI chip-selects */ | ||
| 507 | for (i = 0; i < nr_devices; i++) { | ||
| 508 | if (devices[i].controller_data) | ||
| 509 | cs_pin = (unsigned long) devices[i].controller_data; | ||
| 510 | else if (devices[i].bus_num == 0) | ||
| 511 | cs_pin = spi0_standard_cs[devices[i].chip_select]; | ||
| 512 | else | ||
| 513 | cs_pin = spi1_standard_cs[devices[i].chip_select]; | ||
| 514 | |||
| 515 | if (devices[i].bus_num == 0) | ||
| 516 | enable_spi0 = 1; | ||
| 517 | else | ||
| 518 | enable_spi1 = 1; | ||
| 519 | |||
| 520 | /* enable chip-select pin */ | ||
| 521 | at91_set_gpio_output(cs_pin, 1); | ||
| 522 | |||
| 523 | /* pass chip-select pin to driver */ | ||
| 524 | devices[i].controller_data = (void *) cs_pin; | ||
| 525 | } | ||
| 526 | |||
| 527 | spi_register_board_info(devices, nr_devices); | ||
| 528 | |||
| 529 | /* Configure SPI bus(es) */ | ||
| 530 | if (enable_spi0) { | ||
| 531 | at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI0_MISO */ | ||
| 532 | at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI0_MOSI */ | ||
| 533 | at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI0_SPCK */ | ||
| 534 | |||
| 535 | at91_clock_associate("spi0_clk", &at91sam9g45_spi0_device.dev, "spi_clk"); | ||
| 536 | platform_device_register(&at91sam9g45_spi0_device); | ||
| 537 | } | ||
| 538 | if (enable_spi1) { | ||
| 539 | at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_MISO */ | ||
| 540 | at91_set_A_periph(AT91_PIN_PB15, 0); /* SPI1_MOSI */ | ||
| 541 | at91_set_A_periph(AT91_PIN_PB16, 0); /* SPI1_SPCK */ | ||
| 542 | |||
| 543 | at91_clock_associate("spi1_clk", &at91sam9g45_spi1_device.dev, "spi_clk"); | ||
| 544 | platform_device_register(&at91sam9g45_spi1_device); | ||
| 545 | } | ||
| 546 | } | ||
| 547 | #else | ||
| 548 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} | ||
| 549 | #endif | ||
| 550 | |||
| 551 | |||
| 552 | /* -------------------------------------------------------------------- | ||
| 553 | * LCD Controller | ||
| 554 | * -------------------------------------------------------------------- */ | ||
| 555 | |||
| 556 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) | ||
| 557 | static u64 lcdc_dmamask = DMA_BIT_MASK(32); | ||
| 558 | static struct atmel_lcdfb_info lcdc_data; | ||
| 559 | |||
| 560 | static struct resource lcdc_resources[] = { | ||
| 561 | [0] = { | ||
| 562 | .start = AT91SAM9G45_LCDC_BASE, | ||
| 563 | .end = AT91SAM9G45_LCDC_BASE + SZ_4K - 1, | ||
| 564 | .flags = IORESOURCE_MEM, | ||
| 565 | }, | ||
| 566 | [1] = { | ||
| 567 | .start = AT91SAM9G45_ID_LCDC, | ||
| 568 | .end = AT91SAM9G45_ID_LCDC, | ||
| 569 | .flags = IORESOURCE_IRQ, | ||
| 570 | }, | ||
| 571 | }; | ||
| 572 | |||
| 573 | static struct platform_device at91_lcdc_device = { | ||
| 574 | .name = "atmel_lcdfb", | ||
| 575 | .id = 0, | ||
| 576 | .dev = { | ||
| 577 | .dma_mask = &lcdc_dmamask, | ||
| 578 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 579 | .platform_data = &lcdc_data, | ||
| 580 | }, | ||
| 581 | .resource = lcdc_resources, | ||
| 582 | .num_resources = ARRAY_SIZE(lcdc_resources), | ||
| 583 | }; | ||
| 584 | |||
| 585 | void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) | ||
| 586 | { | ||
| 587 | if (!data) | ||
| 588 | return; | ||
| 589 | |||
| 590 | at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */ | ||
| 591 | |||
| 592 | at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */ | ||
| 593 | at91_set_A_periph(AT91_PIN_PE3, 0); /* LCDVSYNC */ | ||
| 594 | at91_set_A_periph(AT91_PIN_PE4, 0); /* LCDHSYNC */ | ||
| 595 | at91_set_A_periph(AT91_PIN_PE5, 0); /* LCDDOTCK */ | ||
| 596 | at91_set_A_periph(AT91_PIN_PE6, 0); /* LCDDEN */ | ||
| 597 | at91_set_A_periph(AT91_PIN_PE7, 0); /* LCDD0 */ | ||
| 598 | at91_set_A_periph(AT91_PIN_PE8, 0); /* LCDD1 */ | ||
| 599 | at91_set_A_periph(AT91_PIN_PE9, 0); /* LCDD2 */ | ||
| 600 | at91_set_A_periph(AT91_PIN_PE10, 0); /* LCDD3 */ | ||
| 601 | at91_set_A_periph(AT91_PIN_PE11, 0); /* LCDD4 */ | ||
| 602 | at91_set_A_periph(AT91_PIN_PE12, 0); /* LCDD5 */ | ||
| 603 | at91_set_A_periph(AT91_PIN_PE13, 0); /* LCDD6 */ | ||
| 604 | at91_set_A_periph(AT91_PIN_PE14, 0); /* LCDD7 */ | ||
| 605 | at91_set_A_periph(AT91_PIN_PE15, 0); /* LCDD8 */ | ||
| 606 | at91_set_A_periph(AT91_PIN_PE16, 0); /* LCDD9 */ | ||
| 607 | at91_set_A_periph(AT91_PIN_PE17, 0); /* LCDD10 */ | ||
| 608 | at91_set_A_periph(AT91_PIN_PE18, 0); /* LCDD11 */ | ||
| 609 | at91_set_A_periph(AT91_PIN_PE19, 0); /* LCDD12 */ | ||
| 610 | at91_set_A_periph(AT91_PIN_PE20, 0); /* LCDD13 */ | ||
| 611 | at91_set_A_periph(AT91_PIN_PE21, 0); /* LCDD14 */ | ||
| 612 | at91_set_A_periph(AT91_PIN_PE22, 0); /* LCDD15 */ | ||
| 613 | at91_set_A_periph(AT91_PIN_PE23, 0); /* LCDD16 */ | ||
| 614 | at91_set_A_periph(AT91_PIN_PE24, 0); /* LCDD17 */ | ||
| 615 | at91_set_A_periph(AT91_PIN_PE25, 0); /* LCDD18 */ | ||
| 616 | at91_set_A_periph(AT91_PIN_PE26, 0); /* LCDD19 */ | ||
| 617 | at91_set_A_periph(AT91_PIN_PE27, 0); /* LCDD20 */ | ||
| 618 | at91_set_A_periph(AT91_PIN_PE28, 0); /* LCDD21 */ | ||
| 619 | at91_set_A_periph(AT91_PIN_PE29, 0); /* LCDD22 */ | ||
| 620 | at91_set_A_periph(AT91_PIN_PE30, 0); /* LCDD23 */ | ||
| 621 | |||
| 622 | lcdc_data = *data; | ||
| 623 | platform_device_register(&at91_lcdc_device); | ||
| 624 | } | ||
| 625 | #else | ||
| 626 | void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} | ||
| 627 | #endif | ||
| 628 | |||
| 629 | |||
| 630 | /* -------------------------------------------------------------------- | ||
| 631 | * Timer/Counter block | ||
| 632 | * -------------------------------------------------------------------- */ | ||
| 633 | |||
| 634 | #ifdef CONFIG_ATMEL_TCLIB | ||
| 635 | static struct resource tcb0_resources[] = { | ||
| 636 | [0] = { | ||
| 637 | .start = AT91SAM9G45_BASE_TCB0, | ||
| 638 | .end = AT91SAM9G45_BASE_TCB0 + SZ_16K - 1, | ||
| 639 | .flags = IORESOURCE_MEM, | ||
| 640 | }, | ||
| 641 | [1] = { | ||
| 642 | .start = AT91SAM9G45_ID_TCB, | ||
| 643 | .end = AT91SAM9G45_ID_TCB, | ||
| 644 | .flags = IORESOURCE_IRQ, | ||
| 645 | }, | ||
| 646 | }; | ||
| 647 | |||
| 648 | static struct platform_device at91sam9g45_tcb0_device = { | ||
| 649 | .name = "atmel_tcb", | ||
| 650 | .id = 0, | ||
| 651 | .resource = tcb0_resources, | ||
| 652 | .num_resources = ARRAY_SIZE(tcb0_resources), | ||
| 653 | }; | ||
| 654 | |||
| 655 | /* TCB1 begins with TC3 */ | ||
| 656 | static struct resource tcb1_resources[] = { | ||
| 657 | [0] = { | ||
| 658 | .start = AT91SAM9G45_BASE_TCB1, | ||
| 659 | .end = AT91SAM9G45_BASE_TCB1 + SZ_16K - 1, | ||
| 660 | .flags = IORESOURCE_MEM, | ||
| 661 | }, | ||
| 662 | [1] = { | ||
| 663 | .start = AT91SAM9G45_ID_TCB, | ||
| 664 | .end = AT91SAM9G45_ID_TCB, | ||
| 665 | .flags = IORESOURCE_IRQ, | ||
| 666 | }, | ||
| 667 | }; | ||
| 668 | |||
| 669 | static struct platform_device at91sam9g45_tcb1_device = { | ||
| 670 | .name = "atmel_tcb", | ||
| 671 | .id = 1, | ||
| 672 | .resource = tcb1_resources, | ||
| 673 | .num_resources = ARRAY_SIZE(tcb1_resources), | ||
| 674 | }; | ||
| 675 | |||
| 676 | static void __init at91_add_device_tc(void) | ||
| 677 | { | ||
| 678 | /* this chip has one clock and irq for all six TC channels */ | ||
| 679 | at91_clock_associate("tcb_clk", &at91sam9g45_tcb0_device.dev, "t0_clk"); | ||
| 680 | platform_device_register(&at91sam9g45_tcb0_device); | ||
| 681 | at91_clock_associate("tcb_clk", &at91sam9g45_tcb1_device.dev, "t0_clk"); | ||
| 682 | platform_device_register(&at91sam9g45_tcb1_device); | ||
| 683 | } | ||
| 684 | #else | ||
| 685 | static void __init at91_add_device_tc(void) { } | ||
| 686 | #endif | ||
| 687 | |||
| 688 | |||
| 689 | /* -------------------------------------------------------------------- | ||
| 690 | * RTC | ||
| 691 | * -------------------------------------------------------------------- */ | ||
| 692 | |||
| 693 | #if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) | ||
| 694 | static struct platform_device at91sam9g45_rtc_device = { | ||
| 695 | .name = "at91_rtc", | ||
| 696 | .id = -1, | ||
| 697 | .num_resources = 0, | ||
| 698 | }; | ||
| 699 | |||
| 700 | static void __init at91_add_device_rtc(void) | ||
| 701 | { | ||
| 702 | platform_device_register(&at91sam9g45_rtc_device); | ||
| 703 | } | ||
| 704 | #else | ||
| 705 | static void __init at91_add_device_rtc(void) {} | ||
| 706 | #endif | ||
| 707 | |||
| 708 | |||
| 709 | /* -------------------------------------------------------------------- | ||
| 710 | * RTT | ||
| 711 | * -------------------------------------------------------------------- */ | ||
| 712 | |||
| 713 | static struct resource rtt_resources[] = { | ||
| 714 | { | ||
| 715 | .start = AT91_BASE_SYS + AT91_RTT, | ||
| 716 | .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, | ||
| 717 | .flags = IORESOURCE_MEM, | ||
| 718 | } | ||
| 719 | }; | ||
| 720 | |||
| 721 | static struct platform_device at91sam9g45_rtt_device = { | ||
| 722 | .name = "at91_rtt", | ||
| 723 | .id = 0, | ||
| 724 | .resource = rtt_resources, | ||
| 725 | .num_resources = ARRAY_SIZE(rtt_resources), | ||
| 726 | }; | ||
| 727 | |||
| 728 | static void __init at91_add_device_rtt(void) | ||
| 729 | { | ||
| 730 | platform_device_register(&at91sam9g45_rtt_device); | ||
| 731 | } | ||
| 732 | |||
| 733 | |||
| 734 | /* -------------------------------------------------------------------- | ||
| 735 | * Watchdog | ||
| 736 | * -------------------------------------------------------------------- */ | ||
| 737 | |||
| 738 | #if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE) | ||
| 739 | static struct platform_device at91sam9g45_wdt_device = { | ||
| 740 | .name = "at91_wdt", | ||
| 741 | .id = -1, | ||
| 742 | .num_resources = 0, | ||
| 743 | }; | ||
| 744 | |||
| 745 | static void __init at91_add_device_watchdog(void) | ||
| 746 | { | ||
| 747 | platform_device_register(&at91sam9g45_wdt_device); | ||
| 748 | } | ||
| 749 | #else | ||
| 750 | static void __init at91_add_device_watchdog(void) {} | ||
| 751 | #endif | ||
| 752 | |||
| 753 | |||
| 754 | /* -------------------------------------------------------------------- | ||
| 755 | * PWM | ||
| 756 | * --------------------------------------------------------------------*/ | ||
| 757 | |||
| 758 | #if defined(CONFIG_ATMEL_PWM) || defined(CONFIG_ATMEL_PWM_MODULE) | ||
| 759 | static u32 pwm_mask; | ||
| 760 | |||
| 761 | static struct resource pwm_resources[] = { | ||
| 762 | [0] = { | ||
| 763 | .start = AT91SAM9G45_BASE_PWMC, | ||
| 764 | .end = AT91SAM9G45_BASE_PWMC + SZ_16K - 1, | ||
| 765 | .flags = IORESOURCE_MEM, | ||
| 766 | }, | ||
| 767 | [1] = { | ||
| 768 | .start = AT91SAM9G45_ID_PWMC, | ||
| 769 | .end = AT91SAM9G45_ID_PWMC, | ||
| 770 | .flags = IORESOURCE_IRQ, | ||
| 771 | }, | ||
| 772 | }; | ||
| 773 | |||
| 774 | static struct platform_device at91sam9g45_pwm0_device = { | ||
| 775 | .name = "atmel_pwm", | ||
| 776 | .id = -1, | ||
| 777 | .dev = { | ||
| 778 | .platform_data = &pwm_mask, | ||
| 779 | }, | ||
| 780 | .resource = pwm_resources, | ||
| 781 | .num_resources = ARRAY_SIZE(pwm_resources), | ||
| 782 | }; | ||
| 783 | |||
| 784 | void __init at91_add_device_pwm(u32 mask) | ||
| 785 | { | ||
| 786 | if (mask & (1 << AT91_PWM0)) | ||
| 787 | at91_set_B_periph(AT91_PIN_PD24, 1); /* enable PWM0 */ | ||
| 788 | |||
| 789 | if (mask & (1 << AT91_PWM1)) | ||
| 790 | at91_set_B_periph(AT91_PIN_PD31, 1); /* enable PWM1 */ | ||
| 791 | |||
| 792 | if (mask & (1 << AT91_PWM2)) | ||
| 793 | at91_set_B_periph(AT91_PIN_PD26, 1); /* enable PWM2 */ | ||
| 794 | |||
| 795 | if (mask & (1 << AT91_PWM3)) | ||
| 796 | at91_set_B_periph(AT91_PIN_PD0, 1); /* enable PWM3 */ | ||
| 797 | |||
| 798 | pwm_mask = mask; | ||
| 799 | |||
| 800 | platform_device_register(&at91sam9g45_pwm0_device); | ||
| 801 | } | ||
| 802 | #else | ||
| 803 | void __init at91_add_device_pwm(u32 mask) {} | ||
| 804 | #endif | ||
| 805 | |||
| 806 | |||
| 807 | /* -------------------------------------------------------------------- | ||
| 808 | * SSC -- Synchronous Serial Controller | ||
| 809 | * -------------------------------------------------------------------- */ | ||
| 810 | |||
| 811 | #if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE) | ||
| 812 | static u64 ssc0_dmamask = DMA_BIT_MASK(32); | ||
| 813 | |||
| 814 | static struct resource ssc0_resources[] = { | ||
| 815 | [0] = { | ||
| 816 | .start = AT91SAM9G45_BASE_SSC0, | ||
| 817 | .end = AT91SAM9G45_BASE_SSC0 + SZ_16K - 1, | ||
| 818 | .flags = IORESOURCE_MEM, | ||
| 819 | }, | ||
| 820 | [1] = { | ||
| 821 | .start = AT91SAM9G45_ID_SSC0, | ||
| 822 | .end = AT91SAM9G45_ID_SSC0, | ||
| 823 | .flags = IORESOURCE_IRQ, | ||
| 824 | }, | ||
| 825 | }; | ||
| 826 | |||
| 827 | static struct platform_device at91sam9g45_ssc0_device = { | ||
| 828 | .name = "ssc", | ||
| 829 | .id = 0, | ||
| 830 | .dev = { | ||
| 831 | .dma_mask = &ssc0_dmamask, | ||
| 832 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 833 | }, | ||
| 834 | .resource = ssc0_resources, | ||
| 835 | .num_resources = ARRAY_SIZE(ssc0_resources), | ||
| 836 | }; | ||
| 837 | |||
| 838 | static inline void configure_ssc0_pins(unsigned pins) | ||
| 839 | { | ||
| 840 | if (pins & ATMEL_SSC_TF) | ||
| 841 | at91_set_A_periph(AT91_PIN_PD1, 1); | ||
| 842 | if (pins & ATMEL_SSC_TK) | ||
| 843 | at91_set_A_periph(AT91_PIN_PD0, 1); | ||
| 844 | if (pins & ATMEL_SSC_TD) | ||
| 845 | at91_set_A_periph(AT91_PIN_PD2, 1); | ||
| 846 | if (pins & ATMEL_SSC_RD) | ||
| 847 | at91_set_A_periph(AT91_PIN_PD3, 1); | ||
| 848 | if (pins & ATMEL_SSC_RK) | ||
| 849 | at91_set_A_periph(AT91_PIN_PD4, 1); | ||
| 850 | if (pins & ATMEL_SSC_RF) | ||
| 851 | at91_set_A_periph(AT91_PIN_PD5, 1); | ||
| 852 | } | ||
| 853 | |||
| 854 | static u64 ssc1_dmamask = DMA_BIT_MASK(32); | ||
| 855 | |||
| 856 | static struct resource ssc1_resources[] = { | ||
| 857 | [0] = { | ||
| 858 | .start = AT91SAM9G45_BASE_SSC1, | ||
| 859 | .end = AT91SAM9G45_BASE_SSC1 + SZ_16K - 1, | ||
| 860 | .flags = IORESOURCE_MEM, | ||
| 861 | }, | ||
| 862 | [1] = { | ||
| 863 | .start = AT91SAM9G45_ID_SSC1, | ||
| 864 | .end = AT91SAM9G45_ID_SSC1, | ||
| 865 | .flags = IORESOURCE_IRQ, | ||
| 866 | }, | ||
| 867 | }; | ||
| 868 | |||
| 869 | static struct platform_device at91sam9g45_ssc1_device = { | ||
| 870 | .name = "ssc", | ||
| 871 | .id = 1, | ||
| 872 | .dev = { | ||
| 873 | .dma_mask = &ssc1_dmamask, | ||
| 874 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 875 | }, | ||
| 876 | .resource = ssc1_resources, | ||
| 877 | .num_resources = ARRAY_SIZE(ssc1_resources), | ||
| 878 | }; | ||
| 879 | |||
| 880 | static inline void configure_ssc1_pins(unsigned pins) | ||
| 881 | { | ||
| 882 | if (pins & ATMEL_SSC_TF) | ||
| 883 | at91_set_A_periph(AT91_PIN_PD14, 1); | ||
| 884 | if (pins & ATMEL_SSC_TK) | ||
| 885 | at91_set_A_periph(AT91_PIN_PD12, 1); | ||
| 886 | if (pins & ATMEL_SSC_TD) | ||
| 887 | at91_set_A_periph(AT91_PIN_PD10, 1); | ||
| 888 | if (pins & ATMEL_SSC_RD) | ||
| 889 | at91_set_A_periph(AT91_PIN_PD11, 1); | ||
| 890 | if (pins & ATMEL_SSC_RK) | ||
| 891 | at91_set_A_periph(AT91_PIN_PD13, 1); | ||
| 892 | if (pins & ATMEL_SSC_RF) | ||
| 893 | at91_set_A_periph(AT91_PIN_PD15, 1); | ||
| 894 | } | ||
| 895 | |||
| 896 | /* | ||
| 897 | * SSC controllers are accessed through library code, instead of any | ||
| 898 | * kind of all-singing/all-dancing driver. For example one could be | ||
| 899 | * used by a particular I2S audio codec's driver, while another one | ||
| 900 | * on the same system might be used by a custom data capture driver. | ||
| 901 | */ | ||
| 902 | void __init at91_add_device_ssc(unsigned id, unsigned pins) | ||
| 903 | { | ||
| 904 | struct platform_device *pdev; | ||
| 905 | |||
| 906 | /* | ||
| 907 | * NOTE: caller is responsible for passing information matching | ||
| 908 | * "pins" to whatever will be using each particular controller. | ||
| 909 | */ | ||
| 910 | switch (id) { | ||
| 911 | case AT91SAM9G45_ID_SSC0: | ||
| 912 | pdev = &at91sam9g45_ssc0_device; | ||
| 913 | configure_ssc0_pins(pins); | ||
| 914 | at91_clock_associate("ssc0_clk", &pdev->dev, "pclk"); | ||
| 915 | break; | ||
| 916 | case AT91SAM9G45_ID_SSC1: | ||
| 917 | pdev = &at91sam9g45_ssc1_device; | ||
| 918 | configure_ssc1_pins(pins); | ||
| 919 | at91_clock_associate("ssc1_clk", &pdev->dev, "pclk"); | ||
| 920 | break; | ||
| 921 | default: | ||
| 922 | return; | ||
| 923 | } | ||
| 924 | |||
| 925 | platform_device_register(pdev); | ||
| 926 | } | ||
| 927 | |||
| 928 | #else | ||
| 929 | void __init at91_add_device_ssc(unsigned id, unsigned pins) {} | ||
| 930 | #endif | ||
| 931 | |||
| 932 | |||
| 933 | /* -------------------------------------------------------------------- | ||
| 934 | * UART | ||
| 935 | * -------------------------------------------------------------------- */ | ||
| 936 | |||
| 937 | #if defined(CONFIG_SERIAL_ATMEL) | ||
| 938 | static struct resource dbgu_resources[] = { | ||
| 939 | [0] = { | ||
| 940 | .start = AT91_VA_BASE_SYS + AT91_DBGU, | ||
| 941 | .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, | ||
| 942 | .flags = IORESOURCE_MEM, | ||
| 943 | }, | ||
| 944 | [1] = { | ||
| 945 | .start = AT91_ID_SYS, | ||
| 946 | .end = AT91_ID_SYS, | ||
| 947 | .flags = IORESOURCE_IRQ, | ||
| 948 | }, | ||
| 949 | }; | ||
| 950 | |||
| 951 | static struct atmel_uart_data dbgu_data = { | ||
| 952 | .use_dma_tx = 0, | ||
| 953 | .use_dma_rx = 0, | ||
| 954 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | ||
| 955 | }; | ||
| 956 | |||
| 957 | static u64 dbgu_dmamask = DMA_BIT_MASK(32); | ||
| 958 | |||
| 959 | static struct platform_device at91sam9g45_dbgu_device = { | ||
| 960 | .name = "atmel_usart", | ||
| 961 | .id = 0, | ||
| 962 | .dev = { | ||
| 963 | .dma_mask = &dbgu_dmamask, | ||
| 964 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 965 | .platform_data = &dbgu_data, | ||
| 966 | }, | ||
| 967 | .resource = dbgu_resources, | ||
| 968 | .num_resources = ARRAY_SIZE(dbgu_resources), | ||
| 969 | }; | ||
| 970 | |||
| 971 | static inline void configure_dbgu_pins(void) | ||
| 972 | { | ||
| 973 | at91_set_A_periph(AT91_PIN_PB12, 0); /* DRXD */ | ||
| 974 | at91_set_A_periph(AT91_PIN_PB13, 1); /* DTXD */ | ||
| 975 | } | ||
| 976 | |||
| 977 | static struct resource uart0_resources[] = { | ||
| 978 | [0] = { | ||
| 979 | .start = AT91SAM9G45_BASE_US0, | ||
| 980 | .end = AT91SAM9G45_BASE_US0 + SZ_16K - 1, | ||
| 981 | .flags = IORESOURCE_MEM, | ||
| 982 | }, | ||
| 983 | [1] = { | ||
| 984 | .start = AT91SAM9G45_ID_US0, | ||
| 985 | .end = AT91SAM9G45_ID_US0, | ||
| 986 | .flags = IORESOURCE_IRQ, | ||
| 987 | }, | ||
| 988 | }; | ||
| 989 | |||
| 990 | static struct atmel_uart_data uart0_data = { | ||
| 991 | .use_dma_tx = 1, | ||
| 992 | .use_dma_rx = 1, | ||
| 993 | }; | ||
| 994 | |||
| 995 | static u64 uart0_dmamask = DMA_BIT_MASK(32); | ||
| 996 | |||
| 997 | static struct platform_device at91sam9g45_uart0_device = { | ||
| 998 | .name = "atmel_usart", | ||
| 999 | .id = 1, | ||
| 1000 | .dev = { | ||
| 1001 | .dma_mask = &uart0_dmamask, | ||
| 1002 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 1003 | .platform_data = &uart0_data, | ||
| 1004 | }, | ||
| 1005 | .resource = uart0_resources, | ||
| 1006 | .num_resources = ARRAY_SIZE(uart0_resources), | ||
| 1007 | }; | ||
| 1008 | |||
| 1009 | static inline void configure_usart0_pins(unsigned pins) | ||
| 1010 | { | ||
| 1011 | at91_set_A_periph(AT91_PIN_PB19, 1); /* TXD0 */ | ||
| 1012 | at91_set_A_periph(AT91_PIN_PB18, 0); /* RXD0 */ | ||
| 1013 | |||
| 1014 | if (pins & ATMEL_UART_RTS) | ||
| 1015 | at91_set_B_periph(AT91_PIN_PB17, 0); /* RTS0 */ | ||
| 1016 | if (pins & ATMEL_UART_CTS) | ||
| 1017 | at91_set_B_periph(AT91_PIN_PB15, 0); /* CTS0 */ | ||
| 1018 | } | ||
| 1019 | |||
| 1020 | static struct resource uart1_resources[] = { | ||
| 1021 | [0] = { | ||
| 1022 | .start = AT91SAM9G45_BASE_US1, | ||
| 1023 | .end = AT91SAM9G45_BASE_US1 + SZ_16K - 1, | ||
| 1024 | .flags = IORESOURCE_MEM, | ||
| 1025 | }, | ||
| 1026 | [1] = { | ||
| 1027 | .start = AT91SAM9G45_ID_US1, | ||
| 1028 | .end = AT91SAM9G45_ID_US1, | ||
| 1029 | .flags = IORESOURCE_IRQ, | ||
| 1030 | }, | ||
| 1031 | }; | ||
| 1032 | |||
| 1033 | static struct atmel_uart_data uart1_data = { | ||
| 1034 | .use_dma_tx = 1, | ||
| 1035 | .use_dma_rx = 1, | ||
| 1036 | }; | ||
| 1037 | |||
| 1038 | static u64 uart1_dmamask = DMA_BIT_MASK(32); | ||
| 1039 | |||
| 1040 | static struct platform_device at91sam9g45_uart1_device = { | ||
| 1041 | .name = "atmel_usart", | ||
| 1042 | .id = 2, | ||
| 1043 | .dev = { | ||
| 1044 | .dma_mask = &uart1_dmamask, | ||
| 1045 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 1046 | .platform_data = &uart1_data, | ||
| 1047 | }, | ||
| 1048 | .resource = uart1_resources, | ||
| 1049 | .num_resources = ARRAY_SIZE(uart1_resources), | ||
| 1050 | }; | ||
| 1051 | |||
| 1052 | static inline void configure_usart1_pins(unsigned pins) | ||
| 1053 | { | ||
| 1054 | at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD1 */ | ||
| 1055 | at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD1 */ | ||
| 1056 | |||
| 1057 | if (pins & ATMEL_UART_RTS) | ||
| 1058 | at91_set_A_periph(AT91_PIN_PD16, 0); /* RTS1 */ | ||
| 1059 | if (pins & ATMEL_UART_CTS) | ||
| 1060 | at91_set_A_periph(AT91_PIN_PD17, 0); /* CTS1 */ | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | static struct resource uart2_resources[] = { | ||
| 1064 | [0] = { | ||
| 1065 | .start = AT91SAM9G45_BASE_US2, | ||
| 1066 | .end = AT91SAM9G45_BASE_US2 + SZ_16K - 1, | ||
| 1067 | .flags = IORESOURCE_MEM, | ||
| 1068 | }, | ||
| 1069 | [1] = { | ||
| 1070 | .start = AT91SAM9G45_ID_US2, | ||
| 1071 | .end = AT91SAM9G45_ID_US2, | ||
| 1072 | .flags = IORESOURCE_IRQ, | ||
| 1073 | }, | ||
| 1074 | }; | ||
| 1075 | |||
| 1076 | static struct atmel_uart_data uart2_data = { | ||
| 1077 | .use_dma_tx = 1, | ||
| 1078 | .use_dma_rx = 1, | ||
| 1079 | }; | ||
| 1080 | |||
| 1081 | static u64 uart2_dmamask = DMA_BIT_MASK(32); | ||
| 1082 | |||
| 1083 | static struct platform_device at91sam9g45_uart2_device = { | ||
| 1084 | .name = "atmel_usart", | ||
| 1085 | .id = 3, | ||
| 1086 | .dev = { | ||
| 1087 | .dma_mask = &uart2_dmamask, | ||
| 1088 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 1089 | .platform_data = &uart2_data, | ||
| 1090 | }, | ||
| 1091 | .resource = uart2_resources, | ||
| 1092 | .num_resources = ARRAY_SIZE(uart2_resources), | ||
| 1093 | }; | ||
| 1094 | |||
| 1095 | static inline void configure_usart2_pins(unsigned pins) | ||
| 1096 | { | ||
| 1097 | at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD2 */ | ||
| 1098 | at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD2 */ | ||
| 1099 | |||
| 1100 | if (pins & ATMEL_UART_RTS) | ||
| 1101 | at91_set_B_periph(AT91_PIN_PC9, 0); /* RTS2 */ | ||
| 1102 | if (pins & ATMEL_UART_CTS) | ||
| 1103 | at91_set_B_periph(AT91_PIN_PC11, 0); /* CTS2 */ | ||
| 1104 | } | ||
| 1105 | |||
| 1106 | static struct resource uart3_resources[] = { | ||
| 1107 | [0] = { | ||
| 1108 | .start = AT91SAM9G45_BASE_US3, | ||
| 1109 | .end = AT91SAM9G45_BASE_US3 + SZ_16K - 1, | ||
| 1110 | .flags = IORESOURCE_MEM, | ||
| 1111 | }, | ||
| 1112 | [1] = { | ||
| 1113 | .start = AT91SAM9G45_ID_US3, | ||
| 1114 | .end = AT91SAM9G45_ID_US3, | ||
| 1115 | .flags = IORESOURCE_IRQ, | ||
| 1116 | }, | ||
| 1117 | }; | ||
| 1118 | |||
| 1119 | static struct atmel_uart_data uart3_data = { | ||
| 1120 | .use_dma_tx = 1, | ||
| 1121 | .use_dma_rx = 1, | ||
| 1122 | }; | ||
| 1123 | |||
| 1124 | static u64 uart3_dmamask = DMA_BIT_MASK(32); | ||
| 1125 | |||
| 1126 | static struct platform_device at91sam9g45_uart3_device = { | ||
| 1127 | .name = "atmel_usart", | ||
| 1128 | .id = 4, | ||
| 1129 | .dev = { | ||
| 1130 | .dma_mask = &uart3_dmamask, | ||
| 1131 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
| 1132 | .platform_data = &uart3_data, | ||
| 1133 | }, | ||
| 1134 | .resource = uart3_resources, | ||
| 1135 | .num_resources = ARRAY_SIZE(uart3_resources), | ||
| 1136 | }; | ||
| 1137 | |||
| 1138 | static inline void configure_usart3_pins(unsigned pins) | ||
| 1139 | { | ||
| 1140 | at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD3 */ | ||
| 1141 | at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD3 */ | ||
| 1142 | |||
| 1143 | if (pins & ATMEL_UART_RTS) | ||
| 1144 | at91_set_B_periph(AT91_PIN_PA23, 0); /* RTS3 */ | ||
| 1145 | if (pins & ATMEL_UART_CTS) | ||
| 1146 | at91_set_B_periph(AT91_PIN_PA24, 0); /* CTS3 */ | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | ||
| 1150 | struct platform_device *atmel_default_console_device; /* the serial console device */ | ||
| 1151 | |||
| 1152 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) | ||
| 1153 | { | ||
| 1154 | struct platform_device *pdev; | ||
| 1155 | |||
| 1156 | switch (id) { | ||
| 1157 | case 0: /* DBGU */ | ||
| 1158 | pdev = &at91sam9g45_dbgu_device; | ||
| 1159 | configure_dbgu_pins(); | ||
| 1160 | at91_clock_associate("mck", &pdev->dev, "usart"); | ||
| 1161 | break; | ||
| 1162 | case AT91SAM9G45_ID_US0: | ||
| 1163 | pdev = &at91sam9g45_uart0_device; | ||
| 1164 | configure_usart0_pins(pins); | ||
| 1165 | at91_clock_associate("usart0_clk", &pdev->dev, "usart"); | ||
| 1166 | break; | ||
| 1167 | case AT91SAM9G45_ID_US1: | ||
| 1168 | pdev = &at91sam9g45_uart1_device; | ||
| 1169 | configure_usart1_pins(pins); | ||
| 1170 | at91_clock_associate("usart1_clk", &pdev->dev, "usart"); | ||
| 1171 | break; | ||
| 1172 | case AT91SAM9G45_ID_US2: | ||
| 1173 | pdev = &at91sam9g45_uart2_device; | ||
| 1174 | configure_usart2_pins(pins); | ||
| 1175 | at91_clock_associate("usart2_clk", &pdev->dev, "usart"); | ||
| 1176 | break; | ||
| 1177 | case AT91SAM9G45_ID_US3: | ||
| 1178 | pdev = &at91sam9g45_uart3_device; | ||
| 1179 | configure_usart3_pins(pins); | ||
| 1180 | at91_clock_associate("usart3_clk", &pdev->dev, "usart"); | ||
| 1181 | break; | ||
| 1182 | default: | ||
| 1183 | return; | ||
| 1184 | } | ||
| 1185 | pdev->id = portnr; /* update to mapped ID */ | ||
| 1186 | |||
| 1187 | if (portnr < ATMEL_MAX_UART) | ||
| 1188 | at91_uarts[portnr] = pdev; | ||
| 1189 | } | ||
| 1190 | |||
| 1191 | void __init at91_set_serial_console(unsigned portnr) | ||
| 1192 | { | ||
| 1193 | if (portnr < ATMEL_MAX_UART) | ||
| 1194 | atmel_default_console_device = at91_uarts[portnr]; | ||
| 1195 | } | ||
| 1196 | |||
| 1197 | void __init at91_add_device_serial(void) | ||
| 1198 | { | ||
| 1199 | int i; | ||
| 1200 | |||
| 1201 | for (i = 0; i < ATMEL_MAX_UART; i++) { | ||
| 1202 | if (at91_uarts[i]) | ||
| 1203 | platform_device_register(at91_uarts[i]); | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | if (!atmel_default_console_device) | ||
| 1207 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
| 1208 | } | ||
| 1209 | #else | ||
| 1210 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} | ||
| 1211 | void __init at91_set_serial_console(unsigned portnr) {} | ||
| 1212 | void __init at91_add_device_serial(void) {} | ||
| 1213 | #endif | ||
| 1214 | |||
| 1215 | |||
| 1216 | /* -------------------------------------------------------------------- */ | ||
| 1217 | /* | ||
| 1218 | * These devices are always present and don't need any board-specific | ||
| 1219 | * setup. | ||
| 1220 | */ | ||
| 1221 | static int __init at91_add_standard_devices(void) | ||
| 1222 | { | ||
| 1223 | at91_add_device_rtc(); | ||
| 1224 | at91_add_device_rtt(); | ||
| 1225 | at91_add_device_watchdog(); | ||
| 1226 | at91_add_device_tc(); | ||
| 1227 | return 0; | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | arch_initcall(at91_add_standard_devices); | ||
diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c index 970fd6b6753e..61e52b66bc72 100644 --- a/arch/arm/mach-at91/board-afeb-9260v1.c +++ b/arch/arm/mach-at91/board-afeb-9260v1.c | |||
| @@ -174,6 +174,16 @@ static struct i2c_board_info __initdata afeb9260_i2c_devices[] = { | |||
| 174 | }, | 174 | }, |
| 175 | }; | 175 | }; |
| 176 | 176 | ||
| 177 | /* | ||
| 178 | * IDE (CF True IDE mode) | ||
| 179 | */ | ||
| 180 | static struct at91_cf_data afeb9260_cf_data = { | ||
| 181 | .chipselect = 4, | ||
| 182 | .irq_pin = AT91_PIN_PA6, | ||
| 183 | .rst_pin = AT91_PIN_PA7, | ||
| 184 | .flags = AT91_CF_TRUE_IDE, | ||
| 185 | }; | ||
| 186 | |||
| 177 | static void __init afeb9260_board_init(void) | 187 | static void __init afeb9260_board_init(void) |
| 178 | { | 188 | { |
| 179 | /* Serial */ | 189 | /* Serial */ |
| @@ -202,6 +212,8 @@ static void __init afeb9260_board_init(void) | |||
| 202 | ARRAY_SIZE(afeb9260_i2c_devices)); | 212 | ARRAY_SIZE(afeb9260_i2c_devices)); |
| 203 | /* Audio */ | 213 | /* Audio */ |
| 204 | at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); | 214 | at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX); |
| 215 | /* IDE */ | ||
| 216 | at91_add_device_cf(&afeb9260_cf_data); | ||
| 205 | } | 217 | } |
| 206 | 218 | ||
| 207 | MACHINE_START(AFEB9260, "Custom afeb9260 board") | 219 | MACHINE_START(AFEB9260, "Custom afeb9260 board") |
diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c new file mode 100644 index 000000000000..4bc2e9f6ebb5 --- /dev/null +++ b/arch/arm/mach-at91/board-cpu9krea.c | |||
| @@ -0,0 +1,385 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-at91/board-cpu9krea.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 SAN People | ||
| 5 | * Copyright (C) 2006 Atmel | ||
| 6 | * Copyright (C) 2009 Eric Benard - eric@eukrea.com | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/types.h> | ||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/mm.h> | ||
| 26 | #include <linux/module.h> | ||
| 27 | #include <linux/platform_device.h> | ||
| 28 | #include <linux/clk.h> | ||
| 29 | #include <linux/gpio_keys.h> | ||
| 30 | #include <linux/input.h> | ||
| 31 | #include <linux/mtd/physmap.h> | ||
| 32 | |||
| 33 | #include <asm/setup.h> | ||
| 34 | #include <asm/mach-types.h> | ||
| 35 | #include <asm/irq.h> | ||
| 36 | |||
| 37 | #include <asm/mach/arch.h> | ||
| 38 | #include <asm/mach/map.h> | ||
| 39 | #include <asm/mach/irq.h> | ||
| 40 | |||
| 41 | #include <mach/hardware.h> | ||
| 42 | #include <mach/board.h> | ||
| 43 | #include <mach/gpio.h> | ||
| 44 | #include <mach/at91sam9_smc.h> | ||
| 45 | #include <mach/at91sam9260_matrix.h> | ||
| 46 | |||
| 47 | #include "sam9_smc.h" | ||
| 48 | #include "generic.h" | ||
| 49 | |||
| 50 | static void __init cpu9krea_map_io(void) | ||
| 51 | { | ||
| 52 | /* Initialize processor: 18.432 MHz crystal */ | ||
| 53 | at91sam9260_initialize(18432000); | ||
| 54 | |||
| 55 | /* DGBU on ttyS0. (Rx & Tx only) */ | ||
| 56 | at91_register_uart(0, 0, 0); | ||
| 57 | |||
| 58 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | ||
| 59 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | | ||
| 60 | ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR | | ||
| 61 | ATMEL_UART_DCD | ATMEL_UART_RI); | ||
| 62 | |||
| 63 | /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ | ||
| 64 | at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | | ||
| 65 | ATMEL_UART_RTS); | ||
| 66 | |||
| 67 | /* USART2 on ttyS3. (Rx, Tx, RTS, CTS) */ | ||
| 68 | at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | | ||
| 69 | ATMEL_UART_RTS); | ||
| 70 | |||
| 71 | /* USART3 on ttyS4. (Rx, Tx) */ | ||
| 72 | at91_register_uart(AT91SAM9260_ID_US3, 4, 0); | ||
| 73 | |||
| 74 | /* USART4 on ttyS5. (Rx, Tx) */ | ||
| 75 | at91_register_uart(AT91SAM9260_ID_US4, 5, 0); | ||
| 76 | |||
| 77 | /* USART5 on ttyS6. (Rx, Tx) */ | ||
| 78 | at91_register_uart(AT91SAM9260_ID_US5, 6, 0); | ||
| 79 | |||
| 80 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
| 81 | at91_set_serial_console(0); | ||
| 82 | } | ||
| 83 | |||
| 84 | static void __init cpu9krea_init_irq(void) | ||
| 85 | { | ||
| 86 | at91sam9260_init_interrupts(NULL); | ||
| 87 | } | ||
| 88 | |||
| 89 | /* | ||
| 90 | * USB Host port | ||
| 91 | */ | ||
| 92 | static struct at91_usbh_data __initdata cpu9krea_usbh_data = { | ||
| 93 | .ports = 2, | ||
| 94 | }; | ||
| 95 | |||
| 96 | /* | ||
| 97 | * USB Device port | ||
| 98 | */ | ||
| 99 | static struct at91_udc_data __initdata cpu9krea_udc_data = { | ||
| 100 | .vbus_pin = AT91_PIN_PC8, | ||
| 101 | .pullup_pin = 0, /* pull-up driven by UDC */ | ||
| 102 | }; | ||
| 103 | |||
| 104 | /* | ||
| 105 | * MACB Ethernet device | ||
| 106 | */ | ||
| 107 | static struct at91_eth_data __initdata cpu9krea_macb_data = { | ||
| 108 | .is_rmii = 1, | ||
| 109 | }; | ||
| 110 | |||
| 111 | /* | ||
| 112 | * NAND flash | ||
| 113 | */ | ||
| 114 | static struct atmel_nand_data __initdata cpu9krea_nand_data = { | ||
| 115 | .ale = 21, | ||
| 116 | .cle = 22, | ||
| 117 | .rdy_pin = AT91_PIN_PC13, | ||
| 118 | .enable_pin = AT91_PIN_PC14, | ||
| 119 | .bus_width_16 = 0, | ||
| 120 | }; | ||
| 121 | |||
| 122 | #ifdef CONFIG_MACH_CPU9260 | ||
| 123 | static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = { | ||
| 124 | .ncs_read_setup = 0, | ||
| 125 | .nrd_setup = 1, | ||
| 126 | .ncs_write_setup = 0, | ||
| 127 | .nwe_setup = 1, | ||
| 128 | |||
| 129 | .ncs_read_pulse = 3, | ||
| 130 | .nrd_pulse = 3, | ||
| 131 | .ncs_write_pulse = 3, | ||
| 132 | .nwe_pulse = 3, | ||
| 133 | |||
| 134 | .read_cycle = 5, | ||
| 135 | .write_cycle = 5, | ||
| 136 | |||
| 137 | .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | ||
| 138 | | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, | ||
| 139 | .tdf_cycles = 2, | ||
| 140 | }; | ||
| 141 | #else | ||
| 142 | static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = { | ||
| 143 | .ncs_read_setup = 0, | ||
| 144 | .nrd_setup = 2, | ||
| 145 | .ncs_write_setup = 0, | ||
| 146 | .nwe_setup = 2, | ||
| 147 | |||
| 148 | .ncs_read_pulse = 4, | ||
| 149 | .nrd_pulse = 4, | ||
| 150 | .ncs_write_pulse = 4, | ||
| 151 | .nwe_pulse = 4, | ||
| 152 | |||
| 153 | .read_cycle = 7, | ||
| 154 | .write_cycle = 7, | ||
| 155 | |||
| 156 | .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | ||
| 157 | | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, | ||
| 158 | .tdf_cycles = 3, | ||
| 159 | }; | ||
| 160 | #endif | ||
| 161 | |||
| 162 | static void __init cpu9krea_add_device_nand(void) | ||
| 163 | { | ||
| 164 | sam9_smc_configure(3, &cpu9krea_nand_smc_config); | ||
| 165 | at91_add_device_nand(&cpu9krea_nand_data); | ||
| 166 | } | ||
| 167 | |||
| 168 | /* | ||
| 169 | * NOR flash | ||
| 170 | */ | ||
| 171 | static struct physmap_flash_data cpuat9260_nor_data = { | ||
| 172 | .width = 2, | ||
| 173 | }; | ||
| 174 | |||
| 175 | #define NOR_BASE AT91_CHIPSELECT_0 | ||
| 176 | #define NOR_SIZE SZ_64M | ||
| 177 | |||
| 178 | static struct resource nor_flash_resources[] = { | ||
| 179 | { | ||
| 180 | .start = NOR_BASE, | ||
| 181 | .end = NOR_BASE + NOR_SIZE - 1, | ||
| 182 | .flags = IORESOURCE_MEM, | ||
| 183 | } | ||
| 184 | }; | ||
| 185 | |||
| 186 | static struct platform_device cpu9krea_nor_flash = { | ||
| 187 | .name = "physmap-flash", | ||
| 188 | .id = 0, | ||
| 189 | .dev = { | ||
| 190 | .platform_data = &cpuat9260_nor_data, | ||
| 191 | }, | ||
| 192 | .resource = nor_flash_resources, | ||
| 193 | .num_resources = ARRAY_SIZE(nor_flash_resources), | ||
| 194 | }; | ||
| 195 | |||
| 196 | #ifdef CONFIG_MACH_CPU9260 | ||
| 197 | static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = { | ||
| 198 | .ncs_read_setup = 0, | ||
| 199 | .nrd_setup = 1, | ||
| 200 | .ncs_write_setup = 0, | ||
| 201 | .nwe_setup = 1, | ||
| 202 | |||
| 203 | .ncs_read_pulse = 10, | ||
| 204 | .nrd_pulse = 10, | ||
| 205 | .ncs_write_pulse = 6, | ||
| 206 | .nwe_pulse = 6, | ||
| 207 | |||
| 208 | .read_cycle = 12, | ||
| 209 | .write_cycle = 8, | ||
| 210 | |||
| 211 | .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | ||
| 212 | | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | ||
| 213 | | AT91_SMC_DBW_16, | ||
| 214 | .tdf_cycles = 2, | ||
| 215 | }; | ||
| 216 | #else | ||
| 217 | static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = { | ||
| 218 | .ncs_read_setup = 0, | ||
| 219 | .nrd_setup = 1, | ||
| 220 | .ncs_write_setup = 0, | ||
| 221 | .nwe_setup = 1, | ||
| 222 | |||
| 223 | .ncs_read_pulse = 13, | ||
| 224 | .nrd_pulse = 13, | ||
| 225 | .ncs_write_pulse = 8, | ||
| 226 | .nwe_pulse = 8, | ||
| 227 | |||
| 228 | .read_cycle = 15, | ||
| 229 | .write_cycle = 10, | ||
| 230 | |||
| 231 | .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | ||
| 232 | | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | ||
| 233 | | AT91_SMC_DBW_16, | ||
| 234 | .tdf_cycles = 2, | ||
| 235 | }; | ||
| 236 | #endif | ||
| 237 | |||
| 238 | static __init void cpu9krea_add_device_nor(void) | ||
| 239 | { | ||
| 240 | unsigned long csa; | ||
| 241 | |||
| 242 | csa = at91_sys_read(AT91_MATRIX_EBICSA); | ||
| 243 | at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V); | ||
| 244 | |||
| 245 | /* configure chip-select 0 (NOR) */ | ||
| 246 | sam9_smc_configure(0, &cpu9krea_nor_smc_config); | ||
| 247 | |||
| 248 | platform_device_register(&cpu9krea_nor_flash); | ||
| 249 | } | ||
| 250 | |||
| 251 | /* | ||
| 252 | * LEDs | ||
| 253 | */ | ||
| 254 | static struct gpio_led cpu9krea_leds[] = { | ||
| 255 | { /* LED1 */ | ||
| 256 | .name = "LED1", | ||
| 257 | .gpio = AT91_PIN_PC11, | ||
| 258 | .active_low = 1, | ||
| 259 | .default_trigger = "timer", | ||
| 260 | }, | ||
| 261 | { /* LED2 */ | ||
| 262 | .name = "LED2", | ||
| 263 | .gpio = AT91_PIN_PC12, | ||
| 264 | .active_low = 1, | ||
| 265 | .default_trigger = "heartbeat", | ||
| 266 | }, | ||
| 267 | { /* LED3 */ | ||
| 268 | .name = "LED3", | ||
| 269 | .gpio = AT91_PIN_PC7, | ||
| 270 | .active_low = 1, | ||
| 271 | .default_trigger = "none", | ||
| 272 | }, | ||
| 273 | { /* LED4 */ | ||
| 274 | .name = "LED4", | ||
| 275 | .gpio = AT91_PIN_PC9, | ||
| 276 | .active_low = 1, | ||
| 277 | .default_trigger = "none", | ||
| 278 | } | ||
| 279 | }; | ||
| 280 | |||
| 281 | static struct i2c_board_info __initdata cpu9krea_i2c_devices[] = { | ||
| 282 | { | ||
| 283 | I2C_BOARD_INFO("rtc-ds1307", 0x68), | ||
| 284 | .type = "ds1339", | ||
| 285 | }, | ||
| 286 | }; | ||
| 287 | |||
| 288 | /* | ||
| 289 | * GPIO Buttons | ||
| 290 | */ | ||
| 291 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
| 292 | static struct gpio_keys_button cpu9krea_buttons[] = { | ||
| 293 | { | ||
| 294 | .gpio = AT91_PIN_PC3, | ||
| 295 | .code = BTN_0, | ||
| 296 | .desc = "BP1", | ||
| 297 | .active_low = 1, | ||
| 298 | .wakeup = 1, | ||
| 299 | }, | ||
| 300 | { | ||
| 301 | .gpio = AT91_PIN_PB20, | ||
| 302 | .code = BTN_1, | ||
| 303 | .desc = "BP2", | ||
| 304 | .active_low = 1, | ||
| 305 | .wakeup = 1, | ||
| 306 | } | ||
| 307 | }; | ||
| 308 | |||
| 309 | static struct gpio_keys_platform_data cpu9krea_button_data = { | ||
| 310 | .buttons = cpu9krea_buttons, | ||
| 311 | .nbuttons = ARRAY_SIZE(cpu9krea_buttons), | ||
| 312 | }; | ||
| 313 | |||
| 314 | static struct platform_device cpu9krea_button_device = { | ||
| 315 | .name = "gpio-keys", | ||
| 316 | .id = -1, | ||
| 317 | .num_resources = 0, | ||
| 318 | .dev = { | ||
| 319 | .platform_data = &cpu9krea_button_data, | ||
| 320 | } | ||
| 321 | }; | ||
| 322 | |||
| 323 | static void __init cpu9krea_add_device_buttons(void) | ||
| 324 | { | ||
| 325 | at91_set_gpio_input(AT91_PIN_PC3, 1); /* BP1 */ | ||
| 326 | at91_set_deglitch(AT91_PIN_PC3, 1); | ||
| 327 | at91_set_gpio_input(AT91_PIN_PB20, 1); /* BP2 */ | ||
| 328 | at91_set_deglitch(AT91_PIN_PB20, 1); | ||
| 329 | |||
| 330 | platform_device_register(&cpu9krea_button_device); | ||
| 331 | } | ||
| 332 | #else | ||
| 333 | static void __init cpu9krea_add_device_buttons(void) | ||
| 334 | { | ||
| 335 | } | ||
| 336 | #endif | ||
| 337 | |||
| 338 | /* | ||
| 339 | * MCI (SD/MMC) | ||
| 340 | */ | ||
| 341 | static struct at91_mmc_data __initdata cpu9krea_mmc_data = { | ||
| 342 | .slot_b = 0, | ||
| 343 | .wire4 = 1, | ||
| 344 | .det_pin = AT91_PIN_PA29, | ||
| 345 | }; | ||
| 346 | |||
| 347 | static void __init cpu9krea_board_init(void) | ||
| 348 | { | ||
| 349 | /* NOR */ | ||
| 350 | cpu9krea_add_device_nor(); | ||
| 351 | /* Serial */ | ||
| 352 | at91_add_device_serial(); | ||
| 353 | /* USB Host */ | ||
| 354 | at91_add_device_usbh(&cpu9krea_usbh_data); | ||
| 355 | /* USB Device */ | ||
| 356 | at91_add_device_udc(&cpu9krea_udc_data); | ||
| 357 | /* NAND */ | ||
| 358 | cpu9krea_add_device_nand(); | ||
| 359 | /* Ethernet */ | ||
| 360 | at91_add_device_eth(&cpu9krea_macb_data); | ||
| 361 | /* MMC */ | ||
| 362 | at91_add_device_mmc(0, &cpu9krea_mmc_data); | ||
| 363 | /* I2C */ | ||
| 364 | at91_add_device_i2c(cpu9krea_i2c_devices, | ||
| 365 | ARRAY_SIZE(cpu9krea_i2c_devices)); | ||
| 366 | /* LEDs */ | ||
| 367 | at91_gpio_leds(cpu9krea_leds, ARRAY_SIZE(cpu9krea_leds)); | ||
| 368 | /* Push Buttons */ | ||
| 369 | cpu9krea_add_device_buttons(); | ||
| 370 | } | ||
| 371 | |||
| 372 | #ifdef CONFIG_MACH_CPU9260 | ||
| 373 | MACHINE_START(CPUAT9260, "Eukrea CPU9260") | ||
| 374 | #else | ||
| 375 | MACHINE_START(CPUAT9G20, "Eukrea CPU9G20") | ||
| 376 | #endif | ||
| 377 | /* Maintainer: Eric Benard - EUKREA Electromatique */ | ||
| 378 | .phys_io = AT91_BASE_SYS, | ||
| 379 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
| 380 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
| 381 | .timer = &at91sam926x_timer, | ||
| 382 | .map_io = cpu9krea_map_io, | ||
| 383 | .init_irq = cpu9krea_init_irq, | ||
| 384 | .init_machine = cpu9krea_board_init, | ||
| 385 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c new file mode 100644 index 000000000000..a28d99656190 --- /dev/null +++ b/arch/arm/mach-at91/board-cpuat91.c | |||
| @@ -0,0 +1,185 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-at91/board-cpuat91.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 Eric Benard - eric@eukrea.com | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/types.h> | ||
| 22 | #include <linux/init.h> | ||
| 23 | #include <linux/mm.h> | ||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/platform_device.h> | ||
| 26 | #include <linux/mtd/physmap.h> | ||
| 27 | #include <linux/mtd/plat-ram.h> | ||
| 28 | |||
| 29 | #include <mach/hardware.h> | ||
| 30 | #include <asm/setup.h> | ||
| 31 | #include <asm/mach-types.h> | ||
| 32 | #include <asm/irq.h> | ||
| 33 | |||
| 34 | #include <asm/mach/arch.h> | ||
| 35 | #include <asm/mach/map.h> | ||
| 36 | #include <asm/mach/irq.h> | ||
| 37 | |||
| 38 | #include <mach/board.h> | ||
| 39 | #include <mach/gpio.h> | ||
| 40 | #include <mach/at91rm9200_mc.h> | ||
| 41 | |||
| 42 | #include "generic.h" | ||
| 43 | |||
| 44 | static struct gpio_led cpuat91_leds[] = { | ||
| 45 | { | ||
| 46 | .name = "led1", | ||
| 47 | .default_trigger = "heartbeat", | ||
| 48 | .active_low = 1, | ||
| 49 | .gpio = AT91_PIN_PC0, | ||
| 50 | }, | ||
| 51 | }; | ||
| 52 | |||
| 53 | static void __init cpuat91_map_io(void) | ||
| 54 | { | ||
| 55 | /* Initialize processor: 18.432 MHz crystal */ | ||
| 56 | at91rm9200_initialize(18432000, AT91RM9200_PQFP); | ||
| 57 | |||
| 58 | /* DBGU on ttyS0. (Rx & Tx only) */ | ||
| 59 | at91_register_uart(0, 0, 0); | ||
| 60 | |||
| 61 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */ | ||
| 62 | at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | | ||
| 63 | ATMEL_UART_RTS); | ||
| 64 | |||
| 65 | /* USART1 on ttyS2. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | ||
| 66 | at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | | ||
| 67 | ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR | | ||
| 68 | ATMEL_UART_DCD | ATMEL_UART_RI); | ||
| 69 | |||
| 70 | /* USART2 on ttyS3 (Rx, Tx) */ | ||
| 71 | at91_register_uart(AT91RM9200_ID_US2, 3, 0); | ||
| 72 | |||
| 73 | /* USART3 on ttyS4 (Rx, Tx, CTS, RTS) */ | ||
| 74 | at91_register_uart(AT91RM9200_ID_US3, 4, ATMEL_UART_CTS | | ||
| 75 | ATMEL_UART_RTS); | ||
| 76 | |||
| 77 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
| 78 | at91_set_serial_console(0); | ||
| 79 | } | ||
| 80 | |||
| 81 | static void __init cpuat91_init_irq(void) | ||
| 82 | { | ||
| 83 | at91rm9200_init_interrupts(NULL); | ||
| 84 | } | ||
| 85 | |||
| 86 | static struct at91_eth_data __initdata cpuat91_eth_data = { | ||
| 87 | .is_rmii = 1, | ||
| 88 | }; | ||
| 89 | |||
| 90 | static struct at91_usbh_data __initdata cpuat91_usbh_data = { | ||
| 91 | .ports = 1, | ||
| 92 | }; | ||
| 93 | |||
| 94 | static struct at91_udc_data __initdata cpuat91_udc_data = { | ||
| 95 | .vbus_pin = AT91_PIN_PC15, | ||
| 96 | .pullup_pin = AT91_PIN_PC14, | ||
| 97 | }; | ||
| 98 | |||
| 99 | static struct at91_mmc_data __initdata cpuat91_mmc_data = { | ||
| 100 | .det_pin = AT91_PIN_PC2, | ||
| 101 | .wire4 = 1, | ||
| 102 | }; | ||
| 103 | |||
| 104 | static struct physmap_flash_data cpuat91_flash_data = { | ||
| 105 | .width = 2, | ||
| 106 | }; | ||
| 107 | |||
| 108 | static struct resource cpuat91_flash_resource = { | ||
| 109 | .start = AT91_CHIPSELECT_0, | ||
| 110 | .end = AT91_CHIPSELECT_0 + SZ_16M - 1, | ||
| 111 | .flags = IORESOURCE_MEM, | ||
| 112 | }; | ||
| 113 | |||
| 114 | static struct platform_device cpuat91_norflash = { | ||
| 115 | .name = "physmap-flash", | ||
| 116 | .id = 0, | ||
| 117 | .dev = { | ||
| 118 | .platform_data = &cpuat91_flash_data, | ||
| 119 | }, | ||
| 120 | .resource = &cpuat91_flash_resource, | ||
| 121 | .num_resources = 1, | ||
| 122 | }; | ||
| 123 | |||
| 124 | #ifdef CONFIG_MTD_PLATRAM | ||
| 125 | struct platdata_mtd_ram at91_sram_pdata = { | ||
| 126 | .mapname = "SRAM", | ||
| 127 | .bankwidth = 2, | ||
| 128 | }; | ||
| 129 | |||
| 130 | static struct resource at91_sram_resource[] = { | ||
| 131 | [0] = { | ||
| 132 | .start = AT91RM9200_SRAM_BASE, | ||
| 133 | .end = AT91RM9200_SRAM_BASE + AT91RM9200_SRAM_SIZE - 1, | ||
| 134 | .flags = IORESOURCE_MEM, | ||
| 135 | }, | ||
| 136 | }; | ||
| 137 | |||
| 138 | static struct platform_device at91_sram = { | ||
| 139 | .name = "mtd-ram", | ||
| 140 | .id = 0, | ||
| 141 | .resource = at91_sram_resource, | ||
| 142 | .num_resources = ARRAY_SIZE(at91_sram_resource), | ||
| 143 | .dev = { | ||
| 144 | .platform_data = &at91_sram_pdata, | ||
| 145 | }, | ||
| 146 | }; | ||
| 147 | #endif /* MTD_PLATRAM */ | ||
| 148 | |||
| 149 | static struct platform_device *platform_devices[] __initdata = { | ||
| 150 | &cpuat91_norflash, | ||
| 151 | #ifdef CONFIG_MTD_PLATRAM | ||
| 152 | &at91_sram, | ||
| 153 | #endif /* CONFIG_MTD_PLATRAM */ | ||
| 154 | }; | ||
| 155 | |||
| 156 | static void __init cpuat91_board_init(void) | ||
| 157 | { | ||
| 158 | /* Serial */ | ||
| 159 | at91_add_device_serial(); | ||
| 160 | /* LEDs. */ | ||
| 161 | at91_gpio_leds(cpuat91_leds, ARRAY_SIZE(cpuat91_leds)); | ||
| 162 | /* Ethernet */ | ||
| 163 | at91_add_device_eth(&cpuat91_eth_data); | ||
| 164 | /* USB Host */ | ||
| 165 | at91_add_device_usbh(&cpuat91_usbh_data); | ||
| 166 | /* USB Device */ | ||
| 167 | at91_add_device_udc(&cpuat91_udc_data); | ||
| 168 | /* MMC */ | ||
| 169 | at91_add_device_mmc(0, &cpuat91_mmc_data); | ||
| 170 | /* I2C */ | ||
| 171 | at91_add_device_i2c(NULL, 0); | ||
| 172 | /* Platform devices */ | ||
| 173 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | ||
| 174 | } | ||
| 175 | |||
| 176 | MACHINE_START(CPUAT91, "Eukrea") | ||
| 177 | /* Maintainer: Eric Benard - EUKREA Electromatique */ | ||
| 178 | .phys_io = AT91_BASE_SYS, | ||
| 179 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
| 180 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
| 181 | .timer = &at91rm9200_timer, | ||
| 182 | .map_io = cpuat91_map_io, | ||
| 183 | .init_irq = cpuat91_init_irq, | ||
| 184 | .init_machine = cpuat91_board_init, | ||
| 185 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index d5266da55311..f9b19993a7a9 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c | |||
| @@ -287,7 +287,11 @@ static void __init ek_add_device_ts(void) {} | |||
| 287 | */ | 287 | */ |
| 288 | static struct at73c213_board_info at73c213_data = { | 288 | static struct at73c213_board_info at73c213_data = { |
| 289 | .ssc_id = 1, | 289 | .ssc_id = 1, |
| 290 | #if defined(CONFIG_MACH_AT91SAM9261EK) | ||
| 290 | .shortname = "AT91SAM9261-EK external DAC", | 291 | .shortname = "AT91SAM9261-EK external DAC", |
| 292 | #else | ||
| 293 | .shortname = "AT91SAM9G10-EK external DAC", | ||
| 294 | #endif | ||
| 291 | }; | 295 | }; |
| 292 | 296 | ||
| 293 | #if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) | 297 | #if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) |
| @@ -414,6 +418,9 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = { | |||
| 414 | .default_monspecs = &at91fb_default_stn_monspecs, | 418 | .default_monspecs = &at91fb_default_stn_monspecs, |
| 415 | .atmel_lcdfb_power_control = at91_lcdc_stn_power_control, | 419 | .atmel_lcdfb_power_control = at91_lcdc_stn_power_control, |
| 416 | .guard_time = 1, | 420 | .guard_time = 1, |
| 421 | #if defined(CONFIG_MACH_AT91SAM9G10EK) | ||
| 422 | .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, | ||
| 423 | #endif | ||
| 417 | }; | 424 | }; |
| 418 | 425 | ||
| 419 | #else | 426 | #else |
| @@ -467,6 +474,9 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = { | |||
| 467 | .default_monspecs = &at91fb_default_tft_monspecs, | 474 | .default_monspecs = &at91fb_default_tft_monspecs, |
| 468 | .atmel_lcdfb_power_control = at91_lcdc_tft_power_control, | 475 | .atmel_lcdfb_power_control = at91_lcdc_tft_power_control, |
| 469 | .guard_time = 1, | 476 | .guard_time = 1, |
| 477 | #if defined(CONFIG_MACH_AT91SAM9G10EK) | ||
| 478 | .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, | ||
| 479 | #endif | ||
| 470 | }; | 480 | }; |
| 471 | #endif | 481 | #endif |
| 472 | 482 | ||
| @@ -600,7 +610,11 @@ static void __init ek_board_init(void) | |||
| 600 | at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); | 610 | at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); |
| 601 | } | 611 | } |
| 602 | 612 | ||
| 613 | #if defined(CONFIG_MACH_AT91SAM9261EK) | ||
| 603 | MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK") | 614 | MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK") |
| 615 | #else | ||
| 616 | MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK") | ||
| 617 | #endif | ||
| 604 | /* Maintainer: Atmel */ | 618 | /* Maintainer: Atmel */ |
| 605 | .phys_io = AT91_BASE_SYS, | 619 | .phys_io = AT91_BASE_SYS, |
| 606 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | 620 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, |
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index 57d52528f224..1bf7bd4cbe13 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c | |||
| @@ -364,9 +364,9 @@ static void __init ek_add_device_buttons(void) {} | |||
| 364 | 364 | ||
| 365 | /* | 365 | /* |
| 366 | * AC97 | 366 | * AC97 |
| 367 | * reset_pin is not connected: NRST | ||
| 367 | */ | 368 | */ |
| 368 | static struct atmel_ac97_data ek_ac97_data = { | 369 | static struct ac97c_platform_data ek_ac97_data = { |
| 369 | .reset_pin = AT91_PIN_PA13, | ||
| 370 | }; | 370 | }; |
| 371 | 371 | ||
| 372 | 372 | ||
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c index a55398ed1211..ca470d504ea0 100644 --- a/arch/arm/mach-at91/board-sam9g20ek.c +++ b/arch/arm/mach-at91/board-sam9g20ek.c | |||
| @@ -273,6 +273,7 @@ static void __init ek_add_device_buttons(void) {} | |||
| 273 | static struct i2c_board_info __initdata ek_i2c_devices[] = { | 273 | static struct i2c_board_info __initdata ek_i2c_devices[] = { |
| 274 | { | 274 | { |
| 275 | I2C_BOARD_INFO("24c512", 0x50), | 275 | I2C_BOARD_INFO("24c512", 0x50), |
| 276 | I2C_BOARD_INFO("wm8731", 0x1b), | ||
| 276 | }, | 277 | }, |
| 277 | }; | 278 | }; |
| 278 | 279 | ||
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c new file mode 100644 index 000000000000..b8558eae5229 --- /dev/null +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c | |||
| @@ -0,0 +1,389 @@ | |||
| 1 | /* | ||
| 2 | * Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family | ||
| 3 | * | ||
| 4 | * Covers: * AT91SAM9G45-EKES board | ||
| 5 | * * AT91SAM9M10G45-EK board | ||
| 6 | * | ||
| 7 | * Copyright (C) 2009 Atmel Corporation. | ||
| 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 as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/types.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/mm.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/spi/spi.h> | ||
| 22 | #include <linux/fb.h> | ||
| 23 | #include <linux/gpio_keys.h> | ||
| 24 | #include <linux/input.h> | ||
| 25 | #include <linux/leds.h> | ||
| 26 | #include <linux/clk.h> | ||
| 27 | |||
| 28 | #include <mach/hardware.h> | ||
| 29 | #include <video/atmel_lcdc.h> | ||
| 30 | |||
| 31 | #include <asm/setup.h> | ||
| 32 | #include <asm/mach-types.h> | ||
| 33 | #include <asm/irq.h> | ||
| 34 | |||
| 35 | #include <asm/mach/arch.h> | ||
| 36 | #include <asm/mach/map.h> | ||
| 37 | #include <asm/mach/irq.h> | ||
| 38 | |||
| 39 | #include <mach/hardware.h> | ||
| 40 | #include <mach/board.h> | ||
| 41 | #include <mach/gpio.h> | ||
| 42 | #include <mach/at91sam9_smc.h> | ||
| 43 | #include <mach/at91_shdwc.h> | ||
| 44 | |||
| 45 | #include "sam9_smc.h" | ||
| 46 | #include "generic.h" | ||
| 47 | |||
| 48 | |||
| 49 | static void __init ek_map_io(void) | ||
| 50 | { | ||
| 51 | /* Initialize processor: 12.000 MHz crystal */ | ||
| 52 | at91sam9g45_initialize(12000000); | ||
| 53 | |||
| 54 | /* DGBU on ttyS0. (Rx & Tx only) */ | ||
| 55 | at91_register_uart(0, 0, 0); | ||
| 56 | |||
| 57 | /* USART0 not connected on the -EK board */ | ||
| 58 | /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */ | ||
| 59 | at91_register_uart(AT91SAM9G45_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); | ||
| 60 | |||
| 61 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
| 62 | at91_set_serial_console(0); | ||
| 63 | } | ||
| 64 | |||
| 65 | static void __init ek_init_irq(void) | ||
| 66 | { | ||
| 67 | at91sam9g45_init_interrupts(NULL); | ||
| 68 | } | ||
| 69 | |||
| 70 | |||
| 71 | /* | ||
| 72 | * USB HS Host port (common to OHCI & EHCI) | ||
| 73 | */ | ||
| 74 | static struct at91_usbh_data __initdata ek_usbh_hs_data = { | ||
| 75 | .ports = 2, | ||
| 76 | .vbus_pin = {AT91_PIN_PD1, AT91_PIN_PD3}, | ||
| 77 | }; | ||
| 78 | |||
| 79 | |||
| 80 | /* | ||
| 81 | * USB HS Device port | ||
| 82 | */ | ||
| 83 | static struct usba_platform_data __initdata ek_usba_udc_data = { | ||
| 84 | .vbus_pin = AT91_PIN_PB19, | ||
| 85 | }; | ||
| 86 | |||
| 87 | |||
| 88 | /* | ||
| 89 | * SPI devices. | ||
| 90 | */ | ||
| 91 | static struct spi_board_info ek_spi_devices[] = { | ||
| 92 | { /* DataFlash chip */ | ||
| 93 | .modalias = "mtd_dataflash", | ||
| 94 | .chip_select = 0, | ||
| 95 | .max_speed_hz = 15 * 1000 * 1000, | ||
| 96 | .bus_num = 0, | ||
| 97 | }, | ||
| 98 | }; | ||
| 99 | |||
| 100 | |||
| 101 | /* | ||
| 102 | * MACB Ethernet device | ||
| 103 | */ | ||
| 104 | static struct at91_eth_data __initdata ek_macb_data = { | ||
| 105 | .phy_irq_pin = AT91_PIN_PD5, | ||
| 106 | .is_rmii = 1, | ||
| 107 | }; | ||
| 108 | |||
| 109 | |||
| 110 | /* | ||
| 111 | * NAND flash | ||
| 112 | */ | ||
| 113 | static struct mtd_partition __initdata ek_nand_partition[] = { | ||
| 114 | { | ||
| 115 | .name = "Partition 1", | ||
| 116 | .offset = 0, | ||
| 117 | .size = SZ_64M, | ||
| 118 | }, | ||
| 119 | { | ||
| 120 | .name = "Partition 2", | ||
| 121 | .offset = MTDPART_OFS_NXTBLK, | ||
| 122 | .size = MTDPART_SIZ_FULL, | ||
| 123 | }, | ||
| 124 | }; | ||
| 125 | |||
| 126 | static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) | ||
| 127 | { | ||
| 128 | *num_partitions = ARRAY_SIZE(ek_nand_partition); | ||
| 129 | return ek_nand_partition; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* det_pin is not connected */ | ||
| 133 | static struct atmel_nand_data __initdata ek_nand_data = { | ||
| 134 | .ale = 21, | ||
| 135 | .cle = 22, | ||
| 136 | .rdy_pin = AT91_PIN_PC8, | ||
| 137 | .enable_pin = AT91_PIN_PC14, | ||
| 138 | .partition_info = nand_partitions, | ||
| 139 | #if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) | ||
| 140 | .bus_width_16 = 1, | ||
| 141 | #else | ||
| 142 | .bus_width_16 = 0, | ||
| 143 | #endif | ||
| 144 | }; | ||
| 145 | |||
| 146 | static struct sam9_smc_config __initdata ek_nand_smc_config = { | ||
| 147 | .ncs_read_setup = 0, | ||
| 148 | .nrd_setup = 2, | ||
| 149 | .ncs_write_setup = 0, | ||
| 150 | .nwe_setup = 2, | ||
| 151 | |||
| 152 | .ncs_read_pulse = 4, | ||
| 153 | .nrd_pulse = 4, | ||
| 154 | .ncs_write_pulse = 4, | ||
| 155 | .nwe_pulse = 4, | ||
| 156 | |||
| 157 | .read_cycle = 7, | ||
| 158 | .write_cycle = 7, | ||
| 159 | |||
| 160 | .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE, | ||
| 161 | .tdf_cycles = 3, | ||
| 162 | }; | ||
| 163 | |||
| 164 | static void __init ek_add_device_nand(void) | ||
| 165 | { | ||
| 166 | /* setup bus-width (8 or 16) */ | ||
| 167 | if (ek_nand_data.bus_width_16) | ||
| 168 | ek_nand_smc_config.mode |= AT91_SMC_DBW_16; | ||
| 169 | else | ||
| 170 | ek_nand_smc_config.mode |= AT91_SMC_DBW_8; | ||
| 171 | |||
| 172 | /* configure chip-select 3 (NAND) */ | ||
| 173 | sam9_smc_configure(3, &ek_nand_smc_config); | ||
| 174 | |||
| 175 | at91_add_device_nand(&ek_nand_data); | ||
| 176 | } | ||
| 177 | |||
| 178 | |||
| 179 | /* | ||
| 180 | * LCD Controller | ||
| 181 | */ | ||
| 182 | #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) | ||
| 183 | static struct fb_videomode at91_tft_vga_modes[] = { | ||
| 184 | { | ||
| 185 | .name = "LG", | ||
| 186 | .refresh = 60, | ||
| 187 | .xres = 480, .yres = 272, | ||
| 188 | .pixclock = KHZ2PICOS(9000), | ||
| 189 | |||
| 190 | .left_margin = 1, .right_margin = 1, | ||
| 191 | .upper_margin = 40, .lower_margin = 1, | ||
| 192 | .hsync_len = 45, .vsync_len = 1, | ||
| 193 | |||
| 194 | .sync = 0, | ||
| 195 | .vmode = FB_VMODE_NONINTERLACED, | ||
| 196 | }, | ||
| 197 | }; | ||
| 198 | |||
| 199 | static struct fb_monspecs at91fb_default_monspecs = { | ||
| 200 | .manufacturer = "LG", | ||
| 201 | .monitor = "LB043WQ1", | ||
| 202 | |||
| 203 | .modedb = at91_tft_vga_modes, | ||
| 204 | .modedb_len = ARRAY_SIZE(at91_tft_vga_modes), | ||
| 205 | .hfmin = 15000, | ||
| 206 | .hfmax = 17640, | ||
| 207 | .vfmin = 57, | ||
| 208 | .vfmax = 67, | ||
| 209 | }; | ||
| 210 | |||
| 211 | #define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \ | ||
| 212 | | ATMEL_LCDC_DISTYPE_TFT \ | ||
| 213 | | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE) | ||
| 214 | |||
| 215 | /* Driver datas */ | ||
| 216 | static struct atmel_lcdfb_info __initdata ek_lcdc_data = { | ||
| 217 | .lcdcon_is_backlight = true, | ||
| 218 | .default_bpp = 32, | ||
| 219 | .default_dmacon = ATMEL_LCDC_DMAEN, | ||
| 220 | .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2, | ||
| 221 | .default_monspecs = &at91fb_default_monspecs, | ||
| 222 | .guard_time = 9, | ||
| 223 | .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, | ||
| 224 | }; | ||
| 225 | |||
| 226 | #else | ||
| 227 | static struct atmel_lcdfb_info __initdata ek_lcdc_data; | ||
| 228 | #endif | ||
| 229 | |||
| 230 | |||
| 231 | /* | ||
| 232 | * GPIO Buttons | ||
| 233 | */ | ||
| 234 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
| 235 | static struct gpio_keys_button ek_buttons[] = { | ||
| 236 | { /* BP1, "leftclic" */ | ||
| 237 | .code = BTN_LEFT, | ||
| 238 | .gpio = AT91_PIN_PB6, | ||
| 239 | .active_low = 1, | ||
| 240 | .desc = "left_click", | ||
| 241 | .wakeup = 1, | ||
| 242 | }, | ||
| 243 | { /* BP2, "rightclic" */ | ||
| 244 | .code = BTN_RIGHT, | ||
| 245 | .gpio = AT91_PIN_PB7, | ||
| 246 | .active_low = 1, | ||
| 247 | .desc = "right_click", | ||
| 248 | .wakeup = 1, | ||
| 249 | }, | ||
| 250 | /* BP3, "joystick" */ | ||
| 251 | { | ||
| 252 | .code = KEY_LEFT, | ||
| 253 | .gpio = AT91_PIN_PB14, | ||
| 254 | .active_low = 1, | ||
| 255 | .desc = "Joystick Left", | ||
| 256 | }, | ||
| 257 | { | ||
| 258 | .code = KEY_RIGHT, | ||
| 259 | .gpio = AT91_PIN_PB15, | ||
| 260 | .active_low = 1, | ||
| 261 | .desc = "Joystick Right", | ||
| 262 | }, | ||
| 263 | { | ||
| 264 | .code = KEY_UP, | ||
| 265 | .gpio = AT91_PIN_PB16, | ||
| 266 | .active_low = 1, | ||
| 267 | .desc = "Joystick Up", | ||
| 268 | }, | ||
| 269 | { | ||
| 270 | .code = KEY_DOWN, | ||
| 271 | .gpio = AT91_PIN_PB17, | ||
| 272 | .active_low = 1, | ||
| 273 | .desc = "Joystick Down", | ||
| 274 | }, | ||
| 275 | { | ||
| 276 | .code = KEY_ENTER, | ||
| 277 | .gpio = AT91_PIN_PB18, | ||
| 278 | .active_low = 1, | ||
| 279 | .desc = "Joystick Press", | ||
| 280 | }, | ||
| 281 | }; | ||
| 282 | |||
| 283 | static struct gpio_keys_platform_data ek_button_data = { | ||
| 284 | .buttons = ek_buttons, | ||
| 285 | .nbuttons = ARRAY_SIZE(ek_buttons), | ||
| 286 | }; | ||
| 287 | |||
| 288 | static struct platform_device ek_button_device = { | ||
| 289 | .name = "gpio-keys", | ||
| 290 | .id = -1, | ||
| 291 | .num_resources = 0, | ||
| 292 | .dev = { | ||
| 293 | .platform_data = &ek_button_data, | ||
| 294 | } | ||
| 295 | }; | ||
| 296 | |||
| 297 | static void __init ek_add_device_buttons(void) | ||
| 298 | { | ||
| 299 | int i; | ||
| 300 | |||
| 301 | for (i = 0; i < ARRAY_SIZE(ek_buttons); i++) { | ||
| 302 | at91_set_GPIO_periph(ek_buttons[i].gpio, 1); | ||
| 303 | at91_set_deglitch(ek_buttons[i].gpio, 1); | ||
| 304 | } | ||
| 305 | |||
| 306 | platform_device_register(&ek_button_device); | ||
| 307 | } | ||
| 308 | #else | ||
| 309 | static void __init ek_add_device_buttons(void) {} | ||
| 310 | #endif | ||
| 311 | |||
| 312 | |||
| 313 | /* | ||
| 314 | * LEDs ... these could all be PWM-driven, for variable brightness | ||
| 315 | */ | ||
| 316 | static struct gpio_led ek_leds[] = { | ||
| 317 | { /* "top" led, red, powerled */ | ||
| 318 | .name = "d8", | ||
| 319 | .gpio = AT91_PIN_PD30, | ||
| 320 | .default_trigger = "heartbeat", | ||
| 321 | }, | ||
| 322 | { /* "left" led, green, userled2, pwm3 */ | ||
| 323 | .name = "d6", | ||
| 324 | .gpio = AT91_PIN_PD0, | ||
| 325 | .active_low = 1, | ||
| 326 | .default_trigger = "nand-disk", | ||
| 327 | }, | ||
| 328 | #if !(defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE)) | ||
| 329 | { /* "right" led, green, userled1, pwm1 */ | ||
| 330 | .name = "d7", | ||
| 331 | .gpio = AT91_PIN_PD31, | ||
| 332 | .active_low = 1, | ||
| 333 | .default_trigger = "mmc0", | ||
| 334 | }, | ||
| 335 | #endif | ||
| 336 | }; | ||
| 337 | |||
| 338 | |||
| 339 | /* | ||
| 340 | * PWM Leds | ||
| 341 | */ | ||
| 342 | static struct gpio_led ek_pwm_led[] = { | ||
| 343 | #if defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE) | ||
| 344 | { /* "right" led, green, userled1, pwm1 */ | ||
| 345 | .name = "d7", | ||
| 346 | .gpio = 1, /* is PWM channel number */ | ||
| 347 | .active_low = 1, | ||
| 348 | .default_trigger = "none", | ||
| 349 | }, | ||
| 350 | #endif | ||
| 351 | }; | ||
| 352 | |||
| 353 | |||
| 354 | |||
| 355 | static void __init ek_board_init(void) | ||
| 356 | { | ||
| 357 | /* Serial */ | ||
| 358 | at91_add_device_serial(); | ||
| 359 | /* USB HS Host */ | ||
| 360 | at91_add_device_usbh_ohci(&ek_usbh_hs_data); | ||
| 361 | /* USB HS Device */ | ||
| 362 | at91_add_device_usba(&ek_usba_udc_data); | ||
| 363 | /* SPI */ | ||
| 364 | at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); | ||
| 365 | /* Ethernet */ | ||
| 366 | at91_add_device_eth(&ek_macb_data); | ||
| 367 | /* NAND */ | ||
| 368 | ek_add_device_nand(); | ||
| 369 | /* I2C */ | ||
| 370 | at91_add_device_i2c(0, NULL, 0); | ||
| 371 | /* LCD Controller */ | ||
| 372 | at91_add_device_lcdc(&ek_lcdc_data); | ||
| 373 | /* Push Buttons */ | ||
| 374 | ek_add_device_buttons(); | ||
| 375 | /* LEDs */ | ||
| 376 | at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); | ||
| 377 | at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led)); | ||
| 378 | } | ||
| 379 | |||
| 380 | MACHINE_START(AT91SAM9G45EKES, "Atmel AT91SAM9G45-EKES") | ||
| 381 | /* Maintainer: Atmel */ | ||
| 382 | .phys_io = AT91_BASE_SYS, | ||
| 383 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
| 384 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
| 385 | .timer = &at91sam926x_timer, | ||
| 386 | .map_io = ek_map_io, | ||
| 387 | .init_irq = ek_init_irq, | ||
| 388 | .init_machine = ek_board_init, | ||
| 389 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index f6b5672cabd6..9d07679efce7 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | #include <linux/spi/spi.h> | 15 | #include <linux/spi/spi.h> |
| 16 | #include <linux/fb.h> | 16 | #include <linux/fb.h> |
| 17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
| 18 | #include <linux/input.h> | ||
| 19 | #include <linux/gpio_keys.h> | ||
| 18 | 20 | ||
| 19 | #include <video/atmel_lcdc.h> | 21 | #include <video/atmel_lcdc.h> |
| 20 | 22 | ||
| @@ -208,6 +210,79 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data; | |||
| 208 | #endif | 210 | #endif |
| 209 | 211 | ||
| 210 | 212 | ||
| 213 | /* | ||
| 214 | * LEDs | ||
| 215 | */ | ||
| 216 | static struct gpio_led ek_leds[] = { | ||
| 217 | { /* "bottom" led, green, userled1 to be defined */ | ||
| 218 | .name = "ds1", | ||
| 219 | .gpio = AT91_PIN_PD15, | ||
| 220 | .active_low = 1, | ||
| 221 | .default_trigger = "none", | ||
| 222 | }, | ||
| 223 | { /* "bottom" led, green, userled2 to be defined */ | ||
| 224 | .name = "ds2", | ||
| 225 | .gpio = AT91_PIN_PD16, | ||
| 226 | .active_low = 1, | ||
| 227 | .default_trigger = "none", | ||
| 228 | }, | ||
| 229 | { /* "power" led, yellow */ | ||
| 230 | .name = "ds3", | ||
| 231 | .gpio = AT91_PIN_PD14, | ||
| 232 | .default_trigger = "heartbeat", | ||
| 233 | } | ||
| 234 | }; | ||
| 235 | |||
| 236 | |||
| 237 | /* | ||
| 238 | * GPIO Buttons | ||
| 239 | */ | ||
| 240 | #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) | ||
| 241 | static struct gpio_keys_button ek_buttons[] = { | ||
| 242 | { | ||
| 243 | .gpio = AT91_PIN_PB0, | ||
| 244 | .code = BTN_2, | ||
| 245 | .desc = "Right Click", | ||
| 246 | .active_low = 1, | ||
| 247 | .wakeup = 1, | ||
| 248 | }, | ||
| 249 | { | ||
| 250 | .gpio = AT91_PIN_PB1, | ||
| 251 | .code = BTN_1, | ||
| 252 | .desc = "Left Click", | ||
| 253 | .active_low = 1, | ||
| 254 | .wakeup = 1, | ||
| 255 | } | ||
| 256 | }; | ||
| 257 | |||
| 258 | static struct gpio_keys_platform_data ek_button_data = { | ||
| 259 | .buttons = ek_buttons, | ||
| 260 | .nbuttons = ARRAY_SIZE(ek_buttons), | ||
| 261 | }; | ||
| 262 | |||
| 263 | static struct platform_device ek_button_device = { | ||
| 264 | .name = "gpio-keys", | ||
| 265 | .id = -1, | ||
| 266 | .num_resources = 0, | ||
| 267 | .dev = { | ||
| 268 | .platform_data = &ek_button_data, | ||
| 269 | } | ||
| 270 | }; | ||
| 271 | |||
| 272 | static void __init ek_add_device_buttons(void) | ||
| 273 | { | ||
| 274 | at91_set_gpio_input(AT91_PIN_PB1, 1); /* btn1 */ | ||
| 275 | at91_set_deglitch(AT91_PIN_PB1, 1); | ||
| 276 | at91_set_gpio_input(AT91_PIN_PB0, 1); /* btn2 */ | ||
| 277 | at91_set_deglitch(AT91_PIN_PB0, 1); | ||
| 278 | |||
| 279 | platform_device_register(&ek_button_device); | ||
| 280 | } | ||
| 281 | #else | ||
| 282 | static void __init ek_add_device_buttons(void) {} | ||
| 283 | #endif | ||
| 284 | |||
| 285 | |||
| 211 | static void __init ek_board_init(void) | 286 | static void __init ek_board_init(void) |
| 212 | { | 287 | { |
| 213 | /* Serial */ | 288 | /* Serial */ |
| @@ -226,6 +301,10 @@ static void __init ek_board_init(void) | |||
| 226 | at91_add_device_lcdc(&ek_lcdc_data); | 301 | at91_add_device_lcdc(&ek_lcdc_data); |
| 227 | /* Touch Screen Controller */ | 302 | /* Touch Screen Controller */ |
| 228 | at91_add_device_tsadcc(); | 303 | at91_add_device_tsadcc(); |
| 304 | /* LEDs */ | ||
| 305 | at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); | ||
| 306 | /* Push Buttons */ | ||
| 307 | ek_add_device_buttons(); | ||
| 229 | } | 308 | } |
| 230 | 309 | ||
| 231 | MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK") | 310 | MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK") |
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index bac578fe0d3d..c042dcf4725f 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c | |||
| @@ -47,20 +47,25 @@ | |||
| 47 | * Chips have some kind of clocks : group them by functionality | 47 | * Chips have some kind of clocks : group them by functionality |
| 48 | */ | 48 | */ |
| 49 | #define cpu_has_utmi() ( cpu_is_at91cap9() \ | 49 | #define cpu_has_utmi() ( cpu_is_at91cap9() \ |
| 50 | || cpu_is_at91sam9rl()) | 50 | || cpu_is_at91sam9rl() \ |
| 51 | || cpu_is_at91sam9g45()) | ||
| 51 | 52 | ||
| 52 | #define cpu_has_800M_plla() (cpu_is_at91sam9g20()) | 53 | #define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ |
| 54 | || cpu_is_at91sam9g45()) | ||
| 53 | 55 | ||
| 54 | #define cpu_has_pllb() (!cpu_is_at91sam9rl()) | 56 | #define cpu_has_300M_plla() (cpu_is_at91sam9g10()) |
| 55 | 57 | ||
| 56 | #define cpu_has_upll() (0) | 58 | #define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ |
| 59 | || cpu_is_at91sam9g45())) | ||
| 60 | |||
| 61 | #define cpu_has_upll() (cpu_is_at91sam9g45()) | ||
| 57 | 62 | ||
| 58 | /* USB host HS & FS */ | 63 | /* USB host HS & FS */ |
| 59 | #define cpu_has_uhp() (!cpu_is_at91sam9rl()) | 64 | #define cpu_has_uhp() (!cpu_is_at91sam9rl()) |
| 60 | 65 | ||
| 61 | /* USB device FS only */ | 66 | /* USB device FS only */ |
| 62 | #define cpu_has_udpfs() (!cpu_is_at91sam9rl()) | 67 | #define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ |
| 63 | 68 | || cpu_is_at91sam9g45())) | |
| 64 | 69 | ||
| 65 | static LIST_HEAD(clocks); | 70 | static LIST_HEAD(clocks); |
| 66 | static DEFINE_SPINLOCK(clk_lock); | 71 | static DEFINE_SPINLOCK(clk_lock); |
| @@ -133,6 +138,13 @@ static void pmc_uckr_mode(struct clk *clk, int is_on) | |||
| 133 | { | 138 | { |
| 134 | unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); | 139 | unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); |
| 135 | 140 | ||
| 141 | if (cpu_is_at91sam9g45()) { | ||
| 142 | if (is_on) | ||
| 143 | uckr |= AT91_PMC_BIASEN; | ||
| 144 | else | ||
| 145 | uckr &= ~AT91_PMC_BIASEN; | ||
| 146 | } | ||
| 147 | |||
| 136 | if (is_on) { | 148 | if (is_on) { |
| 137 | is_on = AT91_PMC_LOCKU; | 149 | is_on = AT91_PMC_LOCKU; |
| 138 | at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); | 150 | at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); |
| @@ -310,6 +322,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate) | |||
| 310 | unsigned long flags; | 322 | unsigned long flags; |
| 311 | unsigned prescale; | 323 | unsigned prescale; |
| 312 | unsigned long actual; | 324 | unsigned long actual; |
| 325 | unsigned long prev = ULONG_MAX; | ||
| 313 | 326 | ||
| 314 | if (!clk_is_programmable(clk)) | 327 | if (!clk_is_programmable(clk)) |
| 315 | return -EINVAL; | 328 | return -EINVAL; |
| @@ -317,8 +330,16 @@ long clk_round_rate(struct clk *clk, unsigned long rate) | |||
| 317 | 330 | ||
| 318 | actual = clk->parent->rate_hz; | 331 | actual = clk->parent->rate_hz; |
| 319 | for (prescale = 0; prescale < 7; prescale++) { | 332 | for (prescale = 0; prescale < 7; prescale++) { |
| 320 | if (actual && actual <= rate) | 333 | if (actual > rate) |
| 334 | prev = actual; | ||
| 335 | |||
| 336 | if (actual && actual <= rate) { | ||
| 337 | if ((prev - rate) < (rate - actual)) { | ||
| 338 | actual = prev; | ||
| 339 | prescale--; | ||
| 340 | } | ||
| 321 | break; | 341 | break; |
| 342 | } | ||
| 322 | actual >>= 1; | 343 | actual >>= 1; |
| 323 | } | 344 | } |
| 324 | 345 | ||
| @@ -373,6 +394,10 @@ int clk_set_parent(struct clk *clk, struct clk *parent) | |||
| 373 | return -EBUSY; | 394 | return -EBUSY; |
| 374 | if (!clk_is_primary(parent) || !clk_is_programmable(clk)) | 395 | if (!clk_is_primary(parent) || !clk_is_programmable(clk)) |
| 375 | return -EINVAL; | 396 | return -EINVAL; |
| 397 | |||
| 398 | if (cpu_is_at91sam9rl() && parent->id == AT91_PMC_CSS_PLLB) | ||
| 399 | return -EINVAL; | ||
| 400 | |||
| 376 | spin_lock_irqsave(&clk_lock, flags); | 401 | spin_lock_irqsave(&clk_lock, flags); |
| 377 | 402 | ||
| 378 | clk->rate_hz = parent->rate_hz; | 403 | clk->rate_hz = parent->rate_hz; |
| @@ -601,7 +626,9 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock) | |||
| 601 | uhpck.pmc_mask = AT91RM9200_PMC_UHP; | 626 | uhpck.pmc_mask = AT91RM9200_PMC_UHP; |
| 602 | udpck.pmc_mask = AT91RM9200_PMC_UDP; | 627 | udpck.pmc_mask = AT91RM9200_PMC_UDP; |
| 603 | at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); | 628 | at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); |
| 604 | } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { | 629 | } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || |
| 630 | cpu_is_at91sam9263() || cpu_is_at91sam9g20() || | ||
| 631 | cpu_is_at91sam9g10()) { | ||
| 605 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; | 632 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; |
| 606 | udpck.pmc_mask = AT91SAM926x_PMC_UDP; | 633 | udpck.pmc_mask = AT91SAM926x_PMC_UDP; |
| 607 | } else if (cpu_is_at91cap9()) { | 634 | } else if (cpu_is_at91cap9()) { |
| @@ -637,6 +664,7 @@ int __init at91_clock_init(unsigned long main_clock) | |||
| 637 | { | 664 | { |
| 638 | unsigned tmp, freq, mckr; | 665 | unsigned tmp, freq, mckr; |
| 639 | int i; | 666 | int i; |
| 667 | int pll_overclock = false; | ||
| 640 | 668 | ||
| 641 | /* | 669 | /* |
| 642 | * When the bootloader initialized the main oscillator correctly, | 670 | * When the bootloader initialized the main oscillator correctly, |
| @@ -654,12 +682,25 @@ int __init at91_clock_init(unsigned long main_clock) | |||
| 654 | 682 | ||
| 655 | /* report if PLLA is more than mildly overclocked */ | 683 | /* report if PLLA is more than mildly overclocked */ |
| 656 | plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); | 684 | plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); |
| 657 | if ((!cpu_has_800M_plla() && plla.rate_hz > 209000000) | 685 | if (cpu_has_300M_plla()) { |
| 658 | || (cpu_has_800M_plla() && plla.rate_hz > 800000000)) | 686 | if (plla.rate_hz > 300000000) |
| 687 | pll_overclock = true; | ||
| 688 | } else if (cpu_has_800M_plla()) { | ||
| 689 | if (plla.rate_hz > 800000000) | ||
| 690 | pll_overclock = true; | ||
| 691 | } else { | ||
| 692 | if (plla.rate_hz > 209000000) | ||
| 693 | pll_overclock = true; | ||
| 694 | } | ||
| 695 | if (pll_overclock) | ||
| 659 | pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); | 696 | pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); |
| 660 | 697 | ||
| 698 | if (cpu_is_at91sam9g45()) { | ||
| 699 | mckr = at91_sys_read(AT91_PMC_MCKR); | ||
| 700 | plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */ | ||
| 701 | } | ||
| 661 | 702 | ||
| 662 | if (cpu_has_upll() && !cpu_has_pllb()) { | 703 | if (!cpu_has_pllb() && cpu_has_upll()) { |
| 663 | /* setup UTMI clock as the fourth primary clock | 704 | /* setup UTMI clock as the fourth primary clock |
| 664 | * (instead of pllb) */ | 705 | * (instead of pllb) */ |
| 665 | utmi_clk.type |= CLK_TYPE_PRIMARY; | 706 | utmi_clk.type |= CLK_TYPE_PRIMARY; |
| @@ -701,6 +742,9 @@ int __init at91_clock_init(unsigned long main_clock) | |||
| 701 | freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ | 742 | freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ |
| 702 | if (mckr & AT91_PMC_PDIV) | 743 | if (mckr & AT91_PMC_PDIV) |
| 703 | freq /= 2; /* processor clock division */ | 744 | freq /= 2; /* processor clock division */ |
| 745 | } else if (cpu_is_at91sam9g45()) { | ||
| 746 | mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ? | ||
| 747 | freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ | ||
| 704 | } else { | 748 | } else { |
| 705 | mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ | 749 | mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ |
| 706 | } | 750 | } |
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index b5daf7f5e011..88e413b38480 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h | |||
| @@ -14,6 +14,7 @@ extern void __init at91sam9260_initialize(unsigned long main_clock); | |||
| 14 | extern void __init at91sam9261_initialize(unsigned long main_clock); | 14 | extern void __init at91sam9261_initialize(unsigned long main_clock); |
| 15 | extern void __init at91sam9263_initialize(unsigned long main_clock); | 15 | extern void __init at91sam9263_initialize(unsigned long main_clock); |
| 16 | extern void __init at91sam9rl_initialize(unsigned long main_clock); | 16 | extern void __init at91sam9rl_initialize(unsigned long main_clock); |
| 17 | extern void __init at91sam9g45_initialize(unsigned long main_clock); | ||
| 17 | extern void __init at91x40_initialize(unsigned long main_clock); | 18 | extern void __init at91x40_initialize(unsigned long main_clock); |
| 18 | extern void __init at91cap9_initialize(unsigned long main_clock); | 19 | extern void __init at91cap9_initialize(unsigned long main_clock); |
| 19 | 20 | ||
| @@ -23,6 +24,7 @@ extern void __init at91sam9260_init_interrupts(unsigned int priority[]); | |||
| 23 | extern void __init at91sam9261_init_interrupts(unsigned int priority[]); | 24 | extern void __init at91sam9261_init_interrupts(unsigned int priority[]); |
| 24 | extern void __init at91sam9263_init_interrupts(unsigned int priority[]); | 25 | extern void __init at91sam9263_init_interrupts(unsigned int priority[]); |
| 25 | extern void __init at91sam9rl_init_interrupts(unsigned int priority[]); | 26 | extern void __init at91sam9rl_init_interrupts(unsigned int priority[]); |
| 27 | extern void __init at91sam9g45_init_interrupts(unsigned int priority[]); | ||
| 26 | extern void __init at91x40_init_interrupts(unsigned int priority[]); | 28 | extern void __init at91x40_init_interrupts(unsigned int priority[]); |
| 27 | extern void __init at91cap9_init_interrupts(unsigned int priority[]); | 29 | extern void __init at91cap9_init_interrupts(unsigned int priority[]); |
| 28 | extern void __init at91_aic_init(unsigned int priority[]); | 30 | extern void __init at91_aic_init(unsigned int priority[]); |
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index f2236f0e101f..ae4772e744ac 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c | |||
| @@ -44,13 +44,11 @@ static int at91_gpiolib_direction_output(struct gpio_chip *chip, | |||
| 44 | unsigned offset, int val); | 44 | unsigned offset, int val); |
| 45 | static int at91_gpiolib_direction_input(struct gpio_chip *chip, | 45 | static int at91_gpiolib_direction_input(struct gpio_chip *chip, |
| 46 | unsigned offset); | 46 | unsigned offset); |
| 47 | static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset); | ||
| 48 | 47 | ||
| 49 | #define AT91_GPIO_CHIP(name, base_gpio, nr_gpio) \ | 48 | #define AT91_GPIO_CHIP(name, base_gpio, nr_gpio) \ |
| 50 | { \ | 49 | { \ |
| 51 | .chip = { \ | 50 | .chip = { \ |
| 52 | .label = name, \ | 51 | .label = name, \ |
| 53 | .request = at91_gpiolib_request, \ | ||
| 54 | .direction_input = at91_gpiolib_direction_input, \ | 52 | .direction_input = at91_gpiolib_direction_input, \ |
| 55 | .direction_output = at91_gpiolib_direction_output, \ | 53 | .direction_output = at91_gpiolib_direction_output, \ |
| 56 | .get = at91_gpiolib_get, \ | 54 | .get = at91_gpiolib_get, \ |
| @@ -588,19 +586,6 @@ static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val) | |||
| 588 | __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR)); | 586 | __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR)); |
| 589 | } | 587 | } |
| 590 | 588 | ||
| 591 | static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset) | ||
| 592 | { | ||
| 593 | unsigned pin = chip->base + offset; | ||
| 594 | void __iomem *pio = pin_to_controller(pin); | ||
| 595 | unsigned mask = pin_to_mask(pin); | ||
| 596 | |||
| 597 | /* Cannot request GPIOs that are in alternate function mode */ | ||
| 598 | if (!(__raw_readl(pio + PIO_PSR) & mask)) | ||
| 599 | return -EPERM; | ||
| 600 | |||
| 601 | return 0; | ||
| 602 | } | ||
| 603 | |||
| 604 | static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | 589 | static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) |
| 605 | { | 590 | { |
| 606 | int i; | 591 | int i; |
diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h index 3a348ca20773..87de8be17484 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/arch/arm/mach-at91/include/mach/at91sam9261.h | |||
| @@ -95,6 +95,9 @@ | |||
| 95 | #define AT91SAM9261_SRAM_BASE 0x00300000 /* Internal SRAM base address */ | 95 | #define AT91SAM9261_SRAM_BASE 0x00300000 /* Internal SRAM base address */ |
| 96 | #define AT91SAM9261_SRAM_SIZE 0x00028000 /* Internal SRAM size (160Kb) */ | 96 | #define AT91SAM9261_SRAM_SIZE 0x00028000 /* Internal SRAM size (160Kb) */ |
| 97 | 97 | ||
| 98 | #define AT91SAM9G10_SRAM_BASE AT91SAM9261_SRAM_BASE /* Internal SRAM base address */ | ||
| 99 | #define AT91SAM9G10_SRAM_SIZE 0x00004000 /* Internal SRAM size (16Kb) */ | ||
| 100 | |||
| 98 | #define AT91SAM9261_ROM_BASE 0x00400000 /* Internal ROM base address */ | 101 | #define AT91SAM9261_ROM_BASE 0x00400000 /* Internal ROM base address */ |
| 99 | #define AT91SAM9261_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */ | 102 | #define AT91SAM9261_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */ |
| 100 | 103 | ||
diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h new file mode 100644 index 000000000000..a526869aee37 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h | |||
| @@ -0,0 +1,155 @@ | |||
| 1 | /* | ||
| 2 | * Chip-specific header file for the AT91SAM9G45 family | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2009 Atmel Corporation. | ||
| 5 | * | ||
| 6 | * Common definitions. | ||
| 7 | * Based on AT91SAM9G45 preliminary datasheet. | ||
| 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 as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef AT91SAM9G45_H | ||
| 16 | #define AT91SAM9G45_H | ||
| 17 | |||
| 18 | /* | ||
| 19 | * Peripheral identifiers/interrupts. | ||
| 20 | */ | ||
| 21 | #define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ | ||
| 22 | #define AT91_ID_SYS 1 /* System Controller Interrupt */ | ||
| 23 | #define AT91SAM9G45_ID_PIOA 2 /* Parallel I/O Controller A */ | ||
| 24 | #define AT91SAM9G45_ID_PIOB 3 /* Parallel I/O Controller B */ | ||
| 25 | #define AT91SAM9G45_ID_PIOC 4 /* Parallel I/O Controller C */ | ||
| 26 | #define AT91SAM9G45_ID_PIODE 5 /* Parallel I/O Controller D and E */ | ||
| 27 | #define AT91SAM9G45_ID_TRNG 6 /* True Random Number Generator */ | ||
| 28 | #define AT91SAM9G45_ID_US0 7 /* USART 0 */ | ||
| 29 | #define AT91SAM9G45_ID_US1 8 /* USART 1 */ | ||
| 30 | #define AT91SAM9G45_ID_US2 9 /* USART 2 */ | ||
| 31 | #define AT91SAM9G45_ID_US3 10 /* USART 3 */ | ||
| 32 | #define AT91SAM9G45_ID_MCI0 11 /* High Speed Multimedia Card Interface 0 */ | ||
| 33 | #define AT91SAM9G45_ID_TWI0 12 /* Two-Wire Interface 0 */ | ||
| 34 | #define AT91SAM9G45_ID_TWI1 13 /* Two-Wire Interface 1 */ | ||
| 35 | #define AT91SAM9G45_ID_SPI0 14 /* Serial Peripheral Interface 0 */ | ||
| 36 | #define AT91SAM9G45_ID_SPI1 15 /* Serial Peripheral Interface 1 */ | ||
| 37 | #define AT91SAM9G45_ID_SSC0 16 /* Synchronous Serial Controller 0 */ | ||
| 38 | #define AT91SAM9G45_ID_SSC1 17 /* Synchronous Serial Controller 1 */ | ||
| 39 | #define AT91SAM9G45_ID_TCB 18 /* Timer Counter 0, 1, 2, 3, 4 and 5 */ | ||
| 40 | #define AT91SAM9G45_ID_PWMC 19 /* Pulse Width Modulation Controller */ | ||
| 41 | #define AT91SAM9G45_ID_TSC 20 /* Touch Screen ADC Controller */ | ||
| 42 | #define AT91SAM9G45_ID_DMA 21 /* DMA Controller */ | ||
| 43 | #define AT91SAM9G45_ID_UHPHS 22 /* USB Host High Speed */ | ||
| 44 | #define AT91SAM9G45_ID_LCDC 23 /* LCD Controller */ | ||
| 45 | #define AT91SAM9G45_ID_AC97C 24 /* AC97 Controller */ | ||
| 46 | #define AT91SAM9G45_ID_EMAC 25 /* Ethernet MAC */ | ||
| 47 | #define AT91SAM9G45_ID_ISI 26 /* Image Sensor Interface */ | ||
| 48 | #define AT91SAM9G45_ID_UDPHS 27 /* USB Device High Speed */ | ||
| 49 | #define AT91SAM9G45_ID_AESTDESSHA 28 /* AES + T-DES + SHA */ | ||
| 50 | #define AT91SAM9G45_ID_MCI1 29 /* High Speed Multimedia Card Interface 1 */ | ||
| 51 | #define AT91SAM9G45_ID_VDEC 30 /* Video Decoder */ | ||
| 52 | #define AT91SAM9G45_ID_IRQ0 31 /* Advanced Interrupt Controller */ | ||
| 53 | |||
| 54 | /* | ||
| 55 | * User Peripheral physical base addresses. | ||
| 56 | */ | ||
| 57 | #define AT91SAM9G45_BASE_UDPHS 0xfff78000 | ||
| 58 | #define AT91SAM9G45_BASE_TCB0 0xfff7c000 | ||
| 59 | #define AT91SAM9G45_BASE_TC0 0xfff7c000 | ||
| 60 | #define AT91SAM9G45_BASE_TC1 0xfff7c040 | ||
| 61 | #define AT91SAM9G45_BASE_TC2 0xfff7c080 | ||
| 62 | #define AT91SAM9G45_BASE_MCI0 0xfff80000 | ||
| 63 | #define AT91SAM9G45_BASE_TWI0 0xfff84000 | ||
| 64 | #define AT91SAM9G45_BASE_TWI1 0xfff88000 | ||
| 65 | #define AT91SAM9G45_BASE_US0 0xfff8c000 | ||
| 66 | #define AT91SAM9G45_BASE_US1 0xfff90000 | ||
| 67 | #define AT91SAM9G45_BASE_US2 0xfff94000 | ||
| 68 | #define AT91SAM9G45_BASE_US3 0xfff98000 | ||
| 69 | #define AT91SAM9G45_BASE_SSC0 0xfff9c000 | ||
| 70 | #define AT91SAM9G45_BASE_SSC1 0xfffa0000 | ||
| 71 | #define AT91SAM9G45_BASE_SPI0 0xfffa4000 | ||
| 72 | #define AT91SAM9G45_BASE_SPI1 0xfffa8000 | ||
| 73 | #define AT91SAM9G45_BASE_AC97C 0xfffac000 | ||
| 74 | #define AT91SAM9G45_BASE_TSC 0xfffb0000 | ||
| 75 | #define AT91SAM9G45_BASE_ISI 0xfffb4000 | ||
| 76 | #define AT91SAM9G45_BASE_PWMC 0xfffb8000 | ||
| 77 | #define AT91SAM9G45_BASE_EMAC 0xfffbc000 | ||
| 78 | #define AT91SAM9G45_BASE_AES 0xfffc0000 | ||
| 79 | #define AT91SAM9G45_BASE_TDES 0xfffc4000 | ||
| 80 | #define AT91SAM9G45_BASE_SHA 0xfffc8000 | ||
| 81 | #define AT91SAM9G45_BASE_TRNG 0xfffcc000 | ||
| 82 | #define AT91SAM9G45_BASE_MCI1 0xfffd0000 | ||
| 83 | #define AT91SAM9G45_BASE_TCB1 0xfffd4000 | ||
| 84 | #define AT91SAM9G45_BASE_TC3 0xfffd4000 | ||
| 85 | #define AT91SAM9G45_BASE_TC4 0xfffd4040 | ||
| 86 | #define AT91SAM9G45_BASE_TC5 0xfffd4080 | ||
| 87 | #define AT91_BASE_SYS 0xffffe200 | ||
| 88 | |||
| 89 | /* | ||
| 90 | * System Peripherals (offset from AT91_BASE_SYS) | ||
| 91 | */ | ||
| 92 | #define AT91_ECC (0xffffe200 - AT91_BASE_SYS) | ||
| 93 | #define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS) | ||
| 94 | #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) | ||
| 95 | #define AT91_SMC (0xffffe800 - AT91_BASE_SYS) | ||
| 96 | #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) | ||
| 97 | #define AT91_DMA (0xffffec00 - AT91_BASE_SYS) | ||
| 98 | #define AT91_DBGU (0xffffee00 - AT91_BASE_SYS) | ||
| 99 | #define AT91_AIC (0xfffff000 - AT91_BASE_SYS) | ||
| 100 | #define AT91_PIOA (0xfffff200 - AT91_BASE_SYS) | ||
| 101 | #define AT91_PIOB (0xfffff400 - AT91_BASE_SYS) | ||
| 102 | #define AT91_PIOC (0xfffff600 - AT91_BASE_SYS) | ||
| 103 | #define AT91_PIOD (0xfffff800 - AT91_BASE_SYS) | ||
| 104 | #define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS) | ||
| 105 | #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) | ||
| 106 | #define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) | ||
| 107 | #define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS) | ||
| 108 | #define AT91_RTT (0xfffffd20 - AT91_BASE_SYS) | ||
| 109 | #define AT91_PIT (0xfffffd30 - AT91_BASE_SYS) | ||
| 110 | #define AT91_WDT (0xfffffd40 - AT91_BASE_SYS) | ||
| 111 | #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) | ||
| 112 | #define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) | ||
| 113 | |||
| 114 | #define AT91_USART0 AT91SAM9G45_BASE_US0 | ||
| 115 | #define AT91_USART1 AT91SAM9G45_BASE_US1 | ||
| 116 | #define AT91_USART2 AT91SAM9G45_BASE_US2 | ||
| 117 | #define AT91_USART3 AT91SAM9G45_BASE_US3 | ||
| 118 | |||
| 119 | /* | ||
| 120 | * Internal Memory. | ||
| 121 | */ | ||
| 122 | #define AT91SAM9G45_SRAM_BASE 0x00300000 /* Internal SRAM base address */ | ||
| 123 | #define AT91SAM9G45_SRAM_SIZE SZ_64K /* Internal SRAM size (64Kb) */ | ||
| 124 | |||
| 125 | #define AT91SAM9G45_ROM_BASE 0x00400000 /* Internal ROM base address */ | ||
| 126 | #define AT91SAM9G45_ROM_SIZE SZ_64K /* Internal ROM size (64Kb) */ | ||
| 127 | |||
| 128 | #define AT91SAM9G45_LCDC_BASE 0x00500000 /* LCD Controller */ | ||
| 129 | #define AT91SAM9G45_UDPHS_FIFO 0x00600000 /* USB Device HS controller */ | ||
| 130 | #define AT91SAM9G45_OHCI_BASE 0x00700000 /* USB Host controller (OHCI) */ | ||
| 131 | #define AT91SAM9G45_EHCI_BASE 0x00800000 /* USB Host controller (EHCI) */ | ||
| 132 | #define AT91SAM9G45_VDEC_BASE 0x00900000 /* Video Decoder Controller */ | ||
| 133 | |||
| 134 | #define CONFIG_DRAM_BASE AT91_CHIPSELECT_6 | ||
| 135 | |||
| 136 | #define CONSISTENT_DMA_SIZE SZ_4M | ||
| 137 | |||
| 138 | /* | ||
| 139 | * DMA peripheral identifiers | ||
| 140 | * for hardware handshaking interface | ||
| 141 | */ | ||
| 142 | #define AT_DMA_ID_MCI0 0 | ||
| 143 | #define AT_DMA_ID_SPI0_TX 1 | ||
| 144 | #define AT_DMA_ID_SPI0_RX 2 | ||
| 145 | #define AT_DMA_ID_SPI1_TX 3 | ||
| 146 | #define AT_DMA_ID_SPI1_RX 4 | ||
| 147 | #define AT_DMA_ID_SSC0_TX 5 | ||
| 148 | #define AT_DMA_ID_SSC0_RX 6 | ||
| 149 | #define AT_DMA_ID_SSC1_TX 7 | ||
| 150 | #define AT_DMA_ID_SSC1_RX 8 | ||
| 151 | #define AT_DMA_ID_AC97_TX 9 | ||
| 152 | #define AT_DMA_ID_AC97_RX 10 | ||
| 153 | #define AT_DMA_ID_MCI1 13 | ||
| 154 | |||
| 155 | #endif | ||
diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h new file mode 100644 index 000000000000..c972d60e0aeb --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h | |||
| @@ -0,0 +1,153 @@ | |||
| 1 | /* | ||
| 2 | * Matrix-centric header file for the AT91SAM9G45 family | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2009 Atmel Corporation. | ||
| 5 | * | ||
| 6 | * Memory Controllers (MATRIX, EBI) - System peripherals registers. | ||
| 7 | * Based on AT91SAM9G45 preliminary datasheet. | ||
| 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 as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef AT91SAM9G45_MATRIX_H | ||
| 16 | #define AT91SAM9G45_MATRIX_H | ||
| 17 | |||
| 18 | #define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */ | ||
| 19 | #define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */ | ||
| 20 | #define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ | ||
| 21 | #define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ | ||
| 22 | #define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ | ||
| 23 | #define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */ | ||
| 24 | #define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */ | ||
| 25 | #define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */ | ||
| 26 | #define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */ | ||
| 27 | #define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */ | ||
| 28 | #define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */ | ||
| 29 | #define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */ | ||
| 30 | #define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ | ||
| 31 | #define AT91_MATRIX_ULBT_INFINITE (0 << 0) | ||
| 32 | #define AT91_MATRIX_ULBT_SINGLE (1 << 0) | ||
| 33 | #define AT91_MATRIX_ULBT_FOUR (2 << 0) | ||
| 34 | #define AT91_MATRIX_ULBT_EIGHT (3 << 0) | ||
| 35 | #define AT91_MATRIX_ULBT_SIXTEEN (4 << 0) | ||
| 36 | #define AT91_MATRIX_ULBT_THIRTYTWO (5 << 0) | ||
| 37 | #define AT91_MATRIX_ULBT_SIXTYFOUR (6 << 0) | ||
| 38 | #define AT91_MATRIX_ULBT_128 (7 << 0) | ||
| 39 | |||
| 40 | #define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */ | ||
| 41 | #define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */ | ||
| 42 | #define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */ | ||
| 43 | #define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */ | ||
| 44 | #define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */ | ||
| 45 | #define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */ | ||
| 46 | #define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */ | ||
| 47 | #define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */ | ||
| 48 | #define AT91_MATRIX_SLOT_CYCLE (0x1ff << 0) /* Maximum Number of Allowed Cycles for a Burst */ | ||
| 49 | #define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */ | ||
| 50 | #define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16) | ||
| 51 | #define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16) | ||
| 52 | #define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16) | ||
| 53 | #define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */ | ||
| 54 | |||
| 55 | #define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */ | ||
| 56 | #define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */ | ||
| 57 | #define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */ | ||
| 58 | #define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */ | ||
| 59 | #define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */ | ||
| 60 | #define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */ | ||
| 61 | #define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */ | ||
| 62 | #define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */ | ||
| 63 | #define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */ | ||
| 64 | #define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */ | ||
| 65 | #define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */ | ||
| 66 | #define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */ | ||
| 67 | #define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */ | ||
| 68 | #define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */ | ||
| 69 | #define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */ | ||
| 70 | #define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */ | ||
| 71 | #define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */ | ||
| 72 | #define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */ | ||
| 73 | #define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */ | ||
| 74 | #define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */ | ||
| 75 | #define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */ | ||
| 76 | #define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */ | ||
| 77 | #define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */ | ||
| 78 | #define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */ | ||
| 79 | #define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */ | ||
| 80 | #define AT91_MATRIX_M9PR (3 << 4) /* Master 9 Priority (in Register B) */ | ||
| 81 | #define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */ | ||
| 82 | #define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */ | ||
| 83 | |||
| 84 | #define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */ | ||
| 85 | #define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */ | ||
| 86 | #define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */ | ||
| 87 | #define AT91_MATRIX_RCB2 (1 << 2) | ||
| 88 | #define AT91_MATRIX_RCB3 (1 << 3) | ||
| 89 | #define AT91_MATRIX_RCB4 (1 << 4) | ||
| 90 | #define AT91_MATRIX_RCB5 (1 << 5) | ||
| 91 | #define AT91_MATRIX_RCB6 (1 << 6) | ||
| 92 | #define AT91_MATRIX_RCB7 (1 << 7) | ||
| 93 | #define AT91_MATRIX_RCB8 (1 << 8) | ||
| 94 | #define AT91_MATRIX_RCB9 (1 << 9) | ||
| 95 | #define AT91_MATRIX_RCB10 (1 << 10) | ||
| 96 | #define AT91_MATRIX_RCB11 (1 << 11) | ||
| 97 | |||
| 98 | #define AT91_MATRIX_TCMR (AT91_MATRIX + 0x110) /* TCM Configuration Register */ | ||
| 99 | #define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */ | ||
| 100 | #define AT91_MATRIX_ITCM_0 (0 << 0) | ||
| 101 | #define AT91_MATRIX_ITCM_32 (6 << 0) | ||
| 102 | #define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */ | ||
| 103 | #define AT91_MATRIX_DTCM_0 (0 << 4) | ||
| 104 | #define AT91_MATRIX_DTCM_32 (6 << 4) | ||
| 105 | #define AT91_MATRIX_DTCM_64 (7 << 4) | ||
| 106 | #define AT91_MATRIX_TCM_NWS (0x1 << 11) /* Wait state TCM register */ | ||
| 107 | #define AT91_MATRIX_TCM_NO_WS (0x0 << 11) | ||
| 108 | #define AT91_MATRIX_TCM_ONE_WS (0x1 << 11) | ||
| 109 | |||
| 110 | #define AT91_MATRIX_VIDEO (AT91_MATRIX + 0x118) /* Video Mode Configuration Register */ | ||
| 111 | #define AT91C_VDEC_SEL (0x1 << 0) /* Video Mode Selection */ | ||
| 112 | #define AT91C_VDEC_SEL_OFF (0 << 0) | ||
| 113 | #define AT91C_VDEC_SEL_ON (1 << 0) | ||
| 114 | |||
| 115 | #define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x128) /* EBI Chip Select Assignment Register */ | ||
| 116 | #define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ | ||
| 117 | #define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) | ||
| 118 | #define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1) | ||
| 119 | #define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */ | ||
| 120 | #define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) | ||
| 121 | #define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3) | ||
| 122 | #define AT91_MATRIX_EBI_CS4A (1 << 4) /* Chip Select 4 Assignment */ | ||
| 123 | #define AT91_MATRIX_EBI_CS4A_SMC (0 << 4) | ||
| 124 | #define AT91_MATRIX_EBI_CS4A_SMC_CF0 (1 << 4) | ||
| 125 | #define AT91_MATRIX_EBI_CS5A (1 << 5) /* Chip Select 5 Assignment */ | ||
| 126 | #define AT91_MATRIX_EBI_CS5A_SMC (0 << 5) | ||
| 127 | #define AT91_MATRIX_EBI_CS5A_SMC_CF1 (1 << 5) | ||
| 128 | #define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ | ||
| 129 | #define AT91_MATRIX_EBI_DBPU_ON (0 << 8) | ||
| 130 | #define AT91_MATRIX_EBI_DBPU_OFF (1 << 8) | ||
| 131 | #define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */ | ||
| 132 | #define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) | ||
| 133 | #define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) | ||
| 134 | #define AT91_MATRIX_EBI_EBI_IOSR (1 << 17) /* EBI I/O slew rate selection */ | ||
| 135 | #define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17) | ||
| 136 | #define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17) | ||
| 137 | #define AT91_MATRIX_EBI_DDR_IOSR (1 << 18) /* DDR2 dedicated port I/O slew rate selection */ | ||
| 138 | #define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18) | ||
| 139 | #define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18) | ||
| 140 | |||
| 141 | #define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */ | ||
| 142 | #define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */ | ||
| 143 | #define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0) | ||
| 144 | #define AT91_MATRIX_WPMR_WP_WPEN (1 << 0) | ||
| 145 | #define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */ | ||
| 146 | |||
| 147 | #define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */ | ||
| 148 | #define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */ | ||
| 149 | #define AT91_MATRIX_WPSR_NO_WPV (0 << 0) | ||
| 150 | #define AT91_MATRIX_WPSR_WPV (1 << 0) | ||
| 151 | #define AT91_MATRIX_WPSR_WPVSRC (0xFFFF << 8) /* Write Protect Violation Source */ | ||
| 152 | |||
| 153 | #endif | ||
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index e6afff849b85..13f27a4b882d 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <linux/leds.h> | 37 | #include <linux/leds.h> |
| 38 | #include <linux/spi/spi.h> | 38 | #include <linux/spi/spi.h> |
| 39 | #include <linux/usb/atmel_usba_udc.h> | 39 | #include <linux/usb/atmel_usba_udc.h> |
| 40 | #include <sound/atmel-ac97c.h> | ||
| 40 | 41 | ||
| 41 | /* USB Device */ | 42 | /* USB Device */ |
| 42 | struct at91_udc_data { | 43 | struct at91_udc_data { |
| @@ -80,7 +81,8 @@ struct at91_eth_data { | |||
| 80 | }; | 81 | }; |
| 81 | extern void __init at91_add_device_eth(struct at91_eth_data *data); | 82 | extern void __init at91_add_device_eth(struct at91_eth_data *data); |
| 82 | 83 | ||
| 83 | #if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) | 84 | #if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \ |
| 85 | || defined(CONFIG_ARCH_AT91SAM9G45) | ||
| 84 | #define eth_platform_data at91_eth_data | 86 | #define eth_platform_data at91_eth_data |
| 85 | #endif | 87 | #endif |
| 86 | 88 | ||
| @@ -90,6 +92,7 @@ struct at91_usbh_data { | |||
| 90 | u8 vbus_pin[2]; /* port power-control pin */ | 92 | u8 vbus_pin[2]; /* port power-control pin */ |
| 91 | }; | 93 | }; |
| 92 | extern void __init at91_add_device_usbh(struct at91_usbh_data *data); | 94 | extern void __init at91_add_device_usbh(struct at91_usbh_data *data); |
| 95 | extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data); | ||
| 93 | 96 | ||
| 94 | /* NAND / SmartMedia */ | 97 | /* NAND / SmartMedia */ |
| 95 | struct atmel_nand_data { | 98 | struct atmel_nand_data { |
| @@ -105,7 +108,11 @@ struct atmel_nand_data { | |||
| 105 | extern void __init at91_add_device_nand(struct atmel_nand_data *data); | 108 | extern void __init at91_add_device_nand(struct atmel_nand_data *data); |
| 106 | 109 | ||
| 107 | /* I2C*/ | 110 | /* I2C*/ |
| 111 | #if defined(CONFIG_ARCH_AT91SAM9G45) | ||
| 112 | extern void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices); | ||
| 113 | #else | ||
| 108 | extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices); | 114 | extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices); |
| 115 | #endif | ||
| 109 | 116 | ||
| 110 | /* SPI */ | 117 | /* SPI */ |
| 111 | extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices); | 118 | extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices); |
| @@ -168,10 +175,7 @@ struct atmel_lcdfb_info; | |||
| 168 | extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data); | 175 | extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data); |
| 169 | 176 | ||
| 170 | /* AC97 */ | 177 | /* AC97 */ |
| 171 | struct atmel_ac97_data { | 178 | extern void __init at91_add_device_ac97(struct ac97c_platform_data *data); |
| 172 | u8 reset_pin; /* reset */ | ||
| 173 | }; | ||
| 174 | extern void __init at91_add_device_ac97(struct atmel_ac97_data *data); | ||
| 175 | 179 | ||
| 176 | /* ISI */ | 180 | /* ISI */ |
| 177 | extern void __init at91_add_device_isi(void); | 181 | extern void __init at91_add_device_isi(void); |
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index c554c3e4d553..34a9502c48bc 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h +++ b/arch/arm/mach-at91/include/mach/cpu.h | |||
| @@ -21,8 +21,10 @@ | |||
| 21 | #define ARCH_ID_AT91SAM9260 0x019803a0 | 21 | #define ARCH_ID_AT91SAM9260 0x019803a0 |
| 22 | #define ARCH_ID_AT91SAM9261 0x019703a0 | 22 | #define ARCH_ID_AT91SAM9261 0x019703a0 |
| 23 | #define ARCH_ID_AT91SAM9263 0x019607a0 | 23 | #define ARCH_ID_AT91SAM9263 0x019607a0 |
| 24 | #define ARCH_ID_AT91SAM9G10 0x819903a0 | ||
| 24 | #define ARCH_ID_AT91SAM9G20 0x019905a0 | 25 | #define ARCH_ID_AT91SAM9G20 0x019905a0 |
| 25 | #define ARCH_ID_AT91SAM9RL64 0x019b03a0 | 26 | #define ARCH_ID_AT91SAM9RL64 0x019b03a0 |
| 27 | #define ARCH_ID_AT91SAM9G45 0x819b05a0 | ||
| 26 | #define ARCH_ID_AT91CAP9 0x039A03A0 | 28 | #define ARCH_ID_AT91CAP9 0x039A03A0 |
| 27 | 29 | ||
| 28 | #define ARCH_ID_AT91SAM9XE128 0x329973a0 | 30 | #define ARCH_ID_AT91SAM9XE128 0x329973a0 |
| @@ -39,6 +41,15 @@ static inline unsigned long at91_cpu_identify(void) | |||
| 39 | return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION); | 41 | return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION); |
| 40 | } | 42 | } |
| 41 | 43 | ||
| 44 | #define ARCH_EXID_AT91SAM9M11 0x00000001 | ||
| 45 | #define ARCH_EXID_AT91SAM9M10 0x00000002 | ||
| 46 | #define ARCH_EXID_AT91SAM9G45 0x00000004 | ||
| 47 | |||
| 48 | static inline unsigned long at91_exid_identify(void) | ||
| 49 | { | ||
| 50 | return at91_sys_read(AT91_DBGU_EXID); | ||
| 51 | } | ||
| 52 | |||
| 42 | 53 | ||
| 43 | #define ARCH_FAMILY_AT91X92 0x09200000 | 54 | #define ARCH_FAMILY_AT91X92 0x09200000 |
| 44 | #define ARCH_FAMILY_AT91SAM9 0x01900000 | 55 | #define ARCH_FAMILY_AT91SAM9 0x01900000 |
| @@ -87,6 +98,12 @@ static inline unsigned long at91cap9_rev_identify(void) | |||
| 87 | #define cpu_is_at91sam9261() (0) | 98 | #define cpu_is_at91sam9261() (0) |
| 88 | #endif | 99 | #endif |
| 89 | 100 | ||
| 101 | #ifdef CONFIG_ARCH_AT91SAM9G10 | ||
| 102 | #define cpu_is_at91sam9g10() (at91_cpu_identify() == ARCH_ID_AT91SAM9G10) | ||
| 103 | #else | ||
| 104 | #define cpu_is_at91sam9g10() (0) | ||
| 105 | #endif | ||
| 106 | |||
| 90 | #ifdef CONFIG_ARCH_AT91SAM9263 | 107 | #ifdef CONFIG_ARCH_AT91SAM9263 |
| 91 | #define cpu_is_at91sam9263() (at91_cpu_identify() == ARCH_ID_AT91SAM9263) | 108 | #define cpu_is_at91sam9263() (at91_cpu_identify() == ARCH_ID_AT91SAM9263) |
| 92 | #else | 109 | #else |
| @@ -99,6 +116,12 @@ static inline unsigned long at91cap9_rev_identify(void) | |||
| 99 | #define cpu_is_at91sam9rl() (0) | 116 | #define cpu_is_at91sam9rl() (0) |
| 100 | #endif | 117 | #endif |
| 101 | 118 | ||
| 119 | #ifdef CONFIG_ARCH_AT91SAM9G45 | ||
| 120 | #define cpu_is_at91sam9g45() (at91_cpu_identify() == ARCH_ID_AT91SAM9G45) | ||
| 121 | #else | ||
| 122 | #define cpu_is_at91sam9g45() (0) | ||
| 123 | #endif | ||
| 124 | |||
| 102 | #ifdef CONFIG_ARCH_AT91CAP9 | 125 | #ifdef CONFIG_ARCH_AT91CAP9 |
| 103 | #define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9) | 126 | #define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9) |
| 104 | #define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B) | 127 | #define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B) |
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h index da0b681c652c..a0df8b022df2 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h | |||
| @@ -20,12 +20,14 @@ | |||
| 20 | #include <mach/at91rm9200.h> | 20 | #include <mach/at91rm9200.h> |
| 21 | #elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) | 21 | #elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) |
| 22 | #include <mach/at91sam9260.h> | 22 | #include <mach/at91sam9260.h> |
| 23 | #elif defined(CONFIG_ARCH_AT91SAM9261) | 23 | #elif defined(CONFIG_ARCH_AT91SAM9261) || defined(CONFIG_ARCH_AT91SAM9G10) |
| 24 | #include <mach/at91sam9261.h> | 24 | #include <mach/at91sam9261.h> |
| 25 | #elif defined(CONFIG_ARCH_AT91SAM9263) | 25 | #elif defined(CONFIG_ARCH_AT91SAM9263) |
| 26 | #include <mach/at91sam9263.h> | 26 | #include <mach/at91sam9263.h> |
| 27 | #elif defined(CONFIG_ARCH_AT91SAM9RL) | 27 | #elif defined(CONFIG_ARCH_AT91SAM9RL) |
| 28 | #include <mach/at91sam9rl.h> | 28 | #include <mach/at91sam9rl.h> |
| 29 | #elif defined(CONFIG_ARCH_AT91SAM9G45) | ||
| 30 | #include <mach/at91sam9g45.h> | ||
| 29 | #elif defined(CONFIG_ARCH_AT91CAP9) | 31 | #elif defined(CONFIG_ARCH_AT91CAP9) |
| 30 | #include <mach/at91cap9.h> | 32 | #include <mach/at91cap9.h> |
| 31 | #elif defined(CONFIG_ARCH_AT91X40) | 33 | #elif defined(CONFIG_ARCH_AT91X40) |
diff --git a/arch/arm/mach-at91/include/mach/timex.h b/arch/arm/mach-at91/include/mach/timex.h index d84c9948becf..31ac2d97f14c 100644 --- a/arch/arm/mach-at91/include/mach/timex.h +++ b/arch/arm/mach-at91/include/mach/timex.h | |||
| @@ -42,6 +42,11 @@ | |||
| 42 | #define AT91SAM9_MASTER_CLOCK 99300000 | 42 | #define AT91SAM9_MASTER_CLOCK 99300000 |
| 43 | #define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) | 43 | #define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) |
| 44 | 44 | ||
| 45 | #elif defined(CONFIG_ARCH_AT91SAM9G10) | ||
| 46 | |||
| 47 | #define AT91SAM9_MASTER_CLOCK 133000000 | ||
| 48 | #define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) | ||
| 49 | |||
| 45 | #elif defined(CONFIG_ARCH_AT91SAM9263) | 50 | #elif defined(CONFIG_ARCH_AT91SAM9263) |
| 46 | 51 | ||
| 47 | #if defined(CONFIG_MACH_USB_A9263) | 52 | #if defined(CONFIG_MACH_USB_A9263) |
| @@ -62,6 +67,11 @@ | |||
| 62 | #define AT91SAM9_MASTER_CLOCK 132096000 | 67 | #define AT91SAM9_MASTER_CLOCK 132096000 |
| 63 | #define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) | 68 | #define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) |
| 64 | 69 | ||
| 70 | #elif defined(CONFIG_ARCH_AT91SAM9G45) | ||
| 71 | |||
| 72 | #define AT91SAM9_MASTER_CLOCK 133333333 | ||
| 73 | #define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) | ||
| 74 | |||
| 65 | #elif defined(CONFIG_ARCH_AT91CAP9) | 75 | #elif defined(CONFIG_ARCH_AT91CAP9) |
| 66 | 76 | ||
| 67 | #define AT91CAP9_MASTER_CLOCK 100000000 | 77 | #define AT91CAP9_MASTER_CLOCK 100000000 |
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index e26c4fe61fae..4028724d490d 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
| @@ -201,7 +201,8 @@ static int at91_pm_verify_clocks(void) | |||
| 201 | pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); | 201 | pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); |
| 202 | return 0; | 202 | return 0; |
| 203 | } | 203 | } |
| 204 | } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { | 204 | } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() |
| 205 | || cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) { | ||
| 205 | if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) { | 206 | if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) { |
| 206 | pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); | 207 | pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); |
| 207 | return 0; | 208 | return 0; |
diff --git a/arch/arm/mach-bcmring/Kconfig b/arch/arm/mach-bcmring/Kconfig new file mode 100644 index 000000000000..457b4384913e --- /dev/null +++ b/arch/arm/mach-bcmring/Kconfig | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | choice | ||
| 2 | prompt "Processor selection in BCMRING family of devices" | ||
| 3 | depends on ARCH_BCMRING | ||
| 4 | default ARCH_BCM11107 | ||
| 5 | |||
| 6 | config ARCH_FPGA11107 | ||
| 7 | bool "FPGA11107" | ||
| 8 | |||
| 9 | config ARCH_BCM11107 | ||
| 10 | bool "BCM11107" | ||
| 11 | endchoice | ||
| 12 | |||
| 13 | menu "BCMRING Options" | ||
| 14 | depends on ARCH_BCMRING | ||
| 15 | |||
| 16 | config BCM_ZRELADDR | ||
| 17 | hex "Compressed ZREL ADDR" | ||
| 18 | |||
| 19 | endmenu | ||
| 20 | |||
| 21 | # source "drivers/char/bcmring/Kconfig" | ||
diff --git a/arch/arm/mach-bcmring/Makefile b/arch/arm/mach-bcmring/Makefile new file mode 100644 index 000000000000..f8d9fcedf917 --- /dev/null +++ b/arch/arm/mach-bcmring/Makefile | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the linux kernel. | ||
| 3 | # | ||
| 4 | |||
| 5 | # Object file lists. | ||
| 6 | |||
| 7 | obj-y := arch.o mm.o irq.o clock.o core.o timer.o dma.o | ||
| 8 | obj-y += csp/ | ||
diff --git a/arch/arm/mach-bcmring/Makefile.boot b/arch/arm/mach-bcmring/Makefile.boot new file mode 100644 index 000000000000..fb53b283bebb --- /dev/null +++ b/arch/arm/mach-bcmring/Makefile.boot | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | # Address where decompressor will be written and eventually executed. | ||
| 2 | # | ||
| 3 | # default to SDRAM | ||
| 4 | zreladdr-y := $(CONFIG_BCM_ZRELADDR) | ||
| 5 | params_phys-y := 0x00000800 | ||
| 6 | |||
diff --git a/arch/arm/mach-bcmring/arch.c b/arch/arm/mach-bcmring/arch.c new file mode 100644 index 000000000000..0da693b0f7e1 --- /dev/null +++ b/arch/arm/mach-bcmring/arch.c | |||
| @@ -0,0 +1,157 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/types.h> | ||
| 18 | #include <linux/sched.h> | ||
| 19 | #include <linux/interrupt.h> | ||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/errno.h> | ||
| 22 | #include <linux/spinlock.h> | ||
| 23 | #include <linux/module.h> | ||
| 24 | |||
| 25 | #include <linux/proc_fs.h> | ||
| 26 | #include <linux/sysctl.h> | ||
| 27 | |||
| 28 | #include <asm/irq.h> | ||
| 29 | #include <asm/setup.h> | ||
| 30 | #include <asm/mach-types.h> | ||
| 31 | #include <asm/mach/time.h> | ||
| 32 | |||
| 33 | #include <asm/mach/arch.h> | ||
| 34 | #include <mach/dma.h> | ||
| 35 | #include <mach/hardware.h> | ||
| 36 | #include <mach/csp/mm_io.h> | ||
| 37 | #include <mach/csp/chipcHw_def.h> | ||
| 38 | #include <mach/csp/chipcHw_inline.h> | ||
| 39 | |||
| 40 | #include <cfg_global.h> | ||
| 41 | |||
| 42 | #include "core.h" | ||
| 43 | |||
| 44 | HW_DECLARE_SPINLOCK(arch) | ||
| 45 | HW_DECLARE_SPINLOCK(gpio) | ||
| 46 | #if defined(CONFIG_DEBUG_SPINLOCK) | ||
| 47 | EXPORT_SYMBOL(bcmring_gpio_reg_lock); | ||
| 48 | #endif | ||
| 49 | |||
| 50 | /* FIXME: temporary solution */ | ||
| 51 | #define BCM_SYSCTL_REBOOT_WARM 1 | ||
| 52 | #define CTL_BCM_REBOOT 112 | ||
| 53 | |||
| 54 | /* sysctl */ | ||
| 55 | int bcmring_arch_warm_reboot; /* do a warm reboot on hard reset */ | ||
| 56 | |||
| 57 | static struct ctl_table_header *bcmring_sysctl_header; | ||
| 58 | |||
| 59 | static struct ctl_table bcmring_sysctl_warm_reboot[] = { | ||
| 60 | { | ||
| 61 | .ctl_name = BCM_SYSCTL_REBOOT_WARM, | ||
| 62 | .procname = "warm", | ||
| 63 | .data = &bcmring_arch_warm_reboot, | ||
| 64 | .maxlen = sizeof(int), | ||
| 65 | .mode = 0644, | ||
| 66 | .proc_handler = &proc_dointvec}, | ||
| 67 | {} | ||
| 68 | }; | ||
| 69 | |||
| 70 | static struct ctl_table bcmring_sysctl_reboot[] = { | ||
| 71 | { | ||
| 72 | .ctl_name = CTL_BCM_REBOOT, | ||
| 73 | .procname = "reboot", | ||
| 74 | .mode = 0555, | ||
| 75 | .child = bcmring_sysctl_warm_reboot}, | ||
| 76 | {} | ||
| 77 | }; | ||
| 78 | |||
| 79 | static struct platform_device nand_device = { | ||
| 80 | .name = "bcm-nand", | ||
| 81 | .id = -1, | ||
| 82 | }; | ||
| 83 | |||
| 84 | static struct platform_device *devices[] __initdata = { | ||
| 85 | &nand_device, | ||
| 86 | }; | ||
| 87 | |||
| 88 | /**************************************************************************** | ||
| 89 | * | ||
| 90 | * Called from the customize_machine function in arch/arm/kernel/setup.c | ||
| 91 | * | ||
| 92 | * The customize_machine function is tagged as an arch_initcall | ||
| 93 | * (see include/linux/init.h for the order that the various init sections | ||
| 94 | * are called in. | ||
| 95 | * | ||
| 96 | *****************************************************************************/ | ||
| 97 | static void __init bcmring_init_machine(void) | ||
| 98 | { | ||
| 99 | |||
| 100 | bcmring_sysctl_header = register_sysctl_table(bcmring_sysctl_reboot); | ||
| 101 | |||
| 102 | /* Enable spread spectrum */ | ||
| 103 | chipcHw_enableSpreadSpectrum(); | ||
| 104 | |||
| 105 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
| 106 | |||
| 107 | bcmring_amba_init(); | ||
| 108 | |||
| 109 | dma_init(); | ||
| 110 | } | ||
| 111 | |||
| 112 | /**************************************************************************** | ||
| 113 | * | ||
| 114 | * Called from setup_arch (in arch/arm/kernel/setup.c) to fixup any tags | ||
| 115 | * passed in by the boot loader. | ||
| 116 | * | ||
| 117 | *****************************************************************************/ | ||
| 118 | |||
| 119 | static void __init bcmring_fixup(struct machine_desc *desc, | ||
| 120 | struct tag *t, char **cmdline, struct meminfo *mi) { | ||
| 121 | #ifdef CONFIG_BLK_DEV_INITRD | ||
| 122 | printk(KERN_NOTICE "bcmring_fixup\n"); | ||
| 123 | t->hdr.tag = ATAG_CORE; | ||
| 124 | t->hdr.size = tag_size(tag_core); | ||
| 125 | t->u.core.flags = 0; | ||
| 126 | t->u.core.pagesize = PAGE_SIZE; | ||
| 127 | t->u.core.rootdev = 31 << 8 | 0; | ||
| 128 | t = tag_next(t); | ||
| 129 | |||
| 130 | t->hdr.tag = ATAG_MEM; | ||
| 131 | t->hdr.size = tag_size(tag_mem32); | ||
| 132 | t->u.mem.start = CFG_GLOBAL_RAM_BASE; | ||
| 133 | t->u.mem.size = CFG_GLOBAL_RAM_SIZE; | ||
| 134 | |||
| 135 | t = tag_next(t); | ||
| 136 | |||
| 137 | t->hdr.tag = ATAG_NONE; | ||
| 138 | t->hdr.size = 0; | ||
| 139 | #endif | ||
| 140 | } | ||
| 141 | |||
| 142 | /**************************************************************************** | ||
| 143 | * | ||
| 144 | * Machine Description | ||
| 145 | * | ||
| 146 | *****************************************************************************/ | ||
| 147 | |||
| 148 | MACHINE_START(BCMRING, "BCMRING") | ||
| 149 | /* Maintainer: Broadcom Corporation */ | ||
| 150 | .phys_io = MM_IO_START, | ||
| 151 | .io_pg_offst = (MM_IO_BASE >> 18) & 0xfffc, | ||
| 152 | .fixup = bcmring_fixup, | ||
| 153 | .map_io = bcmring_map_io, | ||
| 154 | .init_irq = bcmring_init_irq, | ||
| 155 | .timer = &bcmring_timer, | ||
| 156 | .init_machine = bcmring_init_machine | ||
| 157 | MACHINE_END | ||
diff --git a/arch/arm/mach-bcmring/clock.c b/arch/arm/mach-bcmring/clock.c new file mode 100644 index 000000000000..14bafc38f2dc --- /dev/null +++ b/arch/arm/mach-bcmring/clock.c | |||
| @@ -0,0 +1,224 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2001 - 2009 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/device.h> | ||
| 18 | #include <linux/list.h> | ||
| 19 | #include <linux/errno.h> | ||
| 20 | #include <linux/err.h> | ||
| 21 | #include <linux/string.h> | ||
| 22 | #include <linux/clk.h> | ||
| 23 | #include <linux/spinlock.h> | ||
| 24 | #include <mach/csp/hw_cfg.h> | ||
| 25 | #include <mach/csp/chipcHw_def.h> | ||
| 26 | #include <mach/csp/chipcHw_reg.h> | ||
| 27 | #include <mach/csp/chipcHw_inline.h> | ||
| 28 | |||
| 29 | #include <asm/clkdev.h> | ||
| 30 | |||
| 31 | #include "clock.h" | ||
| 32 | |||
| 33 | #define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) | ||
| 34 | #define clk_is_pll1(x) ((x)->type & CLK_TYPE_PLL1) | ||
| 35 | #define clk_is_pll2(x) ((x)->type & CLK_TYPE_PLL2) | ||
| 36 | #define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) | ||
| 37 | #define clk_is_bypassable(x) ((x)->type & CLK_TYPE_BYPASSABLE) | ||
| 38 | |||
| 39 | #define clk_is_using_xtal(x) ((x)->mode & CLK_MODE_XTAL) | ||
| 40 | |||
| 41 | static DEFINE_SPINLOCK(clk_lock); | ||
| 42 | |||
| 43 | static void __clk_enable(struct clk *clk) | ||
| 44 | { | ||
| 45 | if (!clk) | ||
| 46 | return; | ||
| 47 | |||
| 48 | /* enable parent clock first */ | ||
| 49 | if (clk->parent) | ||
| 50 | __clk_enable(clk->parent); | ||
| 51 | |||
| 52 | if (clk->use_cnt++ == 0) { | ||
| 53 | if (clk_is_pll1(clk)) { /* PLL1 */ | ||
| 54 | chipcHw_pll1Enable(clk->rate_hz, 0); | ||
| 55 | } else if (clk_is_pll2(clk)) { /* PLL2 */ | ||
| 56 | chipcHw_pll2Enable(clk->rate_hz); | ||
| 57 | } else if (clk_is_using_xtal(clk)) { /* source is crystal */ | ||
| 58 | if (!clk_is_primary(clk)) | ||
| 59 | chipcHw_bypassClockEnable(clk->csp_id); | ||
| 60 | } else { /* source is PLL */ | ||
| 61 | chipcHw_setClockEnable(clk->csp_id); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | int clk_enable(struct clk *clk) | ||
| 67 | { | ||
| 68 | unsigned long flags; | ||
| 69 | |||
| 70 | if (!clk) | ||
| 71 | return -EINVAL; | ||
| 72 | |||
| 73 | spin_lock_irqsave(&clk_lock, flags); | ||
| 74 | __clk_enable(clk); | ||
| 75 | spin_unlock_irqrestore(&clk_lock, flags); | ||
| 76 | |||
| 77 | return 0; | ||
| 78 | } | ||
| 79 | EXPORT_SYMBOL(clk_enable); | ||
| 80 | |||
| 81 | static void __clk_disable(struct clk *clk) | ||
| 82 | { | ||
| 83 | if (!clk) | ||
| 84 | return; | ||
| 85 | |||
| 86 | BUG_ON(clk->use_cnt == 0); | ||
| 87 | |||
| 88 | if (--clk->use_cnt == 0) { | ||
| 89 | if (clk_is_pll1(clk)) { /* PLL1 */ | ||
| 90 | chipcHw_pll1Disable(); | ||
| 91 | } else if (clk_is_pll2(clk)) { /* PLL2 */ | ||
| 92 | chipcHw_pll2Disable(); | ||
| 93 | } else if (clk_is_using_xtal(clk)) { /* source is crystal */ | ||
| 94 | if (!clk_is_primary(clk)) | ||
| 95 | chipcHw_bypassClockDisable(clk->csp_id); | ||
| 96 | } else { /* source is PLL */ | ||
| 97 | chipcHw_setClockDisable(clk->csp_id); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | if (clk->parent) | ||
| 102 | __clk_disable(clk->parent); | ||
| 103 | } | ||
| 104 | |||
| 105 | void clk_disable(struct clk *clk) | ||
| 106 | { | ||
| 107 | unsigned long flags; | ||
| 108 | |||
| 109 | if (!clk) | ||
| 110 | return; | ||
| 111 | |||
| 112 | spin_lock_irqsave(&clk_lock, flags); | ||
| 113 | __clk_disable(clk); | ||
| 114 | spin_unlock_irqrestore(&clk_lock, flags); | ||
| 115 | } | ||
| 116 | EXPORT_SYMBOL(clk_disable); | ||
| 117 | |||
| 118 | unsigned long clk_get_rate(struct clk *clk) | ||
| 119 | { | ||
| 120 | if (!clk) | ||
| 121 | return 0; | ||
| 122 | |||
| 123 | return clk->rate_hz; | ||
| 124 | } | ||
| 125 | EXPORT_SYMBOL(clk_get_rate); | ||
| 126 | |||
| 127 | long clk_round_rate(struct clk *clk, unsigned long rate) | ||
| 128 | { | ||
| 129 | unsigned long flags; | ||
| 130 | unsigned long actual; | ||
| 131 | unsigned long rate_hz; | ||
| 132 | |||
| 133 | if (!clk) | ||
| 134 | return -EINVAL; | ||
| 135 | |||
| 136 | if (!clk_is_programmable(clk)) | ||
| 137 | return -EINVAL; | ||
| 138 | |||
| 139 | if (clk->use_cnt) | ||
| 140 | return -EBUSY; | ||
| 141 | |||
| 142 | spin_lock_irqsave(&clk_lock, flags); | ||
| 143 | actual = clk->parent->rate_hz; | ||
| 144 | rate_hz = min(actual, rate); | ||
| 145 | spin_unlock_irqrestore(&clk_lock, flags); | ||
| 146 | |||
| 147 | return rate_hz; | ||
| 148 | } | ||
| 149 | EXPORT_SYMBOL(clk_round_rate); | ||
| 150 | |||
| 151 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
| 152 | { | ||
| 153 | unsigned long flags; | ||
| 154 | unsigned long actual; | ||
| 155 | unsigned long rate_hz; | ||
| 156 | |||
| 157 | if (!clk) | ||
| 158 | return -EINVAL; | ||
| 159 | |||
| 160 | if (!clk_is_programmable(clk)) | ||
| 161 | return -EINVAL; | ||
| 162 | |||
| 163 | if (clk->use_cnt) | ||
| 164 | return -EBUSY; | ||
| 165 | |||
| 166 | spin_lock_irqsave(&clk_lock, flags); | ||
| 167 | actual = clk->parent->rate_hz; | ||
| 168 | rate_hz = min(actual, rate); | ||
| 169 | rate_hz = chipcHw_setClockFrequency(clk->csp_id, rate_hz); | ||
| 170 | clk->rate_hz = rate_hz; | ||
| 171 | spin_unlock_irqrestore(&clk_lock, flags); | ||
| 172 | |||
| 173 | return 0; | ||
| 174 | } | ||
| 175 | EXPORT_SYMBOL(clk_set_rate); | ||
| 176 | |||
| 177 | struct clk *clk_get_parent(struct clk *clk) | ||
| 178 | { | ||
| 179 | if (!clk) | ||
| 180 | return NULL; | ||
| 181 | |||
| 182 | return clk->parent; | ||
| 183 | } | ||
| 184 | EXPORT_SYMBOL(clk_get_parent); | ||
| 185 | |||
| 186 | int clk_set_parent(struct clk *clk, struct clk *parent) | ||
| 187 | { | ||
| 188 | unsigned long flags; | ||
| 189 | struct clk *old_parent; | ||
| 190 | |||
| 191 | if (!clk || !parent) | ||
| 192 | return -EINVAL; | ||
| 193 | |||
| 194 | if (!clk_is_primary(parent) || !clk_is_bypassable(clk)) | ||
| 195 | return -EINVAL; | ||
| 196 | |||
| 197 | /* if more than one user, parent is not allowed */ | ||
| 198 | if (clk->use_cnt > 1) | ||
| 199 | return -EBUSY; | ||
| 200 | |||
| 201 | if (clk->parent == parent) | ||
| 202 | return 0; | ||
| 203 | |||
| 204 | spin_lock_irqsave(&clk_lock, flags); | ||
| 205 | old_parent = clk->parent; | ||
| 206 | clk->parent = parent; | ||
| 207 | if (clk_is_using_xtal(parent)) | ||
| 208 | clk->mode |= CLK_MODE_XTAL; | ||
| 209 | else | ||
| 210 | clk->mode &= (~CLK_MODE_XTAL); | ||
| 211 | |||
| 212 | /* if clock is active */ | ||
| 213 | if (clk->use_cnt != 0) { | ||
| 214 | clk->use_cnt--; | ||
| 215 | /* enable clock with the new parent */ | ||
| 216 | __clk_enable(clk); | ||
| 217 | /* disable the old parent */ | ||
| 218 | __clk_disable(old_parent); | ||
| 219 | } | ||
| 220 | spin_unlock_irqrestore(&clk_lock, flags); | ||
| 221 | |||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | EXPORT_SYMBOL(clk_set_parent); | ||
diff --git a/arch/arm/mach-bcmring/clock.h b/arch/arm/mach-bcmring/clock.h new file mode 100644 index 000000000000..5e0b98138973 --- /dev/null +++ b/arch/arm/mach-bcmring/clock.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2001 - 2009 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | #include <mach/csp/chipcHw_def.h> | ||
| 15 | |||
| 16 | #define CLK_TYPE_PRIMARY 1 /* primary clock must NOT have a parent */ | ||
| 17 | #define CLK_TYPE_PLL1 2 /* PPL1 */ | ||
| 18 | #define CLK_TYPE_PLL2 4 /* PPL2 */ | ||
| 19 | #define CLK_TYPE_PROGRAMMABLE 8 /* programmable clock rate */ | ||
| 20 | #define CLK_TYPE_BYPASSABLE 16 /* parent can be changed */ | ||
| 21 | |||
| 22 | #define CLK_MODE_XTAL 1 /* clock source is from crystal */ | ||
| 23 | |||
| 24 | struct clk { | ||
| 25 | const char *name; /* clock name */ | ||
| 26 | unsigned int type; /* clock type */ | ||
| 27 | unsigned int mode; /* current mode */ | ||
| 28 | volatile int use_bypass; /* indicate if it's in bypass mode */ | ||
| 29 | chipcHw_CLOCK_e csp_id; /* clock ID for CSP CHIPC */ | ||
| 30 | unsigned long rate_hz; /* clock rate in Hz */ | ||
| 31 | unsigned int use_cnt; /* usage count */ | ||
| 32 | struct clk *parent; /* parent clock */ | ||
| 33 | }; | ||
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c new file mode 100644 index 000000000000..492c649f451e --- /dev/null +++ b/arch/arm/mach-bcmring/core.c | |||
| @@ -0,0 +1,367 @@ | |||
| 1 | /* | ||
| 2 | * derived from linux/arch/arm/mach-versatile/core.c | ||
| 3 | * linux/arch/arm/mach-bcmring/core.c | ||
| 4 | * | ||
| 5 | * Copyright (C) 1999 - 2003 ARM Limited | ||
| 6 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | ||
| 22 | /* Portions copyright Broadcom 2008 */ | ||
| 23 | |||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/device.h> | ||
| 26 | #include <linux/dma-mapping.h> | ||
| 27 | #include <linux/platform_device.h> | ||
| 28 | #include <linux/sysdev.h> | ||
| 29 | #include <linux/interrupt.h> | ||
| 30 | #include <linux/amba/bus.h> | ||
| 31 | #include <linux/clocksource.h> | ||
| 32 | #include <linux/clockchips.h> | ||
| 33 | |||
| 34 | #include <linux/amba/bus.h> | ||
| 35 | #include <mach/csp/mm_addr.h> | ||
| 36 | #include <mach/hardware.h> | ||
| 37 | #include <asm/clkdev.h> | ||
| 38 | #include <linux/io.h> | ||
| 39 | #include <asm/irq.h> | ||
| 40 | #include <asm/hardware/arm_timer.h> | ||
| 41 | #include <asm/mach-types.h> | ||
| 42 | |||
| 43 | #include <asm/mach/arch.h> | ||
| 44 | #include <asm/mach/flash.h> | ||
| 45 | #include <asm/mach/irq.h> | ||
| 46 | #include <asm/mach/time.h> | ||
| 47 | #include <asm/mach/map.h> | ||
| 48 | #include <asm/mach/mmc.h> | ||
| 49 | |||
| 50 | #include <cfg_global.h> | ||
| 51 | |||
| 52 | #include "clock.h" | ||
| 53 | |||
| 54 | #include <csp/secHw.h> | ||
| 55 | #include <mach/csp/secHw_def.h> | ||
| 56 | #include <mach/csp/chipcHw_inline.h> | ||
| 57 | #include <mach/csp/tmrHw_reg.h> | ||
| 58 | |||
| 59 | #define AMBA_DEVICE(name, initname, base, plat, size) \ | ||
| 60 | static struct amba_device name##_device = { \ | ||
| 61 | .dev = { \ | ||
| 62 | .coherent_dma_mask = ~0, \ | ||
| 63 | .init_name = initname, \ | ||
| 64 | .platform_data = plat \ | ||
| 65 | }, \ | ||
| 66 | .res = { \ | ||
| 67 | .start = MM_ADDR_IO_##base, \ | ||
| 68 | .end = MM_ADDR_IO_##base + (size) - 1, \ | ||
| 69 | .flags = IORESOURCE_MEM \ | ||
| 70 | }, \ | ||
| 71 | .dma_mask = ~0, \ | ||
| 72 | .irq = { \ | ||
| 73 | IRQ_##base \ | ||
| 74 | } \ | ||
| 75 | } | ||
| 76 | |||
| 77 | |||
| 78 | AMBA_DEVICE(uartA, "uarta", UARTA, NULL, SZ_4K); | ||
| 79 | AMBA_DEVICE(uartB, "uartb", UARTB, NULL, SZ_4K); | ||
| 80 | |||
| 81 | static struct clk pll1_clk = { | ||
| 82 | .name = "PLL1", | ||
| 83 | .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL1, | ||
| 84 | .rate_hz = 2000000000, | ||
| 85 | .use_cnt = 7, | ||
| 86 | }; | ||
| 87 | |||
| 88 | static struct clk uart_clk = { | ||
| 89 | .name = "UART", | ||
| 90 | .type = CLK_TYPE_PROGRAMMABLE, | ||
| 91 | .csp_id = chipcHw_CLOCK_UART, | ||
| 92 | .rate_hz = HW_CFG_UART_CLK_HZ, | ||
| 93 | .parent = &pll1_clk, | ||
| 94 | }; | ||
| 95 | |||
| 96 | static struct clk_lookup lookups[] = { | ||
| 97 | { /* UART0 */ | ||
| 98 | .dev_id = "uarta", | ||
| 99 | .clk = &uart_clk, | ||
| 100 | }, { /* UART1 */ | ||
| 101 | .dev_id = "uartb", | ||
| 102 | .clk = &uart_clk, | ||
| 103 | } | ||
| 104 | }; | ||
| 105 | |||
| 106 | static struct amba_device *amba_devs[] __initdata = { | ||
| 107 | &uartA_device, | ||
| 108 | &uartB_device, | ||
| 109 | }; | ||
| 110 | |||
| 111 | void __init bcmring_amba_init(void) | ||
| 112 | { | ||
| 113 | int i; | ||
| 114 | u32 bus_clock; | ||
| 115 | |||
| 116 | /* Linux is run initially in non-secure mode. Secure peripherals */ | ||
| 117 | /* generate FIQ, and must be handled in secure mode. Until we have */ | ||
| 118 | /* a linux security monitor implementation, keep everything in */ | ||
| 119 | /* non-secure mode. */ | ||
| 120 | chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_SPU); | ||
| 121 | secHw_setUnsecure(secHw_BLK_MASK_CHIP_CONTROL | | ||
| 122 | secHw_BLK_MASK_KEY_SCAN | | ||
| 123 | secHw_BLK_MASK_TOUCH_SCREEN | | ||
| 124 | secHw_BLK_MASK_UART0 | | ||
| 125 | secHw_BLK_MASK_UART1 | | ||
| 126 | secHw_BLK_MASK_WATCHDOG | | ||
| 127 | secHw_BLK_MASK_SPUM | | ||
| 128 | secHw_BLK_MASK_DDR2 | | ||
| 129 | secHw_BLK_MASK_SPU | | ||
| 130 | secHw_BLK_MASK_PKA | | ||
| 131 | secHw_BLK_MASK_RNG | | ||
| 132 | secHw_BLK_MASK_RTC | | ||
| 133 | secHw_BLK_MASK_OTP | | ||
| 134 | secHw_BLK_MASK_BOOT | | ||
| 135 | secHw_BLK_MASK_MPU | | ||
| 136 | secHw_BLK_MASK_TZCTRL | secHw_BLK_MASK_INTR); | ||
| 137 | |||
| 138 | /* Only the devices attached to the AMBA bus are enabled just before the bus is */ | ||
| 139 | /* scanned and the drivers are loaded. The clocks need to be on for the AMBA bus */ | ||
| 140 | /* driver to access these blocks. The bus is probed, and the drivers are loaded. */ | ||
| 141 | /* FIXME Need to remove enable of PIF once CLCD clock enable used properly in FPGA. */ | ||
| 142 | bus_clock = chipcHw_REG_BUS_CLOCK_GE | ||
| 143 | | chipcHw_REG_BUS_CLOCK_SDIO0 | chipcHw_REG_BUS_CLOCK_SDIO1; | ||
| 144 | |||
| 145 | chipcHw_busInterfaceClockEnable(bus_clock); | ||
| 146 | |||
| 147 | for (i = 0; i < ARRAY_SIZE(lookups); i++) | ||
| 148 | clkdev_add(&lookups[i]); | ||
| 149 | |||
| 150 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | ||
| 151 | struct amba_device *d = amba_devs[i]; | ||
| 152 | amba_device_register(d, &iomem_resource); | ||
| 153 | } | ||
| 154 | } | ||
| 155 | |||
| 156 | /* | ||
| 157 | * Where is the timer (VA)? | ||
| 158 | */ | ||
| 159 | #define TIMER0_VA_BASE MM_IO_BASE_TMR | ||
| 160 | #define TIMER1_VA_BASE (MM_IO_BASE_TMR + 0x20) | ||
| 161 | #define TIMER2_VA_BASE (MM_IO_BASE_TMR + 0x40) | ||
| 162 | #define TIMER3_VA_BASE (MM_IO_BASE_TMR + 0x60) | ||
| 163 | |||
| 164 | /* Timer 0 - 25 MHz, Timer3 at bus clock rate, typically 150-166 MHz */ | ||
| 165 | #if defined(CONFIG_ARCH_FPGA11107) | ||
| 166 | /* fpga cpu/bus are currently 30 times slower so scale frequency as well to */ | ||
| 167 | /* slow down Linux's sense of time */ | ||
| 168 | #define TIMER0_FREQUENCY_MHZ (tmrHw_LOW_FREQUENCY_MHZ * 30) | ||
| 169 | #define TIMER1_FREQUENCY_MHZ (tmrHw_LOW_FREQUENCY_MHZ * 30) | ||
| 170 | #define TIMER3_FREQUENCY_MHZ (tmrHw_HIGH_FREQUENCY_MHZ * 30) | ||
| 171 | #define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000 * 30) | ||
| 172 | #else | ||
| 173 | #define TIMER0_FREQUENCY_MHZ tmrHw_LOW_FREQUENCY_MHZ | ||
| 174 | #define TIMER1_FREQUENCY_MHZ tmrHw_LOW_FREQUENCY_MHZ | ||
| 175 | #define TIMER3_FREQUENCY_MHZ tmrHw_HIGH_FREQUENCY_MHZ | ||
| 176 | #define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000) | ||
| 177 | #endif | ||
| 178 | |||
| 179 | #define TICKS_PER_uSEC TIMER0_FREQUENCY_MHZ | ||
| 180 | |||
| 181 | /* | ||
| 182 | * These are useconds NOT ticks. | ||
| 183 | * | ||
| 184 | */ | ||
| 185 | #define mSEC_1 1000 | ||
| 186 | #define mSEC_5 (mSEC_1 * 5) | ||
| 187 | #define mSEC_10 (mSEC_1 * 10) | ||
| 188 | #define mSEC_25 (mSEC_1 * 25) | ||
| 189 | #define SEC_1 (mSEC_1 * 1000) | ||
| 190 | |||
| 191 | /* | ||
| 192 | * How long is the timer interval? | ||
| 193 | */ | ||
| 194 | #define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) | ||
| 195 | #if TIMER_INTERVAL >= 0x100000 | ||
| 196 | #define TIMER_RELOAD (TIMER_INTERVAL >> 8) | ||
| 197 | #define TIMER_DIVISOR (TIMER_CTRL_DIV256) | ||
| 198 | #define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) | ||
| 199 | #elif TIMER_INTERVAL >= 0x10000 | ||
| 200 | #define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ | ||
| 201 | #define TIMER_DIVISOR (TIMER_CTRL_DIV16) | ||
| 202 | #define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) | ||
| 203 | #else | ||
| 204 | #define TIMER_RELOAD (TIMER_INTERVAL) | ||
| 205 | #define TIMER_DIVISOR (TIMER_CTRL_DIV1) | ||
| 206 | #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) | ||
| 207 | #endif | ||
| 208 | |||
| 209 | static void timer_set_mode(enum clock_event_mode mode, | ||
| 210 | struct clock_event_device *clk) | ||
| 211 | { | ||
| 212 | unsigned long ctrl; | ||
| 213 | |||
| 214 | switch (mode) { | ||
| 215 | case CLOCK_EVT_MODE_PERIODIC: | ||
| 216 | writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD); | ||
| 217 | |||
| 218 | ctrl = TIMER_CTRL_PERIODIC; | ||
| 219 | ctrl |= | ||
| 220 | TIMER_DIVISOR | TIMER_CTRL_32BIT | TIMER_CTRL_IE | | ||
| 221 | TIMER_CTRL_ENABLE; | ||
| 222 | break; | ||
| 223 | case CLOCK_EVT_MODE_ONESHOT: | ||
| 224 | /* period set, and timer enabled in 'next_event' hook */ | ||
| 225 | ctrl = TIMER_CTRL_ONESHOT; | ||
| 226 | ctrl |= TIMER_DIVISOR | TIMER_CTRL_32BIT | TIMER_CTRL_IE; | ||
| 227 | break; | ||
| 228 | case CLOCK_EVT_MODE_UNUSED: | ||
| 229 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
| 230 | default: | ||
| 231 | ctrl = 0; | ||
| 232 | } | ||
| 233 | |||
| 234 | writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL); | ||
| 235 | } | ||
| 236 | |||
| 237 | static int timer_set_next_event(unsigned long evt, | ||
| 238 | struct clock_event_device *unused) | ||
| 239 | { | ||
| 240 | unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL); | ||
| 241 | |||
| 242 | writel(evt, TIMER0_VA_BASE + TIMER_LOAD); | ||
| 243 | writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL); | ||
| 244 | |||
| 245 | return 0; | ||
| 246 | } | ||
| 247 | |||
| 248 | static struct clock_event_device timer0_clockevent = { | ||
| 249 | .name = "timer0", | ||
| 250 | .shift = 32, | ||
| 251 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
| 252 | .set_mode = timer_set_mode, | ||
| 253 | .set_next_event = timer_set_next_event, | ||
| 254 | }; | ||
| 255 | |||
| 256 | /* | ||
| 257 | * IRQ handler for the timer | ||
| 258 | */ | ||
| 259 | static irqreturn_t bcmring_timer_interrupt(int irq, void *dev_id) | ||
| 260 | { | ||
| 261 | struct clock_event_device *evt = &timer0_clockevent; | ||
| 262 | |||
| 263 | writel(1, TIMER0_VA_BASE + TIMER_INTCLR); | ||
| 264 | |||
| 265 | evt->event_handler(evt); | ||
| 266 | |||
| 267 | return IRQ_HANDLED; | ||
| 268 | } | ||
| 269 | |||
| 270 | static struct irqaction bcmring_timer_irq = { | ||
| 271 | .name = "bcmring Timer Tick", | ||
| 272 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | ||
| 273 | .handler = bcmring_timer_interrupt, | ||
| 274 | }; | ||
| 275 | |||
| 276 | static cycle_t bcmring_get_cycles_timer1(void) | ||
| 277 | { | ||
| 278 | return ~readl(TIMER1_VA_BASE + TIMER_VALUE); | ||
| 279 | } | ||
| 280 | |||
| 281 | static cycle_t bcmring_get_cycles_timer3(void) | ||
| 282 | { | ||
| 283 | return ~readl(TIMER3_VA_BASE + TIMER_VALUE); | ||
| 284 | } | ||
| 285 | |||
| 286 | static struct clocksource clocksource_bcmring_timer1 = { | ||
| 287 | .name = "timer1", | ||
| 288 | .rating = 200, | ||
| 289 | .read = bcmring_get_cycles_timer1, | ||
| 290 | .mask = CLOCKSOURCE_MASK(32), | ||
| 291 | .shift = 20, | ||
| 292 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
| 293 | }; | ||
| 294 | |||
| 295 | static struct clocksource clocksource_bcmring_timer3 = { | ||
| 296 | .name = "timer3", | ||
| 297 | .rating = 100, | ||
| 298 | .read = bcmring_get_cycles_timer3, | ||
| 299 | .mask = CLOCKSOURCE_MASK(32), | ||
| 300 | .shift = 20, | ||
| 301 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
| 302 | }; | ||
| 303 | |||
| 304 | static int __init bcmring_clocksource_init(void) | ||
| 305 | { | ||
| 306 | /* setup timer1 as free-running clocksource */ | ||
| 307 | writel(0, TIMER1_VA_BASE + TIMER_CTRL); | ||
| 308 | writel(0xffffffff, TIMER1_VA_BASE + TIMER_LOAD); | ||
| 309 | writel(0xffffffff, TIMER1_VA_BASE + TIMER_VALUE); | ||
| 310 | writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, | ||
| 311 | TIMER1_VA_BASE + TIMER_CTRL); | ||
| 312 | |||
| 313 | clocksource_bcmring_timer1.mult = | ||
| 314 | clocksource_khz2mult(TIMER1_FREQUENCY_MHZ * 1000, | ||
| 315 | clocksource_bcmring_timer1.shift); | ||
| 316 | clocksource_register(&clocksource_bcmring_timer1); | ||
| 317 | |||
| 318 | /* setup timer3 as free-running clocksource */ | ||
| 319 | writel(0, TIMER3_VA_BASE + TIMER_CTRL); | ||
| 320 | writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD); | ||
| 321 | writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE); | ||
| 322 | writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, | ||
| 323 | TIMER3_VA_BASE + TIMER_CTRL); | ||
| 324 | |||
| 325 | clocksource_bcmring_timer3.mult = | ||
| 326 | clocksource_khz2mult(TIMER3_FREQUENCY_KHZ, | ||
| 327 | clocksource_bcmring_timer3.shift); | ||
| 328 | clocksource_register(&clocksource_bcmring_timer3); | ||
| 329 | |||
| 330 | return 0; | ||
| 331 | } | ||
| 332 | |||
| 333 | /* | ||
| 334 | * Set up timer interrupt, and return the current time in seconds. | ||
| 335 | */ | ||
| 336 | void __init bcmring_init_timer(void) | ||
| 337 | { | ||
| 338 | printk(KERN_INFO "bcmring_init_timer\n"); | ||
| 339 | /* | ||
| 340 | * Initialise to a known state (all timers off) | ||
| 341 | */ | ||
| 342 | writel(0, TIMER0_VA_BASE + TIMER_CTRL); | ||
| 343 | writel(0, TIMER1_VA_BASE + TIMER_CTRL); | ||
| 344 | writel(0, TIMER2_VA_BASE + TIMER_CTRL); | ||
| 345 | writel(0, TIMER3_VA_BASE + TIMER_CTRL); | ||
| 346 | |||
| 347 | /* | ||
| 348 | * Make irqs happen for the system timer | ||
| 349 | */ | ||
| 350 | setup_irq(IRQ_TIMER0, &bcmring_timer_irq); | ||
| 351 | |||
| 352 | bcmring_clocksource_init(); | ||
| 353 | |||
| 354 | timer0_clockevent.mult = | ||
| 355 | div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift); | ||
| 356 | timer0_clockevent.max_delta_ns = | ||
| 357 | clockevent_delta2ns(0xffffffff, &timer0_clockevent); | ||
| 358 | timer0_clockevent.min_delta_ns = | ||
| 359 | clockevent_delta2ns(0xf, &timer0_clockevent); | ||
| 360 | |||
| 361 | timer0_clockevent.cpumask = cpumask_of(0); | ||
| 362 | clockevents_register_device(&timer0_clockevent); | ||
| 363 | } | ||
| 364 | |||
| 365 | struct sys_timer bcmring_timer = { | ||
| 366 | .init = bcmring_init_timer, | ||
| 367 | }; | ||
diff --git a/arch/arm/mach-bcmring/core.h b/arch/arm/mach-bcmring/core.h new file mode 100644 index 000000000000..b197ba48e36e --- /dev/null +++ b/arch/arm/mach-bcmring/core.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-versatile/core.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 2004 ARM Limited | ||
| 5 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | ||
| 21 | /* Portions copyright Broadcom 2008 */ | ||
| 22 | #ifndef __ASM_ARCH_BCMRING_H | ||
| 23 | #define __ASM_ARCH_BCMRING_H | ||
| 24 | |||
| 25 | void __init bcmring_amba_init(void); | ||
| 26 | void __init bcmring_map_io(void); | ||
| 27 | void __init bcmring_init_irq(void); | ||
| 28 | |||
| 29 | extern struct sys_timer bcmring_timer; | ||
| 30 | #endif | ||
diff --git a/arch/arm/mach-bcmring/csp/Makefile b/arch/arm/mach-bcmring/csp/Makefile new file mode 100644 index 000000000000..648c0377530e --- /dev/null +++ b/arch/arm/mach-bcmring/csp/Makefile | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | obj-y += dmac/ | ||
| 2 | obj-y += tmr/ | ||
| 3 | obj-y += chipc/ | ||
diff --git a/arch/arm/mach-bcmring/csp/chipc/Makefile b/arch/arm/mach-bcmring/csp/chipc/Makefile new file mode 100644 index 000000000000..673952768ee5 --- /dev/null +++ b/arch/arm/mach-bcmring/csp/chipc/Makefile | |||
| @@ -0,0 +1 @@ | |||
| obj-y += chipcHw.o chipcHw_str.o chipcHw_reset.o chipcHw_init.o | |||
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw.c new file mode 100644 index 000000000000..b3a61d860c65 --- /dev/null +++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw.c | |||
| @@ -0,0 +1,776 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file chipcHw.c | ||
| 18 | * | ||
| 19 | * @brief Low level Various CHIP clock controlling routines | ||
| 20 | * | ||
| 21 | * @note | ||
| 22 | * | ||
| 23 | * These routines provide basic clock controlling functionality only. | ||
| 24 | */ | ||
| 25 | /****************************************************************************/ | ||
| 26 | |||
| 27 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 28 | |||
| 29 | #include <csp/errno.h> | ||
| 30 | #include <csp/stdint.h> | ||
| 31 | #include <csp/module.h> | ||
| 32 | |||
| 33 | #include <mach/csp/chipcHw_def.h> | ||
| 34 | #include <mach/csp/chipcHw_inline.h> | ||
| 35 | |||
| 36 | #include <csp/reg.h> | ||
| 37 | #include <csp/delay.h> | ||
| 38 | |||
| 39 | /* ---- Private Constants and Types --------------------------------------- */ | ||
| 40 | |||
| 41 | /* VPM alignment algorithm uses this */ | ||
| 42 | #define MAX_PHASE_ADJUST_COUNT 0xFFFF /* Max number of times allowed to adjust the phase */ | ||
| 43 | #define MAX_PHASE_ALIGN_ATTEMPTS 10 /* Max number of attempt to align the phase */ | ||
| 44 | |||
| 45 | /* Local definition of clock type */ | ||
| 46 | #define PLL_CLOCK 1 /* PLL Clock */ | ||
| 47 | #define NON_PLL_CLOCK 2 /* Divider clock */ | ||
| 48 | |||
| 49 | static int chipcHw_divide(int num, int denom) | ||
| 50 | __attribute__ ((section(".aramtext"))); | ||
| 51 | |||
| 52 | /****************************************************************************/ | ||
| 53 | /** | ||
| 54 | * @brief Set clock fequency for miscellaneous configurable clocks | ||
| 55 | * | ||
| 56 | * This function sets clock frequency | ||
| 57 | * | ||
| 58 | * @return Configured clock frequency in hertz | ||
| 59 | * | ||
| 60 | */ | ||
| 61 | /****************************************************************************/ | ||
| 62 | chipcHw_freq chipcHw_getClockFrequency(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */ | ||
| 63 | ) { | ||
| 64 | volatile uint32_t *pPLLReg = (uint32_t *) 0x0; | ||
| 65 | volatile uint32_t *pClockCtrl = (uint32_t *) 0x0; | ||
| 66 | volatile uint32_t *pDependentClock = (uint32_t *) 0x0; | ||
| 67 | uint32_t vcoFreqPll1Hz = 0; /* Effective VCO frequency for PLL1 in Hz */ | ||
| 68 | uint32_t vcoFreqPll2Hz = 0; /* Effective VCO frequency for PLL2 in Hz */ | ||
| 69 | uint32_t dependentClockType = 0; | ||
| 70 | uint32_t vcoHz = 0; | ||
| 71 | |||
| 72 | /* Get VCO frequencies */ | ||
| 73 | if ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) != chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) { | ||
| 74 | uint64_t adjustFreq = 0; | ||
| 75 | |||
| 76 | vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz * | ||
| 77 | chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) * | ||
| 78 | ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >> | ||
| 79 | chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT); | ||
| 80 | |||
| 81 | /* Adjusted frequency due to chipcHw_REG_PLL_DIVIDER_NDIV_f_SS */ | ||
| 82 | adjustFreq = (uint64_t) chipcHw_XTAL_FREQ_Hz * | ||
| 83 | (uint64_t) chipcHw_REG_PLL_DIVIDER_NDIV_f_SS * | ||
| 84 | chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, (chipcHw_REG_PLL_PREDIVIDER_P2 * (uint64_t) chipcHw_REG_PLL_DIVIDER_FRAC)); | ||
| 85 | vcoFreqPll1Hz += (uint32_t) adjustFreq; | ||
| 86 | } else { | ||
| 87 | vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz * | ||
| 88 | chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) * | ||
| 89 | ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >> | ||
| 90 | chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT); | ||
| 91 | } | ||
| 92 | vcoFreqPll2Hz = | ||
| 93 | chipcHw_XTAL_FREQ_Hz * | ||
| 94 | chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) * | ||
| 95 | ((pChipcHw->PLLPreDivider2 & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >> | ||
| 96 | chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT); | ||
| 97 | |||
| 98 | switch (clock) { | ||
| 99 | case chipcHw_CLOCK_DDR: | ||
| 100 | pPLLReg = &pChipcHw->DDRClock; | ||
| 101 | vcoHz = vcoFreqPll1Hz; | ||
| 102 | break; | ||
| 103 | case chipcHw_CLOCK_ARM: | ||
| 104 | pPLLReg = &pChipcHw->ARMClock; | ||
| 105 | vcoHz = vcoFreqPll1Hz; | ||
| 106 | break; | ||
| 107 | case chipcHw_CLOCK_ESW: | ||
| 108 | pPLLReg = &pChipcHw->ESWClock; | ||
| 109 | vcoHz = vcoFreqPll1Hz; | ||
| 110 | break; | ||
| 111 | case chipcHw_CLOCK_VPM: | ||
| 112 | pPLLReg = &pChipcHw->VPMClock; | ||
| 113 | vcoHz = vcoFreqPll1Hz; | ||
| 114 | break; | ||
| 115 | case chipcHw_CLOCK_ESW125: | ||
| 116 | pPLLReg = &pChipcHw->ESW125Clock; | ||
| 117 | vcoHz = vcoFreqPll1Hz; | ||
| 118 | break; | ||
| 119 | case chipcHw_CLOCK_UART: | ||
| 120 | pPLLReg = &pChipcHw->UARTClock; | ||
| 121 | vcoHz = vcoFreqPll1Hz; | ||
| 122 | break; | ||
| 123 | case chipcHw_CLOCK_SDIO0: | ||
| 124 | pPLLReg = &pChipcHw->SDIO0Clock; | ||
| 125 | vcoHz = vcoFreqPll1Hz; | ||
| 126 | break; | ||
| 127 | case chipcHw_CLOCK_SDIO1: | ||
| 128 | pPLLReg = &pChipcHw->SDIO1Clock; | ||
| 129 | vcoHz = vcoFreqPll1Hz; | ||
| 130 | break; | ||
| 131 | case chipcHw_CLOCK_SPI: | ||
| 132 | pPLLReg = &pChipcHw->SPIClock; | ||
| 133 | vcoHz = vcoFreqPll1Hz; | ||
| 134 | break; | ||
| 135 | case chipcHw_CLOCK_ETM: | ||
| 136 | pPLLReg = &pChipcHw->ETMClock; | ||
| 137 | vcoHz = vcoFreqPll1Hz; | ||
| 138 | break; | ||
| 139 | case chipcHw_CLOCK_USB: | ||
| 140 | pPLLReg = &pChipcHw->USBClock; | ||
| 141 | vcoHz = vcoFreqPll2Hz; | ||
| 142 | break; | ||
| 143 | case chipcHw_CLOCK_LCD: | ||
| 144 | pPLLReg = &pChipcHw->LCDClock; | ||
| 145 | vcoHz = vcoFreqPll2Hz; | ||
| 146 | break; | ||
| 147 | case chipcHw_CLOCK_APM: | ||
| 148 | pPLLReg = &pChipcHw->APMClock; | ||
| 149 | vcoHz = vcoFreqPll2Hz; | ||
| 150 | break; | ||
| 151 | case chipcHw_CLOCK_BUS: | ||
| 152 | pClockCtrl = &pChipcHw->ACLKClock; | ||
| 153 | pDependentClock = &pChipcHw->ARMClock; | ||
| 154 | vcoHz = vcoFreqPll1Hz; | ||
| 155 | dependentClockType = PLL_CLOCK; | ||
| 156 | break; | ||
| 157 | case chipcHw_CLOCK_OTP: | ||
| 158 | pClockCtrl = &pChipcHw->OTPClock; | ||
| 159 | break; | ||
| 160 | case chipcHw_CLOCK_I2C: | ||
| 161 | pClockCtrl = &pChipcHw->I2CClock; | ||
| 162 | break; | ||
| 163 | case chipcHw_CLOCK_I2S0: | ||
| 164 | pClockCtrl = &pChipcHw->I2S0Clock; | ||
| 165 | break; | ||
| 166 | case chipcHw_CLOCK_RTBUS: | ||
| 167 | pClockCtrl = &pChipcHw->RTBUSClock; | ||
| 168 | pDependentClock = &pChipcHw->ACLKClock; | ||
| 169 | dependentClockType = NON_PLL_CLOCK; | ||
| 170 | break; | ||
| 171 | case chipcHw_CLOCK_APM100: | ||
| 172 | pClockCtrl = &pChipcHw->APM100Clock; | ||
| 173 | pDependentClock = &pChipcHw->APMClock; | ||
| 174 | vcoHz = vcoFreqPll2Hz; | ||
| 175 | dependentClockType = PLL_CLOCK; | ||
| 176 | break; | ||
| 177 | case chipcHw_CLOCK_TSC: | ||
| 178 | pClockCtrl = &pChipcHw->TSCClock; | ||
| 179 | break; | ||
| 180 | case chipcHw_CLOCK_LED: | ||
| 181 | pClockCtrl = &pChipcHw->LEDClock; | ||
| 182 | break; | ||
| 183 | case chipcHw_CLOCK_I2S1: | ||
| 184 | pClockCtrl = &pChipcHw->I2S1Clock; | ||
| 185 | break; | ||
| 186 | } | ||
| 187 | |||
| 188 | if (pPLLReg) { | ||
| 189 | /* Obtain PLL clock frequency */ | ||
| 190 | if (*pPLLReg & chipcHw_REG_PLL_CLOCK_BYPASS_SELECT) { | ||
| 191 | /* Return crystal clock frequency when bypassed */ | ||
| 192 | return chipcHw_XTAL_FREQ_Hz; | ||
| 193 | } else if (clock == chipcHw_CLOCK_DDR) { | ||
| 194 | /* DDR frequency is configured in PLLDivider register */ | ||
| 195 | return chipcHw_divide (vcoHz, (((pChipcHw->PLLDivider & 0xFF000000) >> 24) ? ((pChipcHw->PLLDivider & 0xFF000000) >> 24) : 256)); | ||
| 196 | } else { | ||
| 197 | /* From chip revision number B0, LCD clock is internally divided by 2 */ | ||
| 198 | if ((pPLLReg == &pChipcHw->LCDClock) && (chipcHw_getChipRevisionNumber() != chipcHw_REV_NUMBER_A0)) { | ||
| 199 | vcoHz >>= 1; | ||
| 200 | } | ||
| 201 | /* Obtain PLL clock frequency using VCO dividers */ | ||
| 202 | return chipcHw_divide(vcoHz, ((*pPLLReg & chipcHw_REG_PLL_CLOCK_MDIV_MASK) ? (*pPLLReg & chipcHw_REG_PLL_CLOCK_MDIV_MASK) : 256)); | ||
| 203 | } | ||
| 204 | } else if (pClockCtrl) { | ||
| 205 | /* Obtain divider clock frequency */ | ||
| 206 | uint32_t div; | ||
| 207 | uint32_t freq = 0; | ||
| 208 | |||
| 209 | if (*pClockCtrl & chipcHw_REG_DIV_CLOCK_BYPASS_SELECT) { | ||
| 210 | /* Return crystal clock frequency when bypassed */ | ||
| 211 | return chipcHw_XTAL_FREQ_Hz; | ||
| 212 | } else if (pDependentClock) { | ||
| 213 | /* Identify the dependent clock frequency */ | ||
| 214 | switch (dependentClockType) { | ||
| 215 | case PLL_CLOCK: | ||
| 216 | if (*pDependentClock & chipcHw_REG_PLL_CLOCK_BYPASS_SELECT) { | ||
| 217 | /* Use crystal clock frequency when dependent PLL clock is bypassed */ | ||
| 218 | freq = chipcHw_XTAL_FREQ_Hz; | ||
| 219 | } else { | ||
| 220 | /* Obtain PLL clock frequency using VCO dividers */ | ||
| 221 | div = *pDependentClock & chipcHw_REG_PLL_CLOCK_MDIV_MASK; | ||
| 222 | freq = div ? chipcHw_divide(vcoHz, div) : 0; | ||
| 223 | } | ||
| 224 | break; | ||
| 225 | case NON_PLL_CLOCK: | ||
| 226 | if (pDependentClock == (uint32_t *) &pChipcHw->ACLKClock) { | ||
| 227 | freq = chipcHw_getClockFrequency (chipcHw_CLOCK_BUS); | ||
| 228 | } else { | ||
| 229 | if (*pDependentClock & chipcHw_REG_DIV_CLOCK_BYPASS_SELECT) { | ||
| 230 | /* Use crystal clock frequency when dependent divider clock is bypassed */ | ||
| 231 | freq = chipcHw_XTAL_FREQ_Hz; | ||
| 232 | } else { | ||
| 233 | /* Obtain divider clock frequency using XTAL dividers */ | ||
| 234 | div = *pDependentClock & chipcHw_REG_DIV_CLOCK_DIV_MASK; | ||
| 235 | freq = chipcHw_divide (chipcHw_XTAL_FREQ_Hz, (div ? div : 256)); | ||
| 236 | } | ||
| 237 | } | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | } else { | ||
| 241 | /* Dependent on crystal clock */ | ||
| 242 | freq = chipcHw_XTAL_FREQ_Hz; | ||
| 243 | } | ||
| 244 | |||
| 245 | div = *pClockCtrl & chipcHw_REG_DIV_CLOCK_DIV_MASK; | ||
| 246 | return chipcHw_divide(freq, (div ? div : 256)); | ||
| 247 | } | ||
| 248 | return 0; | ||
| 249 | } | ||
| 250 | |||
| 251 | /****************************************************************************/ | ||
| 252 | /** | ||
| 253 | * @brief Set clock fequency for miscellaneous configurable clocks | ||
| 254 | * | ||
| 255 | * This function sets clock frequency | ||
| 256 | * | ||
| 257 | * @return Configured clock frequency in Hz | ||
| 258 | * | ||
| 259 | */ | ||
| 260 | /****************************************************************************/ | ||
| 261 | chipcHw_freq chipcHw_setClockFrequency(chipcHw_CLOCK_e clock, /* [ IN ] Configurable clock */ | ||
| 262 | uint32_t freq /* [ IN ] Clock frequency in Hz */ | ||
| 263 | ) { | ||
| 264 | volatile uint32_t *pPLLReg = (uint32_t *) 0x0; | ||
| 265 | volatile uint32_t *pClockCtrl = (uint32_t *) 0x0; | ||
| 266 | volatile uint32_t *pDependentClock = (uint32_t *) 0x0; | ||
| 267 | uint32_t vcoFreqPll1Hz = 0; /* Effective VCO frequency for PLL1 in Hz */ | ||
| 268 | uint32_t desVcoFreqPll1Hz = 0; /* Desired VCO frequency for PLL1 in Hz */ | ||
| 269 | uint32_t vcoFreqPll2Hz = 0; /* Effective VCO frequency for PLL2 in Hz */ | ||
| 270 | uint32_t dependentClockType = 0; | ||
| 271 | uint32_t vcoHz = 0; | ||
| 272 | uint32_t desVcoHz = 0; | ||
| 273 | |||
| 274 | /* Get VCO frequencies */ | ||
| 275 | if ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) != chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) { | ||
| 276 | uint64_t adjustFreq = 0; | ||
| 277 | |||
| 278 | vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz * | ||
| 279 | chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) * | ||
| 280 | ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >> | ||
| 281 | chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT); | ||
| 282 | |||
| 283 | /* Adjusted frequency due to chipcHw_REG_PLL_DIVIDER_NDIV_f_SS */ | ||
| 284 | adjustFreq = (uint64_t) chipcHw_XTAL_FREQ_Hz * | ||
| 285 | (uint64_t) chipcHw_REG_PLL_DIVIDER_NDIV_f_SS * | ||
| 286 | chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, (chipcHw_REG_PLL_PREDIVIDER_P2 * (uint64_t) chipcHw_REG_PLL_DIVIDER_FRAC)); | ||
| 287 | vcoFreqPll1Hz += (uint32_t) adjustFreq; | ||
| 288 | |||
| 289 | /* Desired VCO frequency */ | ||
| 290 | desVcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz * | ||
| 291 | chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) * | ||
| 292 | (((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >> | ||
| 293 | chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) + 1); | ||
| 294 | } else { | ||
| 295 | vcoFreqPll1Hz = desVcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz * | ||
| 296 | chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) * | ||
| 297 | ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >> | ||
| 298 | chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT); | ||
| 299 | } | ||
| 300 | vcoFreqPll2Hz = chipcHw_XTAL_FREQ_Hz * chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) * | ||
| 301 | ((pChipcHw->PLLPreDivider2 & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >> | ||
| 302 | chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT); | ||
| 303 | |||
| 304 | switch (clock) { | ||
| 305 | case chipcHw_CLOCK_DDR: | ||
| 306 | /* Configure the DDR_ctrl:BUS ratio settings */ | ||
| 307 | { | ||
| 308 | REG_LOCAL_IRQ_SAVE; | ||
| 309 | /* Dvide DDR_phy by two to obtain DDR_ctrl clock */ | ||
| 310 | pChipcHw->DDRClock = (pChipcHw->DDRClock & ~chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK) | ((((freq / 2) / chipcHw_getClockFrequency(chipcHw_CLOCK_BUS)) - 1) | ||
| 311 | << chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT); | ||
| 312 | REG_LOCAL_IRQ_RESTORE; | ||
| 313 | } | ||
| 314 | pPLLReg = &pChipcHw->DDRClock; | ||
| 315 | vcoHz = vcoFreqPll1Hz; | ||
| 316 | desVcoHz = desVcoFreqPll1Hz; | ||
| 317 | break; | ||
| 318 | case chipcHw_CLOCK_ARM: | ||
| 319 | pPLLReg = &pChipcHw->ARMClock; | ||
| 320 | vcoHz = vcoFreqPll1Hz; | ||
| 321 | desVcoHz = desVcoFreqPll1Hz; | ||
| 322 | break; | ||
| 323 | case chipcHw_CLOCK_ESW: | ||
| 324 | pPLLReg = &pChipcHw->ESWClock; | ||
| 325 | vcoHz = vcoFreqPll1Hz; | ||
| 326 | desVcoHz = desVcoFreqPll1Hz; | ||
| 327 | break; | ||
| 328 | case chipcHw_CLOCK_VPM: | ||
| 329 | /* Configure the VPM:BUS ratio settings */ | ||
| 330 | { | ||
| 331 | REG_LOCAL_IRQ_SAVE; | ||
| 332 | pChipcHw->VPMClock = (pChipcHw->VPMClock & ~chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK) | ((chipcHw_divide (freq, chipcHw_getClockFrequency(chipcHw_CLOCK_BUS)) - 1) | ||
| 333 | << chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT); | ||
| 334 | REG_LOCAL_IRQ_RESTORE; | ||
| 335 | } | ||
| 336 | pPLLReg = &pChipcHw->VPMClock; | ||
| 337 | vcoHz = vcoFreqPll1Hz; | ||
| 338 | desVcoHz = desVcoFreqPll1Hz; | ||
| 339 | break; | ||
| 340 | case chipcHw_CLOCK_ESW125: | ||
| 341 | pPLLReg = &pChipcHw->ESW125Clock; | ||
| 342 | vcoHz = vcoFreqPll1Hz; | ||
| 343 | desVcoHz = desVcoFreqPll1Hz; | ||
| 344 | break; | ||
| 345 | case chipcHw_CLOCK_UART: | ||
| 346 | pPLLReg = &pChipcHw->UARTClock; | ||
| 347 | vcoHz = vcoFreqPll1Hz; | ||
| 348 | desVcoHz = desVcoFreqPll1Hz; | ||
| 349 | break; | ||
| 350 | case chipcHw_CLOCK_SDIO0: | ||
| 351 | pPLLReg = &pChipcHw->SDIO0Clock; | ||
| 352 | vcoHz = vcoFreqPll1Hz; | ||
| 353 | desVcoHz = desVcoFreqPll1Hz; | ||
| 354 | break; | ||
| 355 | case chipcHw_CLOCK_SDIO1: | ||
| 356 | pPLLReg = &pChipcHw->SDIO1Clock; | ||
| 357 | vcoHz = vcoFreqPll1Hz; | ||
| 358 | desVcoHz = desVcoFreqPll1Hz; | ||
| 359 | break; | ||
| 360 | case chipcHw_CLOCK_SPI: | ||
| 361 | pPLLReg = &pChipcHw->SPIClock; | ||
| 362 | vcoHz = vcoFreqPll1Hz; | ||
| 363 | desVcoHz = desVcoFreqPll1Hz; | ||
| 364 | break; | ||
| 365 | case chipcHw_CLOCK_ETM: | ||
| 366 | pPLLReg = &pChipcHw->ETMClock; | ||
| 367 | vcoHz = vcoFreqPll1Hz; | ||
| 368 | desVcoHz = desVcoFreqPll1Hz; | ||
| 369 | break; | ||
| 370 | case chipcHw_CLOCK_USB: | ||
| 371 | pPLLReg = &pChipcHw->USBClock; | ||
| 372 | vcoHz = vcoFreqPll2Hz; | ||
| 373 | desVcoHz = vcoFreqPll2Hz; | ||
| 374 | break; | ||
| 375 | case chipcHw_CLOCK_LCD: | ||
| 376 | pPLLReg = &pChipcHw->LCDClock; | ||
| 377 | vcoHz = vcoFreqPll2Hz; | ||
| 378 | desVcoHz = vcoFreqPll2Hz; | ||
| 379 | break; | ||
| 380 | case chipcHw_CLOCK_APM: | ||
| 381 | pPLLReg = &pChipcHw->APMClock; | ||
| 382 | vcoHz = vcoFreqPll2Hz; | ||
| 383 | desVcoHz = vcoFreqPll2Hz; | ||
| 384 | break; | ||
| 385 | case chipcHw_CLOCK_BUS: | ||
| 386 | pClockCtrl = &pChipcHw->ACLKClock; | ||
| 387 | pDependentClock = &pChipcHw->ARMClock; | ||
| 388 | vcoHz = vcoFreqPll1Hz; | ||
| 389 | desVcoHz = desVcoFreqPll1Hz; | ||
| 390 | dependentClockType = PLL_CLOCK; | ||
| 391 | break; | ||
| 392 | case chipcHw_CLOCK_OTP: | ||
| 393 | pClockCtrl = &pChipcHw->OTPClock; | ||
| 394 | break; | ||
| 395 | case chipcHw_CLOCK_I2C: | ||
| 396 | pClockCtrl = &pChipcHw->I2CClock; | ||
| 397 | break; | ||
| 398 | case chipcHw_CLOCK_I2S0: | ||
| 399 | pClockCtrl = &pChipcHw->I2S0Clock; | ||
| 400 | break; | ||
| 401 | case chipcHw_CLOCK_RTBUS: | ||
| 402 | pClockCtrl = &pChipcHw->RTBUSClock; | ||
| 403 | pDependentClock = &pChipcHw->ACLKClock; | ||
| 404 | dependentClockType = NON_PLL_CLOCK; | ||
| 405 | break; | ||
| 406 | case chipcHw_CLOCK_APM100: | ||
| 407 | pClockCtrl = &pChipcHw->APM100Clock; | ||
| 408 | pDependentClock = &pChipcHw->APMClock; | ||
| 409 | vcoHz = vcoFreqPll2Hz; | ||
| 410 | desVcoHz = vcoFreqPll2Hz; | ||
| 411 | dependentClockType = PLL_CLOCK; | ||
| 412 | break; | ||
| 413 | case chipcHw_CLOCK_TSC: | ||
| 414 | pClockCtrl = &pChipcHw->TSCClock; | ||
| 415 | break; | ||
| 416 | case chipcHw_CLOCK_LED: | ||
| 417 | pClockCtrl = &pChipcHw->LEDClock; | ||
| 418 | break; | ||
| 419 | case chipcHw_CLOCK_I2S1: | ||
| 420 | pClockCtrl = &pChipcHw->I2S1Clock; | ||
| 421 | break; | ||
| 422 | } | ||
| 423 | |||
| 424 | if (pPLLReg) { | ||
| 425 | /* Select XTAL as bypass source */ | ||
| 426 | reg32_modify_and(pPLLReg, ~chipcHw_REG_PLL_CLOCK_SOURCE_GPIO); | ||
| 427 | reg32_modify_or(pPLLReg, chipcHw_REG_PLL_CLOCK_BYPASS_SELECT); | ||
| 428 | /* For DDR settings use only the PLL divider clock */ | ||
| 429 | if (pPLLReg == &pChipcHw->DDRClock) { | ||
| 430 | /* Set M1DIV for PLL1, which controls the DDR clock */ | ||
| 431 | reg32_write(&pChipcHw->PLLDivider, (pChipcHw->PLLDivider & 0x00FFFFFF) | ((chipcHw_REG_PLL_DIVIDER_MDIV (desVcoHz, freq)) << 24)); | ||
| 432 | /* Calculate expected frequency */ | ||
| 433 | freq = chipcHw_divide(vcoHz, (((pChipcHw->PLLDivider & 0xFF000000) >> 24) ? ((pChipcHw->PLLDivider & 0xFF000000) >> 24) : 256)); | ||
| 434 | } else { | ||
| 435 | /* From chip revision number B0, LCD clock is internally divided by 2 */ | ||
| 436 | if ((pPLLReg == &pChipcHw->LCDClock) && (chipcHw_getChipRevisionNumber() != chipcHw_REV_NUMBER_A0)) { | ||
| 437 | desVcoHz >>= 1; | ||
| 438 | vcoHz >>= 1; | ||
| 439 | } | ||
| 440 | /* Set MDIV to change the frequency */ | ||
| 441 | reg32_modify_and(pPLLReg, ~(chipcHw_REG_PLL_CLOCK_MDIV_MASK)); | ||
| 442 | reg32_modify_or(pPLLReg, chipcHw_REG_PLL_DIVIDER_MDIV(desVcoHz, freq)); | ||
| 443 | /* Calculate expected frequency */ | ||
| 444 | freq = chipcHw_divide(vcoHz, ((*(pPLLReg) & chipcHw_REG_PLL_CLOCK_MDIV_MASK) ? (*(pPLLReg) & chipcHw_REG_PLL_CLOCK_MDIV_MASK) : 256)); | ||
| 445 | } | ||
| 446 | /* Wait for for atleast 200ns as per the protocol to change frequency */ | ||
| 447 | udelay(1); | ||
| 448 | /* Do not bypass */ | ||
| 449 | reg32_modify_and(pPLLReg, ~chipcHw_REG_PLL_CLOCK_BYPASS_SELECT); | ||
| 450 | /* Return the configured frequency */ | ||
| 451 | return freq; | ||
| 452 | } else if (pClockCtrl) { | ||
| 453 | uint32_t divider = 0; | ||
| 454 | |||
| 455 | /* Divider clock should not be bypassed */ | ||
| 456 | reg32_modify_and(pClockCtrl, | ||
| 457 | ~chipcHw_REG_DIV_CLOCK_BYPASS_SELECT); | ||
| 458 | |||
| 459 | /* Identify the clock source */ | ||
| 460 | if (pDependentClock) { | ||
| 461 | switch (dependentClockType) { | ||
| 462 | case PLL_CLOCK: | ||
| 463 | divider = chipcHw_divide(chipcHw_divide (desVcoHz, (*pDependentClock & chipcHw_REG_PLL_CLOCK_MDIV_MASK)), freq); | ||
| 464 | break; | ||
| 465 | case NON_PLL_CLOCK: | ||
| 466 | { | ||
| 467 | uint32_t sourceClock = 0; | ||
| 468 | |||
| 469 | if (pDependentClock == (uint32_t *) &pChipcHw->ACLKClock) { | ||
| 470 | sourceClock = chipcHw_getClockFrequency (chipcHw_CLOCK_BUS); | ||
| 471 | } else { | ||
| 472 | uint32_t div = *pDependentClock & chipcHw_REG_DIV_CLOCK_DIV_MASK; | ||
| 473 | sourceClock = chipcHw_divide (chipcHw_XTAL_FREQ_Hz, ((div) ? div : 256)); | ||
| 474 | } | ||
| 475 | divider = chipcHw_divide(sourceClock, freq); | ||
| 476 | } | ||
| 477 | break; | ||
| 478 | } | ||
| 479 | } else { | ||
| 480 | divider = chipcHw_divide(chipcHw_XTAL_FREQ_Hz, freq); | ||
| 481 | } | ||
| 482 | |||
| 483 | if (divider) { | ||
| 484 | REG_LOCAL_IRQ_SAVE; | ||
| 485 | /* Set the divider to obtain the required frequency */ | ||
| 486 | *pClockCtrl = (*pClockCtrl & (~chipcHw_REG_DIV_CLOCK_DIV_MASK)) | (((divider > 256) ? chipcHw_REG_DIV_CLOCK_DIV_256 : divider) & chipcHw_REG_DIV_CLOCK_DIV_MASK); | ||
| 487 | REG_LOCAL_IRQ_RESTORE; | ||
| 488 | return freq; | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 492 | return 0; | ||
| 493 | } | ||
| 494 | |||
| 495 | EXPORT_SYMBOL(chipcHw_setClockFrequency); | ||
| 496 | |||
| 497 | /****************************************************************************/ | ||
| 498 | /** | ||
| 499 | * @brief Set VPM clock in sync with BUS clock for Chip Rev #A0 | ||
| 500 | * | ||
| 501 | * This function does the phase adjustment between VPM and BUS clock | ||
| 502 | * | ||
| 503 | * @return >= 0 : On success (# of adjustment required) | ||
| 504 | * -1 : On failure | ||
| 505 | * | ||
| 506 | */ | ||
| 507 | /****************************************************************************/ | ||
| 508 | static int vpmPhaseAlignA0(void) | ||
| 509 | { | ||
| 510 | uint32_t phaseControl; | ||
| 511 | uint32_t phaseValue; | ||
| 512 | uint32_t prevPhaseComp; | ||
| 513 | int iter = 0; | ||
| 514 | int adjustCount = 0; | ||
| 515 | int count = 0; | ||
| 516 | |||
| 517 | for (iter = 0; (iter < MAX_PHASE_ALIGN_ATTEMPTS) && (adjustCount < MAX_PHASE_ADJUST_COUNT); iter++) { | ||
| 518 | phaseControl = (pChipcHw->VPMClock & chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK) >> chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT; | ||
| 519 | phaseValue = 0; | ||
| 520 | prevPhaseComp = 0; | ||
| 521 | |||
| 522 | /* Step 1: Look for falling PH_COMP transition */ | ||
| 523 | |||
| 524 | /* Read the contents of VPM Clock resgister */ | ||
| 525 | phaseValue = pChipcHw->VPMClock; | ||
| 526 | do { | ||
| 527 | /* Store previous value of phase comparator */ | ||
| 528 | prevPhaseComp = phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP; | ||
| 529 | /* Change the value of PH_CTRL. */ | ||
| 530 | reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT)); | ||
| 531 | /* Wait atleast 20 ns */ | ||
| 532 | udelay(1); | ||
| 533 | /* Toggle the LOAD_CH after phase control is written. */ | ||
| 534 | pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE; | ||
| 535 | /* Read the contents of VPM Clock resgister. */ | ||
| 536 | phaseValue = pChipcHw->VPMClock; | ||
| 537 | |||
| 538 | if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0x0) { | ||
| 539 | phaseControl = (0x3F & (phaseControl - 1)); | ||
| 540 | } else { | ||
| 541 | /* Increment to the Phase count value for next write, if Phase is not stable. */ | ||
| 542 | phaseControl = (0x3F & (phaseControl + 1)); | ||
| 543 | } | ||
| 544 | /* Count number of adjustment made */ | ||
| 545 | adjustCount++; | ||
| 546 | } while (((prevPhaseComp == (phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP)) || /* Look for a transition */ | ||
| 547 | ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) != 0x0)) && /* Look for a falling edge */ | ||
| 548 | (adjustCount < MAX_PHASE_ADJUST_COUNT) /* Do not exceed the limit while trying */ | ||
| 549 | ); | ||
| 550 | |||
| 551 | if (adjustCount >= MAX_PHASE_ADJUST_COUNT) { | ||
| 552 | /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */ | ||
| 553 | return -1; | ||
| 554 | } | ||
| 555 | |||
| 556 | /* Step 2: Keep moving forward to make sure falling PH_COMP transition was valid */ | ||
| 557 | |||
| 558 | for (count = 0; (count < 5) && ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0); count++) { | ||
| 559 | phaseControl = (0x3F & (phaseControl + 1)); | ||
| 560 | reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT)); | ||
| 561 | /* Wait atleast 20 ns */ | ||
| 562 | udelay(1); | ||
| 563 | /* Toggle the LOAD_CH after phase control is written. */ | ||
| 564 | pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE; | ||
| 565 | phaseValue = pChipcHw->VPMClock; | ||
| 566 | /* Count number of adjustment made */ | ||
| 567 | adjustCount++; | ||
| 568 | } | ||
| 569 | |||
| 570 | if (adjustCount >= MAX_PHASE_ADJUST_COUNT) { | ||
| 571 | /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */ | ||
| 572 | return -1; | ||
| 573 | } | ||
| 574 | |||
| 575 | if (count != 5) { | ||
| 576 | /* Detected false transition */ | ||
| 577 | continue; | ||
| 578 | } | ||
| 579 | |||
| 580 | /* Step 3: Keep moving backward to make sure falling PH_COMP transition was stable */ | ||
| 581 | |||
| 582 | for (count = 0; (count < 3) && ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0); count++) { | ||
| 583 | phaseControl = (0x3F & (phaseControl - 1)); | ||
| 584 | reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT)); | ||
| 585 | /* Wait atleast 20 ns */ | ||
| 586 | udelay(1); | ||
| 587 | /* Toggle the LOAD_CH after phase control is written. */ | ||
| 588 | pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE; | ||
| 589 | phaseValue = pChipcHw->VPMClock; | ||
| 590 | /* Count number of adjustment made */ | ||
| 591 | adjustCount++; | ||
| 592 | } | ||
| 593 | |||
| 594 | if (adjustCount >= MAX_PHASE_ADJUST_COUNT) { | ||
| 595 | /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */ | ||
| 596 | return -1; | ||
| 597 | } | ||
| 598 | |||
| 599 | if (count != 3) { | ||
| 600 | /* Detected noisy transition */ | ||
| 601 | continue; | ||
| 602 | } | ||
| 603 | |||
| 604 | /* Step 4: Keep moving backward before the original transition took place. */ | ||
| 605 | |||
| 606 | for (count = 0; (count < 5); count++) { | ||
| 607 | phaseControl = (0x3F & (phaseControl - 1)); | ||
| 608 | reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT)); | ||
| 609 | /* Wait atleast 20 ns */ | ||
| 610 | udelay(1); | ||
| 611 | /* Toggle the LOAD_CH after phase control is written. */ | ||
| 612 | pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE; | ||
| 613 | phaseValue = pChipcHw->VPMClock; | ||
| 614 | /* Count number of adjustment made */ | ||
| 615 | adjustCount++; | ||
| 616 | } | ||
| 617 | |||
| 618 | if (adjustCount >= MAX_PHASE_ADJUST_COUNT) { | ||
| 619 | /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */ | ||
| 620 | return -1; | ||
| 621 | } | ||
| 622 | |||
| 623 | if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0) { | ||
| 624 | /* Detected false transition */ | ||
| 625 | continue; | ||
| 626 | } | ||
| 627 | |||
| 628 | /* Step 5: Re discover the valid transition */ | ||
| 629 | |||
| 630 | do { | ||
| 631 | /* Store previous value of phase comparator */ | ||
| 632 | prevPhaseComp = phaseValue; | ||
| 633 | /* Change the value of PH_CTRL. */ | ||
| 634 | reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT)); | ||
| 635 | /* Wait atleast 20 ns */ | ||
| 636 | udelay(1); | ||
| 637 | /* Toggle the LOAD_CH after phase control is written. */ | ||
| 638 | pChipcHw->VPMClock ^= | ||
| 639 | chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE; | ||
| 640 | /* Read the contents of VPM Clock resgister. */ | ||
| 641 | phaseValue = pChipcHw->VPMClock; | ||
| 642 | |||
| 643 | if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0x0) { | ||
| 644 | phaseControl = (0x3F & (phaseControl - 1)); | ||
| 645 | } else { | ||
| 646 | /* Increment to the Phase count value for next write, if Phase is not stable. */ | ||
| 647 | phaseControl = (0x3F & (phaseControl + 1)); | ||
| 648 | } | ||
| 649 | |||
| 650 | /* Count number of adjustment made */ | ||
| 651 | adjustCount++; | ||
| 652 | } while (((prevPhaseComp == (phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP)) || ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) != 0x0)) && (adjustCount < MAX_PHASE_ADJUST_COUNT)); | ||
| 653 | |||
| 654 | if (adjustCount >= MAX_PHASE_ADJUST_COUNT) { | ||
| 655 | /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */ | ||
| 656 | return -1; | ||
| 657 | } else { | ||
| 658 | /* Valid phase must have detected */ | ||
| 659 | break; | ||
| 660 | } | ||
| 661 | } | ||
| 662 | |||
| 663 | /* For VPM Phase should be perfectly aligned. */ | ||
| 664 | phaseControl = (((pChipcHw->VPMClock >> chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT) - 1) & 0x3F); | ||
| 665 | { | ||
| 666 | REG_LOCAL_IRQ_SAVE; | ||
| 667 | |||
| 668 | pChipcHw->VPMClock = (pChipcHw->VPMClock & ~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT); | ||
| 669 | /* Load new phase value */ | ||
| 670 | pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE; | ||
| 671 | |||
| 672 | REG_LOCAL_IRQ_RESTORE; | ||
| 673 | } | ||
| 674 | /* Return the status */ | ||
| 675 | return (int)adjustCount; | ||
| 676 | } | ||
| 677 | |||
| 678 | /****************************************************************************/ | ||
| 679 | /** | ||
| 680 | * @brief Set VPM clock in sync with BUS clock | ||
| 681 | * | ||
| 682 | * This function does the phase adjustment between VPM and BUS clock | ||
| 683 | * | ||
| 684 | * @return >= 0 : On success (# of adjustment required) | ||
| 685 | * -1 : On failure | ||
| 686 | * | ||
| 687 | */ | ||
| 688 | /****************************************************************************/ | ||
| 689 | int chipcHw_vpmPhaseAlign(void) | ||
| 690 | { | ||
| 691 | |||
| 692 | if (chipcHw_getChipRevisionNumber() == chipcHw_REV_NUMBER_A0) { | ||
| 693 | return vpmPhaseAlignA0(); | ||
| 694 | } else { | ||
| 695 | uint32_t phaseControl = chipcHw_getVpmPhaseControl(); | ||
| 696 | uint32_t phaseValue = 0; | ||
| 697 | int adjustCount = 0; | ||
| 698 | |||
| 699 | /* Disable VPM access */ | ||
| 700 | pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE; | ||
| 701 | /* Disable HW VPM phase alignment */ | ||
| 702 | chipcHw_vpmHwPhaseAlignDisable(); | ||
| 703 | /* Enable SW VPM phase alignment */ | ||
| 704 | chipcHw_vpmSwPhaseAlignEnable(); | ||
| 705 | /* Adjust VPM phase */ | ||
| 706 | while (adjustCount < MAX_PHASE_ADJUST_COUNT) { | ||
| 707 | phaseValue = chipcHw_getVpmHwPhaseAlignStatus(); | ||
| 708 | |||
| 709 | /* Adjust phase control value */ | ||
| 710 | if (phaseValue > 0xF) { | ||
| 711 | /* Increment phase control value */ | ||
| 712 | phaseControl++; | ||
| 713 | } else if (phaseValue < 0xF) { | ||
| 714 | /* Decrement phase control value */ | ||
| 715 | phaseControl--; | ||
| 716 | } else { | ||
| 717 | /* Enable VPM access */ | ||
| 718 | pChipcHw->Spare1 |= chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE; | ||
| 719 | /* Return adjust count */ | ||
| 720 | return adjustCount; | ||
| 721 | } | ||
| 722 | /* Change the value of PH_CTRL. */ | ||
| 723 | reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT)); | ||
| 724 | /* Wait atleast 20 ns */ | ||
| 725 | udelay(1); | ||
| 726 | /* Toggle the LOAD_CH after phase control is written. */ | ||
| 727 | pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE; | ||
| 728 | /* Count adjustment */ | ||
| 729 | adjustCount++; | ||
| 730 | } | ||
| 731 | } | ||
| 732 | |||
| 733 | /* Disable VPM access */ | ||
| 734 | pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE; | ||
| 735 | return -1; | ||
| 736 | } | ||
| 737 | |||
| 738 | /****************************************************************************/ | ||
| 739 | /** | ||
| 740 | * @brief Local Divide function | ||
| 741 | * | ||
| 742 | * This function does the divide | ||
| 743 | * | ||
| 744 | * @return divide value | ||
| 745 | * | ||
| 746 | */ | ||
| 747 | /****************************************************************************/ | ||
| 748 | static int chipcHw_divide(int num, int denom) | ||
| 749 | { | ||
| 750 | int r; | ||
| 751 | int t = 1; | ||
| 752 | |||
| 753 | /* Shift denom and t up to the largest value to optimize algorithm */ | ||
| 754 | /* t contains the units of each divide */ | ||
| 755 | while ((denom & 0x40000000) == 0) { /* fails if denom=0 */ | ||
| 756 | denom = denom << 1; | ||
| 757 | t = t << 1; | ||
| 758 | } | ||
| 759 | |||
| 760 | /* Intialize the result */ | ||
| 761 | r = 0; | ||
| 762 | |||
| 763 | do { | ||
| 764 | /* Determine if there exists a positive remainder */ | ||
| 765 | if ((num - denom) >= 0) { | ||
| 766 | /* Accumlate t to the result and calculate a new remainder */ | ||
| 767 | num = num - denom; | ||
| 768 | r = r + t; | ||
| 769 | } | ||
| 770 | /* Continue to shift denom and shift t down to 0 */ | ||
| 771 | denom = denom >> 1; | ||
| 772 | t = t >> 1; | ||
| 773 | } while (t != 0); | ||
| 774 | |||
| 775 | return r; | ||
| 776 | } | ||
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c new file mode 100644 index 000000000000..367df75d4bb3 --- /dev/null +++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c | |||
| @@ -0,0 +1,293 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file chipcHw_init.c | ||
| 18 | * | ||
| 19 | * @brief Low level CHIPC PLL configuration functions | ||
| 20 | * | ||
| 21 | * @note | ||
| 22 | * | ||
| 23 | * These routines provide basic PLL controlling functionality only. | ||
| 24 | */ | ||
| 25 | /****************************************************************************/ | ||
| 26 | |||
| 27 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 28 | |||
| 29 | #include <csp/errno.h> | ||
| 30 | #include <csp/stdint.h> | ||
| 31 | #include <csp/module.h> | ||
| 32 | |||
| 33 | #include <mach/csp/chipcHw_def.h> | ||
| 34 | #include <mach/csp/chipcHw_inline.h> | ||
| 35 | |||
| 36 | #include <csp/reg.h> | ||
| 37 | #include <csp/delay.h> | ||
| 38 | /* ---- Private Constants and Types --------------------------------------- */ | ||
| 39 | |||
| 40 | /* | ||
| 41 | Calculation for NDIV_i to obtain VCO frequency | ||
| 42 | ----------------------------------------------- | ||
| 43 | |||
| 44 | Freq_vco = Freq_ref * (P2 / P1) * (PLL_NDIV_i + PLL_NDIV_f) | ||
| 45 | for Freq_vco = VCO_FREQ_MHz | ||
| 46 | Freq_ref = chipcHw_XTAL_FREQ_Hz | ||
| 47 | PLL_P1 = PLL_P2 = 1 | ||
| 48 | and | ||
| 49 | PLL_NDIV_f = 0 | ||
| 50 | |||
| 51 | We get: | ||
| 52 | PLL_NDIV_i = Freq_vco / Freq_ref = VCO_FREQ_MHz / chipcHw_XTAL_FREQ_Hz | ||
| 53 | |||
| 54 | Calculation for PLL MDIV to obtain frequency Freq_x for channel x | ||
| 55 | ----------------------------------------------------------------- | ||
| 56 | Freq_x = chipcHw_XTAL_FREQ_Hz * PLL_NDIV_i / PLL_MDIV_x = VCO_FREQ_MHz / PLL_MDIV_x | ||
| 57 | |||
| 58 | PLL_MDIV_x = VCO_FREQ_MHz / Freq_x | ||
| 59 | */ | ||
| 60 | |||
| 61 | /* ---- Private Variables ------------------------------------------------- */ | ||
| 62 | /****************************************************************************/ | ||
| 63 | /** | ||
| 64 | * @brief Initializes the PLL2 | ||
| 65 | * | ||
| 66 | * This function initializes the PLL2 | ||
| 67 | * | ||
| 68 | */ | ||
| 69 | /****************************************************************************/ | ||
| 70 | void chipcHw_pll2Enable(uint32_t vcoFreqHz) | ||
| 71 | { | ||
| 72 | uint32_t pllPreDivider2 = 0; | ||
| 73 | |||
| 74 | { | ||
| 75 | REG_LOCAL_IRQ_SAVE; | ||
| 76 | pChipcHw->PLLConfig2 = | ||
| 77 | chipcHw_REG_PLL_CONFIG_D_RESET | | ||
| 78 | chipcHw_REG_PLL_CONFIG_A_RESET; | ||
| 79 | |||
| 80 | pllPreDivider2 = chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN | | ||
| 81 | chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER | | ||
| 82 | (chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) << | ||
| 83 | chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) | | ||
| 84 | (chipcHw_REG_PLL_PREDIVIDER_P1 << | ||
| 85 | chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) | | ||
| 86 | (chipcHw_REG_PLL_PREDIVIDER_P2 << | ||
| 87 | chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT); | ||
| 88 | |||
| 89 | /* Enable CHIPC registers to control the PLL */ | ||
| 90 | pChipcHw->PLLStatus |= chipcHw_REG_PLL_STATUS_CONTROL_ENABLE; | ||
| 91 | |||
| 92 | /* Set pre divider to get desired VCO frequency */ | ||
| 93 | pChipcHw->PLLPreDivider2 = pllPreDivider2; | ||
| 94 | /* Set NDIV Frac */ | ||
| 95 | pChipcHw->PLLDivider2 = chipcHw_REG_PLL_DIVIDER_NDIV_f; | ||
| 96 | |||
| 97 | /* This has to be removed once the default values are fixed for PLL2. */ | ||
| 98 | pChipcHw->PLLControl12 = 0x38000700; | ||
| 99 | pChipcHw->PLLControl22 = 0x00000015; | ||
| 100 | |||
| 101 | /* Reset PLL2 */ | ||
| 102 | if (vcoFreqHz > chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ) { | ||
| 103 | pChipcHw->PLLConfig2 = chipcHw_REG_PLL_CONFIG_D_RESET | | ||
| 104 | chipcHw_REG_PLL_CONFIG_A_RESET | | ||
| 105 | chipcHw_REG_PLL_CONFIG_VCO_1601_3200 | | ||
| 106 | chipcHw_REG_PLL_CONFIG_POWER_DOWN; | ||
| 107 | } else { | ||
| 108 | pChipcHw->PLLConfig2 = chipcHw_REG_PLL_CONFIG_D_RESET | | ||
| 109 | chipcHw_REG_PLL_CONFIG_A_RESET | | ||
| 110 | chipcHw_REG_PLL_CONFIG_VCO_800_1600 | | ||
| 111 | chipcHw_REG_PLL_CONFIG_POWER_DOWN; | ||
| 112 | } | ||
| 113 | REG_LOCAL_IRQ_RESTORE; | ||
| 114 | } | ||
| 115 | |||
| 116 | /* Insert certain amount of delay before deasserting ARESET. */ | ||
| 117 | udelay(1); | ||
| 118 | |||
| 119 | { | ||
| 120 | REG_LOCAL_IRQ_SAVE; | ||
| 121 | /* Remove analog reset and Power on the PLL */ | ||
| 122 | pChipcHw->PLLConfig2 &= | ||
| 123 | ~(chipcHw_REG_PLL_CONFIG_A_RESET | | ||
| 124 | chipcHw_REG_PLL_CONFIG_POWER_DOWN); | ||
| 125 | |||
| 126 | REG_LOCAL_IRQ_RESTORE; | ||
| 127 | |||
| 128 | } | ||
| 129 | |||
| 130 | /* Wait until PLL is locked */ | ||
| 131 | while (!(pChipcHw->PLLStatus2 & chipcHw_REG_PLL_STATUS_LOCKED)) | ||
| 132 | ; | ||
| 133 | |||
| 134 | { | ||
| 135 | REG_LOCAL_IRQ_SAVE; | ||
| 136 | /* Remove digital reset */ | ||
| 137 | pChipcHw->PLLConfig2 &= ~chipcHw_REG_PLL_CONFIG_D_RESET; | ||
| 138 | |||
| 139 | REG_LOCAL_IRQ_RESTORE; | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | EXPORT_SYMBOL(chipcHw_pll2Enable); | ||
| 144 | |||
| 145 | /****************************************************************************/ | ||
| 146 | /** | ||
| 147 | * @brief Initializes the PLL1 | ||
| 148 | * | ||
| 149 | * This function initializes the PLL1 | ||
| 150 | * | ||
| 151 | */ | ||
| 152 | /****************************************************************************/ | ||
| 153 | void chipcHw_pll1Enable(uint32_t vcoFreqHz, chipcHw_SPREAD_SPECTRUM_e ssSupport) | ||
| 154 | { | ||
| 155 | uint32_t pllPreDivider = 0; | ||
| 156 | |||
| 157 | { | ||
| 158 | REG_LOCAL_IRQ_SAVE; | ||
| 159 | |||
| 160 | pChipcHw->PLLConfig = | ||
| 161 | chipcHw_REG_PLL_CONFIG_D_RESET | | ||
| 162 | chipcHw_REG_PLL_CONFIG_A_RESET; | ||
| 163 | /* Setting VCO frequency */ | ||
| 164 | if (ssSupport == chipcHw_SPREAD_SPECTRUM_ALLOW) { | ||
| 165 | pllPreDivider = | ||
| 166 | chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_1_8 | | ||
| 167 | ((chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) - | ||
| 168 | 1) << chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) | | ||
| 169 | (chipcHw_REG_PLL_PREDIVIDER_P1 << | ||
| 170 | chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) | | ||
| 171 | (chipcHw_REG_PLL_PREDIVIDER_P2 << | ||
| 172 | chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT); | ||
| 173 | } else { | ||
| 174 | pllPreDivider = chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN | | ||
| 175 | chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER | | ||
| 176 | (chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) << | ||
| 177 | chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) | | ||
| 178 | (chipcHw_REG_PLL_PREDIVIDER_P1 << | ||
| 179 | chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) | | ||
| 180 | (chipcHw_REG_PLL_PREDIVIDER_P2 << | ||
| 181 | chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT); | ||
| 182 | } | ||
| 183 | |||
| 184 | /* Enable CHIPC registers to control the PLL */ | ||
| 185 | pChipcHw->PLLStatus |= chipcHw_REG_PLL_STATUS_CONTROL_ENABLE; | ||
| 186 | |||
| 187 | /* Set pre divider to get desired VCO frequency */ | ||
| 188 | pChipcHw->PLLPreDivider = pllPreDivider; | ||
| 189 | /* Set NDIV Frac */ | ||
| 190 | if (ssSupport == chipcHw_SPREAD_SPECTRUM_ALLOW) { | ||
| 191 | pChipcHw->PLLDivider = chipcHw_REG_PLL_DIVIDER_M1DIV | | ||
| 192 | chipcHw_REG_PLL_DIVIDER_NDIV_f_SS; | ||
| 193 | } else { | ||
| 194 | pChipcHw->PLLDivider = chipcHw_REG_PLL_DIVIDER_M1DIV | | ||
| 195 | chipcHw_REG_PLL_DIVIDER_NDIV_f; | ||
| 196 | } | ||
| 197 | |||
| 198 | /* Reset PLL1 */ | ||
| 199 | if (vcoFreqHz > chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ) { | ||
| 200 | pChipcHw->PLLConfig = chipcHw_REG_PLL_CONFIG_D_RESET | | ||
| 201 | chipcHw_REG_PLL_CONFIG_A_RESET | | ||
| 202 | chipcHw_REG_PLL_CONFIG_VCO_1601_3200 | | ||
| 203 | chipcHw_REG_PLL_CONFIG_POWER_DOWN; | ||
| 204 | } else { | ||
| 205 | pChipcHw->PLLConfig = chipcHw_REG_PLL_CONFIG_D_RESET | | ||
| 206 | chipcHw_REG_PLL_CONFIG_A_RESET | | ||
| 207 | chipcHw_REG_PLL_CONFIG_VCO_800_1600 | | ||
| 208 | chipcHw_REG_PLL_CONFIG_POWER_DOWN; | ||
| 209 | } | ||
| 210 | |||
| 211 | REG_LOCAL_IRQ_RESTORE; | ||
| 212 | |||
| 213 | /* Insert certain amount of delay before deasserting ARESET. */ | ||
| 214 | udelay(1); | ||
| 215 | |||
| 216 | { | ||
| 217 | REG_LOCAL_IRQ_SAVE; | ||
| 218 | /* Remove analog reset and Power on the PLL */ | ||
| 219 | pChipcHw->PLLConfig &= | ||
| 220 | ~(chipcHw_REG_PLL_CONFIG_A_RESET | | ||
| 221 | chipcHw_REG_PLL_CONFIG_POWER_DOWN); | ||
| 222 | REG_LOCAL_IRQ_RESTORE; | ||
| 223 | } | ||
| 224 | |||
| 225 | /* Wait until PLL is locked */ | ||
| 226 | while (!(pChipcHw->PLLStatus & chipcHw_REG_PLL_STATUS_LOCKED) | ||
| 227 | || !(pChipcHw-> | ||
| 228 | PLLStatus2 & chipcHw_REG_PLL_STATUS_LOCKED)) | ||
| 229 | ; | ||
| 230 | |||
| 231 | /* Remove digital reset */ | ||
| 232 | { | ||
| 233 | REG_LOCAL_IRQ_SAVE; | ||
| 234 | pChipcHw->PLLConfig &= ~chipcHw_REG_PLL_CONFIG_D_RESET; | ||
| 235 | REG_LOCAL_IRQ_RESTORE; | ||
| 236 | } | ||
| 237 | } | ||
| 238 | } | ||
| 239 | |||
| 240 | EXPORT_SYMBOL(chipcHw_pll1Enable); | ||
| 241 | |||
| 242 | /****************************************************************************/ | ||
| 243 | /** | ||
| 244 | * @brief Initializes the chipc module | ||
| 245 | * | ||
| 246 | * This function initializes the PLLs and core system clocks | ||
| 247 | * | ||
| 248 | */ | ||
| 249 | /****************************************************************************/ | ||
| 250 | |||
| 251 | void chipcHw_Init(chipcHw_INIT_PARAM_t *initParam /* [ IN ] Misc chip initialization parameter */ | ||
| 252 | ) { | ||
| 253 | #if !(defined(__KERNEL__) && !defined(STANDALONE)) | ||
| 254 | delay_init(); | ||
| 255 | #endif | ||
| 256 | |||
| 257 | /* Do not program PLL, when warm reset */ | ||
| 258 | if (!(chipcHw_getStickyBits() & chipcHw_REG_STICKY_CHIP_WARM_RESET)) { | ||
| 259 | chipcHw_pll1Enable(initParam->pllVcoFreqHz, | ||
| 260 | initParam->ssSupport); | ||
| 261 | chipcHw_pll2Enable(initParam->pll2VcoFreqHz); | ||
| 262 | } else { | ||
| 263 | /* Clear sticky bits */ | ||
| 264 | chipcHw_clearStickyBits(chipcHw_REG_STICKY_CHIP_WARM_RESET); | ||
| 265 | } | ||
| 266 | /* Clear sticky bits */ | ||
| 267 | chipcHw_clearStickyBits(chipcHw_REG_STICKY_CHIP_SOFT_RESET); | ||
| 268 | |||
| 269 | /* Before configuring the ARM clock, atleast we need to make sure BUS clock maintains the proper ratio with ARM clock */ | ||
| 270 | pChipcHw->ACLKClock = | ||
| 271 | (pChipcHw-> | ||
| 272 | ACLKClock & ~chipcHw_REG_ACLKClock_CLK_DIV_MASK) | (initParam-> | ||
| 273 | armBusRatio & | ||
| 274 | chipcHw_REG_ACLKClock_CLK_DIV_MASK); | ||
| 275 | |||
| 276 | /* Set various core component frequencies. The order in which this is done is important for some. */ | ||
| 277 | /* The RTBUS (DDR PHY) is derived from the BUS, and the BUS from the ARM, and VPM needs to know BUS */ | ||
| 278 | /* frequency to find its ratio with the BUS. Hence we must set the ARM first, followed by the BUS, */ | ||
| 279 | /* then VPM and RTBUS. */ | ||
| 280 | |||
| 281 | chipcHw_setClockFrequency(chipcHw_CLOCK_ARM, | ||
| 282 | initParam->busClockFreqHz * | ||
| 283 | initParam->armBusRatio); | ||
| 284 | chipcHw_setClockFrequency(chipcHw_CLOCK_BUS, initParam->busClockFreqHz); | ||
| 285 | chipcHw_setClockFrequency(chipcHw_CLOCK_VPM, | ||
| 286 | initParam->busClockFreqHz * | ||
| 287 | initParam->vpmBusRatio); | ||
| 288 | chipcHw_setClockFrequency(chipcHw_CLOCK_DDR, | ||
| 289 | initParam->busClockFreqHz * | ||
| 290 | initParam->ddrBusRatio); | ||
| 291 | chipcHw_setClockFrequency(chipcHw_CLOCK_RTBUS, | ||
| 292 | initParam->busClockFreqHz / 2); | ||
| 293 | } | ||
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c new file mode 100644 index 000000000000..2671d8896bbb --- /dev/null +++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 16 | #include <csp/stdint.h> | ||
| 17 | #include <mach/csp/chipcHw_def.h> | ||
| 18 | #include <mach/csp/chipcHw_inline.h> | ||
| 19 | #include <csp/intcHw.h> | ||
| 20 | #include <csp/cache.h> | ||
| 21 | |||
| 22 | /* ---- Private Constants and Types --------------------------------------- */ | ||
| 23 | /* ---- Private Variables ------------------------------------------------- */ | ||
| 24 | void chipcHw_reset_run_from_aram(void); | ||
| 25 | |||
| 26 | typedef void (*RUNFUNC) (void); | ||
| 27 | |||
| 28 | /****************************************************************************/ | ||
| 29 | /** | ||
| 30 | * @brief warmReset | ||
| 31 | * | ||
| 32 | * @note warmReset configures the clocks which are not reset back to the state | ||
| 33 | * required to execute on reset. To do so we need to copy the code into internal | ||
| 34 | * memory to change the ARM clock while we are not executing from DDR. | ||
| 35 | */ | ||
| 36 | /****************************************************************************/ | ||
| 37 | void chipcHw_reset(uint32_t mask) | ||
| 38 | { | ||
| 39 | int i = 0; | ||
| 40 | RUNFUNC runFunc = (RUNFUNC) (unsigned long)MM_ADDR_IO_ARAM; | ||
| 41 | |||
| 42 | /* Disable all interrupts */ | ||
| 43 | intcHw_irq_disable(INTCHW_INTC0, 0xffffffff); | ||
| 44 | intcHw_irq_disable(INTCHW_INTC1, 0xffffffff); | ||
| 45 | intcHw_irq_disable(INTCHW_SINTC, 0xffffffff); | ||
| 46 | |||
| 47 | { | ||
| 48 | REG_LOCAL_IRQ_SAVE; | ||
| 49 | if (mask & chipcHw_REG_SOFT_RESET_CHIP_SOFT) { | ||
| 50 | chipcHw_softReset(chipcHw_REG_SOFT_RESET_CHIP_SOFT); | ||
| 51 | } | ||
| 52 | /* Bypass the PLL clocks before reboot */ | ||
| 53 | pChipcHw->UARTClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT; | ||
| 54 | pChipcHw->SPIClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT; | ||
| 55 | |||
| 56 | /* Copy the chipcHw_warmReset_run_from_aram function into ARAM */ | ||
| 57 | do { | ||
| 58 | ((uint32_t *) MM_IO_BASE_ARAM)[i] = | ||
| 59 | ((uint32_t *) &chipcHw_reset_run_from_aram)[i]; | ||
| 60 | i++; | ||
| 61 | } while (((uint32_t *) MM_IO_BASE_ARAM)[i - 1] != 0xe1a0f00f); /* 0xe1a0f00f == asm ("mov r15, r15"); */ | ||
| 62 | |||
| 63 | CSP_CACHE_FLUSH_ALL; | ||
| 64 | |||
| 65 | /* run the function from ARAM */ | ||
| 66 | runFunc(); | ||
| 67 | |||
| 68 | /* Code will never get here, but include it to balance REG_LOCAL_IRQ_SAVE above */ | ||
| 69 | REG_LOCAL_IRQ_RESTORE; | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | /* This function must run from internal memory */ | ||
| 74 | void chipcHw_reset_run_from_aram(void) | ||
| 75 | { | ||
| 76 | /* Make sure, pipeline is filled with instructions coming from ARAM */ | ||
| 77 | __asm (" nop \n\t" | ||
| 78 | " nop \n\t" | ||
| 79 | #if defined(__KERNEL__) && !defined(STANDALONE) | ||
| 80 | " MRC p15,#0x0,r0,c1,c0,#0 \n\t" | ||
| 81 | " BIC r0,r0,#0xd \n\t" | ||
| 82 | " MCR p15,#0x0,r0,c1,c0,#0 \n\t" | ||
| 83 | " nop \n\t" | ||
| 84 | " nop \n\t" | ||
| 85 | " nop \n\t" | ||
| 86 | " nop \n\t" | ||
| 87 | " nop \n\t" | ||
| 88 | " nop \n\t" | ||
| 89 | #endif | ||
| 90 | " nop \n\t" | ||
| 91 | " nop \n\t" | ||
| 92 | /* Bypass the ARM clock and switch to XTAL clock */ | ||
| 93 | " MOV r2,#0x80000000 \n\t" | ||
| 94 | " LDR r3,[r2,#8] \n\t" | ||
| 95 | " ORR r3,r3,#0x20000 \n\t" | ||
| 96 | " STR r3,[r2,#8] \n\t" | ||
| 97 | |||
| 98 | " nop \n\t" | ||
| 99 | " nop \n\t" | ||
| 100 | " nop \n\t" | ||
| 101 | " nop \n\t" | ||
| 102 | " nop \n\t" | ||
| 103 | " nop \n\t" | ||
| 104 | " nop \n\t" | ||
| 105 | " nop \n\t" | ||
| 106 | " nop \n\t" | ||
| 107 | " nop \n\t" | ||
| 108 | " nop \n\t" | ||
| 109 | " nop \n\t" | ||
| 110 | " nop \n\t" | ||
| 111 | " nop \n\t" | ||
| 112 | " nop \n\t" | ||
| 113 | " nop \n\t" | ||
| 114 | " nop \n\t" | ||
| 115 | " nop \n\t" | ||
| 116 | " nop \n\t" | ||
| 117 | " nop \n\t" | ||
| 118 | /* Issue reset */ | ||
| 119 | " MOV r3,#0x2 \n\t" | ||
| 120 | " STR r3,[r2,#0x80] \n\t" | ||
| 121 | /* End here */ | ||
| 122 | " MOV pc,pc \n\t"); | ||
| 123 | /* 0xe1a0f00f == asm ("mov r15, r15"); */ | ||
| 124 | } | ||
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c new file mode 100644 index 000000000000..54ad964fe94c --- /dev/null +++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | /****************************************************************************/ | ||
| 15 | /** | ||
| 16 | * @file chipcHw_str.c | ||
| 17 | * | ||
| 18 | * @brief Contains strings which are useful to linux and csp | ||
| 19 | * | ||
| 20 | * @note | ||
| 21 | */ | ||
| 22 | /****************************************************************************/ | ||
| 23 | |||
| 24 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 25 | |||
| 26 | #include <mach/csp/chipcHw_inline.h> | ||
| 27 | |||
| 28 | /* ---- Private Constants and Types --------------------------------------- */ | ||
| 29 | |||
| 30 | static const char *gMuxStr[] = { | ||
| 31 | "GPIO", /* 0 */ | ||
| 32 | "KeyPad", /* 1 */ | ||
| 33 | "I2C-Host", /* 2 */ | ||
| 34 | "SPI", /* 3 */ | ||
| 35 | "Uart", /* 4 */ | ||
| 36 | "LED-Mtx-P", /* 5 */ | ||
| 37 | "LED-Mtx-S", /* 6 */ | ||
| 38 | "SDIO-0", /* 7 */ | ||
| 39 | "SDIO-1", /* 8 */ | ||
| 40 | "PCM", /* 9 */ | ||
| 41 | "I2S", /* 10 */ | ||
| 42 | "ETM", /* 11 */ | ||
| 43 | "Debug", /* 12 */ | ||
| 44 | "Misc", /* 13 */ | ||
| 45 | "0xE", /* 14 */ | ||
| 46 | "0xF", /* 15 */ | ||
| 47 | }; | ||
| 48 | |||
| 49 | /****************************************************************************/ | ||
| 50 | /** | ||
| 51 | * @brief Retrieves a string representation of the mux setting for a pin. | ||
| 52 | * | ||
| 53 | * @return Pointer to a character string. | ||
| 54 | */ | ||
| 55 | /****************************************************************************/ | ||
| 56 | |||
| 57 | const char *chipcHw_getGpioPinFunctionStr(int pin) | ||
| 58 | { | ||
| 59 | if ((pin < 0) || (pin >= chipcHw_GPIO_COUNT)) { | ||
| 60 | return ""; | ||
| 61 | } | ||
| 62 | |||
| 63 | return gMuxStr[chipcHw_getGpioPinFunction(pin)]; | ||
| 64 | } | ||
diff --git a/arch/arm/mach-bcmring/csp/dmac/Makefile b/arch/arm/mach-bcmring/csp/dmac/Makefile new file mode 100644 index 000000000000..fb1104fe56b2 --- /dev/null +++ b/arch/arm/mach-bcmring/csp/dmac/Makefile | |||
| @@ -0,0 +1 @@ | |||
| obj-y += dmacHw.o dmacHw_extra.o \ No newline at end of file | |||
diff --git a/arch/arm/mach-bcmring/csp/dmac/dmacHw.c b/arch/arm/mach-bcmring/csp/dmac/dmacHw.c new file mode 100644 index 000000000000..7b9bac2d79a5 --- /dev/null +++ b/arch/arm/mach-bcmring/csp/dmac/dmacHw.c | |||
| @@ -0,0 +1,917 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file dmacHw.c | ||
| 18 | * | ||
| 19 | * @brief Low level DMA controller driver routines | ||
| 20 | * | ||
| 21 | * @note | ||
| 22 | * | ||
| 23 | * These routines provide basic DMA functionality only. | ||
| 24 | */ | ||
| 25 | /****************************************************************************/ | ||
| 26 | |||
| 27 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 28 | #include <csp/stdint.h> | ||
| 29 | #include <csp/string.h> | ||
| 30 | #include <stddef.h> | ||
| 31 | |||
| 32 | #include <csp/dmacHw.h> | ||
| 33 | #include <mach/csp/dmacHw_reg.h> | ||
| 34 | #include <mach/csp/dmacHw_priv.h> | ||
| 35 | #include <mach/csp/chipcHw_inline.h> | ||
| 36 | |||
| 37 | /* ---- External Function Prototypes ------------------------------------- */ | ||
| 38 | |||
| 39 | /* Allocate DMA control blocks */ | ||
| 40 | dmacHw_CBLK_t dmacHw_gCblk[dmacHw_MAX_CHANNEL_COUNT]; | ||
| 41 | |||
| 42 | uint32_t dmaChannelCount_0 = dmacHw_MAX_CHANNEL_COUNT / 2; | ||
| 43 | uint32_t dmaChannelCount_1 = dmacHw_MAX_CHANNEL_COUNT / 2; | ||
| 44 | |||
| 45 | /****************************************************************************/ | ||
| 46 | /** | ||
| 47 | * @brief Get maximum FIFO for a DMA channel | ||
| 48 | * | ||
| 49 | * @return Maximum allowable FIFO size | ||
| 50 | * | ||
| 51 | * | ||
| 52 | */ | ||
| 53 | /****************************************************************************/ | ||
| 54 | static uint32_t GetFifoSize(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */ | ||
| 55 | ) { | ||
| 56 | uint32_t val = 0; | ||
| 57 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 58 | dmacHw_MISC_t *pMiscReg = | ||
| 59 | (dmacHw_MISC_t *) dmacHw_REG_MISC_BASE(pCblk->module); | ||
| 60 | |||
| 61 | switch (pCblk->channel) { | ||
| 62 | case 0: | ||
| 63 | val = (pMiscReg->CompParm2.lo & 0x70000000) >> 28; | ||
| 64 | break; | ||
| 65 | case 1: | ||
| 66 | val = (pMiscReg->CompParm3.hi & 0x70000000) >> 28; | ||
| 67 | break; | ||
| 68 | case 2: | ||
| 69 | val = (pMiscReg->CompParm3.lo & 0x70000000) >> 28; | ||
| 70 | break; | ||
| 71 | case 3: | ||
| 72 | val = (pMiscReg->CompParm4.hi & 0x70000000) >> 28; | ||
| 73 | break; | ||
| 74 | case 4: | ||
| 75 | val = (pMiscReg->CompParm4.lo & 0x70000000) >> 28; | ||
| 76 | break; | ||
| 77 | case 5: | ||
| 78 | val = (pMiscReg->CompParm5.hi & 0x70000000) >> 28; | ||
| 79 | break; | ||
| 80 | case 6: | ||
| 81 | val = (pMiscReg->CompParm5.lo & 0x70000000) >> 28; | ||
| 82 | break; | ||
| 83 | case 7: | ||
| 84 | val = (pMiscReg->CompParm6.hi & 0x70000000) >> 28; | ||
| 85 | break; | ||
| 86 | } | ||
| 87 | |||
| 88 | if (val <= 0x4) { | ||
| 89 | return 8 << val; | ||
| 90 | } else { | ||
| 91 | dmacHw_ASSERT(0); | ||
| 92 | } | ||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | /****************************************************************************/ | ||
| 97 | /** | ||
| 98 | * @brief Program channel register to initiate transfer | ||
| 99 | * | ||
| 100 | * @return void | ||
| 101 | * | ||
| 102 | * | ||
| 103 | * @note | ||
| 104 | * - Descriptor buffer MUST ALWAYS be flushed before calling this function | ||
| 105 | * - This function should also be called from ISR to program the channel with | ||
| 106 | * pending descriptors | ||
| 107 | */ | ||
| 108 | /****************************************************************************/ | ||
| 109 | void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 110 | dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 111 | void *pDescriptor /* [ IN ] Descriptor buffer */ | ||
| 112 | ) { | ||
| 113 | dmacHw_DESC_RING_t *pRing; | ||
| 114 | dmacHw_DESC_t *pProg; | ||
| 115 | dmacHw_CBLK_t *pCblk; | ||
| 116 | |||
| 117 | pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 118 | pRing = dmacHw_GET_DESC_RING(pDescriptor); | ||
| 119 | |||
| 120 | if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) { | ||
| 121 | /* Not safe yet to program the channel */ | ||
| 122 | return; | ||
| 123 | } | ||
| 124 | |||
| 125 | if (pCblk->varDataStarted) { | ||
| 126 | if (pCblk->descUpdated) { | ||
| 127 | pCblk->descUpdated = 0; | ||
| 128 | pProg = | ||
| 129 | (dmacHw_DESC_t *) ((uint32_t) | ||
| 130 | dmacHw_REG_LLP(pCblk->module, | ||
| 131 | pCblk->channel) + | ||
| 132 | pRing->virt2PhyOffset); | ||
| 133 | |||
| 134 | /* Load descriptor if not loaded */ | ||
| 135 | if (!(pProg->ctl.hi & dmacHw_REG_CTL_DONE)) { | ||
| 136 | dmacHw_SET_SAR(pCblk->module, pCblk->channel, | ||
| 137 | pProg->sar); | ||
| 138 | dmacHw_SET_DAR(pCblk->module, pCblk->channel, | ||
| 139 | pProg->dar); | ||
| 140 | dmacHw_REG_CTL_LO(pCblk->module, | ||
| 141 | pCblk->channel) = | ||
| 142 | pProg->ctl.lo; | ||
| 143 | dmacHw_REG_CTL_HI(pCblk->module, | ||
| 144 | pCblk->channel) = | ||
| 145 | pProg->ctl.hi; | ||
| 146 | } else if (pProg == (dmacHw_DESC_t *) pRing->pEnd->llp) { | ||
| 147 | /* Return as end descriptor is processed */ | ||
| 148 | return; | ||
| 149 | } else { | ||
| 150 | dmacHw_ASSERT(0); | ||
| 151 | } | ||
| 152 | } else { | ||
| 153 | return; | ||
| 154 | } | ||
| 155 | } else { | ||
| 156 | if (pConfig->transferMode == dmacHw_TRANSFER_MODE_PERIODIC) { | ||
| 157 | /* Do not make a single chain, rather process one descriptor at a time */ | ||
| 158 | pProg = pRing->pHead; | ||
| 159 | /* Point to the next descriptor for next iteration */ | ||
| 160 | dmacHw_NEXT_DESC(pRing, pHead); | ||
| 161 | } else { | ||
| 162 | /* Return if no more pending descriptor */ | ||
| 163 | if (pRing->pEnd == NULL) { | ||
| 164 | return; | ||
| 165 | } | ||
| 166 | |||
| 167 | pProg = pRing->pProg; | ||
| 168 | if (pConfig->transferMode == | ||
| 169 | dmacHw_TRANSFER_MODE_CONTINUOUS) { | ||
| 170 | /* Make sure a complete ring can be formed */ | ||
| 171 | dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pEnd-> | ||
| 172 | llp == pRing->pProg); | ||
| 173 | /* Make sure pProg pointing to the pHead */ | ||
| 174 | dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pProg == | ||
| 175 | pRing->pHead); | ||
| 176 | /* Make a complete ring */ | ||
| 177 | do { | ||
| 178 | pRing->pProg->ctl.lo |= | ||
| 179 | (dmacHw_REG_CTL_LLP_DST_EN | | ||
| 180 | dmacHw_REG_CTL_LLP_SRC_EN); | ||
| 181 | pRing->pProg = | ||
| 182 | (dmacHw_DESC_t *) pRing->pProg->llp; | ||
| 183 | } while (pRing->pProg != pRing->pHead); | ||
| 184 | } else { | ||
| 185 | /* Make a single long chain */ | ||
| 186 | while (pRing->pProg != pRing->pEnd) { | ||
| 187 | pRing->pProg->ctl.lo |= | ||
| 188 | (dmacHw_REG_CTL_LLP_DST_EN | | ||
| 189 | dmacHw_REG_CTL_LLP_SRC_EN); | ||
| 190 | pRing->pProg = | ||
| 191 | (dmacHw_DESC_t *) pRing->pProg->llp; | ||
| 192 | } | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | /* Program the channel registers */ | ||
| 197 | dmacHw_SET_SAR(pCblk->module, pCblk->channel, pProg->sar); | ||
| 198 | dmacHw_SET_DAR(pCblk->module, pCblk->channel, pProg->dar); | ||
| 199 | dmacHw_SET_LLP(pCblk->module, pCblk->channel, | ||
| 200 | (uint32_t) pProg - pRing->virt2PhyOffset); | ||
| 201 | dmacHw_REG_CTL_LO(pCblk->module, pCblk->channel) = | ||
| 202 | pProg->ctl.lo; | ||
| 203 | dmacHw_REG_CTL_HI(pCblk->module, pCblk->channel) = | ||
| 204 | pProg->ctl.hi; | ||
| 205 | if (pRing->pEnd) { | ||
| 206 | /* Remember the descriptor to use next */ | ||
| 207 | pRing->pProg = (dmacHw_DESC_t *) pRing->pEnd->llp; | ||
| 208 | } | ||
| 209 | /* Indicate no more pending descriptor */ | ||
| 210 | pRing->pEnd = (dmacHw_DESC_t *) NULL; | ||
| 211 | } | ||
| 212 | /* Start DMA operation */ | ||
| 213 | dmacHw_DMA_START(pCblk->module, pCblk->channel); | ||
| 214 | } | ||
| 215 | |||
| 216 | /****************************************************************************/ | ||
| 217 | /** | ||
| 218 | * @brief Initializes DMA | ||
| 219 | * | ||
| 220 | * This function initializes DMA CSP driver | ||
| 221 | * | ||
| 222 | * @note | ||
| 223 | * Must be called before using any DMA channel | ||
| 224 | */ | ||
| 225 | /****************************************************************************/ | ||
| 226 | void dmacHw_initDma(void) | ||
| 227 | { | ||
| 228 | |||
| 229 | uint32_t i = 0; | ||
| 230 | |||
| 231 | dmaChannelCount_0 = dmacHw_GET_NUM_CHANNEL(0); | ||
| 232 | dmaChannelCount_1 = dmacHw_GET_NUM_CHANNEL(1); | ||
| 233 | |||
| 234 | /* Enable access to the DMA block */ | ||
| 235 | chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_DMAC0); | ||
| 236 | chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_DMAC1); | ||
| 237 | |||
| 238 | if ((dmaChannelCount_0 + dmaChannelCount_1) > dmacHw_MAX_CHANNEL_COUNT) { | ||
| 239 | dmacHw_ASSERT(0); | ||
| 240 | } | ||
| 241 | |||
| 242 | memset((void *)dmacHw_gCblk, 0, | ||
| 243 | sizeof(dmacHw_CBLK_t) * (dmaChannelCount_0 + dmaChannelCount_1)); | ||
| 244 | for (i = 0; i < dmaChannelCount_0; i++) { | ||
| 245 | dmacHw_gCblk[i].module = 0; | ||
| 246 | dmacHw_gCblk[i].channel = i; | ||
| 247 | } | ||
| 248 | for (i = 0; i < dmaChannelCount_1; i++) { | ||
| 249 | dmacHw_gCblk[i + dmaChannelCount_0].module = 1; | ||
| 250 | dmacHw_gCblk[i + dmaChannelCount_0].channel = i; | ||
| 251 | } | ||
| 252 | } | ||
| 253 | |||
| 254 | /****************************************************************************/ | ||
| 255 | /** | ||
| 256 | * @brief Exit function for DMA | ||
| 257 | * | ||
| 258 | * This function isolates DMA from the system | ||
| 259 | * | ||
| 260 | */ | ||
| 261 | /****************************************************************************/ | ||
| 262 | void dmacHw_exitDma(void) | ||
| 263 | { | ||
| 264 | /* Disable access to the DMA block */ | ||
| 265 | chipcHw_busInterfaceClockDisable(chipcHw_REG_BUS_CLOCK_DMAC0); | ||
| 266 | chipcHw_busInterfaceClockDisable(chipcHw_REG_BUS_CLOCK_DMAC1); | ||
| 267 | } | ||
| 268 | |||
| 269 | /****************************************************************************/ | ||
| 270 | /** | ||
| 271 | * @brief Gets a handle to a DMA channel | ||
| 272 | * | ||
| 273 | * This function returns a handle, representing a control block of a particular DMA channel | ||
| 274 | * | ||
| 275 | * @return -1 - On Failure | ||
| 276 | * handle - On Success, representing a channel control block | ||
| 277 | * | ||
| 278 | * @note | ||
| 279 | * None Channel ID must be created using "dmacHw_MAKE_CHANNEL_ID" macro | ||
| 280 | */ | ||
| 281 | /****************************************************************************/ | ||
| 282 | dmacHw_HANDLE_t dmacHw_getChannelHandle(dmacHw_ID_t channelId /* [ IN ] DMA Channel Id */ | ||
| 283 | ) { | ||
| 284 | int idx; | ||
| 285 | |||
| 286 | switch ((channelId >> 8)) { | ||
| 287 | case 0: | ||
| 288 | dmacHw_ASSERT((channelId & 0xff) < dmaChannelCount_0); | ||
| 289 | idx = (channelId & 0xff); | ||
| 290 | break; | ||
| 291 | case 1: | ||
| 292 | dmacHw_ASSERT((channelId & 0xff) < dmaChannelCount_1); | ||
| 293 | idx = dmaChannelCount_0 + (channelId & 0xff); | ||
| 294 | break; | ||
| 295 | default: | ||
| 296 | dmacHw_ASSERT(0); | ||
| 297 | return (dmacHw_HANDLE_t) -1; | ||
| 298 | } | ||
| 299 | |||
| 300 | return dmacHw_CBLK_TO_HANDLE(&dmacHw_gCblk[idx]); | ||
| 301 | } | ||
| 302 | |||
| 303 | /****************************************************************************/ | ||
| 304 | /** | ||
| 305 | * @brief Initializes a DMA channel for use | ||
| 306 | * | ||
| 307 | * This function initializes and resets a DMA channel for use | ||
| 308 | * | ||
| 309 | * @return -1 - On Failure | ||
| 310 | * 0 - On Success | ||
| 311 | * | ||
| 312 | * @note | ||
| 313 | * None | ||
| 314 | */ | ||
| 315 | /****************************************************************************/ | ||
| 316 | int dmacHw_initChannel(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */ | ||
| 317 | ) { | ||
| 318 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 319 | int module = pCblk->module; | ||
| 320 | int channel = pCblk->channel; | ||
| 321 | |||
| 322 | /* Reinitialize the control block */ | ||
| 323 | memset((void *)pCblk, 0, sizeof(dmacHw_CBLK_t)); | ||
| 324 | pCblk->module = module; | ||
| 325 | pCblk->channel = channel; | ||
| 326 | |||
| 327 | /* Enable DMA controller */ | ||
| 328 | dmacHw_DMA_ENABLE(pCblk->module); | ||
| 329 | /* Reset DMA channel */ | ||
| 330 | dmacHw_RESET_CONTROL_LO(pCblk->module, pCblk->channel); | ||
| 331 | dmacHw_RESET_CONTROL_HI(pCblk->module, pCblk->channel); | ||
| 332 | dmacHw_RESET_CONFIG_LO(pCblk->module, pCblk->channel); | ||
| 333 | dmacHw_RESET_CONFIG_HI(pCblk->module, pCblk->channel); | ||
| 334 | |||
| 335 | /* Clear all raw interrupt status */ | ||
| 336 | dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel); | ||
| 337 | dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel); | ||
| 338 | dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel); | ||
| 339 | |||
| 340 | /* Mask event specific interrupts */ | ||
| 341 | dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel); | ||
| 342 | dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel); | ||
| 343 | dmacHw_STRAN_INT_DISABLE(pCblk->module, pCblk->channel); | ||
| 344 | dmacHw_DTRAN_INT_DISABLE(pCblk->module, pCblk->channel); | ||
| 345 | dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel); | ||
| 346 | |||
| 347 | return 0; | ||
| 348 | } | ||
| 349 | |||
| 350 | /****************************************************************************/ | ||
| 351 | /** | ||
| 352 | * @brief Finds amount of memory required to form a descriptor ring | ||
| 353 | * | ||
| 354 | * | ||
| 355 | * @return Number of bytes required to form a descriptor ring | ||
| 356 | * | ||
| 357 | * | ||
| 358 | */ | ||
| 359 | /****************************************************************************/ | ||
| 360 | uint32_t dmacHw_descriptorLen(uint32_t descCnt /* [ IN ] Number of descriptor in the ring */ | ||
| 361 | ) { | ||
| 362 | /* Need extra 4 byte to ensure 32 bit alignment */ | ||
| 363 | return (descCnt * sizeof(dmacHw_DESC_t)) + sizeof(dmacHw_DESC_RING_t) + | ||
| 364 | sizeof(uint32_t); | ||
| 365 | } | ||
| 366 | |||
| 367 | /****************************************************************************/ | ||
| 368 | /** | ||
| 369 | * @brief Initializes descriptor ring | ||
| 370 | * | ||
| 371 | * This function will initializes the descriptor ring of a DMA channel | ||
| 372 | * | ||
| 373 | * | ||
| 374 | * @return -1 - On failure | ||
| 375 | * 0 - On success | ||
| 376 | * @note | ||
| 377 | * - "len" parameter should be obtained from "dmacHw_descriptorLen" | ||
| 378 | * - Descriptor buffer MUST be 32 bit aligned and uncached as it is | ||
| 379 | * accessed by ARM and DMA | ||
| 380 | */ | ||
| 381 | /****************************************************************************/ | ||
| 382 | int dmacHw_initDescriptor(void *pDescriptorVirt, /* [ IN ] Virtual address of uncahced buffer allocated to form descriptor ring */ | ||
| 383 | uint32_t descriptorPhyAddr, /* [ IN ] Physical address of pDescriptorVirt (descriptor buffer) */ | ||
| 384 | uint32_t len, /* [ IN ] Size of the pBuf */ | ||
| 385 | uint32_t num /* [ IN ] Number of descriptor in the ring */ | ||
| 386 | ) { | ||
| 387 | uint32_t i; | ||
| 388 | dmacHw_DESC_RING_t *pRing; | ||
| 389 | dmacHw_DESC_t *pDesc; | ||
| 390 | |||
| 391 | /* Check the alignment of the descriptor */ | ||
| 392 | if ((uint32_t) pDescriptorVirt & 0x00000003) { | ||
| 393 | dmacHw_ASSERT(0); | ||
| 394 | return -1; | ||
| 395 | } | ||
| 396 | |||
| 397 | /* Check if enough space has been allocated for descriptor ring */ | ||
| 398 | if (len < dmacHw_descriptorLen(num)) { | ||
| 399 | return -1; | ||
| 400 | } | ||
| 401 | |||
| 402 | pRing = dmacHw_GET_DESC_RING(pDescriptorVirt); | ||
| 403 | pRing->pHead = | ||
| 404 | (dmacHw_DESC_t *) ((uint32_t) pRing + sizeof(dmacHw_DESC_RING_t)); | ||
| 405 | pRing->pFree = pRing->pTail = pRing->pEnd = pRing->pHead; | ||
| 406 | pRing->pProg = dmacHw_DESC_INIT; | ||
| 407 | /* Initialize link item chain, starting from the head */ | ||
| 408 | pDesc = pRing->pHead; | ||
| 409 | /* Find the offset between virtual to physical address */ | ||
| 410 | pRing->virt2PhyOffset = (uint32_t) pDescriptorVirt - descriptorPhyAddr; | ||
| 411 | |||
| 412 | /* Form the descriptor ring */ | ||
| 413 | for (i = 0; i < num - 1; i++) { | ||
| 414 | /* Clear link list item */ | ||
| 415 | memset((void *)pDesc, 0, sizeof(dmacHw_DESC_t)); | ||
| 416 | /* Point to the next item in the physical address */ | ||
| 417 | pDesc->llpPhy = (uint32_t) (pDesc + 1) - pRing->virt2PhyOffset; | ||
| 418 | /* Point to the next item in the virtual address */ | ||
| 419 | pDesc->llp = (uint32_t) (pDesc + 1); | ||
| 420 | /* Mark descriptor is ready to use */ | ||
| 421 | pDesc->ctl.hi = dmacHw_DESC_FREE; | ||
| 422 | /* Look into next link list item */ | ||
| 423 | pDesc++; | ||
| 424 | } | ||
| 425 | |||
| 426 | /* Clear last link list item */ | ||
| 427 | memset((void *)pDesc, 0, sizeof(dmacHw_DESC_t)); | ||
| 428 | /* Last item pointing to the first item in the | ||
| 429 | physical address to complete the ring */ | ||
| 430 | pDesc->llpPhy = (uint32_t) pRing->pHead - pRing->virt2PhyOffset; | ||
| 431 | /* Last item pointing to the first item in the | ||
| 432 | virtual address to complete the ring | ||
| 433 | */ | ||
| 434 | pDesc->llp = (uint32_t) pRing->pHead; | ||
| 435 | /* Mark descriptor is ready to use */ | ||
| 436 | pDesc->ctl.hi = dmacHw_DESC_FREE; | ||
| 437 | /* Set the number of descriptors in the ring */ | ||
| 438 | pRing->num = num; | ||
| 439 | return 0; | ||
| 440 | } | ||
| 441 | |||
| 442 | /****************************************************************************/ | ||
| 443 | /** | ||
| 444 | * @brief Configure DMA channel | ||
| 445 | * | ||
| 446 | * @return 0 : On success | ||
| 447 | * -1 : On failure | ||
| 448 | */ | ||
| 449 | /****************************************************************************/ | ||
| 450 | int dmacHw_configChannel(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 451 | dmacHw_CONFIG_t *pConfig /* [ IN ] Configuration settings */ | ||
| 452 | ) { | ||
| 453 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 454 | uint32_t cfgHigh = 0; | ||
| 455 | int srcTrSize; | ||
| 456 | int dstTrSize; | ||
| 457 | |||
| 458 | pCblk->varDataStarted = 0; | ||
| 459 | pCblk->userData = NULL; | ||
| 460 | |||
| 461 | /* Configure | ||
| 462 | - Burst transaction when enough data in available in FIFO | ||
| 463 | - AHB Access protection 1 | ||
| 464 | - Source and destination peripheral ports | ||
| 465 | */ | ||
| 466 | cfgHigh = | ||
| 467 | dmacHw_REG_CFG_HI_FIFO_ENOUGH | dmacHw_REG_CFG_HI_AHB_HPROT_1 | | ||
| 468 | dmacHw_SRC_PERI_INTF(pConfig-> | ||
| 469 | srcPeripheralPort) | | ||
| 470 | dmacHw_DST_PERI_INTF(pConfig->dstPeripheralPort); | ||
| 471 | /* Set priority */ | ||
| 472 | dmacHw_SET_CHANNEL_PRIORITY(pCblk->module, pCblk->channel, | ||
| 473 | pConfig->channelPriority); | ||
| 474 | |||
| 475 | if (pConfig->dstStatusRegisterAddress != 0) { | ||
| 476 | /* Destination status update enable */ | ||
| 477 | cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_DST_STAT; | ||
| 478 | /* Configure status registers */ | ||
| 479 | dmacHw_SET_DSTATAR(pCblk->module, pCblk->channel, | ||
| 480 | pConfig->dstStatusRegisterAddress); | ||
| 481 | } | ||
| 482 | |||
| 483 | if (pConfig->srcStatusRegisterAddress != 0) { | ||
| 484 | /* Source status update enable */ | ||
| 485 | cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_SRC_STAT; | ||
| 486 | /* Source status update enable */ | ||
| 487 | dmacHw_SET_SSTATAR(pCblk->module, pCblk->channel, | ||
| 488 | pConfig->srcStatusRegisterAddress); | ||
| 489 | } | ||
| 490 | /* Configure the config high register */ | ||
| 491 | dmacHw_GET_CONFIG_HI(pCblk->module, pCblk->channel) = cfgHigh; | ||
| 492 | |||
| 493 | /* Clear all raw interrupt status */ | ||
| 494 | dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel); | ||
| 495 | dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel); | ||
| 496 | dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel); | ||
| 497 | |||
| 498 | /* Configure block interrupt */ | ||
| 499 | if (pConfig->blockTransferInterrupt == dmacHw_INTERRUPT_ENABLE) { | ||
| 500 | dmacHw_BLOCK_INT_ENABLE(pCblk->module, pCblk->channel); | ||
| 501 | } else { | ||
| 502 | dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel); | ||
| 503 | } | ||
| 504 | /* Configure complete transfer interrupt */ | ||
| 505 | if (pConfig->completeTransferInterrupt == dmacHw_INTERRUPT_ENABLE) { | ||
| 506 | dmacHw_TRAN_INT_ENABLE(pCblk->module, pCblk->channel); | ||
| 507 | } else { | ||
| 508 | dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel); | ||
| 509 | } | ||
| 510 | /* Configure error interrupt */ | ||
| 511 | if (pConfig->errorInterrupt == dmacHw_INTERRUPT_ENABLE) { | ||
| 512 | dmacHw_ERROR_INT_ENABLE(pCblk->module, pCblk->channel); | ||
| 513 | } else { | ||
| 514 | dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel); | ||
| 515 | } | ||
| 516 | /* Configure gather register */ | ||
| 517 | if (pConfig->srcGatherWidth) { | ||
| 518 | srcTrSize = | ||
| 519 | dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth); | ||
| 520 | if (! | ||
| 521 | ((pConfig->srcGatherWidth % srcTrSize) | ||
| 522 | && (pConfig->srcGatherJump % srcTrSize))) { | ||
| 523 | dmacHw_REG_SGR_LO(pCblk->module, pCblk->channel) = | ||
| 524 | ((pConfig->srcGatherWidth / | ||
| 525 | srcTrSize) << 20) | (pConfig->srcGatherJump / | ||
| 526 | srcTrSize); | ||
| 527 | } else { | ||
| 528 | return -1; | ||
| 529 | } | ||
| 530 | } | ||
| 531 | /* Configure scatter register */ | ||
| 532 | if (pConfig->dstScatterWidth) { | ||
| 533 | dstTrSize = | ||
| 534 | dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth); | ||
| 535 | if (! | ||
| 536 | ((pConfig->dstScatterWidth % dstTrSize) | ||
| 537 | && (pConfig->dstScatterJump % dstTrSize))) { | ||
| 538 | dmacHw_REG_DSR_LO(pCblk->module, pCblk->channel) = | ||
| 539 | ((pConfig->dstScatterWidth / | ||
| 540 | dstTrSize) << 20) | (pConfig->dstScatterJump / | ||
| 541 | dstTrSize); | ||
| 542 | } else { | ||
| 543 | return -1; | ||
| 544 | } | ||
| 545 | } | ||
| 546 | return 0; | ||
| 547 | } | ||
| 548 | |||
| 549 | /****************************************************************************/ | ||
| 550 | /** | ||
| 551 | * @brief Indicates whether DMA transfer is in progress or completed | ||
| 552 | * | ||
| 553 | * @return DMA transfer status | ||
| 554 | * dmacHw_TRANSFER_STATUS_BUSY: DMA Transfer ongoing | ||
| 555 | * dmacHw_TRANSFER_STATUS_DONE: DMA Transfer completed | ||
| 556 | * dmacHw_TRANSFER_STATUS_ERROR: DMA Transfer error | ||
| 557 | * | ||
| 558 | */ | ||
| 559 | /****************************************************************************/ | ||
| 560 | dmacHw_TRANSFER_STATUS_e dmacHw_transferCompleted(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */ | ||
| 561 | ) { | ||
| 562 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 563 | |||
| 564 | if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) { | ||
| 565 | return dmacHw_TRANSFER_STATUS_BUSY; | ||
| 566 | } else if (dmacHw_REG_INT_RAW_ERROR(pCblk->module) & | ||
| 567 | (0x00000001 << pCblk->channel)) { | ||
| 568 | return dmacHw_TRANSFER_STATUS_ERROR; | ||
| 569 | } | ||
| 570 | |||
| 571 | return dmacHw_TRANSFER_STATUS_DONE; | ||
| 572 | } | ||
| 573 | |||
| 574 | /****************************************************************************/ | ||
| 575 | /** | ||
| 576 | * @brief Set descriptors for known data length | ||
| 577 | * | ||
| 578 | * When DMA has to work as a flow controller, this function prepares the | ||
| 579 | * descriptor chain to transfer data | ||
| 580 | * | ||
| 581 | * from: | ||
| 582 | * - Memory to memory | ||
| 583 | * - Peripheral to memory | ||
| 584 | * - Memory to Peripheral | ||
| 585 | * - Peripheral to Peripheral | ||
| 586 | * | ||
| 587 | * @return -1 - On failure | ||
| 588 | * 0 - On success | ||
| 589 | * | ||
| 590 | */ | ||
| 591 | /****************************************************************************/ | ||
| 592 | int dmacHw_setDataDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 593 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 594 | void *pSrcAddr, /* [ IN ] Source (Peripheral/Memory) address */ | ||
| 595 | void *pDstAddr, /* [ IN ] Destination (Peripheral/Memory) address */ | ||
| 596 | size_t dataLen /* [ IN ] Data length in bytes */ | ||
| 597 | ) { | ||
| 598 | dmacHw_TRANSACTION_WIDTH_e dstTrWidth; | ||
| 599 | dmacHw_TRANSACTION_WIDTH_e srcTrWidth; | ||
| 600 | dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor); | ||
| 601 | dmacHw_DESC_t *pStart; | ||
| 602 | dmacHw_DESC_t *pProg; | ||
| 603 | int srcTs = 0; | ||
| 604 | int blkTs = 0; | ||
| 605 | int oddSize = 0; | ||
| 606 | int descCount = 0; | ||
| 607 | int count = 0; | ||
| 608 | int dstTrSize = 0; | ||
| 609 | int srcTrSize = 0; | ||
| 610 | uint32_t maxBlockSize = dmacHw_MAX_BLOCKSIZE; | ||
| 611 | |||
| 612 | dstTrSize = dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth); | ||
| 613 | srcTrSize = dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth); | ||
| 614 | |||
| 615 | /* Skip Tx if buffer is NULL or length is unknown */ | ||
| 616 | if ((pSrcAddr == NULL) || (pDstAddr == NULL) || (dataLen == 0)) { | ||
| 617 | /* Do not initiate transfer */ | ||
| 618 | return -1; | ||
| 619 | } | ||
| 620 | |||
| 621 | /* Ensure scatter and gather are transaction aligned */ | ||
| 622 | if ((pConfig->srcGatherWidth % srcTrSize) | ||
| 623 | || (pConfig->dstScatterWidth % dstTrSize)) { | ||
| 624 | return -2; | ||
| 625 | } | ||
| 626 | |||
| 627 | /* | ||
| 628 | Background 1: DMAC can not perform DMA if source and destination addresses are | ||
| 629 | not properly aligned with the channel's transaction width. So, for successful | ||
| 630 | DMA transfer, transaction width must be set according to the alignment of the | ||
| 631 | source and destination address. | ||
| 632 | */ | ||
| 633 | |||
| 634 | /* Adjust destination transaction width if destination address is not aligned properly */ | ||
| 635 | dstTrWidth = pConfig->dstMaxTransactionWidth; | ||
| 636 | while (dmacHw_ADDRESS_MASK(dstTrSize) & (uint32_t) pDstAddr) { | ||
| 637 | dstTrWidth = dmacHw_GetNextTrWidth(dstTrWidth); | ||
| 638 | dstTrSize = dmacHw_GetTrWidthInBytes(dstTrWidth); | ||
| 639 | } | ||
| 640 | |||
| 641 | /* Adjust source transaction width if source address is not aligned properly */ | ||
| 642 | srcTrWidth = pConfig->srcMaxTransactionWidth; | ||
| 643 | while (dmacHw_ADDRESS_MASK(srcTrSize) & (uint32_t) pSrcAddr) { | ||
| 644 | srcTrWidth = dmacHw_GetNextTrWidth(srcTrWidth); | ||
| 645 | srcTrSize = dmacHw_GetTrWidthInBytes(srcTrWidth); | ||
| 646 | } | ||
| 647 | |||
| 648 | /* Find the maximum transaction per descriptor */ | ||
| 649 | if (pConfig->maxDataPerBlock | ||
| 650 | && ((pConfig->maxDataPerBlock / srcTrSize) < | ||
| 651 | dmacHw_MAX_BLOCKSIZE)) { | ||
| 652 | maxBlockSize = pConfig->maxDataPerBlock / srcTrSize; | ||
| 653 | } | ||
| 654 | |||
| 655 | /* Find number of source transactions needed to complete the DMA transfer */ | ||
| 656 | srcTs = dataLen / srcTrSize; | ||
| 657 | /* Find the odd number of bytes that need to be transferred as single byte transaction width */ | ||
| 658 | if (srcTs && (dstTrSize > srcTrSize)) { | ||
| 659 | oddSize = dataLen % dstTrSize; | ||
| 660 | /* Adjust source transaction count due to "oddSize" */ | ||
| 661 | srcTs = srcTs - (oddSize / srcTrSize); | ||
| 662 | } else { | ||
| 663 | oddSize = dataLen % srcTrSize; | ||
| 664 | } | ||
| 665 | /* Adjust "descCount" due to "oddSize" */ | ||
| 666 | if (oddSize) { | ||
| 667 | descCount++; | ||
| 668 | } | ||
| 669 | /* Find the number of descriptor needed for total "srcTs" */ | ||
| 670 | if (srcTs) { | ||
| 671 | descCount += ((srcTs - 1) / maxBlockSize) + 1; | ||
| 672 | } | ||
| 673 | |||
| 674 | /* Check the availability of "descCount" discriptors in the ring */ | ||
| 675 | pProg = pRing->pHead; | ||
| 676 | for (count = 0; (descCount <= pRing->num) && (count < descCount); | ||
| 677 | count++) { | ||
| 678 | if ((pProg->ctl.hi & dmacHw_DESC_FREE) == 0) { | ||
| 679 | /* Sufficient descriptors are not available */ | ||
| 680 | return -3; | ||
| 681 | } | ||
| 682 | pProg = (dmacHw_DESC_t *) pProg->llp; | ||
| 683 | } | ||
| 684 | |||
| 685 | /* Remember the link list item to program the channel registers */ | ||
| 686 | pStart = pProg = pRing->pHead; | ||
| 687 | /* Make a link list with "descCount(=count)" number of descriptors */ | ||
| 688 | while (count) { | ||
| 689 | /* Reset channel control information */ | ||
| 690 | pProg->ctl.lo = 0; | ||
| 691 | /* Enable source gather if configured */ | ||
| 692 | if (pConfig->srcGatherWidth) { | ||
| 693 | pProg->ctl.lo |= dmacHw_REG_CTL_SG_ENABLE; | ||
| 694 | } | ||
| 695 | /* Enable destination scatter if configured */ | ||
| 696 | if (pConfig->dstScatterWidth) { | ||
| 697 | pProg->ctl.lo |= dmacHw_REG_CTL_DS_ENABLE; | ||
| 698 | } | ||
| 699 | /* Set source and destination address */ | ||
| 700 | pProg->sar = (uint32_t) pSrcAddr; | ||
| 701 | pProg->dar = (uint32_t) pDstAddr; | ||
| 702 | /* Use "devCtl" to mark that user memory need to be freed later if needed */ | ||
| 703 | if (pProg == pRing->pHead) { | ||
| 704 | pProg->devCtl = dmacHw_FREE_USER_MEMORY; | ||
| 705 | } else { | ||
| 706 | pProg->devCtl = 0; | ||
| 707 | } | ||
| 708 | |||
| 709 | blkTs = srcTs; | ||
| 710 | |||
| 711 | /* Special treatmeant for last descriptor */ | ||
| 712 | if (count == 1) { | ||
| 713 | /* Mark the last descriptor */ | ||
| 714 | pProg->ctl.lo &= | ||
| 715 | ~(dmacHw_REG_CTL_LLP_DST_EN | | ||
| 716 | dmacHw_REG_CTL_LLP_SRC_EN); | ||
| 717 | /* Treatment for odd data bytes */ | ||
| 718 | if (oddSize) { | ||
| 719 | /* Adjust for single byte transaction width */ | ||
| 720 | switch (pConfig->transferType) { | ||
| 721 | case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM: | ||
| 722 | dstTrWidth = | ||
| 723 | dmacHw_DST_TRANSACTION_WIDTH_8; | ||
| 724 | blkTs = | ||
| 725 | (oddSize / srcTrSize) + | ||
| 726 | ((oddSize % srcTrSize) ? 1 : 0); | ||
| 727 | break; | ||
| 728 | case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL: | ||
| 729 | srcTrWidth = | ||
| 730 | dmacHw_SRC_TRANSACTION_WIDTH_8; | ||
| 731 | blkTs = oddSize; | ||
| 732 | break; | ||
| 733 | case dmacHw_TRANSFER_TYPE_MEM_TO_MEM: | ||
| 734 | srcTrWidth = | ||
| 735 | dmacHw_SRC_TRANSACTION_WIDTH_8; | ||
| 736 | dstTrWidth = | ||
| 737 | dmacHw_DST_TRANSACTION_WIDTH_8; | ||
| 738 | blkTs = oddSize; | ||
| 739 | break; | ||
| 740 | case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL: | ||
| 741 | /* Do not adjust the transaction width */ | ||
| 742 | break; | ||
| 743 | } | ||
| 744 | } else { | ||
| 745 | srcTs -= blkTs; | ||
| 746 | } | ||
| 747 | } else { | ||
| 748 | if (srcTs / maxBlockSize) { | ||
| 749 | blkTs = maxBlockSize; | ||
| 750 | } | ||
| 751 | /* Remaining source transactions for next iteration */ | ||
| 752 | srcTs -= blkTs; | ||
| 753 | } | ||
| 754 | /* Must have a valid source transactions */ | ||
| 755 | dmacHw_ASSERT(blkTs > 0); | ||
| 756 | /* Set control information */ | ||
| 757 | if (pConfig->flowControler == dmacHw_FLOW_CONTROL_DMA) { | ||
| 758 | pProg->ctl.lo |= pConfig->transferType | | ||
| 759 | pConfig->srcUpdate | | ||
| 760 | pConfig->dstUpdate | | ||
| 761 | srcTrWidth | | ||
| 762 | dstTrWidth | | ||
| 763 | pConfig->srcMaxBurstWidth | | ||
| 764 | pConfig->dstMaxBurstWidth | | ||
| 765 | pConfig->srcMasterInterface | | ||
| 766 | pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN; | ||
| 767 | } else { | ||
| 768 | uint32_t transferType = 0; | ||
| 769 | switch (pConfig->transferType) { | ||
| 770 | case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM: | ||
| 771 | transferType = dmacHw_REG_CTL_TTFC_PM_PERI; | ||
| 772 | break; | ||
| 773 | case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL: | ||
| 774 | transferType = dmacHw_REG_CTL_TTFC_MP_PERI; | ||
| 775 | break; | ||
| 776 | default: | ||
| 777 | dmacHw_ASSERT(0); | ||
| 778 | } | ||
| 779 | pProg->ctl.lo |= transferType | | ||
| 780 | pConfig->srcUpdate | | ||
| 781 | pConfig->dstUpdate | | ||
| 782 | srcTrWidth | | ||
| 783 | dstTrWidth | | ||
| 784 | pConfig->srcMaxBurstWidth | | ||
| 785 | pConfig->dstMaxBurstWidth | | ||
| 786 | pConfig->srcMasterInterface | | ||
| 787 | pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN; | ||
| 788 | } | ||
| 789 | |||
| 790 | /* Set block transaction size */ | ||
| 791 | pProg->ctl.hi = blkTs & dmacHw_REG_CTL_BLOCK_TS_MASK; | ||
| 792 | /* Look for next descriptor */ | ||
| 793 | if (count > 1) { | ||
| 794 | /* Point to the next descriptor */ | ||
| 795 | pProg = (dmacHw_DESC_t *) pProg->llp; | ||
| 796 | |||
| 797 | /* Update source and destination address for next iteration */ | ||
| 798 | switch (pConfig->transferType) { | ||
| 799 | case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM: | ||
| 800 | if (pConfig->dstScatterWidth) { | ||
| 801 | pDstAddr = | ||
| 802 | (char *)pDstAddr + | ||
| 803 | blkTs * srcTrSize + | ||
| 804 | (((blkTs * srcTrSize) / | ||
| 805 | pConfig->dstScatterWidth) * | ||
| 806 | pConfig->dstScatterJump); | ||
| 807 | } else { | ||
| 808 | pDstAddr = | ||
| 809 | (char *)pDstAddr + | ||
| 810 | blkTs * srcTrSize; | ||
| 811 | } | ||
| 812 | break; | ||
| 813 | case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL: | ||
| 814 | if (pConfig->srcGatherWidth) { | ||
| 815 | pSrcAddr = | ||
| 816 | (char *)pDstAddr + | ||
| 817 | blkTs * srcTrSize + | ||
| 818 | (((blkTs * srcTrSize) / | ||
| 819 | pConfig->srcGatherWidth) * | ||
| 820 | pConfig->srcGatherJump); | ||
| 821 | } else { | ||
| 822 | pSrcAddr = | ||
| 823 | (char *)pSrcAddr + | ||
| 824 | blkTs * srcTrSize; | ||
| 825 | } | ||
| 826 | break; | ||
| 827 | case dmacHw_TRANSFER_TYPE_MEM_TO_MEM: | ||
| 828 | if (pConfig->dstScatterWidth) { | ||
| 829 | pDstAddr = | ||
| 830 | (char *)pDstAddr + | ||
| 831 | blkTs * srcTrSize + | ||
| 832 | (((blkTs * srcTrSize) / | ||
| 833 | pConfig->dstScatterWidth) * | ||
| 834 | pConfig->dstScatterJump); | ||
| 835 | } else { | ||
| 836 | pDstAddr = | ||
| 837 | (char *)pDstAddr + | ||
| 838 | blkTs * srcTrSize; | ||
| 839 | } | ||
| 840 | |||
| 841 | if (pConfig->srcGatherWidth) { | ||
| 842 | pSrcAddr = | ||
| 843 | (char *)pDstAddr + | ||
| 844 | blkTs * srcTrSize + | ||
| 845 | (((blkTs * srcTrSize) / | ||
| 846 | pConfig->srcGatherWidth) * | ||
| 847 | pConfig->srcGatherJump); | ||
| 848 | } else { | ||
| 849 | pSrcAddr = | ||
| 850 | (char *)pSrcAddr + | ||
| 851 | blkTs * srcTrSize; | ||
| 852 | } | ||
| 853 | break; | ||
| 854 | case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL: | ||
| 855 | /* Do not adjust the address */ | ||
| 856 | break; | ||
| 857 | default: | ||
| 858 | dmacHw_ASSERT(0); | ||
| 859 | } | ||
| 860 | } else { | ||
| 861 | /* At the end of transfer "srcTs" must be zero */ | ||
| 862 | dmacHw_ASSERT(srcTs == 0); | ||
| 863 | } | ||
| 864 | count--; | ||
| 865 | } | ||
| 866 | |||
| 867 | /* Remember the descriptor to initialize the registers */ | ||
| 868 | if (pRing->pProg == dmacHw_DESC_INIT) { | ||
| 869 | pRing->pProg = pStart; | ||
| 870 | } | ||
| 871 | /* Indicate that the descriptor is updated */ | ||
| 872 | pRing->pEnd = pProg; | ||
| 873 | /* Head pointing to the next descriptor */ | ||
| 874 | pRing->pHead = (dmacHw_DESC_t *) pProg->llp; | ||
| 875 | /* Update Tail pointer if destination is a peripheral, | ||
| 876 | because no one is going to read from the pTail | ||
| 877 | */ | ||
| 878 | if (!dmacHw_DST_IS_MEMORY(pConfig->transferType)) { | ||
| 879 | pRing->pTail = pRing->pHead; | ||
| 880 | } | ||
| 881 | return 0; | ||
| 882 | } | ||
| 883 | |||
| 884 | /****************************************************************************/ | ||
| 885 | /** | ||
| 886 | * @brief Provides DMA controller attributes | ||
| 887 | * | ||
| 888 | * | ||
| 889 | * @return DMA controller attributes | ||
| 890 | * | ||
| 891 | * @note | ||
| 892 | * None | ||
| 893 | */ | ||
| 894 | /****************************************************************************/ | ||
| 895 | uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 896 | dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controler attribute of type dmacHw_CONTROLLER_ATTRIB_e */ | ||
| 897 | ) { | ||
| 898 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 899 | |||
| 900 | switch (attr) { | ||
| 901 | case dmacHw_CONTROLLER_ATTRIB_CHANNEL_NUM: | ||
| 902 | return dmacHw_GET_NUM_CHANNEL(pCblk->module); | ||
| 903 | case dmacHw_CONTROLLER_ATTRIB_CHANNEL_MAX_BLOCK_SIZE: | ||
| 904 | return (1 << | ||
| 905 | (dmacHw_GET_MAX_BLOCK_SIZE | ||
| 906 | (pCblk->module, pCblk->module) + 2)) - 8; | ||
| 907 | case dmacHw_CONTROLLER_ATTRIB_MASTER_INTF_NUM: | ||
| 908 | return dmacHw_GET_NUM_INTERFACE(pCblk->module); | ||
| 909 | case dmacHw_CONTROLLER_ATTRIB_CHANNEL_BUS_WIDTH: | ||
| 910 | return 32 << dmacHw_GET_CHANNEL_DATA_WIDTH(pCblk->module, | ||
| 911 | pCblk->channel); | ||
| 912 | case dmacHw_CONTROLLER_ATTRIB_CHANNEL_FIFO_SIZE: | ||
| 913 | return GetFifoSize(handle); | ||
| 914 | } | ||
| 915 | dmacHw_ASSERT(0); | ||
| 916 | return 0; | ||
| 917 | } | ||
diff --git a/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c new file mode 100644 index 000000000000..ff7b436d0935 --- /dev/null +++ b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c | |||
| @@ -0,0 +1,1017 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file dmacHw_extra.c | ||
| 18 | * | ||
| 19 | * @brief Extra Low level DMA controller driver routines | ||
| 20 | * | ||
| 21 | * @note | ||
| 22 | * | ||
| 23 | * These routines provide basic DMA functionality only. | ||
| 24 | */ | ||
| 25 | /****************************************************************************/ | ||
| 26 | |||
| 27 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 28 | |||
| 29 | #include <csp/stdint.h> | ||
| 30 | #include <stddef.h> | ||
| 31 | |||
| 32 | #include <csp/dmacHw.h> | ||
| 33 | #include <mach/csp/dmacHw_reg.h> | ||
| 34 | #include <mach/csp/dmacHw_priv.h> | ||
| 35 | |||
| 36 | extern dmacHw_CBLK_t dmacHw_gCblk[dmacHw_MAX_CHANNEL_COUNT]; /* Declared in dmacHw.c */ | ||
| 37 | |||
| 38 | /* ---- External Function Prototypes ------------------------------------- */ | ||
| 39 | |||
| 40 | /* ---- Internal Use Function Prototypes --------------------------------- */ | ||
| 41 | /****************************************************************************/ | ||
| 42 | /** | ||
| 43 | * @brief Overwrites data length in the descriptor | ||
| 44 | * | ||
| 45 | * This function overwrites data length in the descriptor | ||
| 46 | * | ||
| 47 | * | ||
| 48 | * @return void | ||
| 49 | * | ||
| 50 | * @note | ||
| 51 | * This is only used for PCM channel | ||
| 52 | */ | ||
| 53 | /****************************************************************************/ | ||
| 54 | void dmacHw_setDataLength(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 55 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 56 | size_t dataLen /* [ IN ] Data length in bytes */ | ||
| 57 | ); | ||
| 58 | |||
| 59 | /****************************************************************************/ | ||
| 60 | /** | ||
| 61 | * @brief Helper function to display DMA registers | ||
| 62 | * | ||
| 63 | * @return void | ||
| 64 | * | ||
| 65 | * | ||
| 66 | * @note | ||
| 67 | * None | ||
| 68 | */ | ||
| 69 | /****************************************************************************/ | ||
| 70 | static void DisplayRegisterContents(int module, /* [ IN ] DMA Controller unit (0-1) */ | ||
| 71 | int channel, /* [ IN ] DMA Channel (0-7) / -1(all) */ | ||
| 72 | int (*fpPrint) (const char *, ...) /* [ IN ] Callback to the print function */ | ||
| 73 | ) { | ||
| 74 | int chan; | ||
| 75 | |||
| 76 | (*fpPrint) ("Displaying register content \n\n"); | ||
| 77 | (*fpPrint) ("Module %d: Interrupt raw transfer 0x%X\n", | ||
| 78 | module, (uint32_t) (dmacHw_REG_INT_RAW_TRAN(module))); | ||
| 79 | (*fpPrint) ("Module %d: Interrupt raw block 0x%X\n", | ||
| 80 | module, (uint32_t) (dmacHw_REG_INT_RAW_BLOCK(module))); | ||
| 81 | (*fpPrint) ("Module %d: Interrupt raw src transfer 0x%X\n", | ||
| 82 | module, (uint32_t) (dmacHw_REG_INT_RAW_STRAN(module))); | ||
| 83 | (*fpPrint) ("Module %d: Interrupt raw dst transfer 0x%X\n", | ||
| 84 | module, (uint32_t) (dmacHw_REG_INT_RAW_DTRAN(module))); | ||
| 85 | (*fpPrint) ("Module %d: Interrupt raw error 0x%X\n", | ||
| 86 | module, (uint32_t) (dmacHw_REG_INT_RAW_ERROR(module))); | ||
| 87 | (*fpPrint) ("--------------------------------------------------\n"); | ||
| 88 | (*fpPrint) ("Module %d: Interrupt stat transfer 0x%X\n", | ||
| 89 | module, (uint32_t) (dmacHw_REG_INT_STAT_TRAN(module))); | ||
| 90 | (*fpPrint) ("Module %d: Interrupt stat block 0x%X\n", | ||
| 91 | module, (uint32_t) (dmacHw_REG_INT_STAT_BLOCK(module))); | ||
| 92 | (*fpPrint) ("Module %d: Interrupt stat src transfer 0x%X\n", | ||
| 93 | module, (uint32_t) (dmacHw_REG_INT_STAT_STRAN(module))); | ||
| 94 | (*fpPrint) ("Module %d: Interrupt stat dst transfer 0x%X\n", | ||
| 95 | module, (uint32_t) (dmacHw_REG_INT_STAT_DTRAN(module))); | ||
| 96 | (*fpPrint) ("Module %d: Interrupt stat error 0x%X\n", | ||
| 97 | module, (uint32_t) (dmacHw_REG_INT_STAT_ERROR(module))); | ||
| 98 | (*fpPrint) ("--------------------------------------------------\n"); | ||
| 99 | (*fpPrint) ("Module %d: Interrupt mask transfer 0x%X\n", | ||
| 100 | module, (uint32_t) (dmacHw_REG_INT_MASK_TRAN(module))); | ||
| 101 | (*fpPrint) ("Module %d: Interrupt mask block 0x%X\n", | ||
| 102 | module, (uint32_t) (dmacHw_REG_INT_MASK_BLOCK(module))); | ||
| 103 | (*fpPrint) ("Module %d: Interrupt mask src transfer 0x%X\n", | ||
| 104 | module, (uint32_t) (dmacHw_REG_INT_MASK_STRAN(module))); | ||
| 105 | (*fpPrint) ("Module %d: Interrupt mask dst transfer 0x%X\n", | ||
| 106 | module, (uint32_t) (dmacHw_REG_INT_MASK_DTRAN(module))); | ||
| 107 | (*fpPrint) ("Module %d: Interrupt mask error 0x%X\n", | ||
| 108 | module, (uint32_t) (dmacHw_REG_INT_MASK_ERROR(module))); | ||
| 109 | (*fpPrint) ("--------------------------------------------------\n"); | ||
| 110 | (*fpPrint) ("Module %d: Interrupt clear transfer 0x%X\n", | ||
| 111 | module, (uint32_t) (dmacHw_REG_INT_CLEAR_TRAN(module))); | ||
| 112 | (*fpPrint) ("Module %d: Interrupt clear block 0x%X\n", | ||
| 113 | module, (uint32_t) (dmacHw_REG_INT_CLEAR_BLOCK(module))); | ||
| 114 | (*fpPrint) ("Module %d: Interrupt clear src transfer 0x%X\n", | ||
| 115 | module, (uint32_t) (dmacHw_REG_INT_CLEAR_STRAN(module))); | ||
| 116 | (*fpPrint) ("Module %d: Interrupt clear dst transfer 0x%X\n", | ||
| 117 | module, (uint32_t) (dmacHw_REG_INT_CLEAR_DTRAN(module))); | ||
| 118 | (*fpPrint) ("Module %d: Interrupt clear error 0x%X\n", | ||
| 119 | module, (uint32_t) (dmacHw_REG_INT_CLEAR_ERROR(module))); | ||
| 120 | (*fpPrint) ("--------------------------------------------------\n"); | ||
| 121 | (*fpPrint) ("Module %d: SW source req 0x%X\n", | ||
| 122 | module, (uint32_t) (dmacHw_REG_SW_HS_SRC_REQ(module))); | ||
| 123 | (*fpPrint) ("Module %d: SW dest req 0x%X\n", | ||
| 124 | module, (uint32_t) (dmacHw_REG_SW_HS_DST_REQ(module))); | ||
| 125 | (*fpPrint) ("Module %d: SW source signal 0x%X\n", | ||
| 126 | module, (uint32_t) (dmacHw_REG_SW_HS_SRC_SGL_REQ(module))); | ||
| 127 | (*fpPrint) ("Module %d: SW dest signal 0x%X\n", | ||
| 128 | module, (uint32_t) (dmacHw_REG_SW_HS_DST_SGL_REQ(module))); | ||
| 129 | (*fpPrint) ("Module %d: SW source last 0x%X\n", | ||
| 130 | module, (uint32_t) (dmacHw_REG_SW_HS_SRC_LST_REQ(module))); | ||
| 131 | (*fpPrint) ("Module %d: SW dest last 0x%X\n", | ||
| 132 | module, (uint32_t) (dmacHw_REG_SW_HS_DST_LST_REQ(module))); | ||
| 133 | (*fpPrint) ("--------------------------------------------------\n"); | ||
| 134 | (*fpPrint) ("Module %d: misc config 0x%X\n", | ||
| 135 | module, (uint32_t) (dmacHw_REG_MISC_CFG(module))); | ||
| 136 | (*fpPrint) ("Module %d: misc channel enable 0x%X\n", | ||
| 137 | module, (uint32_t) (dmacHw_REG_MISC_CH_ENABLE(module))); | ||
| 138 | (*fpPrint) ("Module %d: misc ID 0x%X\n", | ||
| 139 | module, (uint32_t) (dmacHw_REG_MISC_ID(module))); | ||
| 140 | (*fpPrint) ("Module %d: misc test 0x%X\n", | ||
| 141 | module, (uint32_t) (dmacHw_REG_MISC_TEST(module))); | ||
| 142 | |||
| 143 | if (channel == -1) { | ||
| 144 | for (chan = 0; chan < 8; chan++) { | ||
| 145 | (*fpPrint) | ||
| 146 | ("--------------------------------------------------\n"); | ||
| 147 | (*fpPrint) | ||
| 148 | ("Module %d: Channel %d Source 0x%X\n", | ||
| 149 | module, chan, | ||
| 150 | (uint32_t) (dmacHw_REG_SAR(module, chan))); | ||
| 151 | (*fpPrint) | ||
| 152 | ("Module %d: Channel %d Destination 0x%X\n", | ||
| 153 | module, chan, | ||
| 154 | (uint32_t) (dmacHw_REG_DAR(module, chan))); | ||
| 155 | (*fpPrint) | ||
| 156 | ("Module %d: Channel %d LLP 0x%X\n", | ||
| 157 | module, chan, | ||
| 158 | (uint32_t) (dmacHw_REG_LLP(module, chan))); | ||
| 159 | (*fpPrint) | ||
| 160 | ("Module %d: Channel %d Control (LO) 0x%X\n", | ||
| 161 | module, chan, | ||
| 162 | (uint32_t) (dmacHw_REG_CTL_LO(module, chan))); | ||
| 163 | (*fpPrint) | ||
| 164 | ("Module %d: Channel %d Control (HI) 0x%X\n", | ||
| 165 | module, chan, | ||
| 166 | (uint32_t) (dmacHw_REG_CTL_HI(module, chan))); | ||
| 167 | (*fpPrint) | ||
| 168 | ("Module %d: Channel %d Source Stats 0x%X\n", | ||
| 169 | module, chan, | ||
| 170 | (uint32_t) (dmacHw_REG_SSTAT(module, chan))); | ||
| 171 | (*fpPrint) | ||
| 172 | ("Module %d: Channel %d Dest Stats 0x%X\n", | ||
| 173 | module, chan, | ||
| 174 | (uint32_t) (dmacHw_REG_DSTAT(module, chan))); | ||
| 175 | (*fpPrint) | ||
| 176 | ("Module %d: Channel %d Source Stats Addr 0x%X\n", | ||
| 177 | module, chan, | ||
| 178 | (uint32_t) (dmacHw_REG_SSTATAR(module, chan))); | ||
| 179 | (*fpPrint) | ||
| 180 | ("Module %d: Channel %d Dest Stats Addr 0x%X\n", | ||
| 181 | module, chan, | ||
| 182 | (uint32_t) (dmacHw_REG_DSTATAR(module, chan))); | ||
| 183 | (*fpPrint) | ||
| 184 | ("Module %d: Channel %d Config (LO) 0x%X\n", | ||
| 185 | module, chan, | ||
| 186 | (uint32_t) (dmacHw_REG_CFG_LO(module, chan))); | ||
| 187 | (*fpPrint) | ||
| 188 | ("Module %d: Channel %d Config (HI) 0x%X\n", | ||
| 189 | module, chan, | ||
| 190 | (uint32_t) (dmacHw_REG_CFG_HI(module, chan))); | ||
| 191 | } | ||
| 192 | } else { | ||
| 193 | chan = channel; | ||
| 194 | (*fpPrint) | ||
| 195 | ("--------------------------------------------------\n"); | ||
| 196 | (*fpPrint) | ||
| 197 | ("Module %d: Channel %d Source 0x%X\n", | ||
| 198 | module, chan, (uint32_t) (dmacHw_REG_SAR(module, chan))); | ||
| 199 | (*fpPrint) | ||
| 200 | ("Module %d: Channel %d Destination 0x%X\n", | ||
| 201 | module, chan, (uint32_t) (dmacHw_REG_DAR(module, chan))); | ||
| 202 | (*fpPrint) | ||
| 203 | ("Module %d: Channel %d LLP 0x%X\n", | ||
| 204 | module, chan, (uint32_t) (dmacHw_REG_LLP(module, chan))); | ||
| 205 | (*fpPrint) | ||
| 206 | ("Module %d: Channel %d Control (LO) 0x%X\n", | ||
| 207 | module, chan, | ||
| 208 | (uint32_t) (dmacHw_REG_CTL_LO(module, chan))); | ||
| 209 | (*fpPrint) | ||
| 210 | ("Module %d: Channel %d Control (HI) 0x%X\n", | ||
| 211 | module, chan, | ||
| 212 | (uint32_t) (dmacHw_REG_CTL_HI(module, chan))); | ||
| 213 | (*fpPrint) | ||
| 214 | ("Module %d: Channel %d Source Stats 0x%X\n", | ||
| 215 | module, chan, (uint32_t) (dmacHw_REG_SSTAT(module, chan))); | ||
| 216 | (*fpPrint) | ||
| 217 | ("Module %d: Channel %d Dest Stats 0x%X\n", | ||
| 218 | module, chan, (uint32_t) (dmacHw_REG_DSTAT(module, chan))); | ||
| 219 | (*fpPrint) | ||
| 220 | ("Module %d: Channel %d Source Stats Addr 0x%X\n", | ||
| 221 | module, chan, | ||
| 222 | (uint32_t) (dmacHw_REG_SSTATAR(module, chan))); | ||
| 223 | (*fpPrint) | ||
| 224 | ("Module %d: Channel %d Dest Stats Addr 0x%X\n", | ||
| 225 | module, chan, | ||
| 226 | (uint32_t) (dmacHw_REG_DSTATAR(module, chan))); | ||
| 227 | (*fpPrint) | ||
| 228 | ("Module %d: Channel %d Config (LO) 0x%X\n", | ||
| 229 | module, chan, | ||
| 230 | (uint32_t) (dmacHw_REG_CFG_LO(module, chan))); | ||
| 231 | (*fpPrint) | ||
| 232 | ("Module %d: Channel %d Config (HI) 0x%X\n", | ||
| 233 | module, chan, | ||
| 234 | (uint32_t) (dmacHw_REG_CFG_HI(module, chan))); | ||
| 235 | } | ||
| 236 | } | ||
| 237 | |||
| 238 | /****************************************************************************/ | ||
| 239 | /** | ||
| 240 | * @brief Helper function to display descriptor ring | ||
| 241 | * | ||
| 242 | * @return void | ||
| 243 | * | ||
| 244 | * | ||
| 245 | * @note | ||
| 246 | * None | ||
| 247 | */ | ||
| 248 | /****************************************************************************/ | ||
| 249 | static void DisplayDescRing(void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 250 | int (*fpPrint) (const char *, ...) /* [ IN ] Callback to the print function */ | ||
| 251 | ) { | ||
| 252 | dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor); | ||
| 253 | dmacHw_DESC_t *pStart; | ||
| 254 | |||
| 255 | if (pRing->pHead == NULL) { | ||
| 256 | return; | ||
| 257 | } | ||
| 258 | |||
| 259 | pStart = pRing->pHead; | ||
| 260 | |||
| 261 | while ((dmacHw_DESC_t *) pStart->llp != pRing->pHead) { | ||
| 262 | if (pStart == pRing->pHead) { | ||
| 263 | (*fpPrint) ("Head\n"); | ||
| 264 | } | ||
| 265 | if (pStart == pRing->pTail) { | ||
| 266 | (*fpPrint) ("Tail\n"); | ||
| 267 | } | ||
| 268 | if (pStart == pRing->pProg) { | ||
| 269 | (*fpPrint) ("Prog\n"); | ||
| 270 | } | ||
| 271 | if (pStart == pRing->pEnd) { | ||
| 272 | (*fpPrint) ("End\n"); | ||
| 273 | } | ||
| 274 | if (pStart == pRing->pFree) { | ||
| 275 | (*fpPrint) ("Free\n"); | ||
| 276 | } | ||
| 277 | (*fpPrint) ("0x%X:\n", (uint32_t) pStart); | ||
| 278 | (*fpPrint) ("sar 0x%0X\n", pStart->sar); | ||
| 279 | (*fpPrint) ("dar 0x%0X\n", pStart->dar); | ||
| 280 | (*fpPrint) ("llp 0x%0X\n", pStart->llp); | ||
| 281 | (*fpPrint) ("ctl.lo 0x%0X\n", pStart->ctl.lo); | ||
| 282 | (*fpPrint) ("ctl.hi 0x%0X\n", pStart->ctl.hi); | ||
| 283 | (*fpPrint) ("sstat 0x%0X\n", pStart->sstat); | ||
| 284 | (*fpPrint) ("dstat 0x%0X\n", pStart->dstat); | ||
| 285 | (*fpPrint) ("devCtl 0x%0X\n", pStart->devCtl); | ||
| 286 | |||
| 287 | pStart = (dmacHw_DESC_t *) pStart->llp; | ||
| 288 | } | ||
| 289 | if (pStart == pRing->pHead) { | ||
| 290 | (*fpPrint) ("Head\n"); | ||
| 291 | } | ||
| 292 | if (pStart == pRing->pTail) { | ||
| 293 | (*fpPrint) ("Tail\n"); | ||
| 294 | } | ||
| 295 | if (pStart == pRing->pProg) { | ||
| 296 | (*fpPrint) ("Prog\n"); | ||
| 297 | } | ||
| 298 | if (pStart == pRing->pEnd) { | ||
| 299 | (*fpPrint) ("End\n"); | ||
| 300 | } | ||
| 301 | if (pStart == pRing->pFree) { | ||
| 302 | (*fpPrint) ("Free\n"); | ||
| 303 | } | ||
| 304 | (*fpPrint) ("0x%X:\n", (uint32_t) pStart); | ||
| 305 | (*fpPrint) ("sar 0x%0X\n", pStart->sar); | ||
| 306 | (*fpPrint) ("dar 0x%0X\n", pStart->dar); | ||
| 307 | (*fpPrint) ("llp 0x%0X\n", pStart->llp); | ||
| 308 | (*fpPrint) ("ctl.lo 0x%0X\n", pStart->ctl.lo); | ||
| 309 | (*fpPrint) ("ctl.hi 0x%0X\n", pStart->ctl.hi); | ||
| 310 | (*fpPrint) ("sstat 0x%0X\n", pStart->sstat); | ||
| 311 | (*fpPrint) ("dstat 0x%0X\n", pStart->dstat); | ||
| 312 | (*fpPrint) ("devCtl 0x%0X\n", pStart->devCtl); | ||
| 313 | } | ||
| 314 | |||
| 315 | /****************************************************************************/ | ||
| 316 | /** | ||
| 317 | * @brief Check if DMA channel is the flow controller | ||
| 318 | * | ||
| 319 | * @return 1 : If DMA is a flow controler | ||
| 320 | * 0 : Peripheral is the flow controller | ||
| 321 | * | ||
| 322 | * @note | ||
| 323 | * None | ||
| 324 | */ | ||
| 325 | /****************************************************************************/ | ||
| 326 | static inline int DmaIsFlowController(void *pDescriptor /* [ IN ] Descriptor buffer */ | ||
| 327 | ) { | ||
| 328 | uint32_t ttfc = | ||
| 329 | (dmacHw_GET_DESC_RING(pDescriptor))->pTail->ctl. | ||
| 330 | lo & dmacHw_REG_CTL_TTFC_MASK; | ||
| 331 | |||
| 332 | switch (ttfc) { | ||
| 333 | case dmacHw_REG_CTL_TTFC_MM_DMAC: | ||
| 334 | case dmacHw_REG_CTL_TTFC_MP_DMAC: | ||
| 335 | case dmacHw_REG_CTL_TTFC_PM_DMAC: | ||
| 336 | case dmacHw_REG_CTL_TTFC_PP_DMAC: | ||
| 337 | return 1; | ||
| 338 | } | ||
| 339 | |||
| 340 | return 0; | ||
| 341 | } | ||
| 342 | |||
| 343 | /****************************************************************************/ | ||
| 344 | /** | ||
| 345 | * @brief Overwrites data length in the descriptor | ||
| 346 | * | ||
| 347 | * This function overwrites data length in the descriptor | ||
| 348 | * | ||
| 349 | * | ||
| 350 | * @return void | ||
| 351 | * | ||
| 352 | * @note | ||
| 353 | * This is only used for PCM channel | ||
| 354 | */ | ||
| 355 | /****************************************************************************/ | ||
| 356 | void dmacHw_setDataLength(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 357 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 358 | size_t dataLen /* [ IN ] Data length in bytes */ | ||
| 359 | ) { | ||
| 360 | dmacHw_DESC_t *pProg; | ||
| 361 | dmacHw_DESC_t *pHead; | ||
| 362 | int srcTs = 0; | ||
| 363 | int srcTrSize = 0; | ||
| 364 | |||
| 365 | pHead = (dmacHw_GET_DESC_RING(pDescriptor))->pHead; | ||
| 366 | pProg = pHead; | ||
| 367 | |||
| 368 | srcTrSize = dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth); | ||
| 369 | srcTs = dataLen / srcTrSize; | ||
| 370 | do { | ||
| 371 | pProg->ctl.hi = srcTs & dmacHw_REG_CTL_BLOCK_TS_MASK; | ||
| 372 | pProg = (dmacHw_DESC_t *) pProg->llp; | ||
| 373 | } while (pProg != pHead); | ||
| 374 | } | ||
| 375 | |||
| 376 | /****************************************************************************/ | ||
| 377 | /** | ||
| 378 | * @brief Clears the interrupt | ||
| 379 | * | ||
| 380 | * This function clears the DMA channel specific interrupt | ||
| 381 | * | ||
| 382 | * | ||
| 383 | * @return void | ||
| 384 | * | ||
| 385 | * @note | ||
| 386 | * Must be called under the context of ISR | ||
| 387 | */ | ||
| 388 | /****************************************************************************/ | ||
| 389 | void dmacHw_clearInterrupt(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */ | ||
| 390 | ) { | ||
| 391 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 392 | |||
| 393 | dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel); | ||
| 394 | dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel); | ||
| 395 | dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel); | ||
| 396 | } | ||
| 397 | |||
| 398 | /****************************************************************************/ | ||
| 399 | /** | ||
| 400 | * @brief Returns the cause of channel specific DMA interrupt | ||
| 401 | * | ||
| 402 | * This function returns the cause of interrupt | ||
| 403 | * | ||
| 404 | * @return Interrupt status, each bit representing a specific type of interrupt | ||
| 405 | * | ||
| 406 | * @note | ||
| 407 | * Should be called under the context of ISR | ||
| 408 | */ | ||
| 409 | /****************************************************************************/ | ||
| 410 | dmacHw_INTERRUPT_STATUS_e dmacHw_getInterruptStatus(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */ | ||
| 411 | ) { | ||
| 412 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 413 | dmacHw_INTERRUPT_STATUS_e status = dmacHw_INTERRUPT_STATUS_NONE; | ||
| 414 | |||
| 415 | if (dmacHw_REG_INT_STAT_TRAN(pCblk->module) & | ||
| 416 | ((0x00000001 << pCblk->channel))) { | ||
| 417 | status |= dmacHw_INTERRUPT_STATUS_TRANS; | ||
| 418 | } | ||
| 419 | if (dmacHw_REG_INT_STAT_BLOCK(pCblk->module) & | ||
| 420 | ((0x00000001 << pCblk->channel))) { | ||
| 421 | status |= dmacHw_INTERRUPT_STATUS_BLOCK; | ||
| 422 | } | ||
| 423 | if (dmacHw_REG_INT_STAT_ERROR(pCblk->module) & | ||
| 424 | ((0x00000001 << pCblk->channel))) { | ||
| 425 | status |= dmacHw_INTERRUPT_STATUS_ERROR; | ||
| 426 | } | ||
| 427 | |||
| 428 | return status; | ||
| 429 | } | ||
| 430 | |||
| 431 | /****************************************************************************/ | ||
| 432 | /** | ||
| 433 | * @brief Indentifies a DMA channel causing interrupt | ||
| 434 | * | ||
| 435 | * This functions returns a channel causing interrupt of type dmacHw_INTERRUPT_STATUS_e | ||
| 436 | * | ||
| 437 | * @return NULL : No channel causing DMA interrupt | ||
| 438 | * ! NULL : Handle to a channel causing DMA interrupt | ||
| 439 | * @note | ||
| 440 | * dmacHw_clearInterrupt() must be called with a valid handle after calling this function | ||
| 441 | */ | ||
| 442 | /****************************************************************************/ | ||
| 443 | dmacHw_HANDLE_t dmacHw_getInterruptSource(void) | ||
| 444 | { | ||
| 445 | uint32_t i; | ||
| 446 | |||
| 447 | for (i = 0; i < dmaChannelCount_0 + dmaChannelCount_1; i++) { | ||
| 448 | if ((dmacHw_REG_INT_STAT_TRAN(dmacHw_gCblk[i].module) & | ||
| 449 | ((0x00000001 << dmacHw_gCblk[i].channel))) | ||
| 450 | || (dmacHw_REG_INT_STAT_BLOCK(dmacHw_gCblk[i].module) & | ||
| 451 | ((0x00000001 << dmacHw_gCblk[i].channel))) | ||
| 452 | || (dmacHw_REG_INT_STAT_ERROR(dmacHw_gCblk[i].module) & | ||
| 453 | ((0x00000001 << dmacHw_gCblk[i].channel))) | ||
| 454 | ) { | ||
| 455 | return dmacHw_CBLK_TO_HANDLE(&dmacHw_gCblk[i]); | ||
| 456 | } | ||
| 457 | } | ||
| 458 | return dmacHw_CBLK_TO_HANDLE(NULL); | ||
| 459 | } | ||
| 460 | |||
| 461 | /****************************************************************************/ | ||
| 462 | /** | ||
| 463 | * @brief Estimates number of descriptor needed to perform certain DMA transfer | ||
| 464 | * | ||
| 465 | * | ||
| 466 | * @return On failure : -1 | ||
| 467 | * On success : Number of descriptor count | ||
| 468 | * | ||
| 469 | * | ||
| 470 | */ | ||
| 471 | /****************************************************************************/ | ||
| 472 | int dmacHw_calculateDescriptorCount(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 473 | void *pSrcAddr, /* [ IN ] Source (Peripheral/Memory) address */ | ||
| 474 | void *pDstAddr, /* [ IN ] Destination (Peripheral/Memory) address */ | ||
| 475 | size_t dataLen /* [ IN ] Data length in bytes */ | ||
| 476 | ) { | ||
| 477 | int srcTs = 0; | ||
| 478 | int oddSize = 0; | ||
| 479 | int descCount = 0; | ||
| 480 | int dstTrSize = 0; | ||
| 481 | int srcTrSize = 0; | ||
| 482 | uint32_t maxBlockSize = dmacHw_MAX_BLOCKSIZE; | ||
| 483 | dmacHw_TRANSACTION_WIDTH_e dstTrWidth; | ||
| 484 | dmacHw_TRANSACTION_WIDTH_e srcTrWidth; | ||
| 485 | |||
| 486 | dstTrSize = dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth); | ||
| 487 | srcTrSize = dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth); | ||
| 488 | |||
| 489 | /* Skip Tx if buffer is NULL or length is unknown */ | ||
| 490 | if ((pSrcAddr == NULL) || (pDstAddr == NULL) || (dataLen == 0)) { | ||
| 491 | /* Do not initiate transfer */ | ||
| 492 | return -1; | ||
| 493 | } | ||
| 494 | |||
| 495 | /* Ensure scatter and gather are transaction aligned */ | ||
| 496 | if (pConfig->srcGatherWidth % srcTrSize | ||
| 497 | || pConfig->dstScatterWidth % dstTrSize) { | ||
| 498 | return -1; | ||
| 499 | } | ||
| 500 | |||
| 501 | /* | ||
| 502 | Background 1: DMAC can not perform DMA if source and destination addresses are | ||
| 503 | not properly aligned with the channel's transaction width. So, for successful | ||
| 504 | DMA transfer, transaction width must be set according to the alignment of the | ||
| 505 | source and destination address. | ||
| 506 | */ | ||
| 507 | |||
| 508 | /* Adjust destination transaction width if destination address is not aligned properly */ | ||
| 509 | dstTrWidth = pConfig->dstMaxTransactionWidth; | ||
| 510 | while (dmacHw_ADDRESS_MASK(dstTrSize) & (uint32_t) pDstAddr) { | ||
| 511 | dstTrWidth = dmacHw_GetNextTrWidth(dstTrWidth); | ||
| 512 | dstTrSize = dmacHw_GetTrWidthInBytes(dstTrWidth); | ||
| 513 | } | ||
| 514 | |||
| 515 | /* Adjust source transaction width if source address is not aligned properly */ | ||
| 516 | srcTrWidth = pConfig->srcMaxTransactionWidth; | ||
| 517 | while (dmacHw_ADDRESS_MASK(srcTrSize) & (uint32_t) pSrcAddr) { | ||
| 518 | srcTrWidth = dmacHw_GetNextTrWidth(srcTrWidth); | ||
| 519 | srcTrSize = dmacHw_GetTrWidthInBytes(srcTrWidth); | ||
| 520 | } | ||
| 521 | |||
| 522 | /* Find the maximum transaction per descriptor */ | ||
| 523 | if (pConfig->maxDataPerBlock | ||
| 524 | && ((pConfig->maxDataPerBlock / srcTrSize) < | ||
| 525 | dmacHw_MAX_BLOCKSIZE)) { | ||
| 526 | maxBlockSize = pConfig->maxDataPerBlock / srcTrSize; | ||
| 527 | } | ||
| 528 | |||
| 529 | /* Find number of source transactions needed to complete the DMA transfer */ | ||
| 530 | srcTs = dataLen / srcTrSize; | ||
| 531 | /* Find the odd number of bytes that need to be transferred as single byte transaction width */ | ||
| 532 | if (srcTs && (dstTrSize > srcTrSize)) { | ||
| 533 | oddSize = dataLen % dstTrSize; | ||
| 534 | /* Adjust source transaction count due to "oddSize" */ | ||
| 535 | srcTs = srcTs - (oddSize / srcTrSize); | ||
| 536 | } else { | ||
| 537 | oddSize = dataLen % srcTrSize; | ||
| 538 | } | ||
| 539 | /* Adjust "descCount" due to "oddSize" */ | ||
| 540 | if (oddSize) { | ||
| 541 | descCount++; | ||
| 542 | } | ||
| 543 | |||
| 544 | /* Find the number of descriptor needed for total "srcTs" */ | ||
| 545 | if (srcTs) { | ||
| 546 | descCount += ((srcTs - 1) / maxBlockSize) + 1; | ||
| 547 | } | ||
| 548 | |||
| 549 | return descCount; | ||
| 550 | } | ||
| 551 | |||
| 552 | /****************************************************************************/ | ||
| 553 | /** | ||
| 554 | * @brief Check the existance of pending descriptor | ||
| 555 | * | ||
| 556 | * This function confirmes if there is any pending descriptor in the chain | ||
| 557 | * to program the channel | ||
| 558 | * | ||
| 559 | * @return 1 : Channel need to be programmed with pending descriptor | ||
| 560 | * 0 : No more pending descriptor to programe the channel | ||
| 561 | * | ||
| 562 | * @note | ||
| 563 | * - This function should be called from ISR in case there are pending | ||
| 564 | * descriptor to program the channel. | ||
| 565 | * | ||
| 566 | * Example: | ||
| 567 | * | ||
| 568 | * dmac_isr () | ||
| 569 | * { | ||
| 570 | * ... | ||
| 571 | * if (dmacHw_descriptorPending (handle)) | ||
| 572 | * { | ||
| 573 | * dmacHw_initiateTransfer (handle); | ||
| 574 | * } | ||
| 575 | * } | ||
| 576 | * | ||
| 577 | */ | ||
| 578 | /****************************************************************************/ | ||
| 579 | uint32_t dmacHw_descriptorPending(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 580 | void *pDescriptor /* [ IN ] Descriptor buffer */ | ||
| 581 | ) { | ||
| 582 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 583 | dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor); | ||
| 584 | |||
| 585 | /* Make sure channel is not busy */ | ||
| 586 | if (!CHANNEL_BUSY(pCblk->module, pCblk->channel)) { | ||
| 587 | /* Check if pEnd is not processed */ | ||
| 588 | if (pRing->pEnd) { | ||
| 589 | /* Something left for processing */ | ||
| 590 | return 1; | ||
| 591 | } | ||
| 592 | } | ||
| 593 | return 0; | ||
| 594 | } | ||
| 595 | |||
| 596 | /****************************************************************************/ | ||
| 597 | /** | ||
| 598 | * @brief Program channel register to stop transfer | ||
| 599 | * | ||
| 600 | * Ensures the channel is not doing any transfer after calling this function | ||
| 601 | * | ||
| 602 | * @return void | ||
| 603 | * | ||
| 604 | */ | ||
| 605 | /****************************************************************************/ | ||
| 606 | void dmacHw_stopTransfer(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */ | ||
| 607 | ) { | ||
| 608 | dmacHw_CBLK_t *pCblk; | ||
| 609 | |||
| 610 | pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 611 | |||
| 612 | /* Stop the channel */ | ||
| 613 | dmacHw_DMA_STOP(pCblk->module, pCblk->channel); | ||
| 614 | } | ||
| 615 | |||
| 616 | /****************************************************************************/ | ||
| 617 | /** | ||
| 618 | * @brief Deallocates source or destination memory, allocated | ||
| 619 | * | ||
| 620 | * This function can be called to deallocate data memory that was DMAed successfully | ||
| 621 | * | ||
| 622 | * @return On failure : -1 | ||
| 623 | * On success : Number of buffer freed | ||
| 624 | * | ||
| 625 | * @note | ||
| 626 | * This function will be called ONLY, when source OR destination address is pointing | ||
| 627 | * to dynamic memory | ||
| 628 | */ | ||
| 629 | /****************************************************************************/ | ||
| 630 | int dmacHw_freeMem(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 631 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 632 | void (*fpFree) (void *) /* [ IN ] Function pointer to free data memory */ | ||
| 633 | ) { | ||
| 634 | dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor); | ||
| 635 | uint32_t count = 0; | ||
| 636 | |||
| 637 | if (fpFree == NULL) { | ||
| 638 | return -1; | ||
| 639 | } | ||
| 640 | |||
| 641 | while ((pRing->pFree != pRing->pTail) | ||
| 642 | && (pRing->pFree->ctl.lo & dmacHw_DESC_FREE)) { | ||
| 643 | if (pRing->pFree->devCtl == dmacHw_FREE_USER_MEMORY) { | ||
| 644 | /* Identify, which memory to free */ | ||
| 645 | if (dmacHw_DST_IS_MEMORY(pConfig->transferType)) { | ||
| 646 | (*fpFree) ((void *)pRing->pFree->dar); | ||
| 647 | } else { | ||
| 648 | /* Destination was a peripheral */ | ||
| 649 | (*fpFree) ((void *)pRing->pFree->sar); | ||
| 650 | } | ||
| 651 | /* Unmark user memory to indicate it is freed */ | ||
| 652 | pRing->pFree->devCtl = ~dmacHw_FREE_USER_MEMORY; | ||
| 653 | } | ||
| 654 | dmacHw_NEXT_DESC(pRing, pFree); | ||
| 655 | |||
| 656 | count++; | ||
| 657 | } | ||
| 658 | |||
| 659 | return count; | ||
| 660 | } | ||
| 661 | |||
| 662 | /****************************************************************************/ | ||
| 663 | /** | ||
| 664 | * @brief Prepares descriptor ring, when source peripheral working as a flow controller | ||
| 665 | * | ||
| 666 | * This function will update the discriptor ring by allocating buffers, when source peripheral | ||
| 667 | * has to work as a flow controller to transfer data from: | ||
| 668 | * - Peripheral to memory. | ||
| 669 | * | ||
| 670 | * @return On failure : -1 | ||
| 671 | * On success : Number of descriptor updated | ||
| 672 | * | ||
| 673 | * | ||
| 674 | * @note | ||
| 675 | * Channel must be configured for peripheral to memory transfer | ||
| 676 | * | ||
| 677 | */ | ||
| 678 | /****************************************************************************/ | ||
| 679 | int dmacHw_setVariableDataDescriptor(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 680 | dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 681 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 682 | uint32_t srcAddr, /* [ IN ] Source peripheral address */ | ||
| 683 | void *(*fpAlloc) (int len), /* [ IN ] Function pointer that provides destination memory */ | ||
| 684 | int len, /* [ IN ] Number of bytes "fpAlloc" will allocate for destination */ | ||
| 685 | int num /* [ IN ] Number of descriptor to set */ | ||
| 686 | ) { | ||
| 687 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 688 | dmacHw_DESC_t *pProg = NULL; | ||
| 689 | dmacHw_DESC_t *pLast = NULL; | ||
| 690 | dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor); | ||
| 691 | uint32_t dstAddr; | ||
| 692 | uint32_t controlParam; | ||
| 693 | int i; | ||
| 694 | |||
| 695 | dmacHw_ASSERT(pConfig->transferType == | ||
| 696 | dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM); | ||
| 697 | |||
| 698 | if (num > pRing->num) { | ||
| 699 | return -1; | ||
| 700 | } | ||
| 701 | |||
| 702 | pLast = pRing->pEnd; /* Last descriptor updated */ | ||
| 703 | pProg = pRing->pHead; /* First descriptor in the new list */ | ||
| 704 | |||
| 705 | controlParam = pConfig->srcUpdate | | ||
| 706 | pConfig->dstUpdate | | ||
| 707 | pConfig->srcMaxTransactionWidth | | ||
| 708 | pConfig->dstMaxTransactionWidth | | ||
| 709 | pConfig->srcMasterInterface | | ||
| 710 | pConfig->dstMasterInterface | | ||
| 711 | pConfig->srcMaxBurstWidth | | ||
| 712 | pConfig->dstMaxBurstWidth | | ||
| 713 | dmacHw_REG_CTL_TTFC_PM_PERI | | ||
| 714 | dmacHw_REG_CTL_LLP_DST_EN | | ||
| 715 | dmacHw_REG_CTL_LLP_SRC_EN | dmacHw_REG_CTL_INT_EN; | ||
| 716 | |||
| 717 | for (i = 0; i < num; i++) { | ||
| 718 | /* Allocate Rx buffer only for idle descriptor */ | ||
| 719 | if (((pRing->pHead->ctl.hi & dmacHw_DESC_FREE) == 0) || | ||
| 720 | ((dmacHw_DESC_t *) pRing->pHead->llp == pRing->pTail) | ||
| 721 | ) { | ||
| 722 | /* Rx descriptor is not idle */ | ||
| 723 | break; | ||
| 724 | } | ||
| 725 | /* Set source address */ | ||
| 726 | pRing->pHead->sar = srcAddr; | ||
| 727 | if (fpAlloc) { | ||
| 728 | /* Allocate memory for buffer in descriptor */ | ||
| 729 | dstAddr = (uint32_t) (*fpAlloc) (len); | ||
| 730 | /* Check the destination address */ | ||
| 731 | if (dstAddr == 0) { | ||
| 732 | if (i == 0) { | ||
| 733 | /* Not a single descriptor is available */ | ||
| 734 | return -1; | ||
| 735 | } | ||
| 736 | break; | ||
| 737 | } | ||
| 738 | /* Set destination address */ | ||
| 739 | pRing->pHead->dar = dstAddr; | ||
| 740 | } | ||
| 741 | /* Set control information */ | ||
| 742 | pRing->pHead->ctl.lo = controlParam; | ||
| 743 | /* Use "devCtl" to mark the memory that need to be freed later */ | ||
| 744 | pRing->pHead->devCtl = dmacHw_FREE_USER_MEMORY; | ||
| 745 | /* Descriptor is now owned by the channel */ | ||
| 746 | pRing->pHead->ctl.hi = 0; | ||
| 747 | /* Remember the descriptor last updated */ | ||
| 748 | pRing->pEnd = pRing->pHead; | ||
| 749 | /* Update next descriptor */ | ||
| 750 | dmacHw_NEXT_DESC(pRing, pHead); | ||
| 751 | } | ||
| 752 | |||
| 753 | /* Mark the end of the list */ | ||
| 754 | pRing->pEnd->ctl.lo &= | ||
| 755 | ~(dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN); | ||
| 756 | /* Connect the list */ | ||
| 757 | if (pLast != pProg) { | ||
| 758 | pLast->ctl.lo |= | ||
| 759 | dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN; | ||
| 760 | } | ||
| 761 | /* Mark the descriptors are updated */ | ||
| 762 | pCblk->descUpdated = 1; | ||
| 763 | if (!pCblk->varDataStarted) { | ||
| 764 | /* LLP must be pointing to the first descriptor */ | ||
| 765 | dmacHw_SET_LLP(pCblk->module, pCblk->channel, | ||
| 766 | (uint32_t) pProg - pRing->virt2PhyOffset); | ||
| 767 | /* Channel, handling variable data started */ | ||
| 768 | pCblk->varDataStarted = 1; | ||
| 769 | } | ||
| 770 | |||
| 771 | return i; | ||
| 772 | } | ||
| 773 | |||
| 774 | /****************************************************************************/ | ||
| 775 | /** | ||
| 776 | * @brief Read data DMAed to memory | ||
| 777 | * | ||
| 778 | * This function will read data that has been DMAed to memory while transfering from: | ||
| 779 | * - Memory to memory | ||
| 780 | * - Peripheral to memory | ||
| 781 | * | ||
| 782 | * @param handle - | ||
| 783 | * @param ppBbuf - | ||
| 784 | * @param pLen - | ||
| 785 | * | ||
| 786 | * @return 0 - No more data is available to read | ||
| 787 | * 1 - More data might be available to read | ||
| 788 | * | ||
| 789 | */ | ||
| 790 | /****************************************************************************/ | ||
| 791 | int dmacHw_readTransferredData(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 792 | dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 793 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 794 | void **ppBbuf, /* [ OUT ] Data received */ | ||
| 795 | size_t *pLlen /* [ OUT ] Length of the data received */ | ||
| 796 | ) { | ||
| 797 | dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor); | ||
| 798 | |||
| 799 | (void)handle; | ||
| 800 | |||
| 801 | if (pConfig->transferMode != dmacHw_TRANSFER_MODE_CONTINUOUS) { | ||
| 802 | if (((pRing->pTail->ctl.hi & dmacHw_DESC_FREE) == 0) || | ||
| 803 | (pRing->pTail == pRing->pHead) | ||
| 804 | ) { | ||
| 805 | /* No receive data available */ | ||
| 806 | *ppBbuf = (char *)NULL; | ||
| 807 | *pLlen = 0; | ||
| 808 | |||
| 809 | return 0; | ||
| 810 | } | ||
| 811 | } | ||
| 812 | |||
| 813 | /* Return read buffer and length */ | ||
| 814 | *ppBbuf = (char *)pRing->pTail->dar; | ||
| 815 | |||
| 816 | /* Extract length of the received data */ | ||
| 817 | if (DmaIsFlowController(pDescriptor)) { | ||
| 818 | uint32_t srcTrSize = 0; | ||
| 819 | |||
| 820 | switch (pRing->pTail->ctl.lo & dmacHw_REG_CTL_SRC_TR_WIDTH_MASK) { | ||
| 821 | case dmacHw_REG_CTL_SRC_TR_WIDTH_8: | ||
| 822 | srcTrSize = 1; | ||
| 823 | break; | ||
| 824 | case dmacHw_REG_CTL_SRC_TR_WIDTH_16: | ||
| 825 | srcTrSize = 2; | ||
| 826 | break; | ||
| 827 | case dmacHw_REG_CTL_SRC_TR_WIDTH_32: | ||
| 828 | srcTrSize = 4; | ||
| 829 | break; | ||
| 830 | case dmacHw_REG_CTL_SRC_TR_WIDTH_64: | ||
| 831 | srcTrSize = 8; | ||
| 832 | break; | ||
| 833 | default: | ||
| 834 | dmacHw_ASSERT(0); | ||
| 835 | } | ||
| 836 | /* Calculate length from the block size */ | ||
| 837 | *pLlen = | ||
| 838 | (pRing->pTail->ctl.hi & dmacHw_REG_CTL_BLOCK_TS_MASK) * | ||
| 839 | srcTrSize; | ||
| 840 | } else { | ||
| 841 | /* Extract length from the source peripheral */ | ||
| 842 | *pLlen = pRing->pTail->sstat; | ||
| 843 | } | ||
| 844 | |||
| 845 | /* Advance tail to next descriptor */ | ||
| 846 | dmacHw_NEXT_DESC(pRing, pTail); | ||
| 847 | |||
| 848 | return 1; | ||
| 849 | } | ||
| 850 | |||
| 851 | /****************************************************************************/ | ||
| 852 | /** | ||
| 853 | * @brief Set descriptor carrying control information | ||
| 854 | * | ||
| 855 | * This function will be used to send specific control information to the device | ||
| 856 | * using the DMA channel | ||
| 857 | * | ||
| 858 | * | ||
| 859 | * @return -1 - On failure | ||
| 860 | * 0 - On success | ||
| 861 | * | ||
| 862 | * @note | ||
| 863 | * None | ||
| 864 | */ | ||
| 865 | /****************************************************************************/ | ||
| 866 | int dmacHw_setControlDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 867 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 868 | uint32_t ctlAddress, /* [ IN ] Address of the device control register */ | ||
| 869 | uint32_t control /* [ IN ] Device control information */ | ||
| 870 | ) { | ||
| 871 | dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor); | ||
| 872 | |||
| 873 | if (ctlAddress == 0) { | ||
| 874 | return -1; | ||
| 875 | } | ||
| 876 | |||
| 877 | /* Check the availability of descriptors in the ring */ | ||
| 878 | if ((pRing->pHead->ctl.hi & dmacHw_DESC_FREE) == 0) { | ||
| 879 | return -1; | ||
| 880 | } | ||
| 881 | /* Set control information */ | ||
| 882 | pRing->pHead->devCtl = control; | ||
| 883 | /* Set source and destination address */ | ||
| 884 | pRing->pHead->sar = (uint32_t) &pRing->pHead->devCtl; | ||
| 885 | pRing->pHead->dar = ctlAddress; | ||
| 886 | /* Set control parameters */ | ||
| 887 | if (pConfig->flowControler == dmacHw_FLOW_CONTROL_DMA) { | ||
| 888 | pRing->pHead->ctl.lo = pConfig->transferType | | ||
| 889 | dmacHw_SRC_ADDRESS_UPDATE_MODE_INC | | ||
| 890 | dmacHw_DST_ADDRESS_UPDATE_MODE_INC | | ||
| 891 | dmacHw_SRC_TRANSACTION_WIDTH_32 | | ||
| 892 | pConfig->dstMaxTransactionWidth | | ||
| 893 | dmacHw_SRC_BURST_WIDTH_0 | | ||
| 894 | dmacHw_DST_BURST_WIDTH_0 | | ||
| 895 | pConfig->srcMasterInterface | | ||
| 896 | pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN; | ||
| 897 | } else { | ||
| 898 | uint32_t transferType = 0; | ||
| 899 | switch (pConfig->transferType) { | ||
| 900 | case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM: | ||
| 901 | transferType = dmacHw_REG_CTL_TTFC_PM_PERI; | ||
| 902 | break; | ||
| 903 | case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL: | ||
| 904 | transferType = dmacHw_REG_CTL_TTFC_MP_PERI; | ||
| 905 | break; | ||
| 906 | default: | ||
| 907 | dmacHw_ASSERT(0); | ||
| 908 | } | ||
| 909 | pRing->pHead->ctl.lo = transferType | | ||
| 910 | dmacHw_SRC_ADDRESS_UPDATE_MODE_INC | | ||
| 911 | dmacHw_DST_ADDRESS_UPDATE_MODE_INC | | ||
| 912 | dmacHw_SRC_TRANSACTION_WIDTH_32 | | ||
| 913 | pConfig->dstMaxTransactionWidth | | ||
| 914 | dmacHw_SRC_BURST_WIDTH_0 | | ||
| 915 | dmacHw_DST_BURST_WIDTH_0 | | ||
| 916 | pConfig->srcMasterInterface | | ||
| 917 | pConfig->dstMasterInterface | | ||
| 918 | pConfig->flowControler | dmacHw_REG_CTL_INT_EN; | ||
| 919 | } | ||
| 920 | |||
| 921 | /* Set block transaction size to one 32 bit transaction */ | ||
| 922 | pRing->pHead->ctl.hi = dmacHw_REG_CTL_BLOCK_TS_MASK & 1; | ||
| 923 | |||
| 924 | /* Remember the descriptor to initialize the registers */ | ||
| 925 | if (pRing->pProg == dmacHw_DESC_INIT) { | ||
| 926 | pRing->pProg = pRing->pHead; | ||
| 927 | } | ||
| 928 | pRing->pEnd = pRing->pHead; | ||
| 929 | |||
| 930 | /* Advance the descriptor */ | ||
| 931 | dmacHw_NEXT_DESC(pRing, pHead); | ||
| 932 | |||
| 933 | /* Update Tail pointer if destination is a peripheral */ | ||
| 934 | if (!dmacHw_DST_IS_MEMORY(pConfig->transferType)) { | ||
| 935 | pRing->pTail = pRing->pHead; | ||
| 936 | } | ||
| 937 | return 0; | ||
| 938 | } | ||
| 939 | |||
| 940 | /****************************************************************************/ | ||
| 941 | /** | ||
| 942 | * @brief Sets channel specific user data | ||
| 943 | * | ||
| 944 | * This function associates user data to a specif DMA channel | ||
| 945 | * | ||
| 946 | */ | ||
| 947 | /****************************************************************************/ | ||
| 948 | void dmacHw_setChannelUserData(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 949 | void *userData /* [ IN ] User data */ | ||
| 950 | ) { | ||
| 951 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 952 | |||
| 953 | pCblk->userData = userData; | ||
| 954 | } | ||
| 955 | |||
| 956 | /****************************************************************************/ | ||
| 957 | /** | ||
| 958 | * @brief Gets channel specific user data | ||
| 959 | * | ||
| 960 | * This function returns user data specific to a DMA channel | ||
| 961 | * | ||
| 962 | * @return user data | ||
| 963 | */ | ||
| 964 | /****************************************************************************/ | ||
| 965 | void *dmacHw_getChannelUserData(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */ | ||
| 966 | ) { | ||
| 967 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 968 | |||
| 969 | return pCblk->userData; | ||
| 970 | } | ||
| 971 | |||
| 972 | /****************************************************************************/ | ||
| 973 | /** | ||
| 974 | * @brief Resets descriptor control information | ||
| 975 | * | ||
| 976 | * @return void | ||
| 977 | */ | ||
| 978 | /****************************************************************************/ | ||
| 979 | void dmacHw_resetDescriptorControl(void *pDescriptor /* [ IN ] Descriptor buffer */ | ||
| 980 | ) { | ||
| 981 | int i; | ||
| 982 | dmacHw_DESC_RING_t *pRing; | ||
| 983 | dmacHw_DESC_t *pDesc; | ||
| 984 | |||
| 985 | pRing = dmacHw_GET_DESC_RING(pDescriptor); | ||
| 986 | pDesc = pRing->pHead; | ||
| 987 | |||
| 988 | for (i = 0; i < pRing->num; i++) { | ||
| 989 | /* Mark descriptor is ready to use */ | ||
| 990 | pDesc->ctl.hi = dmacHw_DESC_FREE; | ||
| 991 | /* Look into next link list item */ | ||
| 992 | pDesc++; | ||
| 993 | } | ||
| 994 | pRing->pFree = pRing->pTail = pRing->pEnd = pRing->pHead; | ||
| 995 | pRing->pProg = dmacHw_DESC_INIT; | ||
| 996 | } | ||
| 997 | |||
| 998 | /****************************************************************************/ | ||
| 999 | /** | ||
| 1000 | * @brief Displays channel specific registers and other control parameters | ||
| 1001 | * | ||
| 1002 | * @return void | ||
| 1003 | * | ||
| 1004 | * | ||
| 1005 | * @note | ||
| 1006 | * None | ||
| 1007 | */ | ||
| 1008 | /****************************************************************************/ | ||
| 1009 | void dmacHw_printDebugInfo(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 1010 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 1011 | int (*fpPrint) (const char *, ...) /* [ IN ] Print callback function */ | ||
| 1012 | ) { | ||
| 1013 | dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); | ||
| 1014 | |||
| 1015 | DisplayRegisterContents(pCblk->module, pCblk->channel, fpPrint); | ||
| 1016 | DisplayDescRing(pDescriptor, fpPrint); | ||
| 1017 | } | ||
diff --git a/arch/arm/mach-bcmring/csp/tmr/Makefile b/arch/arm/mach-bcmring/csp/tmr/Makefile new file mode 100644 index 000000000000..244a61ab7697 --- /dev/null +++ b/arch/arm/mach-bcmring/csp/tmr/Makefile | |||
| @@ -0,0 +1 @@ | |||
| obj-y += tmrHw.o | |||
diff --git a/arch/arm/mach-bcmring/csp/tmr/tmrHw.c b/arch/arm/mach-bcmring/csp/tmr/tmrHw.c new file mode 100644 index 000000000000..5c1c9a0e5ed2 --- /dev/null +++ b/arch/arm/mach-bcmring/csp/tmr/tmrHw.c | |||
| @@ -0,0 +1,576 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file tmrHw.c | ||
| 18 | * | ||
| 19 | * @brief Low level Timer driver routines | ||
| 20 | * | ||
| 21 | * @note | ||
| 22 | * | ||
| 23 | * These routines provide basic timer functionality only. | ||
| 24 | */ | ||
| 25 | /****************************************************************************/ | ||
| 26 | |||
| 27 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 28 | |||
| 29 | #include <csp/errno.h> | ||
| 30 | #include <csp/stdint.h> | ||
| 31 | |||
| 32 | #include <csp/tmrHw.h> | ||
| 33 | #include <mach/csp/tmrHw_reg.h> | ||
| 34 | |||
| 35 | #define tmrHw_ASSERT(a) if (!(a)) *(char *)0 = 0 | ||
| 36 | #define tmrHw_MILLISEC_PER_SEC (1000) | ||
| 37 | |||
| 38 | #define tmrHw_LOW_1_RESOLUTION_COUNT (tmrHw_LOW_RESOLUTION_CLOCK / tmrHw_MILLISEC_PER_SEC) | ||
| 39 | #define tmrHw_LOW_1_MAX_MILLISEC (0xFFFFFFFF / tmrHw_LOW_1_RESOLUTION_COUNT) | ||
| 40 | #define tmrHw_LOW_16_RESOLUTION_COUNT (tmrHw_LOW_1_RESOLUTION_COUNT / 16) | ||
| 41 | #define tmrHw_LOW_16_MAX_MILLISEC (0xFFFFFFFF / tmrHw_LOW_16_RESOLUTION_COUNT) | ||
| 42 | #define tmrHw_LOW_256_RESOLUTION_COUNT (tmrHw_LOW_1_RESOLUTION_COUNT / 256) | ||
| 43 | #define tmrHw_LOW_256_MAX_MILLISEC (0xFFFFFFFF / tmrHw_LOW_256_RESOLUTION_COUNT) | ||
| 44 | |||
| 45 | #define tmrHw_HIGH_1_RESOLUTION_COUNT (tmrHw_HIGH_RESOLUTION_CLOCK / tmrHw_MILLISEC_PER_SEC) | ||
| 46 | #define tmrHw_HIGH_1_MAX_MILLISEC (0xFFFFFFFF / tmrHw_HIGH_1_RESOLUTION_COUNT) | ||
| 47 | #define tmrHw_HIGH_16_RESOLUTION_COUNT (tmrHw_HIGH_1_RESOLUTION_COUNT / 16) | ||
| 48 | #define tmrHw_HIGH_16_MAX_MILLISEC (0xFFFFFFFF / tmrHw_HIGH_16_RESOLUTION_COUNT) | ||
| 49 | #define tmrHw_HIGH_256_RESOLUTION_COUNT (tmrHw_HIGH_1_RESOLUTION_COUNT / 256) | ||
| 50 | #define tmrHw_HIGH_256_MAX_MILLISEC (0xFFFFFFFF / tmrHw_HIGH_256_RESOLUTION_COUNT) | ||
| 51 | |||
| 52 | static void ResetTimer(tmrHw_ID_t timerId) | ||
| 53 | __attribute__ ((section(".aramtext"))); | ||
| 54 | static int tmrHw_divide(int num, int denom) | ||
| 55 | __attribute__ ((section(".aramtext"))); | ||
| 56 | |||
| 57 | /****************************************************************************/ | ||
| 58 | /** | ||
| 59 | * @brief Get timer capability | ||
| 60 | * | ||
| 61 | * This function returns various capabilities/attributes of a timer | ||
| 62 | * | ||
| 63 | * @return Capability | ||
| 64 | * | ||
| 65 | */ | ||
| 66 | /****************************************************************************/ | ||
| 67 | uint32_t tmrHw_getTimerCapability(tmrHw_ID_t timerId, /* [ IN ] Timer Id */ | ||
| 68 | tmrHw_CAPABILITY_e capability /* [ IN ] Timer capability */ | ||
| 69 | ) { | ||
| 70 | switch (capability) { | ||
| 71 | case tmrHw_CAPABILITY_CLOCK: | ||
| 72 | return (timerId <= | ||
| 73 | 1) ? tmrHw_LOW_RESOLUTION_CLOCK : | ||
| 74 | tmrHw_HIGH_RESOLUTION_CLOCK; | ||
| 75 | case tmrHw_CAPABILITY_RESOLUTION: | ||
| 76 | return 32; | ||
| 77 | default: | ||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | |||
| 83 | /****************************************************************************/ | ||
| 84 | /** | ||
| 85 | * @brief Resets a timer | ||
| 86 | * | ||
| 87 | * This function initializes timer | ||
| 88 | * | ||
| 89 | * @return void | ||
| 90 | * | ||
| 91 | */ | ||
| 92 | /****************************************************************************/ | ||
| 93 | static void ResetTimer(tmrHw_ID_t timerId /* [ IN ] Timer Id */ | ||
| 94 | ) { | ||
| 95 | /* Reset timer */ | ||
| 96 | pTmrHw[timerId].LoadValue = 0; | ||
| 97 | pTmrHw[timerId].CurrentValue = 0xFFFFFFFF; | ||
| 98 | pTmrHw[timerId].Control = 0; | ||
| 99 | pTmrHw[timerId].BackgroundLoad = 0; | ||
| 100 | /* Always configure as a 32 bit timer */ | ||
| 101 | pTmrHw[timerId].Control |= tmrHw_CONTROL_32BIT; | ||
| 102 | /* Clear interrupt only if raw status interrupt is set */ | ||
| 103 | if (pTmrHw[timerId].RawInterruptStatus) { | ||
| 104 | pTmrHw[timerId].InterruptClear = 0xFFFFFFFF; | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | /****************************************************************************/ | ||
| 109 | /** | ||
| 110 | * @brief Sets counter value for an interval in ms | ||
| 111 | * | ||
| 112 | * @return On success: Effective counter value set | ||
| 113 | * On failure: 0 | ||
| 114 | * | ||
| 115 | */ | ||
| 116 | /****************************************************************************/ | ||
| 117 | static tmrHw_INTERVAL_t SetTimerPeriod(tmrHw_ID_t timerId, /* [ IN ] Timer Id */ | ||
| 118 | tmrHw_INTERVAL_t msec /* [ IN ] Interval in milli-second */ | ||
| 119 | ) { | ||
| 120 | uint32_t scale = 0; | ||
| 121 | uint32_t count = 0; | ||
| 122 | |||
| 123 | if (timerId == 0 || timerId == 1) { | ||
| 124 | if (msec <= tmrHw_LOW_1_MAX_MILLISEC) { | ||
| 125 | pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1; | ||
| 126 | scale = tmrHw_LOW_1_RESOLUTION_COUNT; | ||
| 127 | } else if (msec <= tmrHw_LOW_16_MAX_MILLISEC) { | ||
| 128 | pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16; | ||
| 129 | scale = tmrHw_LOW_16_RESOLUTION_COUNT; | ||
| 130 | } else if (msec <= tmrHw_LOW_256_MAX_MILLISEC) { | ||
| 131 | pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256; | ||
| 132 | scale = tmrHw_LOW_256_RESOLUTION_COUNT; | ||
| 133 | } else { | ||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | count = msec * scale; | ||
| 138 | /* Set counter value */ | ||
| 139 | pTmrHw[timerId].LoadValue = count; | ||
| 140 | pTmrHw[timerId].BackgroundLoad = count; | ||
| 141 | |||
| 142 | } else if (timerId == 2 || timerId == 3) { | ||
| 143 | if (msec <= tmrHw_HIGH_1_MAX_MILLISEC) { | ||
| 144 | pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1; | ||
| 145 | scale = tmrHw_HIGH_1_RESOLUTION_COUNT; | ||
| 146 | } else if (msec <= tmrHw_HIGH_16_MAX_MILLISEC) { | ||
| 147 | pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16; | ||
| 148 | scale = tmrHw_HIGH_16_RESOLUTION_COUNT; | ||
| 149 | } else if (msec <= tmrHw_HIGH_256_MAX_MILLISEC) { | ||
| 150 | pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256; | ||
| 151 | scale = tmrHw_HIGH_256_RESOLUTION_COUNT; | ||
| 152 | } else { | ||
| 153 | return 0; | ||
| 154 | } | ||
| 155 | |||
| 156 | count = msec * scale; | ||
| 157 | /* Set counter value */ | ||
| 158 | pTmrHw[timerId].LoadValue = count; | ||
| 159 | pTmrHw[timerId].BackgroundLoad = count; | ||
| 160 | } | ||
| 161 | return count / scale; | ||
| 162 | } | ||
| 163 | |||
| 164 | /****************************************************************************/ | ||
| 165 | /** | ||
| 166 | * @brief Configures a periodic timer in terms of timer interrupt rate | ||
| 167 | * | ||
| 168 | * This function initializes a periodic timer to generate specific number of | ||
| 169 | * timer interrupt per second | ||
| 170 | * | ||
| 171 | * @return On success: Effective timer frequency | ||
| 172 | * On failure: 0 | ||
| 173 | * | ||
| 174 | */ | ||
| 175 | /****************************************************************************/ | ||
| 176 | tmrHw_RATE_t tmrHw_setPeriodicTimerRate(tmrHw_ID_t timerId, /* [ IN ] Timer Id */ | ||
| 177 | tmrHw_RATE_t rate /* [ IN ] Number of timer interrupt per second */ | ||
| 178 | ) { | ||
| 179 | uint32_t resolution = 0; | ||
| 180 | uint32_t count = 0; | ||
| 181 | ResetTimer(timerId); | ||
| 182 | |||
| 183 | /* Set timer mode periodic */ | ||
| 184 | pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC; | ||
| 185 | pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT; | ||
| 186 | /* Set timer in highest resolution */ | ||
| 187 | pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1; | ||
| 188 | |||
| 189 | if (rate && (timerId == 0 || timerId == 1)) { | ||
| 190 | if (rate > tmrHw_LOW_RESOLUTION_CLOCK) { | ||
| 191 | return 0; | ||
| 192 | } | ||
| 193 | resolution = tmrHw_LOW_RESOLUTION_CLOCK; | ||
| 194 | } else if (rate && (timerId == 2 || timerId == 3)) { | ||
| 195 | if (rate > tmrHw_HIGH_RESOLUTION_CLOCK) { | ||
| 196 | return 0; | ||
| 197 | } else { | ||
| 198 | resolution = tmrHw_HIGH_RESOLUTION_CLOCK; | ||
| 199 | } | ||
| 200 | } else { | ||
| 201 | return 0; | ||
| 202 | } | ||
| 203 | /* Find the counter value */ | ||
| 204 | count = resolution / rate; | ||
| 205 | /* Set counter value */ | ||
| 206 | pTmrHw[timerId].LoadValue = count; | ||
| 207 | pTmrHw[timerId].BackgroundLoad = count; | ||
| 208 | |||
| 209 | return resolution / count; | ||
| 210 | } | ||
| 211 | |||
| 212 | /****************************************************************************/ | ||
| 213 | /** | ||
| 214 | * @brief Configures a periodic timer to generate timer interrupt after | ||
| 215 | * certain time interval | ||
| 216 | * | ||
| 217 | * This function initializes a periodic timer to generate timer interrupt | ||
| 218 | * after every time interval in millisecond | ||
| 219 | * | ||
| 220 | * @return On success: Effective interval set in milli-second | ||
| 221 | * On failure: 0 | ||
| 222 | * | ||
| 223 | */ | ||
| 224 | /****************************************************************************/ | ||
| 225 | tmrHw_INTERVAL_t tmrHw_setPeriodicTimerInterval(tmrHw_ID_t timerId, /* [ IN ] Timer Id */ | ||
| 226 | tmrHw_INTERVAL_t msec /* [ IN ] Interval in milli-second */ | ||
| 227 | ) { | ||
| 228 | ResetTimer(timerId); | ||
| 229 | |||
| 230 | /* Set timer mode periodic */ | ||
| 231 | pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC; | ||
| 232 | pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT; | ||
| 233 | |||
| 234 | return SetTimerPeriod(timerId, msec); | ||
| 235 | } | ||
| 236 | |||
| 237 | /****************************************************************************/ | ||
| 238 | /** | ||
| 239 | * @brief Configures a periodic timer to generate timer interrupt just once | ||
| 240 | * after certain time interval | ||
| 241 | * | ||
| 242 | * This function initializes a periodic timer to generate a single ticks after | ||
| 243 | * certain time interval in millisecond | ||
| 244 | * | ||
| 245 | * @return On success: Effective interval set in milli-second | ||
| 246 | * On failure: 0 | ||
| 247 | * | ||
| 248 | */ | ||
| 249 | /****************************************************************************/ | ||
| 250 | tmrHw_INTERVAL_t tmrHw_setOneshotTimerInterval(tmrHw_ID_t timerId, /* [ IN ] Timer Id */ | ||
| 251 | tmrHw_INTERVAL_t msec /* [ IN ] Interval in milli-second */ | ||
| 252 | ) { | ||
| 253 | ResetTimer(timerId); | ||
| 254 | |||
| 255 | /* Set timer mode oneshot */ | ||
| 256 | pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC; | ||
| 257 | pTmrHw[timerId].Control |= tmrHw_CONTROL_ONESHOT; | ||
| 258 | |||
| 259 | return SetTimerPeriod(timerId, msec); | ||
| 260 | } | ||
| 261 | |||
| 262 | /****************************************************************************/ | ||
| 263 | /** | ||
| 264 | * @brief Configures a timer to run as a free running timer | ||
| 265 | * | ||
| 266 | * This function initializes a timer to run as a free running timer | ||
| 267 | * | ||
| 268 | * @return Timer resolution (count / sec) | ||
| 269 | * | ||
| 270 | */ | ||
| 271 | /****************************************************************************/ | ||
| 272 | tmrHw_RATE_t tmrHw_setFreeRunningTimer(tmrHw_ID_t timerId, /* [ IN ] Timer Id */ | ||
| 273 | uint32_t divider /* [ IN ] Dividing the clock frequency */ | ||
| 274 | ) { | ||
| 275 | uint32_t scale = 0; | ||
| 276 | |||
| 277 | ResetTimer(timerId); | ||
| 278 | /* Set timer as free running mode */ | ||
| 279 | pTmrHw[timerId].Control &= ~tmrHw_CONTROL_PERIODIC; | ||
| 280 | pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT; | ||
| 281 | |||
| 282 | if (divider >= 64) { | ||
| 283 | pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256; | ||
| 284 | scale = 256; | ||
| 285 | } else if (divider >= 8) { | ||
| 286 | pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16; | ||
| 287 | scale = 16; | ||
| 288 | } else { | ||
| 289 | pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1; | ||
| 290 | scale = 1; | ||
| 291 | } | ||
| 292 | |||
| 293 | if (timerId == 0 || timerId == 1) { | ||
| 294 | return tmrHw_divide(tmrHw_LOW_RESOLUTION_CLOCK, scale); | ||
| 295 | } else if (timerId == 2 || timerId == 3) { | ||
| 296 | return tmrHw_divide(tmrHw_HIGH_RESOLUTION_CLOCK, scale); | ||
| 297 | } | ||
| 298 | |||
| 299 | return 0; | ||
| 300 | } | ||
| 301 | |||
| 302 | /****************************************************************************/ | ||
| 303 | /** | ||
| 304 | * @brief Starts a timer | ||
| 305 | * | ||
| 306 | * This function starts a preconfigured timer | ||
| 307 | * | ||
| 308 | * @return -1 - On Failure | ||
| 309 | * 0 - On Success | ||
| 310 | * | ||
| 311 | */ | ||
| 312 | /****************************************************************************/ | ||
| 313 | int tmrHw_startTimer(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 314 | ) { | ||
| 315 | pTmrHw[timerId].Control |= tmrHw_CONTROL_TIMER_ENABLE; | ||
| 316 | return 0; | ||
| 317 | } | ||
| 318 | |||
| 319 | /****************************************************************************/ | ||
| 320 | /** | ||
| 321 | * @brief Stops a timer | ||
| 322 | * | ||
| 323 | * This function stops a running timer | ||
| 324 | * | ||
| 325 | * @return -1 - On Failure | ||
| 326 | * 0 - On Success | ||
| 327 | * | ||
| 328 | */ | ||
| 329 | /****************************************************************************/ | ||
| 330 | int tmrHw_stopTimer(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 331 | ) { | ||
| 332 | pTmrHw[timerId].Control &= ~tmrHw_CONTROL_TIMER_ENABLE; | ||
| 333 | return 0; | ||
| 334 | } | ||
| 335 | |||
| 336 | /****************************************************************************/ | ||
| 337 | /** | ||
| 338 | * @brief Gets current timer count | ||
| 339 | * | ||
| 340 | * This function returns the current timer value | ||
| 341 | * | ||
| 342 | * @return Current downcounting timer value | ||
| 343 | * | ||
| 344 | */ | ||
| 345 | /****************************************************************************/ | ||
| 346 | uint32_t tmrHw_GetCurrentCount(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 347 | ) { | ||
| 348 | /* return 32 bit timer value */ | ||
| 349 | switch (pTmrHw[timerId].Control & tmrHw_CONTROL_MODE_MASK) { | ||
| 350 | case tmrHw_CONTROL_FREE_RUNNING: | ||
| 351 | if (pTmrHw[timerId].CurrentValue) { | ||
| 352 | return tmrHw_MAX_COUNT - pTmrHw[timerId].CurrentValue; | ||
| 353 | } | ||
| 354 | break; | ||
| 355 | case tmrHw_CONTROL_PERIODIC: | ||
| 356 | case tmrHw_CONTROL_ONESHOT: | ||
| 357 | return pTmrHw[timerId].BackgroundLoad - | ||
| 358 | pTmrHw[timerId].CurrentValue; | ||
| 359 | } | ||
| 360 | return 0; | ||
| 361 | } | ||
| 362 | |||
| 363 | /****************************************************************************/ | ||
| 364 | /** | ||
| 365 | * @brief Gets timer count rate | ||
| 366 | * | ||
| 367 | * This function returns the number of counts per second | ||
| 368 | * | ||
| 369 | * @return Count rate | ||
| 370 | * | ||
| 371 | */ | ||
| 372 | /****************************************************************************/ | ||
| 373 | tmrHw_RATE_t tmrHw_getCountRate(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 374 | ) { | ||
| 375 | uint32_t divider = 0; | ||
| 376 | |||
| 377 | switch (pTmrHw[timerId].Control & tmrHw_CONTROL_PRESCALE_MASK) { | ||
| 378 | case tmrHw_CONTROL_PRESCALE_1: | ||
| 379 | divider = 1; | ||
| 380 | break; | ||
| 381 | case tmrHw_CONTROL_PRESCALE_16: | ||
| 382 | divider = 16; | ||
| 383 | break; | ||
| 384 | case tmrHw_CONTROL_PRESCALE_256: | ||
| 385 | divider = 256; | ||
| 386 | break; | ||
| 387 | default: | ||
| 388 | tmrHw_ASSERT(0); | ||
| 389 | } | ||
| 390 | |||
| 391 | if (timerId == 0 || timerId == 1) { | ||
| 392 | return tmrHw_divide(tmrHw_LOW_RESOLUTION_CLOCK, divider); | ||
| 393 | } else { | ||
| 394 | return tmrHw_divide(tmrHw_HIGH_RESOLUTION_CLOCK, divider); | ||
| 395 | } | ||
| 396 | return 0; | ||
| 397 | } | ||
| 398 | |||
| 399 | /****************************************************************************/ | ||
| 400 | /** | ||
| 401 | * @brief Enables timer interrupt | ||
| 402 | * | ||
| 403 | * This function enables the timer interrupt | ||
| 404 | * | ||
| 405 | * @return N/A | ||
| 406 | * | ||
| 407 | */ | ||
| 408 | /****************************************************************************/ | ||
| 409 | void tmrHw_enableInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 410 | ) { | ||
| 411 | pTmrHw[timerId].Control |= tmrHw_CONTROL_INTERRUPT_ENABLE; | ||
| 412 | } | ||
| 413 | |||
| 414 | /****************************************************************************/ | ||
| 415 | /** | ||
| 416 | * @brief Disables timer interrupt | ||
| 417 | * | ||
| 418 | * This function disable the timer interrupt | ||
| 419 | * | ||
| 420 | * @return N/A | ||
| 421 | * | ||
| 422 | */ | ||
| 423 | /****************************************************************************/ | ||
| 424 | void tmrHw_disableInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 425 | ) { | ||
| 426 | pTmrHw[timerId].Control &= ~tmrHw_CONTROL_INTERRUPT_ENABLE; | ||
| 427 | } | ||
| 428 | |||
| 429 | /****************************************************************************/ | ||
| 430 | /** | ||
| 431 | * @brief Clears the interrupt | ||
| 432 | * | ||
| 433 | * This function clears the timer interrupt | ||
| 434 | * | ||
| 435 | * @return N/A | ||
| 436 | * | ||
| 437 | * @note | ||
| 438 | * Must be called under the context of ISR | ||
| 439 | */ | ||
| 440 | /****************************************************************************/ | ||
| 441 | void tmrHw_clearInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 442 | ) { | ||
| 443 | pTmrHw[timerId].InterruptClear = 0x1; | ||
| 444 | } | ||
| 445 | |||
| 446 | /****************************************************************************/ | ||
| 447 | /** | ||
| 448 | * @brief Gets the interrupt status | ||
| 449 | * | ||
| 450 | * This function returns timer interrupt status | ||
| 451 | * | ||
| 452 | * @return Interrupt status | ||
| 453 | */ | ||
| 454 | /****************************************************************************/ | ||
| 455 | tmrHw_INTERRUPT_STATUS_e tmrHw_getInterruptStatus(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 456 | ) { | ||
| 457 | if (pTmrHw[timerId].InterruptStatus) { | ||
| 458 | return tmrHw_INTERRUPT_STATUS_SET; | ||
| 459 | } else { | ||
| 460 | return tmrHw_INTERRUPT_STATUS_UNSET; | ||
| 461 | } | ||
| 462 | } | ||
| 463 | |||
| 464 | /****************************************************************************/ | ||
| 465 | /** | ||
| 466 | * @brief Indentifies a timer causing interrupt | ||
| 467 | * | ||
| 468 | * This functions returns a timer causing interrupt | ||
| 469 | * | ||
| 470 | * @return 0xFFFFFFFF : No timer causing an interrupt | ||
| 471 | * ! 0xFFFFFFFF : timer causing an interrupt | ||
| 472 | * @note | ||
| 473 | * tmrHw_clearIntrrupt() must be called with a valid timer id after calling this function | ||
| 474 | */ | ||
| 475 | /****************************************************************************/ | ||
| 476 | tmrHw_ID_t tmrHw_getInterruptSource(void /* void */ | ||
| 477 | ) { | ||
| 478 | int i; | ||
| 479 | |||
| 480 | for (i = 0; i < tmrHw_TIMER_NUM_COUNT; i++) { | ||
| 481 | if (pTmrHw[i].InterruptStatus) { | ||
| 482 | return i; | ||
| 483 | } | ||
| 484 | } | ||
| 485 | |||
| 486 | return 0xFFFFFFFF; | ||
| 487 | } | ||
| 488 | |||
| 489 | /****************************************************************************/ | ||
| 490 | /** | ||
| 491 | * @brief Displays specific timer registers | ||
| 492 | * | ||
| 493 | * | ||
| 494 | * @return void | ||
| 495 | * | ||
| 496 | */ | ||
| 497 | /****************************************************************************/ | ||
| 498 | void tmrHw_printDebugInfo(tmrHw_ID_t timerId, /* [ IN ] Timer id */ | ||
| 499 | int (*fpPrint) (const char *, ...) /* [ IN ] Print callback function */ | ||
| 500 | ) { | ||
| 501 | (*fpPrint) ("Displaying register contents \n\n"); | ||
| 502 | (*fpPrint) ("Timer %d: Load value 0x%X\n", timerId, | ||
| 503 | pTmrHw[timerId].LoadValue); | ||
| 504 | (*fpPrint) ("Timer %d: Background load value 0x%X\n", timerId, | ||
| 505 | pTmrHw[timerId].BackgroundLoad); | ||
| 506 | (*fpPrint) ("Timer %d: Control 0x%X\n", timerId, | ||
| 507 | pTmrHw[timerId].Control); | ||
| 508 | (*fpPrint) ("Timer %d: Interrupt clear 0x%X\n", timerId, | ||
| 509 | pTmrHw[timerId].InterruptClear); | ||
| 510 | (*fpPrint) ("Timer %d: Interrupt raw interrupt 0x%X\n", timerId, | ||
| 511 | pTmrHw[timerId].RawInterruptStatus); | ||
| 512 | (*fpPrint) ("Timer %d: Interrupt status 0x%X\n", timerId, | ||
| 513 | pTmrHw[timerId].InterruptStatus); | ||
| 514 | } | ||
| 515 | |||
| 516 | /****************************************************************************/ | ||
| 517 | /** | ||
| 518 | * @brief Use a timer to perform a busy wait delay for a number of usecs. | ||
| 519 | * | ||
| 520 | * @return N/A | ||
| 521 | */ | ||
| 522 | /****************************************************************************/ | ||
| 523 | void tmrHw_udelay(tmrHw_ID_t timerId, /* [ IN ] Timer id */ | ||
| 524 | unsigned long usecs /* [ IN ] usec to delay */ | ||
| 525 | ) { | ||
| 526 | tmrHw_RATE_t usec_tick_rate; | ||
| 527 | tmrHw_COUNT_t start_time; | ||
| 528 | tmrHw_COUNT_t delta_time; | ||
| 529 | |||
| 530 | start_time = tmrHw_GetCurrentCount(timerId); | ||
| 531 | usec_tick_rate = tmrHw_divide(tmrHw_getCountRate(timerId), 1000000); | ||
| 532 | delta_time = usecs * usec_tick_rate; | ||
| 533 | |||
| 534 | /* Busy wait */ | ||
| 535 | while (delta_time > (tmrHw_GetCurrentCount(timerId) - start_time)) | ||
| 536 | ; | ||
| 537 | } | ||
| 538 | |||
| 539 | /****************************************************************************/ | ||
| 540 | /** | ||
| 541 | * @brief Local Divide function | ||
| 542 | * | ||
| 543 | * This function does the divide | ||
| 544 | * | ||
| 545 | * @return divide value | ||
| 546 | * | ||
| 547 | */ | ||
| 548 | /****************************************************************************/ | ||
| 549 | static int tmrHw_divide(int num, int denom) | ||
| 550 | { | ||
| 551 | int r; | ||
| 552 | int t = 1; | ||
| 553 | |||
| 554 | /* Shift denom and t up to the largest value to optimize algorithm */ | ||
| 555 | /* t contains the units of each divide */ | ||
| 556 | while ((denom & 0x40000000) == 0) { /* fails if denom=0 */ | ||
| 557 | denom = denom << 1; | ||
| 558 | t = t << 1; | ||
| 559 | } | ||
| 560 | |||
| 561 | /* Intialize the result */ | ||
| 562 | r = 0; | ||
| 563 | |||
| 564 | do { | ||
| 565 | /* Determine if there exists a positive remainder */ | ||
| 566 | if ((num - denom) >= 0) { | ||
| 567 | /* Accumlate t to the result and calculate a new remainder */ | ||
| 568 | num = num - denom; | ||
| 569 | r = r + t; | ||
| 570 | } | ||
| 571 | /* Continue to shift denom and shift t down to 0 */ | ||
| 572 | denom = denom >> 1; | ||
| 573 | t = t >> 1; | ||
| 574 | } while (t != 0); | ||
| 575 | return r; | ||
| 576 | } | ||
diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c new file mode 100644 index 000000000000..7b20fccb9d4e --- /dev/null +++ b/arch/arm/mach-bcmring/dma.c | |||
| @@ -0,0 +1,2321 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file dma.c | ||
| 18 | * | ||
| 19 | * @brief Implements the DMA interface. | ||
| 20 | */ | ||
| 21 | /****************************************************************************/ | ||
| 22 | |||
| 23 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 24 | |||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/device.h> | ||
| 27 | #include <linux/dma-mapping.h> | ||
| 28 | #include <linux/interrupt.h> | ||
| 29 | #include <linux/irqreturn.h> | ||
| 30 | #include <linux/proc_fs.h> | ||
| 31 | |||
| 32 | #include <mach/timer.h> | ||
| 33 | |||
| 34 | #include <linux/mm.h> | ||
| 35 | #include <linux/pfn.h> | ||
| 36 | #include <asm/atomic.h> | ||
| 37 | #include <mach/dma.h> | ||
| 38 | |||
| 39 | /* I don't quite understand why dc4 fails when this is set to 1 and DMA is enabled */ | ||
| 40 | /* especially since dc4 doesn't use kmalloc'd memory. */ | ||
| 41 | |||
| 42 | #define ALLOW_MAP_OF_KMALLOC_MEMORY 0 | ||
| 43 | |||
| 44 | /* ---- Public Variables ------------------------------------------------- */ | ||
| 45 | |||
| 46 | /* ---- Private Constants and Types -------------------------------------- */ | ||
| 47 | |||
| 48 | #define MAKE_HANDLE(controllerIdx, channelIdx) (((controllerIdx) << 4) | (channelIdx)) | ||
| 49 | |||
| 50 | #define CONTROLLER_FROM_HANDLE(handle) (((handle) >> 4) & 0x0f) | ||
| 51 | #define CHANNEL_FROM_HANDLE(handle) ((handle) & 0x0f) | ||
| 52 | |||
| 53 | #define DMA_MAP_DEBUG 0 | ||
| 54 | |||
| 55 | #if DMA_MAP_DEBUG | ||
| 56 | # define DMA_MAP_PRINT(fmt, args...) printk("%s: " fmt, __func__, ## args) | ||
| 57 | #else | ||
| 58 | # define DMA_MAP_PRINT(fmt, args...) | ||
| 59 | #endif | ||
| 60 | |||
| 61 | /* ---- Private Variables ------------------------------------------------ */ | ||
| 62 | |||
| 63 | static DMA_Global_t gDMA; | ||
| 64 | static struct proc_dir_entry *gDmaDir; | ||
| 65 | |||
| 66 | static atomic_t gDmaStatMemTypeKmalloc = ATOMIC_INIT(0); | ||
| 67 | static atomic_t gDmaStatMemTypeVmalloc = ATOMIC_INIT(0); | ||
| 68 | static atomic_t gDmaStatMemTypeUser = ATOMIC_INIT(0); | ||
| 69 | static atomic_t gDmaStatMemTypeCoherent = ATOMIC_INIT(0); | ||
| 70 | |||
| 71 | #include "dma_device.c" | ||
| 72 | |||
| 73 | /* ---- Private Function Prototypes -------------------------------------- */ | ||
| 74 | |||
| 75 | /* ---- Functions ------------------------------------------------------- */ | ||
| 76 | |||
| 77 | /****************************************************************************/ | ||
| 78 | /** | ||
| 79 | * Displays information for /proc/dma/mem-type | ||
| 80 | */ | ||
| 81 | /****************************************************************************/ | ||
| 82 | |||
| 83 | static int dma_proc_read_mem_type(char *buf, char **start, off_t offset, | ||
| 84 | int count, int *eof, void *data) | ||
| 85 | { | ||
| 86 | int len = 0; | ||
| 87 | |||
| 88 | len += sprintf(buf + len, "dma_map_mem statistics\n"); | ||
| 89 | len += | ||
| 90 | sprintf(buf + len, "coherent: %d\n", | ||
| 91 | atomic_read(&gDmaStatMemTypeCoherent)); | ||
| 92 | len += | ||
| 93 | sprintf(buf + len, "kmalloc: %d\n", | ||
| 94 | atomic_read(&gDmaStatMemTypeKmalloc)); | ||
| 95 | len += | ||
| 96 | sprintf(buf + len, "vmalloc: %d\n", | ||
| 97 | atomic_read(&gDmaStatMemTypeVmalloc)); | ||
| 98 | len += | ||
| 99 | sprintf(buf + len, "user: %d\n", | ||
| 100 | atomic_read(&gDmaStatMemTypeUser)); | ||
| 101 | |||
| 102 | return len; | ||
| 103 | } | ||
| 104 | |||
| 105 | /****************************************************************************/ | ||
| 106 | /** | ||
| 107 | * Displays information for /proc/dma/channels | ||
| 108 | */ | ||
| 109 | /****************************************************************************/ | ||
| 110 | |||
| 111 | static int dma_proc_read_channels(char *buf, char **start, off_t offset, | ||
| 112 | int count, int *eof, void *data) | ||
| 113 | { | ||
| 114 | int controllerIdx; | ||
| 115 | int channelIdx; | ||
| 116 | int limit = count - 200; | ||
| 117 | int len = 0; | ||
| 118 | DMA_Channel_t *channel; | ||
| 119 | |||
| 120 | if (down_interruptible(&gDMA.lock) < 0) { | ||
| 121 | return -ERESTARTSYS; | ||
| 122 | } | ||
| 123 | |||
| 124 | for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS; | ||
| 125 | controllerIdx++) { | ||
| 126 | for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS; | ||
| 127 | channelIdx++) { | ||
| 128 | if (len >= limit) { | ||
| 129 | break; | ||
| 130 | } | ||
| 131 | |||
| 132 | channel = | ||
| 133 | &gDMA.controller[controllerIdx].channel[channelIdx]; | ||
| 134 | |||
| 135 | len += | ||
| 136 | sprintf(buf + len, "%d:%d ", controllerIdx, | ||
| 137 | channelIdx); | ||
| 138 | |||
| 139 | if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) != | ||
| 140 | 0) { | ||
| 141 | len += | ||
| 142 | sprintf(buf + len, "Dedicated for %s ", | ||
| 143 | DMA_gDeviceAttribute[channel-> | ||
| 144 | devType].name); | ||
| 145 | } else { | ||
| 146 | len += sprintf(buf + len, "Shared "); | ||
| 147 | } | ||
| 148 | |||
| 149 | if ((channel->flags & DMA_CHANNEL_FLAG_NO_ISR) != 0) { | ||
| 150 | len += sprintf(buf + len, "No ISR "); | ||
| 151 | } | ||
| 152 | |||
| 153 | if ((channel->flags & DMA_CHANNEL_FLAG_LARGE_FIFO) != 0) { | ||
| 154 | len += sprintf(buf + len, "Fifo: 128 "); | ||
| 155 | } else { | ||
| 156 | len += sprintf(buf + len, "Fifo: 64 "); | ||
| 157 | } | ||
| 158 | |||
| 159 | if ((channel->flags & DMA_CHANNEL_FLAG_IN_USE) != 0) { | ||
| 160 | len += | ||
| 161 | sprintf(buf + len, "InUse by %s", | ||
| 162 | DMA_gDeviceAttribute[channel-> | ||
| 163 | devType].name); | ||
| 164 | #if (DMA_DEBUG_TRACK_RESERVATION) | ||
| 165 | len += | ||
| 166 | sprintf(buf + len, " (%s:%d)", | ||
| 167 | channel->fileName, | ||
| 168 | channel->lineNum); | ||
| 169 | #endif | ||
| 170 | } else { | ||
| 171 | len += sprintf(buf + len, "Avail "); | ||
| 172 | } | ||
| 173 | |||
| 174 | if (channel->lastDevType != DMA_DEVICE_NONE) { | ||
| 175 | len += | ||
| 176 | sprintf(buf + len, "Last use: %s ", | ||
| 177 | DMA_gDeviceAttribute[channel-> | ||
| 178 | lastDevType]. | ||
| 179 | name); | ||
| 180 | } | ||
| 181 | |||
| 182 | len += sprintf(buf + len, "\n"); | ||
| 183 | } | ||
| 184 | } | ||
| 185 | up(&gDMA.lock); | ||
| 186 | *eof = 1; | ||
| 187 | |||
| 188 | return len; | ||
| 189 | } | ||
| 190 | |||
| 191 | /****************************************************************************/ | ||
| 192 | /** | ||
| 193 | * Displays information for /proc/dma/devices | ||
| 194 | */ | ||
| 195 | /****************************************************************************/ | ||
| 196 | |||
| 197 | static int dma_proc_read_devices(char *buf, char **start, off_t offset, | ||
| 198 | int count, int *eof, void *data) | ||
| 199 | { | ||
| 200 | int limit = count - 200; | ||
| 201 | int len = 0; | ||
| 202 | int devIdx; | ||
| 203 | |||
| 204 | if (down_interruptible(&gDMA.lock) < 0) { | ||
| 205 | return -ERESTARTSYS; | ||
| 206 | } | ||
| 207 | |||
| 208 | for (devIdx = 0; devIdx < DMA_NUM_DEVICE_ENTRIES; devIdx++) { | ||
| 209 | DMA_DeviceAttribute_t *devAttr = &DMA_gDeviceAttribute[devIdx]; | ||
| 210 | |||
| 211 | if (devAttr->name == NULL) { | ||
| 212 | continue; | ||
| 213 | } | ||
| 214 | |||
| 215 | if (len >= limit) { | ||
| 216 | break; | ||
| 217 | } | ||
| 218 | |||
| 219 | len += sprintf(buf + len, "%-12s ", devAttr->name); | ||
| 220 | |||
| 221 | if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) { | ||
| 222 | len += | ||
| 223 | sprintf(buf + len, "Dedicated %d:%d ", | ||
| 224 | devAttr->dedicatedController, | ||
| 225 | devAttr->dedicatedChannel); | ||
| 226 | } else { | ||
| 227 | len += sprintf(buf + len, "Shared DMA:"); | ||
| 228 | if ((devAttr->flags & DMA_DEVICE_FLAG_ON_DMA0) != 0) { | ||
| 229 | len += sprintf(buf + len, "0"); | ||
| 230 | } | ||
| 231 | if ((devAttr->flags & DMA_DEVICE_FLAG_ON_DMA1) != 0) { | ||
| 232 | len += sprintf(buf + len, "1"); | ||
| 233 | } | ||
| 234 | len += sprintf(buf + len, " "); | ||
| 235 | } | ||
| 236 | if ((devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) != 0) { | ||
| 237 | len += sprintf(buf + len, "NoISR "); | ||
| 238 | } | ||
| 239 | if ((devAttr->flags & DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO) != 0) { | ||
| 240 | len += sprintf(buf + len, "Allow-128 "); | ||
| 241 | } | ||
| 242 | |||
| 243 | len += | ||
| 244 | sprintf(buf + len, | ||
| 245 | "Xfer #: %Lu Ticks: %Lu Bytes: %Lu DescLen: %u\n", | ||
| 246 | devAttr->numTransfers, devAttr->transferTicks, | ||
| 247 | devAttr->transferBytes, | ||
| 248 | devAttr->ring.bytesAllocated); | ||
| 249 | |||
| 250 | } | ||
| 251 | |||
| 252 | up(&gDMA.lock); | ||
| 253 | *eof = 1; | ||
| 254 | |||
| 255 | return len; | ||
| 256 | } | ||
| 257 | |||
| 258 | /****************************************************************************/ | ||
| 259 | /** | ||
| 260 | * Determines if a DMA_Device_t is "valid". | ||
| 261 | * | ||
| 262 | * @return | ||
| 263 | * TRUE - dma device is valid | ||
| 264 | * FALSE - dma device isn't valid | ||
| 265 | */ | ||
| 266 | /****************************************************************************/ | ||
| 267 | |||
| 268 | static inline int IsDeviceValid(DMA_Device_t device) | ||
| 269 | { | ||
| 270 | return (device >= 0) && (device < DMA_NUM_DEVICE_ENTRIES); | ||
| 271 | } | ||
| 272 | |||
| 273 | /****************************************************************************/ | ||
| 274 | /** | ||
| 275 | * Translates a DMA handle into a pointer to a channel. | ||
| 276 | * | ||
| 277 | * @return | ||
| 278 | * non-NULL - pointer to DMA_Channel_t | ||
| 279 | * NULL - DMA Handle was invalid | ||
| 280 | */ | ||
| 281 | /****************************************************************************/ | ||
| 282 | |||
| 283 | static inline DMA_Channel_t *HandleToChannel(DMA_Handle_t handle) | ||
| 284 | { | ||
| 285 | int controllerIdx; | ||
| 286 | int channelIdx; | ||
| 287 | |||
| 288 | controllerIdx = CONTROLLER_FROM_HANDLE(handle); | ||
| 289 | channelIdx = CHANNEL_FROM_HANDLE(handle); | ||
| 290 | |||
| 291 | if ((controllerIdx > DMA_NUM_CONTROLLERS) | ||
| 292 | || (channelIdx > DMA_NUM_CHANNELS)) { | ||
| 293 | return NULL; | ||
| 294 | } | ||
| 295 | return &gDMA.controller[controllerIdx].channel[channelIdx]; | ||
| 296 | } | ||
| 297 | |||
| 298 | /****************************************************************************/ | ||
| 299 | /** | ||
| 300 | * Interrupt handler which is called to process DMA interrupts. | ||
| 301 | */ | ||
| 302 | /****************************************************************************/ | ||
| 303 | |||
| 304 | static irqreturn_t dma_interrupt_handler(int irq, void *dev_id) | ||
| 305 | { | ||
| 306 | DMA_Channel_t *channel; | ||
| 307 | DMA_DeviceAttribute_t *devAttr; | ||
| 308 | int irqStatus; | ||
| 309 | |||
| 310 | channel = (DMA_Channel_t *) dev_id; | ||
| 311 | |||
| 312 | /* Figure out why we were called, and knock down the interrupt */ | ||
| 313 | |||
| 314 | irqStatus = dmacHw_getInterruptStatus(channel->dmacHwHandle); | ||
| 315 | dmacHw_clearInterrupt(channel->dmacHwHandle); | ||
| 316 | |||
| 317 | if ((channel->devType < 0) | ||
| 318 | || (channel->devType > DMA_NUM_DEVICE_ENTRIES)) { | ||
| 319 | printk(KERN_ERR "dma_interrupt_handler: Invalid devType: %d\n", | ||
| 320 | channel->devType); | ||
| 321 | return IRQ_NONE; | ||
| 322 | } | ||
| 323 | devAttr = &DMA_gDeviceAttribute[channel->devType]; | ||
| 324 | |||
| 325 | /* Update stats */ | ||
| 326 | |||
| 327 | if ((irqStatus & dmacHw_INTERRUPT_STATUS_TRANS) != 0) { | ||
| 328 | devAttr->transferTicks += | ||
| 329 | (timer_get_tick_count() - devAttr->transferStartTime); | ||
| 330 | } | ||
| 331 | |||
| 332 | if ((irqStatus & dmacHw_INTERRUPT_STATUS_ERROR) != 0) { | ||
| 333 | printk(KERN_ERR | ||
| 334 | "dma_interrupt_handler: devType :%d DMA error (%s)\n", | ||
| 335 | channel->devType, devAttr->name); | ||
| 336 | } else { | ||
| 337 | devAttr->numTransfers++; | ||
| 338 | devAttr->transferBytes += devAttr->numBytes; | ||
| 339 | } | ||
| 340 | |||
| 341 | /* Call any installed handler */ | ||
| 342 | |||
| 343 | if (devAttr->devHandler != NULL) { | ||
| 344 | devAttr->devHandler(channel->devType, irqStatus, | ||
| 345 | devAttr->userData); | ||
| 346 | } | ||
| 347 | |||
| 348 | return IRQ_HANDLED; | ||
| 349 | } | ||
| 350 | |||
| 351 | /****************************************************************************/ | ||
| 352 | /** | ||
| 353 | * Allocates memory to hold a descriptor ring. The descriptor ring then | ||
| 354 | * needs to be populated by making one or more calls to | ||
| 355 | * dna_add_descriptors. | ||
| 356 | * | ||
| 357 | * The returned descriptor ring will be automatically initialized. | ||
| 358 | * | ||
| 359 | * @return | ||
| 360 | * 0 Descriptor ring was allocated successfully | ||
| 361 | * -EINVAL Invalid parameters passed in | ||
| 362 | * -ENOMEM Unable to allocate memory for the desired number of descriptors. | ||
| 363 | */ | ||
| 364 | /****************************************************************************/ | ||
| 365 | |||
| 366 | int dma_alloc_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to populate */ | ||
| 367 | int numDescriptors /* Number of descriptors that need to be allocated. */ | ||
| 368 | ) { | ||
| 369 | size_t bytesToAlloc = dmacHw_descriptorLen(numDescriptors); | ||
| 370 | |||
| 371 | if ((ring == NULL) || (numDescriptors <= 0)) { | ||
| 372 | return -EINVAL; | ||
| 373 | } | ||
| 374 | |||
| 375 | ring->physAddr = 0; | ||
| 376 | ring->descriptorsAllocated = 0; | ||
| 377 | ring->bytesAllocated = 0; | ||
| 378 | |||
| 379 | ring->virtAddr = dma_alloc_writecombine(NULL, | ||
| 380 | bytesToAlloc, | ||
| 381 | &ring->physAddr, | ||
| 382 | GFP_KERNEL); | ||
| 383 | if (ring->virtAddr == NULL) { | ||
| 384 | return -ENOMEM; | ||
| 385 | } | ||
| 386 | |||
| 387 | ring->bytesAllocated = bytesToAlloc; | ||
| 388 | ring->descriptorsAllocated = numDescriptors; | ||
| 389 | |||
| 390 | return dma_init_descriptor_ring(ring, numDescriptors); | ||
| 391 | } | ||
| 392 | |||
| 393 | EXPORT_SYMBOL(dma_alloc_descriptor_ring); | ||
| 394 | |||
| 395 | /****************************************************************************/ | ||
| 396 | /** | ||
| 397 | * Releases the memory which was previously allocated for a descriptor ring. | ||
| 398 | */ | ||
| 399 | /****************************************************************************/ | ||
| 400 | |||
| 401 | void dma_free_descriptor_ring(DMA_DescriptorRing_t *ring /* Descriptor to release */ | ||
| 402 | ) { | ||
| 403 | if (ring->virtAddr != NULL) { | ||
| 404 | dma_free_writecombine(NULL, | ||
| 405 | ring->bytesAllocated, | ||
| 406 | ring->virtAddr, ring->physAddr); | ||
| 407 | } | ||
| 408 | |||
| 409 | ring->bytesAllocated = 0; | ||
| 410 | ring->descriptorsAllocated = 0; | ||
| 411 | ring->virtAddr = NULL; | ||
| 412 | ring->physAddr = 0; | ||
| 413 | } | ||
| 414 | |||
| 415 | EXPORT_SYMBOL(dma_free_descriptor_ring); | ||
| 416 | |||
| 417 | /****************************************************************************/ | ||
| 418 | /** | ||
| 419 | * Initializes a descriptor ring, so that descriptors can be added to it. | ||
| 420 | * Once a descriptor ring has been allocated, it may be reinitialized for | ||
| 421 | * use with additional/different regions of memory. | ||
| 422 | * | ||
| 423 | * Note that if 7 descriptors are allocated, it's perfectly acceptable to | ||
| 424 | * initialize the ring with a smaller number of descriptors. The amount | ||
| 425 | * of memory allocated for the descriptor ring will not be reduced, and | ||
| 426 | * the descriptor ring may be reinitialized later | ||
| 427 | * | ||
| 428 | * @return | ||
| 429 | * 0 Descriptor ring was initialized successfully | ||
| 430 | * -ENOMEM The descriptor which was passed in has insufficient space | ||
| 431 | * to hold the desired number of descriptors. | ||
| 432 | */ | ||
| 433 | /****************************************************************************/ | ||
| 434 | |||
| 435 | int dma_init_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to initialize */ | ||
| 436 | int numDescriptors /* Number of descriptors to initialize. */ | ||
| 437 | ) { | ||
| 438 | if (ring->virtAddr == NULL) { | ||
| 439 | return -EINVAL; | ||
| 440 | } | ||
| 441 | if (dmacHw_initDescriptor(ring->virtAddr, | ||
| 442 | ring->physAddr, | ||
| 443 | ring->bytesAllocated, numDescriptors) < 0) { | ||
| 444 | printk(KERN_ERR | ||
| 445 | "dma_init_descriptor_ring: dmacHw_initDescriptor failed\n"); | ||
| 446 | return -ENOMEM; | ||
| 447 | } | ||
| 448 | |||
| 449 | return 0; | ||
| 450 | } | ||
| 451 | |||
| 452 | EXPORT_SYMBOL(dma_init_descriptor_ring); | ||
| 453 | |||
| 454 | /****************************************************************************/ | ||
| 455 | /** | ||
| 456 | * Determines the number of descriptors which would be required for a | ||
| 457 | * transfer of the indicated memory region. | ||
| 458 | * | ||
| 459 | * This function also needs to know which DMA device this transfer will | ||
| 460 | * be destined for, so that the appropriate DMA configuration can be retrieved. | ||
| 461 | * DMA parameters such as transfer width, and whether this is a memory-to-memory | ||
| 462 | * or memory-to-peripheral, etc can all affect the actual number of descriptors | ||
| 463 | * required. | ||
| 464 | * | ||
| 465 | * @return | ||
| 466 | * > 0 Returns the number of descriptors required for the indicated transfer | ||
| 467 | * -ENODEV - Device handed in is invalid. | ||
| 468 | * -EINVAL Invalid parameters | ||
| 469 | * -ENOMEM Memory exhausted | ||
| 470 | */ | ||
| 471 | /****************************************************************************/ | ||
| 472 | |||
| 473 | int dma_calculate_descriptor_count(DMA_Device_t device, /* DMA Device that this will be associated with */ | ||
| 474 | dma_addr_t srcData, /* Place to get data to write to device */ | ||
| 475 | dma_addr_t dstData, /* Pointer to device data address */ | ||
| 476 | size_t numBytes /* Number of bytes to transfer to the device */ | ||
| 477 | ) { | ||
| 478 | int numDescriptors; | ||
| 479 | DMA_DeviceAttribute_t *devAttr; | ||
| 480 | |||
| 481 | if (!IsDeviceValid(device)) { | ||
| 482 | return -ENODEV; | ||
| 483 | } | ||
| 484 | devAttr = &DMA_gDeviceAttribute[device]; | ||
| 485 | |||
| 486 | numDescriptors = dmacHw_calculateDescriptorCount(&devAttr->config, | ||
| 487 | (void *)srcData, | ||
| 488 | (void *)dstData, | ||
| 489 | numBytes); | ||
| 490 | if (numDescriptors < 0) { | ||
| 491 | printk(KERN_ERR | ||
| 492 | "dma_calculate_descriptor_count: dmacHw_calculateDescriptorCount failed\n"); | ||
| 493 | return -EINVAL; | ||
| 494 | } | ||
| 495 | |||
| 496 | return numDescriptors; | ||
| 497 | } | ||
| 498 | |||
| 499 | EXPORT_SYMBOL(dma_calculate_descriptor_count); | ||
| 500 | |||
| 501 | /****************************************************************************/ | ||
| 502 | /** | ||
| 503 | * Adds a region of memory to the descriptor ring. Note that it may take | ||
| 504 | * multiple descriptors for each region of memory. It is the callers | ||
| 505 | * responsibility to allocate a sufficiently large descriptor ring. | ||
| 506 | * | ||
| 507 | * @return | ||
| 508 | * 0 Descriptors were added successfully | ||
| 509 | * -ENODEV Device handed in is invalid. | ||
| 510 | * -EINVAL Invalid parameters | ||
| 511 | * -ENOMEM Memory exhausted | ||
| 512 | */ | ||
| 513 | /****************************************************************************/ | ||
| 514 | |||
| 515 | int dma_add_descriptors(DMA_DescriptorRing_t *ring, /* Descriptor ring to add descriptors to */ | ||
| 516 | DMA_Device_t device, /* DMA Device that descriptors are for */ | ||
| 517 | dma_addr_t srcData, /* Place to get data (memory or device) */ | ||
| 518 | dma_addr_t dstData, /* Place to put data (memory or device) */ | ||
| 519 | size_t numBytes /* Number of bytes to transfer to the device */ | ||
| 520 | ) { | ||
| 521 | int rc; | ||
| 522 | DMA_DeviceAttribute_t *devAttr; | ||
| 523 | |||
| 524 | if (!IsDeviceValid(device)) { | ||
| 525 | return -ENODEV; | ||
| 526 | } | ||
| 527 | devAttr = &DMA_gDeviceAttribute[device]; | ||
| 528 | |||
| 529 | rc = dmacHw_setDataDescriptor(&devAttr->config, | ||
| 530 | ring->virtAddr, | ||
| 531 | (void *)srcData, | ||
| 532 | (void *)dstData, numBytes); | ||
| 533 | if (rc < 0) { | ||
| 534 | printk(KERN_ERR | ||
| 535 | "dma_add_descriptors: dmacHw_setDataDescriptor failed with code: %d\n", | ||
| 536 | rc); | ||
| 537 | return -ENOMEM; | ||
| 538 | } | ||
| 539 | |||
| 540 | return 0; | ||
| 541 | } | ||
| 542 | |||
| 543 | EXPORT_SYMBOL(dma_add_descriptors); | ||
| 544 | |||
| 545 | /****************************************************************************/ | ||
| 546 | /** | ||
| 547 | * Sets the descriptor ring associated with a device. | ||
| 548 | * | ||
| 549 | * Once set, the descriptor ring will be associated with the device, even | ||
| 550 | * across channel request/free calls. Passing in a NULL descriptor ring | ||
| 551 | * will release any descriptor ring currently associated with the device. | ||
| 552 | * | ||
| 553 | * Note: If you call dma_transfer, or one of the other dma_alloc_ functions | ||
| 554 | * the descriptor ring may be released and reallocated. | ||
| 555 | * | ||
| 556 | * Note: This function will release the descriptor memory for any current | ||
| 557 | * descriptor ring associated with this device. | ||
| 558 | * | ||
| 559 | * @return | ||
| 560 | * 0 Descriptors were added successfully | ||
| 561 | * -ENODEV Device handed in is invalid. | ||
| 562 | */ | ||
| 563 | /****************************************************************************/ | ||
| 564 | |||
| 565 | int dma_set_device_descriptor_ring(DMA_Device_t device, /* Device to update the descriptor ring for. */ | ||
| 566 | DMA_DescriptorRing_t *ring /* Descriptor ring to add descriptors to */ | ||
| 567 | ) { | ||
| 568 | DMA_DeviceAttribute_t *devAttr; | ||
| 569 | |||
| 570 | if (!IsDeviceValid(device)) { | ||
| 571 | return -ENODEV; | ||
| 572 | } | ||
| 573 | devAttr = &DMA_gDeviceAttribute[device]; | ||
| 574 | |||
| 575 | /* Free the previously allocated descriptor ring */ | ||
| 576 | |||
| 577 | dma_free_descriptor_ring(&devAttr->ring); | ||
| 578 | |||
| 579 | if (ring != NULL) { | ||
| 580 | /* Copy in the new one */ | ||
| 581 | |||
| 582 | devAttr->ring = *ring; | ||
| 583 | } | ||
| 584 | |||
| 585 | /* Set things up so that if dma_transfer is called then this descriptor */ | ||
| 586 | /* ring will get freed. */ | ||
| 587 | |||
| 588 | devAttr->prevSrcData = 0; | ||
| 589 | devAttr->prevDstData = 0; | ||
| 590 | devAttr->prevNumBytes = 0; | ||
| 591 | |||
| 592 | return 0; | ||
| 593 | } | ||
| 594 | |||
| 595 | EXPORT_SYMBOL(dma_set_device_descriptor_ring); | ||
| 596 | |||
| 597 | /****************************************************************************/ | ||
| 598 | /** | ||
| 599 | * Retrieves the descriptor ring associated with a device. | ||
| 600 | * | ||
| 601 | * @return | ||
| 602 | * 0 Descriptors were added successfully | ||
| 603 | * -ENODEV Device handed in is invalid. | ||
| 604 | */ | ||
| 605 | /****************************************************************************/ | ||
| 606 | |||
| 607 | int dma_get_device_descriptor_ring(DMA_Device_t device, /* Device to retrieve the descriptor ring for. */ | ||
| 608 | DMA_DescriptorRing_t *ring /* Place to store retrieved ring */ | ||
| 609 | ) { | ||
| 610 | DMA_DeviceAttribute_t *devAttr; | ||
| 611 | |||
| 612 | memset(ring, 0, sizeof(*ring)); | ||
| 613 | |||
| 614 | if (!IsDeviceValid(device)) { | ||
| 615 | return -ENODEV; | ||
| 616 | } | ||
| 617 | devAttr = &DMA_gDeviceAttribute[device]; | ||
| 618 | |||
| 619 | *ring = devAttr->ring; | ||
| 620 | |||
| 621 | return 0; | ||
| 622 | } | ||
| 623 | |||
| 624 | EXPORT_SYMBOL(dma_get_device_descriptor_ring); | ||
| 625 | |||
| 626 | /****************************************************************************/ | ||
| 627 | /** | ||
| 628 | * Configures a DMA channel. | ||
| 629 | * | ||
| 630 | * @return | ||
| 631 | * >= 0 - Initialization was successfull. | ||
| 632 | * | ||
| 633 | * -EBUSY - Device is currently being used. | ||
| 634 | * -ENODEV - Device handed in is invalid. | ||
| 635 | */ | ||
| 636 | /****************************************************************************/ | ||
| 637 | |||
| 638 | static int ConfigChannel(DMA_Handle_t handle) | ||
| 639 | { | ||
| 640 | DMA_Channel_t *channel; | ||
| 641 | DMA_DeviceAttribute_t *devAttr; | ||
| 642 | int controllerIdx; | ||
| 643 | |||
| 644 | channel = HandleToChannel(handle); | ||
| 645 | if (channel == NULL) { | ||
| 646 | return -ENODEV; | ||
| 647 | } | ||
| 648 | devAttr = &DMA_gDeviceAttribute[channel->devType]; | ||
| 649 | controllerIdx = CONTROLLER_FROM_HANDLE(handle); | ||
| 650 | |||
| 651 | if ((devAttr->flags & DMA_DEVICE_FLAG_PORT_PER_DMAC) != 0) { | ||
| 652 | if (devAttr->config.transferType == | ||
| 653 | dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL) { | ||
| 654 | devAttr->config.dstPeripheralPort = | ||
| 655 | devAttr->dmacPort[controllerIdx]; | ||
| 656 | } else if (devAttr->config.transferType == | ||
| 657 | dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM) { | ||
| 658 | devAttr->config.srcPeripheralPort = | ||
| 659 | devAttr->dmacPort[controllerIdx]; | ||
| 660 | } | ||
| 661 | } | ||
| 662 | |||
| 663 | if (dmacHw_configChannel(channel->dmacHwHandle, &devAttr->config) != 0) { | ||
| 664 | printk(KERN_ERR "ConfigChannel: dmacHw_configChannel failed\n"); | ||
| 665 | return -EIO; | ||
| 666 | } | ||
| 667 | |||
| 668 | return 0; | ||
| 669 | } | ||
| 670 | |||
| 671 | /****************************************************************************/ | ||
| 672 | /** | ||
| 673 | * Intializes all of the data structures associated with the DMA. | ||
| 674 | * @return | ||
| 675 | * >= 0 - Initialization was successfull. | ||
| 676 | * | ||
| 677 | * -EBUSY - Device is currently being used. | ||
| 678 | * -ENODEV - Device handed in is invalid. | ||
| 679 | */ | ||
| 680 | /****************************************************************************/ | ||
| 681 | |||
| 682 | int dma_init(void) | ||
| 683 | { | ||
| 684 | int rc = 0; | ||
| 685 | int controllerIdx; | ||
| 686 | int channelIdx; | ||
| 687 | DMA_Device_t devIdx; | ||
| 688 | DMA_Channel_t *channel; | ||
| 689 | DMA_Handle_t dedicatedHandle; | ||
| 690 | |||
| 691 | memset(&gDMA, 0, sizeof(gDMA)); | ||
| 692 | |||
| 693 | init_MUTEX_LOCKED(&gDMA.lock); | ||
| 694 | init_waitqueue_head(&gDMA.freeChannelQ); | ||
| 695 | |||
| 696 | /* Initialize the Hardware */ | ||
| 697 | |||
| 698 | dmacHw_initDma(); | ||
| 699 | |||
| 700 | /* Start off by marking all of the DMA channels as shared. */ | ||
| 701 | |||
| 702 | for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS; | ||
| 703 | controllerIdx++) { | ||
| 704 | for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS; | ||
| 705 | channelIdx++) { | ||
| 706 | channel = | ||
| 707 | &gDMA.controller[controllerIdx].channel[channelIdx]; | ||
| 708 | |||
| 709 | channel->flags = 0; | ||
| 710 | channel->devType = DMA_DEVICE_NONE; | ||
| 711 | channel->lastDevType = DMA_DEVICE_NONE; | ||
| 712 | |||
| 713 | #if (DMA_DEBUG_TRACK_RESERVATION) | ||
| 714 | channel->fileName = ""; | ||
| 715 | channel->lineNum = 0; | ||
| 716 | #endif | ||
| 717 | |||
| 718 | channel->dmacHwHandle = | ||
| 719 | dmacHw_getChannelHandle(dmacHw_MAKE_CHANNEL_ID | ||
| 720 | (controllerIdx, | ||
| 721 | channelIdx)); | ||
| 722 | dmacHw_initChannel(channel->dmacHwHandle); | ||
| 723 | } | ||
| 724 | } | ||
| 725 | |||
| 726 | /* Record any special attributes that channels may have */ | ||
| 727 | |||
| 728 | gDMA.controller[0].channel[0].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO; | ||
| 729 | gDMA.controller[0].channel[1].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO; | ||
| 730 | gDMA.controller[1].channel[0].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO; | ||
| 731 | gDMA.controller[1].channel[1].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO; | ||
| 732 | |||
| 733 | /* Now walk through and record the dedicated channels. */ | ||
| 734 | |||
| 735 | for (devIdx = 0; devIdx < DMA_NUM_DEVICE_ENTRIES; devIdx++) { | ||
| 736 | DMA_DeviceAttribute_t *devAttr = &DMA_gDeviceAttribute[devIdx]; | ||
| 737 | |||
| 738 | if (((devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) != 0) | ||
| 739 | && ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) == 0)) { | ||
| 740 | printk(KERN_ERR | ||
| 741 | "DMA Device: %s Can only request NO_ISR for dedicated devices\n", | ||
| 742 | devAttr->name); | ||
| 743 | rc = -EINVAL; | ||
| 744 | goto out; | ||
| 745 | } | ||
| 746 | |||
| 747 | if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) { | ||
| 748 | /* This is a dedicated device. Mark the channel as being reserved. */ | ||
| 749 | |||
| 750 | if (devAttr->dedicatedController >= DMA_NUM_CONTROLLERS) { | ||
| 751 | printk(KERN_ERR | ||
| 752 | "DMA Device: %s DMA Controller %d is out of range\n", | ||
| 753 | devAttr->name, | ||
| 754 | devAttr->dedicatedController); | ||
| 755 | rc = -EINVAL; | ||
| 756 | goto out; | ||
| 757 | } | ||
| 758 | |||
| 759 | if (devAttr->dedicatedChannel >= DMA_NUM_CHANNELS) { | ||
| 760 | printk(KERN_ERR | ||
| 761 | "DMA Device: %s DMA Channel %d is out of range\n", | ||
| 762 | devAttr->name, | ||
| 763 | devAttr->dedicatedChannel); | ||
| 764 | rc = -EINVAL; | ||
| 765 | goto out; | ||
| 766 | } | ||
| 767 | |||
| 768 | dedicatedHandle = | ||
| 769 | MAKE_HANDLE(devAttr->dedicatedController, | ||
| 770 | devAttr->dedicatedChannel); | ||
| 771 | channel = HandleToChannel(dedicatedHandle); | ||
| 772 | |||
| 773 | if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) != | ||
| 774 | 0) { | ||
| 775 | printk | ||
| 776 | ("DMA Device: %s attempting to use same DMA Controller:Channel (%d:%d) as %s\n", | ||
| 777 | devAttr->name, | ||
| 778 | devAttr->dedicatedController, | ||
| 779 | devAttr->dedicatedChannel, | ||
| 780 | DMA_gDeviceAttribute[channel->devType]. | ||
| 781 | name); | ||
| 782 | rc = -EBUSY; | ||
| 783 | goto out; | ||
| 784 | } | ||
| 785 | |||
| 786 | channel->flags |= DMA_CHANNEL_FLAG_IS_DEDICATED; | ||
| 787 | channel->devType = devIdx; | ||
| 788 | |||
| 789 | if (devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) { | ||
| 790 | channel->flags |= DMA_CHANNEL_FLAG_NO_ISR; | ||
| 791 | } | ||
| 792 | |||
| 793 | /* For dedicated channels, we can go ahead and configure the DMA channel now */ | ||
| 794 | /* as well. */ | ||
| 795 | |||
| 796 | ConfigChannel(dedicatedHandle); | ||
| 797 | } | ||
| 798 | } | ||
| 799 | |||
| 800 | /* Go through and register the interrupt handlers */ | ||
| 801 | |||
| 802 | for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS; | ||
| 803 | controllerIdx++) { | ||
| 804 | for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS; | ||
| 805 | channelIdx++) { | ||
| 806 | channel = | ||
| 807 | &gDMA.controller[controllerIdx].channel[channelIdx]; | ||
| 808 | |||
| 809 | if ((channel->flags & DMA_CHANNEL_FLAG_NO_ISR) == 0) { | ||
| 810 | snprintf(channel->name, sizeof(channel->name), | ||
| 811 | "dma %d:%d %s", controllerIdx, | ||
| 812 | channelIdx, | ||
| 813 | channel->devType == | ||
| 814 | DMA_DEVICE_NONE ? "" : | ||
| 815 | DMA_gDeviceAttribute[channel->devType]. | ||
| 816 | name); | ||
| 817 | |||
| 818 | rc = | ||
| 819 | request_irq(IRQ_DMA0C0 + | ||
| 820 | (controllerIdx * | ||
| 821 | DMA_NUM_CHANNELS) + | ||
| 822 | channelIdx, | ||
| 823 | dma_interrupt_handler, | ||
| 824 | IRQF_DISABLED, channel->name, | ||
| 825 | channel); | ||
| 826 | if (rc != 0) { | ||
| 827 | printk(KERN_ERR | ||
| 828 | "request_irq for IRQ_DMA%dC%d failed\n", | ||
| 829 | controllerIdx, channelIdx); | ||
| 830 | } | ||
| 831 | } | ||
| 832 | } | ||
| 833 | } | ||
| 834 | |||
| 835 | /* Create /proc/dma/channels and /proc/dma/devices */ | ||
| 836 | |||
| 837 | gDmaDir = create_proc_entry("dma", S_IFDIR | S_IRUGO | S_IXUGO, NULL); | ||
| 838 | |||
| 839 | if (gDmaDir == NULL) { | ||
| 840 | printk(KERN_ERR "Unable to create /proc/dma\n"); | ||
| 841 | } else { | ||
| 842 | create_proc_read_entry("channels", 0, gDmaDir, | ||
| 843 | dma_proc_read_channels, NULL); | ||
| 844 | create_proc_read_entry("devices", 0, gDmaDir, | ||
| 845 | dma_proc_read_devices, NULL); | ||
| 846 | create_proc_read_entry("mem-type", 0, gDmaDir, | ||
| 847 | dma_proc_read_mem_type, NULL); | ||
| 848 | } | ||
| 849 | |||
| 850 | out: | ||
| 851 | |||
| 852 | up(&gDMA.lock); | ||
| 853 | |||
| 854 | return rc; | ||
| 855 | } | ||
| 856 | |||
| 857 | /****************************************************************************/ | ||
| 858 | /** | ||
| 859 | * Reserves a channel for use with @a dev. If the device is setup to use | ||
| 860 | * a shared channel, then this function will block until a free channel | ||
| 861 | * becomes available. | ||
| 862 | * | ||
| 863 | * @return | ||
| 864 | * >= 0 - A valid DMA Handle. | ||
| 865 | * -EBUSY - Device is currently being used. | ||
| 866 | * -ENODEV - Device handed in is invalid. | ||
| 867 | */ | ||
| 868 | /****************************************************************************/ | ||
| 869 | |||
| 870 | #if (DMA_DEBUG_TRACK_RESERVATION) | ||
| 871 | DMA_Handle_t dma_request_channel_dbg | ||
| 872 | (DMA_Device_t dev, const char *fileName, int lineNum) | ||
| 873 | #else | ||
| 874 | DMA_Handle_t dma_request_channel(DMA_Device_t dev) | ||
| 875 | #endif | ||
| 876 | { | ||
| 877 | DMA_Handle_t handle; | ||
| 878 | DMA_DeviceAttribute_t *devAttr; | ||
| 879 | DMA_Channel_t *channel; | ||
| 880 | int controllerIdx; | ||
| 881 | int controllerIdx2; | ||
| 882 | int channelIdx; | ||
| 883 | |||
| 884 | if (down_interruptible(&gDMA.lock) < 0) { | ||
| 885 | return -ERESTARTSYS; | ||
| 886 | } | ||
| 887 | |||
| 888 | if ((dev < 0) || (dev >= DMA_NUM_DEVICE_ENTRIES)) { | ||
| 889 | handle = -ENODEV; | ||
| 890 | goto out; | ||
| 891 | } | ||
| 892 | devAttr = &DMA_gDeviceAttribute[dev]; | ||
| 893 | |||
| 894 | #if (DMA_DEBUG_TRACK_RESERVATION) | ||
| 895 | { | ||
| 896 | char *s; | ||
| 897 | |||
| 898 | s = strrchr(fileName, '/'); | ||
| 899 | if (s != NULL) { | ||
| 900 | fileName = s + 1; | ||
| 901 | } | ||
| 902 | } | ||
| 903 | #endif | ||
| 904 | if ((devAttr->flags & DMA_DEVICE_FLAG_IN_USE) != 0) { | ||
| 905 | /* This device has already been requested and not been freed */ | ||
| 906 | |||
| 907 | printk(KERN_ERR "%s: device %s is already requested\n", | ||
| 908 | __func__, devAttr->name); | ||
| 909 | handle = -EBUSY; | ||
| 910 | goto out; | ||
| 911 | } | ||
| 912 | |||
| 913 | if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) { | ||
| 914 | /* This device has a dedicated channel. */ | ||
| 915 | |||
| 916 | channel = | ||
| 917 | &gDMA.controller[devAttr->dedicatedController]. | ||
| 918 | channel[devAttr->dedicatedChannel]; | ||
| 919 | if ((channel->flags & DMA_CHANNEL_FLAG_IN_USE) != 0) { | ||
| 920 | handle = -EBUSY; | ||
| 921 | goto out; | ||
| 922 | } | ||
| 923 | |||
| 924 | channel->flags |= DMA_CHANNEL_FLAG_IN_USE; | ||
| 925 | devAttr->flags |= DMA_DEVICE_FLAG_IN_USE; | ||
| 926 | |||
| 927 | #if (DMA_DEBUG_TRACK_RESERVATION) | ||
| 928 | channel->fileName = fileName; | ||
| 929 | channel->lineNum = lineNum; | ||
| 930 | #endif | ||
| 931 | handle = | ||
| 932 | MAKE_HANDLE(devAttr->dedicatedController, | ||
| 933 | devAttr->dedicatedChannel); | ||
| 934 | goto out; | ||
| 935 | } | ||
| 936 | |||
| 937 | /* This device needs to use one of the shared channels. */ | ||
| 938 | |||
| 939 | handle = DMA_INVALID_HANDLE; | ||
| 940 | while (handle == DMA_INVALID_HANDLE) { | ||
| 941 | /* Scan through the shared channels and see if one is available */ | ||
| 942 | |||
| 943 | for (controllerIdx2 = 0; controllerIdx2 < DMA_NUM_CONTROLLERS; | ||
| 944 | controllerIdx2++) { | ||
| 945 | /* Check to see if we should try on controller 1 first. */ | ||
| 946 | |||
| 947 | controllerIdx = controllerIdx2; | ||
| 948 | if ((devAttr-> | ||
| 949 | flags & DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST) != 0) { | ||
| 950 | controllerIdx = 1 - controllerIdx; | ||
| 951 | } | ||
| 952 | |||
| 953 | /* See if the device is available on the controller being tested */ | ||
| 954 | |||
| 955 | if ((devAttr-> | ||
| 956 | flags & (DMA_DEVICE_FLAG_ON_DMA0 << controllerIdx)) | ||
| 957 | != 0) { | ||
| 958 | for (channelIdx = 0; | ||
| 959 | channelIdx < DMA_NUM_CHANNELS; | ||
| 960 | channelIdx++) { | ||
| 961 | channel = | ||
| 962 | &gDMA.controller[controllerIdx]. | ||
| 963 | channel[channelIdx]; | ||
| 964 | |||
| 965 | if (((channel-> | ||
| 966 | flags & | ||
| 967 | DMA_CHANNEL_FLAG_IS_DEDICATED) == | ||
| 968 | 0) | ||
| 969 | && | ||
| 970 | ((channel-> | ||
| 971 | flags & DMA_CHANNEL_FLAG_IN_USE) | ||
| 972 | == 0)) { | ||
| 973 | if (((channel-> | ||
| 974 | flags & | ||
| 975 | DMA_CHANNEL_FLAG_LARGE_FIFO) | ||
| 976 | != 0) | ||
| 977 | && | ||
| 978 | ((devAttr-> | ||
| 979 | flags & | ||
| 980 | DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO) | ||
| 981 | == 0)) { | ||
| 982 | /* This channel is a large fifo - don't tie it up */ | ||
| 983 | /* with devices that we don't want using it. */ | ||
| 984 | |||
| 985 | continue; | ||
| 986 | } | ||
| 987 | |||
| 988 | channel->flags |= | ||
| 989 | DMA_CHANNEL_FLAG_IN_USE; | ||
| 990 | channel->devType = dev; | ||
| 991 | devAttr->flags |= | ||
| 992 | DMA_DEVICE_FLAG_IN_USE; | ||
| 993 | |||
| 994 | #if (DMA_DEBUG_TRACK_RESERVATION) | ||
| 995 | channel->fileName = fileName; | ||
| 996 | channel->lineNum = lineNum; | ||
| 997 | #endif | ||
| 998 | handle = | ||
| 999 | MAKE_HANDLE(controllerIdx, | ||
| 1000 | channelIdx); | ||
| 1001 | |||
| 1002 | /* Now that we've reserved the channel - we can go ahead and configure it */ | ||
| 1003 | |||
| 1004 | if (ConfigChannel(handle) != 0) { | ||
| 1005 | handle = -EIO; | ||
| 1006 | printk(KERN_ERR | ||
| 1007 | "dma_request_channel: ConfigChannel failed\n"); | ||
| 1008 | } | ||
| 1009 | goto out; | ||
| 1010 | } | ||
| 1011 | } | ||
| 1012 | } | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | /* No channels are currently available. Let's wait for one to free up. */ | ||
| 1016 | |||
| 1017 | { | ||
| 1018 | DEFINE_WAIT(wait); | ||
| 1019 | |||
| 1020 | prepare_to_wait(&gDMA.freeChannelQ, &wait, | ||
| 1021 | TASK_INTERRUPTIBLE); | ||
| 1022 | up(&gDMA.lock); | ||
| 1023 | schedule(); | ||
| 1024 | finish_wait(&gDMA.freeChannelQ, &wait); | ||
| 1025 | |||
| 1026 | if (signal_pending(current)) { | ||
| 1027 | /* We don't currently hold gDMA.lock, so we return directly */ | ||
| 1028 | |||
| 1029 | return -ERESTARTSYS; | ||
| 1030 | } | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | if (down_interruptible(&gDMA.lock)) { | ||
| 1034 | return -ERESTARTSYS; | ||
| 1035 | } | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | out: | ||
| 1039 | up(&gDMA.lock); | ||
| 1040 | |||
| 1041 | return handle; | ||
| 1042 | } | ||
| 1043 | |||
| 1044 | /* Create both _dbg and non _dbg functions for modules. */ | ||
| 1045 | |||
| 1046 | #if (DMA_DEBUG_TRACK_RESERVATION) | ||
| 1047 | #undef dma_request_channel | ||
| 1048 | DMA_Handle_t dma_request_channel(DMA_Device_t dev) | ||
| 1049 | { | ||
| 1050 | return dma_request_channel_dbg(dev, __FILE__, __LINE__); | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | EXPORT_SYMBOL(dma_request_channel_dbg); | ||
| 1054 | #endif | ||
| 1055 | EXPORT_SYMBOL(dma_request_channel); | ||
| 1056 | |||
| 1057 | /****************************************************************************/ | ||
| 1058 | /** | ||
| 1059 | * Frees a previously allocated DMA Handle. | ||
| 1060 | */ | ||
| 1061 | /****************************************************************************/ | ||
| 1062 | |||
| 1063 | int dma_free_channel(DMA_Handle_t handle /* DMA handle. */ | ||
| 1064 | ) { | ||
| 1065 | int rc = 0; | ||
| 1066 | DMA_Channel_t *channel; | ||
| 1067 | DMA_DeviceAttribute_t *devAttr; | ||
| 1068 | |||
| 1069 | if (down_interruptible(&gDMA.lock) < 0) { | ||
| 1070 | return -ERESTARTSYS; | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | channel = HandleToChannel(handle); | ||
| 1074 | if (channel == NULL) { | ||
| 1075 | rc = -EINVAL; | ||
| 1076 | goto out; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | devAttr = &DMA_gDeviceAttribute[channel->devType]; | ||
| 1080 | |||
| 1081 | if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) == 0) { | ||
| 1082 | channel->lastDevType = channel->devType; | ||
| 1083 | channel->devType = DMA_DEVICE_NONE; | ||
| 1084 | } | ||
| 1085 | channel->flags &= ~DMA_CHANNEL_FLAG_IN_USE; | ||
| 1086 | devAttr->flags &= ~DMA_DEVICE_FLAG_IN_USE; | ||
| 1087 | |||
| 1088 | out: | ||
| 1089 | up(&gDMA.lock); | ||
| 1090 | |||
| 1091 | wake_up_interruptible(&gDMA.freeChannelQ); | ||
| 1092 | |||
| 1093 | return rc; | ||
| 1094 | } | ||
| 1095 | |||
| 1096 | EXPORT_SYMBOL(dma_free_channel); | ||
| 1097 | |||
| 1098 | /****************************************************************************/ | ||
| 1099 | /** | ||
| 1100 | * Determines if a given device has been configured as using a shared | ||
| 1101 | * channel. | ||
| 1102 | * | ||
| 1103 | * @return | ||
| 1104 | * 0 Device uses a dedicated channel | ||
| 1105 | * > zero Device uses a shared channel | ||
| 1106 | * < zero Error code | ||
| 1107 | */ | ||
| 1108 | /****************************************************************************/ | ||
| 1109 | |||
| 1110 | int dma_device_is_channel_shared(DMA_Device_t device /* Device to check. */ | ||
| 1111 | ) { | ||
| 1112 | DMA_DeviceAttribute_t *devAttr; | ||
| 1113 | |||
| 1114 | if (!IsDeviceValid(device)) { | ||
| 1115 | return -ENODEV; | ||
| 1116 | } | ||
| 1117 | devAttr = &DMA_gDeviceAttribute[device]; | ||
| 1118 | |||
| 1119 | return ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) == 0); | ||
| 1120 | } | ||
| 1121 | |||
| 1122 | EXPORT_SYMBOL(dma_device_is_channel_shared); | ||
| 1123 | |||
| 1124 | /****************************************************************************/ | ||
| 1125 | /** | ||
| 1126 | * Allocates buffers for the descriptors. This is normally done automatically | ||
| 1127 | * but needs to be done explicitly when initiating a dma from interrupt | ||
| 1128 | * context. | ||
| 1129 | * | ||
| 1130 | * @return | ||
| 1131 | * 0 Descriptors were allocated successfully | ||
| 1132 | * -EINVAL Invalid device type for this kind of transfer | ||
| 1133 | * (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) | ||
| 1134 | * -ENOMEM Memory exhausted | ||
| 1135 | */ | ||
| 1136 | /****************************************************************************/ | ||
| 1137 | |||
| 1138 | int dma_alloc_descriptors(DMA_Handle_t handle, /* DMA Handle */ | ||
| 1139 | dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */ | ||
| 1140 | dma_addr_t srcData, /* Place to get data to write to device */ | ||
| 1141 | dma_addr_t dstData, /* Pointer to device data address */ | ||
| 1142 | size_t numBytes /* Number of bytes to transfer to the device */ | ||
| 1143 | ) { | ||
| 1144 | DMA_Channel_t *channel; | ||
| 1145 | DMA_DeviceAttribute_t *devAttr; | ||
| 1146 | int numDescriptors; | ||
| 1147 | size_t ringBytesRequired; | ||
| 1148 | int rc = 0; | ||
| 1149 | |||
| 1150 | channel = HandleToChannel(handle); | ||
| 1151 | if (channel == NULL) { | ||
| 1152 | return -ENODEV; | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | devAttr = &DMA_gDeviceAttribute[channel->devType]; | ||
| 1156 | |||
| 1157 | if (devAttr->config.transferType != transferType) { | ||
| 1158 | return -EINVAL; | ||
| 1159 | } | ||
| 1160 | |||
| 1161 | /* Figure out how many descriptors we need. */ | ||
| 1162 | |||
| 1163 | /* printk("srcData: 0x%08x dstData: 0x%08x, numBytes: %d\n", */ | ||
| 1164 | /* srcData, dstData, numBytes); */ | ||
| 1165 | |||
| 1166 | numDescriptors = dmacHw_calculateDescriptorCount(&devAttr->config, | ||
| 1167 | (void *)srcData, | ||
| 1168 | (void *)dstData, | ||
| 1169 | numBytes); | ||
| 1170 | if (numDescriptors < 0) { | ||
| 1171 | printk(KERN_ERR "%s: dmacHw_calculateDescriptorCount failed\n", | ||
| 1172 | __func__); | ||
| 1173 | return -EINVAL; | ||
| 1174 | } | ||
| 1175 | |||
| 1176 | /* Check to see if we can reuse the existing descriptor ring, or if we need to allocate */ | ||
| 1177 | /* a new one. */ | ||
| 1178 | |||
| 1179 | ringBytesRequired = dmacHw_descriptorLen(numDescriptors); | ||
| 1180 | |||
| 1181 | /* printk("ringBytesRequired: %d\n", ringBytesRequired); */ | ||
| 1182 | |||
| 1183 | if (ringBytesRequired > devAttr->ring.bytesAllocated) { | ||
| 1184 | /* Make sure that this code path is never taken from interrupt context. */ | ||
| 1185 | /* It's OK for an interrupt to initiate a DMA transfer, but the descriptor */ | ||
| 1186 | /* allocation needs to have already been done. */ | ||
| 1187 | |||
| 1188 | might_sleep(); | ||
| 1189 | |||
| 1190 | /* Free the old descriptor ring and allocate a new one. */ | ||
| 1191 | |||
| 1192 | dma_free_descriptor_ring(&devAttr->ring); | ||
| 1193 | |||
| 1194 | /* And allocate a new one. */ | ||
| 1195 | |||
| 1196 | rc = | ||
| 1197 | dma_alloc_descriptor_ring(&devAttr->ring, | ||
| 1198 | numDescriptors); | ||
| 1199 | if (rc < 0) { | ||
| 1200 | printk(KERN_ERR | ||
| 1201 | "%s: dma_alloc_descriptor_ring(%d) failed\n", | ||
| 1202 | __func__, numDescriptors); | ||
| 1203 | return rc; | ||
| 1204 | } | ||
| 1205 | /* Setup the descriptor for this transfer */ | ||
| 1206 | |||
| 1207 | if (dmacHw_initDescriptor(devAttr->ring.virtAddr, | ||
| 1208 | devAttr->ring.physAddr, | ||
| 1209 | devAttr->ring.bytesAllocated, | ||
| 1210 | numDescriptors) < 0) { | ||
| 1211 | printk(KERN_ERR "%s: dmacHw_initDescriptor failed\n", | ||
| 1212 | __func__); | ||
| 1213 | return -EINVAL; | ||
| 1214 | } | ||
| 1215 | } else { | ||
| 1216 | /* We've already got enough ring buffer allocated. All we need to do is reset */ | ||
| 1217 | /* any control information, just in case the previous DMA was stopped. */ | ||
| 1218 | |||
| 1219 | dmacHw_resetDescriptorControl(devAttr->ring.virtAddr); | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | /* dma_alloc/free both set the prevSrc/DstData to 0. If they happen to be the same */ | ||
| 1223 | /* as last time, then we don't need to call setDataDescriptor again. */ | ||
| 1224 | |||
| 1225 | if (dmacHw_setDataDescriptor(&devAttr->config, | ||
| 1226 | devAttr->ring.virtAddr, | ||
| 1227 | (void *)srcData, | ||
| 1228 | (void *)dstData, numBytes) < 0) { | ||
| 1229 | printk(KERN_ERR "%s: dmacHw_setDataDescriptor failed\n", | ||
| 1230 | __func__); | ||
| 1231 | return -EINVAL; | ||
| 1232 | } | ||
| 1233 | |||
| 1234 | /* Remember the critical information for this transfer so that we can eliminate */ | ||
| 1235 | /* another call to dma_alloc_descriptors if the caller reuses the same buffers */ | ||
| 1236 | |||
| 1237 | devAttr->prevSrcData = srcData; | ||
| 1238 | devAttr->prevDstData = dstData; | ||
| 1239 | devAttr->prevNumBytes = numBytes; | ||
| 1240 | |||
| 1241 | return 0; | ||
| 1242 | } | ||
| 1243 | |||
| 1244 | EXPORT_SYMBOL(dma_alloc_descriptors); | ||
| 1245 | |||
| 1246 | /****************************************************************************/ | ||
| 1247 | /** | ||
| 1248 | * Allocates and sets up descriptors for a double buffered circular buffer. | ||
| 1249 | * | ||
| 1250 | * This is primarily intended to be used for things like the ingress samples | ||
| 1251 | * from a microphone. | ||
| 1252 | * | ||
| 1253 | * @return | ||
| 1254 | * > 0 Number of descriptors actually allocated. | ||
| 1255 | * -EINVAL Invalid device type for this kind of transfer | ||
| 1256 | * (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) | ||
| 1257 | * -ENOMEM Memory exhausted | ||
| 1258 | */ | ||
| 1259 | /****************************************************************************/ | ||
| 1260 | |||
| 1261 | int dma_alloc_double_dst_descriptors(DMA_Handle_t handle, /* DMA Handle */ | ||
| 1262 | dma_addr_t srcData, /* Physical address of source data */ | ||
| 1263 | dma_addr_t dstData1, /* Physical address of first destination buffer */ | ||
| 1264 | dma_addr_t dstData2, /* Physical address of second destination buffer */ | ||
| 1265 | size_t numBytes /* Number of bytes in each destination buffer */ | ||
| 1266 | ) { | ||
| 1267 | DMA_Channel_t *channel; | ||
| 1268 | DMA_DeviceAttribute_t *devAttr; | ||
| 1269 | int numDst1Descriptors; | ||
| 1270 | int numDst2Descriptors; | ||
| 1271 | int numDescriptors; | ||
| 1272 | size_t ringBytesRequired; | ||
| 1273 | int rc = 0; | ||
| 1274 | |||
| 1275 | channel = HandleToChannel(handle); | ||
| 1276 | if (channel == NULL) { | ||
| 1277 | return -ENODEV; | ||
| 1278 | } | ||
| 1279 | |||
| 1280 | devAttr = &DMA_gDeviceAttribute[channel->devType]; | ||
| 1281 | |||
| 1282 | /* Figure out how many descriptors we need. */ | ||
| 1283 | |||
| 1284 | /* printk("srcData: 0x%08x dstData: 0x%08x, numBytes: %d\n", */ | ||
| 1285 | /* srcData, dstData, numBytes); */ | ||
| 1286 | |||
| 1287 | numDst1Descriptors = | ||
| 1288 | dmacHw_calculateDescriptorCount(&devAttr->config, (void *)srcData, | ||
| 1289 | (void *)dstData1, numBytes); | ||
| 1290 | if (numDst1Descriptors < 0) { | ||
| 1291 | return -EINVAL; | ||
| 1292 | } | ||
| 1293 | numDst2Descriptors = | ||
| 1294 | dmacHw_calculateDescriptorCount(&devAttr->config, (void *)srcData, | ||
| 1295 | (void *)dstData2, numBytes); | ||
| 1296 | if (numDst2Descriptors < 0) { | ||
| 1297 | return -EINVAL; | ||
| 1298 | } | ||
| 1299 | numDescriptors = numDst1Descriptors + numDst2Descriptors; | ||
| 1300 | /* printk("numDescriptors: %d\n", numDescriptors); */ | ||
| 1301 | |||
| 1302 | /* Check to see if we can reuse the existing descriptor ring, or if we need to allocate */ | ||
| 1303 | /* a new one. */ | ||
| 1304 | |||
| 1305 | ringBytesRequired = dmacHw_descriptorLen(numDescriptors); | ||
| 1306 | |||
| 1307 | /* printk("ringBytesRequired: %d\n", ringBytesRequired); */ | ||
| 1308 | |||
| 1309 | if (ringBytesRequired > devAttr->ring.bytesAllocated) { | ||
| 1310 | /* Make sure that this code path is never taken from interrupt context. */ | ||
| 1311 | /* It's OK for an interrupt to initiate a DMA transfer, but the descriptor */ | ||
| 1312 | /* allocation needs to have already been done. */ | ||
| 1313 | |||
| 1314 | might_sleep(); | ||
| 1315 | |||
| 1316 | /* Free the old descriptor ring and allocate a new one. */ | ||
| 1317 | |||
| 1318 | dma_free_descriptor_ring(&devAttr->ring); | ||
| 1319 | |||
| 1320 | /* And allocate a new one. */ | ||
| 1321 | |||
| 1322 | rc = | ||
| 1323 | dma_alloc_descriptor_ring(&devAttr->ring, | ||
| 1324 | numDescriptors); | ||
| 1325 | if (rc < 0) { | ||
| 1326 | printk(KERN_ERR | ||
| 1327 | "%s: dma_alloc_descriptor_ring(%d) failed\n", | ||
| 1328 | __func__, ringBytesRequired); | ||
| 1329 | return rc; | ||
| 1330 | } | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | /* Setup the descriptor for this transfer. Since this function is used with */ | ||
| 1334 | /* CONTINUOUS DMA operations, we need to reinitialize every time, otherwise */ | ||
| 1335 | /* setDataDescriptor will keep trying to append onto the end. */ | ||
| 1336 | |||
| 1337 | if (dmacHw_initDescriptor(devAttr->ring.virtAddr, | ||
| 1338 | devAttr->ring.physAddr, | ||
| 1339 | devAttr->ring.bytesAllocated, | ||
| 1340 | numDescriptors) < 0) { | ||
| 1341 | printk(KERN_ERR "%s: dmacHw_initDescriptor failed\n", __func__); | ||
| 1342 | return -EINVAL; | ||
| 1343 | } | ||
| 1344 | |||
| 1345 | /* dma_alloc/free both set the prevSrc/DstData to 0. If they happen to be the same */ | ||
| 1346 | /* as last time, then we don't need to call setDataDescriptor again. */ | ||
| 1347 | |||
| 1348 | if (dmacHw_setDataDescriptor(&devAttr->config, | ||
| 1349 | devAttr->ring.virtAddr, | ||
| 1350 | (void *)srcData, | ||
| 1351 | (void *)dstData1, numBytes) < 0) { | ||
| 1352 | printk(KERN_ERR "%s: dmacHw_setDataDescriptor 1 failed\n", | ||
| 1353 | __func__); | ||
| 1354 | return -EINVAL; | ||
| 1355 | } | ||
| 1356 | if (dmacHw_setDataDescriptor(&devAttr->config, | ||
| 1357 | devAttr->ring.virtAddr, | ||
| 1358 | (void *)srcData, | ||
| 1359 | (void *)dstData2, numBytes) < 0) { | ||
| 1360 | printk(KERN_ERR "%s: dmacHw_setDataDescriptor 2 failed\n", | ||
| 1361 | __func__); | ||
| 1362 | return -EINVAL; | ||
| 1363 | } | ||
| 1364 | |||
| 1365 | /* You should use dma_start_transfer rather than dma_transfer_xxx so we don't */ | ||
| 1366 | /* try to make the 'prev' variables right. */ | ||
| 1367 | |||
| 1368 | devAttr->prevSrcData = 0; | ||
| 1369 | devAttr->prevDstData = 0; | ||
| 1370 | devAttr->prevNumBytes = 0; | ||
| 1371 | |||
| 1372 | return numDescriptors; | ||
| 1373 | } | ||
| 1374 | |||
| 1375 | EXPORT_SYMBOL(dma_alloc_double_dst_descriptors); | ||
| 1376 | |||
| 1377 | /****************************************************************************/ | ||
| 1378 | /** | ||
| 1379 | * Initiates a transfer when the descriptors have already been setup. | ||
| 1380 | * | ||
| 1381 | * This is a special case, and normally, the dma_transfer_xxx functions should | ||
| 1382 | * be used. | ||
| 1383 | * | ||
| 1384 | * @return | ||
| 1385 | * 0 Transfer was started successfully | ||
| 1386 | * -ENODEV Invalid handle | ||
| 1387 | */ | ||
| 1388 | /****************************************************************************/ | ||
| 1389 | |||
| 1390 | int dma_start_transfer(DMA_Handle_t handle) | ||
| 1391 | { | ||
| 1392 | DMA_Channel_t *channel; | ||
| 1393 | DMA_DeviceAttribute_t *devAttr; | ||
| 1394 | |||
| 1395 | channel = HandleToChannel(handle); | ||
| 1396 | if (channel == NULL) { | ||
| 1397 | return -ENODEV; | ||
| 1398 | } | ||
| 1399 | devAttr = &DMA_gDeviceAttribute[channel->devType]; | ||
| 1400 | |||
| 1401 | dmacHw_initiateTransfer(channel->dmacHwHandle, &devAttr->config, | ||
| 1402 | devAttr->ring.virtAddr); | ||
| 1403 | |||
| 1404 | /* Since we got this far, everything went successfully */ | ||
| 1405 | |||
| 1406 | return 0; | ||
| 1407 | } | ||
| 1408 | |||
| 1409 | EXPORT_SYMBOL(dma_start_transfer); | ||
| 1410 | |||
| 1411 | /****************************************************************************/ | ||
| 1412 | /** | ||
| 1413 | * Stops a previously started DMA transfer. | ||
| 1414 | * | ||
| 1415 | * @return | ||
| 1416 | * 0 Transfer was stopped successfully | ||
| 1417 | * -ENODEV Invalid handle | ||
| 1418 | */ | ||
| 1419 | /****************************************************************************/ | ||
| 1420 | |||
| 1421 | int dma_stop_transfer(DMA_Handle_t handle) | ||
| 1422 | { | ||
| 1423 | DMA_Channel_t *channel; | ||
| 1424 | |||
| 1425 | channel = HandleToChannel(handle); | ||
| 1426 | if (channel == NULL) { | ||
| 1427 | return -ENODEV; | ||
| 1428 | } | ||
| 1429 | |||
| 1430 | dmacHw_stopTransfer(channel->dmacHwHandle); | ||
| 1431 | |||
| 1432 | return 0; | ||
| 1433 | } | ||
| 1434 | |||
| 1435 | EXPORT_SYMBOL(dma_stop_transfer); | ||
| 1436 | |||
| 1437 | /****************************************************************************/ | ||
| 1438 | /** | ||
| 1439 | * Waits for a DMA to complete by polling. This function is only intended | ||
| 1440 | * to be used for testing. Interrupts should be used for most DMA operations. | ||
| 1441 | */ | ||
| 1442 | /****************************************************************************/ | ||
| 1443 | |||
| 1444 | int dma_wait_transfer_done(DMA_Handle_t handle) | ||
| 1445 | { | ||
| 1446 | DMA_Channel_t *channel; | ||
| 1447 | dmacHw_TRANSFER_STATUS_e status; | ||
| 1448 | |||
| 1449 | channel = HandleToChannel(handle); | ||
| 1450 | if (channel == NULL) { | ||
| 1451 | return -ENODEV; | ||
| 1452 | } | ||
| 1453 | |||
| 1454 | while ((status = | ||
| 1455 | dmacHw_transferCompleted(channel->dmacHwHandle)) == | ||
| 1456 | dmacHw_TRANSFER_STATUS_BUSY) { | ||
| 1457 | ; | ||
| 1458 | } | ||
| 1459 | |||
| 1460 | if (status == dmacHw_TRANSFER_STATUS_ERROR) { | ||
| 1461 | printk(KERN_ERR "%s: DMA transfer failed\n", __func__); | ||
| 1462 | return -EIO; | ||
| 1463 | } | ||
| 1464 | return 0; | ||
| 1465 | } | ||
| 1466 | |||
| 1467 | EXPORT_SYMBOL(dma_wait_transfer_done); | ||
| 1468 | |||
| 1469 | /****************************************************************************/ | ||
| 1470 | /** | ||
| 1471 | * Initiates a DMA, allocating the descriptors as required. | ||
| 1472 | * | ||
| 1473 | * @return | ||
| 1474 | * 0 Transfer was started successfully | ||
| 1475 | * -EINVAL Invalid device type for this kind of transfer | ||
| 1476 | * (i.e. the device is _DEV_TO_MEM and not _MEM_TO_DEV) | ||
| 1477 | */ | ||
| 1478 | /****************************************************************************/ | ||
| 1479 | |||
| 1480 | int dma_transfer(DMA_Handle_t handle, /* DMA Handle */ | ||
| 1481 | dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */ | ||
| 1482 | dma_addr_t srcData, /* Place to get data to write to device */ | ||
| 1483 | dma_addr_t dstData, /* Pointer to device data address */ | ||
| 1484 | size_t numBytes /* Number of bytes to transfer to the device */ | ||
| 1485 | ) { | ||
| 1486 | DMA_Channel_t *channel; | ||
| 1487 | DMA_DeviceAttribute_t *devAttr; | ||
| 1488 | int rc = 0; | ||
| 1489 | |||
| 1490 | channel = HandleToChannel(handle); | ||
| 1491 | if (channel == NULL) { | ||
| 1492 | return -ENODEV; | ||
| 1493 | } | ||
| 1494 | |||
| 1495 | devAttr = &DMA_gDeviceAttribute[channel->devType]; | ||
| 1496 | |||
| 1497 | if (devAttr->config.transferType != transferType) { | ||
| 1498 | return -EINVAL; | ||
| 1499 | } | ||
| 1500 | |||
| 1501 | /* We keep track of the information about the previous request for this */ | ||
| 1502 | /* device, and if the attributes match, then we can use the descriptors we setup */ | ||
| 1503 | /* the last time, and not have to reinitialize everything. */ | ||
| 1504 | |||
| 1505 | { | ||
| 1506 | rc = | ||
| 1507 | dma_alloc_descriptors(handle, transferType, srcData, | ||
| 1508 | dstData, numBytes); | ||
| 1509 | if (rc != 0) { | ||
| 1510 | return rc; | ||
| 1511 | } | ||
| 1512 | } | ||
| 1513 | |||
| 1514 | /* And kick off the transfer */ | ||
| 1515 | |||
| 1516 | devAttr->numBytes = numBytes; | ||
| 1517 | devAttr->transferStartTime = timer_get_tick_count(); | ||
| 1518 | |||
| 1519 | dmacHw_initiateTransfer(channel->dmacHwHandle, &devAttr->config, | ||
| 1520 | devAttr->ring.virtAddr); | ||
| 1521 | |||
| 1522 | /* Since we got this far, everything went successfully */ | ||
| 1523 | |||
| 1524 | return 0; | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | EXPORT_SYMBOL(dma_transfer); | ||
| 1528 | |||
| 1529 | /****************************************************************************/ | ||
| 1530 | /** | ||
| 1531 | * Set the callback function which will be called when a transfer completes. | ||
| 1532 | * If a NULL callback function is set, then no callback will occur. | ||
| 1533 | * | ||
| 1534 | * @note @a devHandler will be called from IRQ context. | ||
| 1535 | * | ||
| 1536 | * @return | ||
| 1537 | * 0 - Success | ||
| 1538 | * -ENODEV - Device handed in is invalid. | ||
| 1539 | */ | ||
| 1540 | /****************************************************************************/ | ||
| 1541 | |||
| 1542 | int dma_set_device_handler(DMA_Device_t dev, /* Device to set the callback for. */ | ||
| 1543 | DMA_DeviceHandler_t devHandler, /* Function to call when the DMA completes */ | ||
| 1544 | void *userData /* Pointer which will be passed to devHandler. */ | ||
| 1545 | ) { | ||
| 1546 | DMA_DeviceAttribute_t *devAttr; | ||
| 1547 | unsigned long flags; | ||
| 1548 | |||
| 1549 | if (!IsDeviceValid(dev)) { | ||
| 1550 | return -ENODEV; | ||
| 1551 | } | ||
| 1552 | devAttr = &DMA_gDeviceAttribute[dev]; | ||
| 1553 | |||
| 1554 | local_irq_save(flags); | ||
| 1555 | |||
| 1556 | devAttr->userData = userData; | ||
| 1557 | devAttr->devHandler = devHandler; | ||
| 1558 | |||
| 1559 | local_irq_restore(flags); | ||
| 1560 | |||
| 1561 | return 0; | ||
| 1562 | } | ||
| 1563 | |||
| 1564 | EXPORT_SYMBOL(dma_set_device_handler); | ||
| 1565 | |||
| 1566 | /****************************************************************************/ | ||
| 1567 | /** | ||
| 1568 | * Initializes a memory mapping structure | ||
| 1569 | */ | ||
| 1570 | /****************************************************************************/ | ||
| 1571 | |||
| 1572 | int dma_init_mem_map(DMA_MemMap_t *memMap) | ||
| 1573 | { | ||
| 1574 | memset(memMap, 0, sizeof(*memMap)); | ||
| 1575 | |||
| 1576 | init_MUTEX(&memMap->lock); | ||
| 1577 | |||
| 1578 | return 0; | ||
| 1579 | } | ||
| 1580 | |||
| 1581 | EXPORT_SYMBOL(dma_init_mem_map); | ||
| 1582 | |||
| 1583 | /****************************************************************************/ | ||
| 1584 | /** | ||
| 1585 | * Releases any memory currently being held by a memory mapping structure. | ||
| 1586 | */ | ||
| 1587 | /****************************************************************************/ | ||
| 1588 | |||
| 1589 | int dma_term_mem_map(DMA_MemMap_t *memMap) | ||
| 1590 | { | ||
| 1591 | down(&memMap->lock); /* Just being paranoid */ | ||
| 1592 | |||
| 1593 | /* Free up any allocated memory */ | ||
| 1594 | |||
| 1595 | up(&memMap->lock); | ||
| 1596 | memset(memMap, 0, sizeof(*memMap)); | ||
| 1597 | |||
| 1598 | return 0; | ||
| 1599 | } | ||
| 1600 | |||
| 1601 | EXPORT_SYMBOL(dma_term_mem_map); | ||
| 1602 | |||
| 1603 | /****************************************************************************/ | ||
| 1604 | /** | ||
| 1605 | * Looks at a memory address and categorizes it. | ||
| 1606 | * | ||
| 1607 | * @return One of the values from the DMA_MemType_t enumeration. | ||
| 1608 | */ | ||
| 1609 | /****************************************************************************/ | ||
| 1610 | |||
| 1611 | DMA_MemType_t dma_mem_type(void *addr) | ||
| 1612 | { | ||
| 1613 | unsigned long addrVal = (unsigned long)addr; | ||
| 1614 | |||
| 1615 | if (addrVal >= VMALLOC_END) { | ||
| 1616 | /* NOTE: DMA virtual memory space starts at 0xFFxxxxxx */ | ||
| 1617 | |||
| 1618 | /* dma_alloc_xxx pages are physically and virtually contiguous */ | ||
| 1619 | |||
| 1620 | return DMA_MEM_TYPE_DMA; | ||
| 1621 | } | ||
| 1622 | |||
| 1623 | /* Technically, we could add one more classification. Addresses between VMALLOC_END */ | ||
| 1624 | /* and the beginning of the DMA virtual address could be considered to be I/O space. */ | ||
| 1625 | /* Right now, nobody cares about this particular classification, so we ignore it. */ | ||
| 1626 | |||
| 1627 | if (is_vmalloc_addr(addr)) { | ||
| 1628 | /* Address comes from the vmalloc'd region. Pages are virtually */ | ||
| 1629 | /* contiguous but NOT physically contiguous */ | ||
| 1630 | |||
| 1631 | return DMA_MEM_TYPE_VMALLOC; | ||
| 1632 | } | ||
| 1633 | |||
| 1634 | if (addrVal >= PAGE_OFFSET) { | ||
| 1635 | /* PAGE_OFFSET is typically 0xC0000000 */ | ||
| 1636 | |||
| 1637 | /* kmalloc'd pages are physically contiguous */ | ||
| 1638 | |||
| 1639 | return DMA_MEM_TYPE_KMALLOC; | ||
| 1640 | } | ||
| 1641 | |||
| 1642 | return DMA_MEM_TYPE_USER; | ||
| 1643 | } | ||
| 1644 | |||
| 1645 | EXPORT_SYMBOL(dma_mem_type); | ||
| 1646 | |||
| 1647 | /****************************************************************************/ | ||
| 1648 | /** | ||
| 1649 | * Looks at a memory address and determines if we support DMA'ing to/from | ||
| 1650 | * that type of memory. | ||
| 1651 | * | ||
| 1652 | * @return boolean - | ||
| 1653 | * return value != 0 means dma supported | ||
| 1654 | * return value == 0 means dma not supported | ||
| 1655 | */ | ||
| 1656 | /****************************************************************************/ | ||
| 1657 | |||
| 1658 | int dma_mem_supports_dma(void *addr) | ||
| 1659 | { | ||
| 1660 | DMA_MemType_t memType = dma_mem_type(addr); | ||
| 1661 | |||
| 1662 | return (memType == DMA_MEM_TYPE_DMA) | ||
| 1663 | #if ALLOW_MAP_OF_KMALLOC_MEMORY | ||
| 1664 | || (memType == DMA_MEM_TYPE_KMALLOC) | ||
| 1665 | #endif | ||
| 1666 | || (memType == DMA_MEM_TYPE_USER); | ||
| 1667 | } | ||
| 1668 | |||
| 1669 | EXPORT_SYMBOL(dma_mem_supports_dma); | ||
| 1670 | |||
| 1671 | /****************************************************************************/ | ||
| 1672 | /** | ||
| 1673 | * Maps in a memory region such that it can be used for performing a DMA. | ||
| 1674 | * | ||
| 1675 | * @return | ||
| 1676 | */ | ||
| 1677 | /****************************************************************************/ | ||
| 1678 | |||
| 1679 | int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */ | ||
| 1680 | enum dma_data_direction dir /* Direction that the mapping will be going */ | ||
| 1681 | ) { | ||
| 1682 | int rc; | ||
| 1683 | |||
| 1684 | down(&memMap->lock); | ||
| 1685 | |||
| 1686 | DMA_MAP_PRINT("memMap: %p\n", memMap); | ||
| 1687 | |||
| 1688 | if (memMap->inUse) { | ||
| 1689 | printk(KERN_ERR "%s: memory map %p is already being used\n", | ||
| 1690 | __func__, memMap); | ||
| 1691 | rc = -EBUSY; | ||
| 1692 | goto out; | ||
| 1693 | } | ||
| 1694 | |||
| 1695 | memMap->inUse = 1; | ||
| 1696 | memMap->dir = dir; | ||
| 1697 | memMap->numRegionsUsed = 0; | ||
| 1698 | |||
| 1699 | rc = 0; | ||
| 1700 | |||
| 1701 | out: | ||
| 1702 | |||
| 1703 | DMA_MAP_PRINT("returning %d", rc); | ||
| 1704 | |||
| 1705 | up(&memMap->lock); | ||
| 1706 | |||
| 1707 | return rc; | ||
| 1708 | } | ||
| 1709 | |||
| 1710 | EXPORT_SYMBOL(dma_map_start); | ||
| 1711 | |||
| 1712 | /****************************************************************************/ | ||
| 1713 | /** | ||
| 1714 | * Adds a segment of memory to a memory map. Each segment is both | ||
| 1715 | * physically and virtually contiguous. | ||
| 1716 | * | ||
| 1717 | * @return 0 on success, error code otherwise. | ||
| 1718 | */ | ||
| 1719 | /****************************************************************************/ | ||
| 1720 | |||
| 1721 | static int dma_map_add_segment(DMA_MemMap_t *memMap, /* Stores state information about the map */ | ||
| 1722 | DMA_Region_t *region, /* Region that the segment belongs to */ | ||
| 1723 | void *virtAddr, /* Virtual address of the segment being added */ | ||
| 1724 | dma_addr_t physAddr, /* Physical address of the segment being added */ | ||
| 1725 | size_t numBytes /* Number of bytes of the segment being added */ | ||
| 1726 | ) { | ||
| 1727 | DMA_Segment_t *segment; | ||
| 1728 | |||
| 1729 | DMA_MAP_PRINT("memMap:%p va:%p pa:0x%x #:%d\n", memMap, virtAddr, | ||
| 1730 | physAddr, numBytes); | ||
| 1731 | |||
| 1732 | /* Sanity check */ | ||
| 1733 | |||
| 1734 | if (((unsigned long)virtAddr < (unsigned long)region->virtAddr) | ||
| 1735 | || (((unsigned long)virtAddr + numBytes)) > | ||
| 1736 | ((unsigned long)region->virtAddr + region->numBytes)) { | ||
| 1737 | printk(KERN_ERR | ||
| 1738 | "%s: virtAddr %p is outside region @ %p len: %d\n", | ||
| 1739 | __func__, virtAddr, region->virtAddr, region->numBytes); | ||
| 1740 | return -EINVAL; | ||
| 1741 | } | ||
| 1742 | |||
| 1743 | if (region->numSegmentsUsed > 0) { | ||
| 1744 | /* Check to see if this segment is physically contiguous with the previous one */ | ||
| 1745 | |||
| 1746 | segment = ®ion->segment[region->numSegmentsUsed - 1]; | ||
| 1747 | |||
| 1748 | if ((segment->physAddr + segment->numBytes) == physAddr) { | ||
| 1749 | /* It is - just add on to the end */ | ||
| 1750 | |||
| 1751 | DMA_MAP_PRINT("appending %d bytes to last segment\n", | ||
| 1752 | numBytes); | ||
| 1753 | |||
| 1754 | segment->numBytes += numBytes; | ||
| 1755 | |||
| 1756 | return 0; | ||
| 1757 | } | ||
| 1758 | } | ||
| 1759 | |||
| 1760 | /* Reallocate to hold more segments, if required. */ | ||
| 1761 | |||
| 1762 | if (region->numSegmentsUsed >= region->numSegmentsAllocated) { | ||
| 1763 | DMA_Segment_t *newSegment; | ||
| 1764 | size_t oldSize = | ||
| 1765 | region->numSegmentsAllocated * sizeof(*newSegment); | ||
| 1766 | int newAlloc = region->numSegmentsAllocated + 4; | ||
| 1767 | size_t newSize = newAlloc * sizeof(*newSegment); | ||
| 1768 | |||
| 1769 | newSegment = kmalloc(newSize, GFP_KERNEL); | ||
| 1770 | if (newSegment == NULL) { | ||
| 1771 | return -ENOMEM; | ||
| 1772 | } | ||
| 1773 | memcpy(newSegment, region->segment, oldSize); | ||
| 1774 | memset(&((uint8_t *) newSegment)[oldSize], 0, | ||
| 1775 | newSize - oldSize); | ||
| 1776 | kfree(region->segment); | ||
| 1777 | |||
| 1778 | region->numSegmentsAllocated = newAlloc; | ||
| 1779 | region->segment = newSegment; | ||
| 1780 | } | ||
| 1781 | |||
| 1782 | segment = ®ion->segment[region->numSegmentsUsed]; | ||
| 1783 | region->numSegmentsUsed++; | ||
| 1784 | |||
| 1785 | segment->virtAddr = virtAddr; | ||
| 1786 | segment->physAddr = physAddr; | ||
| 1787 | segment->numBytes = numBytes; | ||
| 1788 | |||
| 1789 | DMA_MAP_PRINT("returning success\n"); | ||
| 1790 | |||
| 1791 | return 0; | ||
| 1792 | } | ||
| 1793 | |||
| 1794 | /****************************************************************************/ | ||
| 1795 | /** | ||
| 1796 | * Adds a region of memory to a memory map. Each region is virtually | ||
| 1797 | * contiguous, but not necessarily physically contiguous. | ||
| 1798 | * | ||
| 1799 | * @return 0 on success, error code otherwise. | ||
| 1800 | */ | ||
| 1801 | /****************************************************************************/ | ||
| 1802 | |||
| 1803 | int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */ | ||
| 1804 | void *mem, /* Virtual address that we want to get a map of */ | ||
| 1805 | size_t numBytes /* Number of bytes being mapped */ | ||
| 1806 | ) { | ||
| 1807 | unsigned long addr = (unsigned long)mem; | ||
| 1808 | unsigned int offset; | ||
| 1809 | int rc = 0; | ||
| 1810 | DMA_Region_t *region; | ||
| 1811 | dma_addr_t physAddr; | ||
| 1812 | |||
| 1813 | down(&memMap->lock); | ||
| 1814 | |||
| 1815 | DMA_MAP_PRINT("memMap:%p va:%p #:%d\n", memMap, mem, numBytes); | ||
| 1816 | |||
| 1817 | if (!memMap->inUse) { | ||
| 1818 | printk(KERN_ERR "%s: Make sure you call dma_map_start first\n", | ||
| 1819 | __func__); | ||
| 1820 | rc = -EINVAL; | ||
| 1821 | goto out; | ||
| 1822 | } | ||
| 1823 | |||
| 1824 | /* Reallocate to hold more regions. */ | ||
| 1825 | |||
| 1826 | if (memMap->numRegionsUsed >= memMap->numRegionsAllocated) { | ||
| 1827 | DMA_Region_t *newRegion; | ||
| 1828 | size_t oldSize = | ||
| 1829 | memMap->numRegionsAllocated * sizeof(*newRegion); | ||
| 1830 | int newAlloc = memMap->numRegionsAllocated + 4; | ||
| 1831 | size_t newSize = newAlloc * sizeof(*newRegion); | ||
| 1832 | |||
| 1833 | newRegion = kmalloc(newSize, GFP_KERNEL); | ||
| 1834 | if (newRegion == NULL) { | ||
| 1835 | rc = -ENOMEM; | ||
| 1836 | goto out; | ||
| 1837 | } | ||
| 1838 | memcpy(newRegion, memMap->region, oldSize); | ||
| 1839 | memset(&((uint8_t *) newRegion)[oldSize], 0, newSize - oldSize); | ||
| 1840 | |||
| 1841 | kfree(memMap->region); | ||
| 1842 | |||
| 1843 | memMap->numRegionsAllocated = newAlloc; | ||
| 1844 | memMap->region = newRegion; | ||
| 1845 | } | ||
| 1846 | |||
| 1847 | region = &memMap->region[memMap->numRegionsUsed]; | ||
| 1848 | memMap->numRegionsUsed++; | ||
| 1849 | |||
| 1850 | offset = addr & ~PAGE_MASK; | ||
| 1851 | |||
| 1852 | region->memType = dma_mem_type(mem); | ||
| 1853 | region->virtAddr = mem; | ||
| 1854 | region->numBytes = numBytes; | ||
| 1855 | region->numSegmentsUsed = 0; | ||
| 1856 | region->numLockedPages = 0; | ||
| 1857 | region->lockedPages = NULL; | ||
| 1858 | |||
| 1859 | switch (region->memType) { | ||
| 1860 | case DMA_MEM_TYPE_VMALLOC: | ||
| 1861 | { | ||
| 1862 | atomic_inc(&gDmaStatMemTypeVmalloc); | ||
| 1863 | |||
| 1864 | /* printk(KERN_ERR "%s: vmalloc'd pages are not supported\n", __func__); */ | ||
| 1865 | |||
| 1866 | /* vmalloc'd pages are not physically contiguous */ | ||
| 1867 | |||
| 1868 | rc = -EINVAL; | ||
| 1869 | break; | ||
| 1870 | } | ||
| 1871 | |||
| 1872 | case DMA_MEM_TYPE_KMALLOC: | ||
| 1873 | { | ||
| 1874 | atomic_inc(&gDmaStatMemTypeKmalloc); | ||
| 1875 | |||
| 1876 | /* kmalloc'd pages are physically contiguous, so they'll have exactly */ | ||
| 1877 | /* one segment */ | ||
| 1878 | |||
| 1879 | #if ALLOW_MAP_OF_KMALLOC_MEMORY | ||
| 1880 | physAddr = | ||
| 1881 | dma_map_single(NULL, mem, numBytes, memMap->dir); | ||
| 1882 | rc = dma_map_add_segment(memMap, region, mem, physAddr, | ||
| 1883 | numBytes); | ||
| 1884 | #else | ||
| 1885 | rc = -EINVAL; | ||
| 1886 | #endif | ||
| 1887 | break; | ||
| 1888 | } | ||
| 1889 | |||
| 1890 | case DMA_MEM_TYPE_DMA: | ||
| 1891 | { | ||
| 1892 | /* dma_alloc_xxx pages are physically contiguous */ | ||
| 1893 | |||
| 1894 | atomic_inc(&gDmaStatMemTypeCoherent); | ||
| 1895 | |||
| 1896 | physAddr = (vmalloc_to_pfn(mem) << PAGE_SHIFT) + offset; | ||
| 1897 | |||
| 1898 | dma_sync_single_for_cpu(NULL, physAddr, numBytes, | ||
| 1899 | memMap->dir); | ||
| 1900 | rc = dma_map_add_segment(memMap, region, mem, physAddr, | ||
| 1901 | numBytes); | ||
| 1902 | break; | ||
| 1903 | } | ||
| 1904 | |||
| 1905 | case DMA_MEM_TYPE_USER: | ||
| 1906 | { | ||
| 1907 | size_t firstPageOffset; | ||
| 1908 | size_t firstPageSize; | ||
| 1909 | struct page **pages; | ||
| 1910 | struct task_struct *userTask; | ||
| 1911 | |||
| 1912 | atomic_inc(&gDmaStatMemTypeUser); | ||
| 1913 | |||
| 1914 | #if 1 | ||
| 1915 | /* If the pages are user pages, then the dma_mem_map_set_user_task function */ | ||
| 1916 | /* must have been previously called. */ | ||
| 1917 | |||
| 1918 | if (memMap->userTask == NULL) { | ||
| 1919 | printk(KERN_ERR | ||
| 1920 | "%s: must call dma_mem_map_set_user_task when using user-mode memory\n", | ||
| 1921 | __func__); | ||
| 1922 | return -EINVAL; | ||
| 1923 | } | ||
| 1924 | |||
| 1925 | /* User pages need to be locked. */ | ||
| 1926 | |||
| 1927 | firstPageOffset = | ||
| 1928 | (unsigned long)region->virtAddr & (PAGE_SIZE - 1); | ||
| 1929 | firstPageSize = PAGE_SIZE - firstPageOffset; | ||
| 1930 | |||
| 1931 | region->numLockedPages = (firstPageOffset | ||
| 1932 | + region->numBytes + | ||
| 1933 | PAGE_SIZE - 1) / PAGE_SIZE; | ||
| 1934 | pages = | ||
| 1935 | kmalloc(region->numLockedPages * | ||
| 1936 | sizeof(struct page *), GFP_KERNEL); | ||
| 1937 | |||
| 1938 | if (pages == NULL) { | ||
| 1939 | region->numLockedPages = 0; | ||
| 1940 | return -ENOMEM; | ||
| 1941 | } | ||
| 1942 | |||
| 1943 | userTask = memMap->userTask; | ||
| 1944 | |||
| 1945 | down_read(&userTask->mm->mmap_sem); | ||
| 1946 | rc = get_user_pages(userTask, /* task */ | ||
| 1947 | userTask->mm, /* mm */ | ||
| 1948 | (unsigned long)region->virtAddr, /* start */ | ||
| 1949 | region->numLockedPages, /* len */ | ||
| 1950 | memMap->dir == DMA_FROM_DEVICE, /* write */ | ||
| 1951 | 0, /* force */ | ||
| 1952 | pages, /* pages (array of pointers to page) */ | ||
| 1953 | NULL); /* vmas */ | ||
| 1954 | up_read(&userTask->mm->mmap_sem); | ||
| 1955 | |||
| 1956 | if (rc != region->numLockedPages) { | ||
| 1957 | kfree(pages); | ||
| 1958 | region->numLockedPages = 0; | ||
| 1959 | |||
| 1960 | if (rc >= 0) { | ||
| 1961 | rc = -EINVAL; | ||
| 1962 | } | ||
| 1963 | } else { | ||
| 1964 | uint8_t *virtAddr = region->virtAddr; | ||
| 1965 | size_t bytesRemaining; | ||
| 1966 | int pageIdx; | ||
| 1967 | |||
| 1968 | rc = 0; /* Since get_user_pages returns +ve number */ | ||
| 1969 | |||
| 1970 | region->lockedPages = pages; | ||
| 1971 | |||
| 1972 | /* We've locked the user pages. Now we need to walk them and figure */ | ||
| 1973 | /* out the physical addresses. */ | ||
| 1974 | |||
| 1975 | /* The first page may be partial */ | ||
| 1976 | |||
| 1977 | dma_map_add_segment(memMap, | ||
| 1978 | region, | ||
| 1979 | virtAddr, | ||
| 1980 | PFN_PHYS(page_to_pfn | ||
| 1981 | (pages[0])) + | ||
| 1982 | firstPageOffset, | ||
| 1983 | firstPageSize); | ||
| 1984 | |||
| 1985 | virtAddr += firstPageSize; | ||
| 1986 | bytesRemaining = | ||
| 1987 | region->numBytes - firstPageSize; | ||
| 1988 | |||
| 1989 | for (pageIdx = 1; | ||
| 1990 | pageIdx < region->numLockedPages; | ||
| 1991 | pageIdx++) { | ||
| 1992 | size_t bytesThisPage = | ||
| 1993 | (bytesRemaining > | ||
| 1994 | PAGE_SIZE ? PAGE_SIZE : | ||
| 1995 | bytesRemaining); | ||
| 1996 | |||
| 1997 | DMA_MAP_PRINT | ||
| 1998 | ("pageIdx:%d pages[pageIdx]=%p pfn=%u phys=%u\n", | ||
| 1999 | pageIdx, pages[pageIdx], | ||
| 2000 | page_to_pfn(pages[pageIdx]), | ||
| 2001 | PFN_PHYS(page_to_pfn | ||
| 2002 | (pages[pageIdx]))); | ||
| 2003 | |||
| 2004 | dma_map_add_segment(memMap, | ||
| 2005 | region, | ||
| 2006 | virtAddr, | ||
| 2007 | PFN_PHYS(page_to_pfn | ||
| 2008 | (pages | ||
| 2009 | [pageIdx])), | ||
| 2010 | bytesThisPage); | ||
| 2011 | |||
| 2012 | virtAddr += bytesThisPage; | ||
| 2013 | bytesRemaining -= bytesThisPage; | ||
| 2014 | } | ||
| 2015 | } | ||
| 2016 | #else | ||
| 2017 | printk(KERN_ERR | ||
| 2018 | "%s: User mode pages are not yet supported\n", | ||
| 2019 | __func__); | ||
| 2020 | |||
| 2021 | /* user pages are not physically contiguous */ | ||
| 2022 | |||
| 2023 | rc = -EINVAL; | ||
| 2024 | #endif | ||
| 2025 | break; | ||
| 2026 | } | ||
| 2027 | |||
| 2028 | default: | ||
| 2029 | { | ||
| 2030 | printk(KERN_ERR "%s: Unsupported memory type: %d\n", | ||
| 2031 | __func__, region->memType); | ||
| 2032 | |||
| 2033 | rc = -EINVAL; | ||
| 2034 | break; | ||
| 2035 | } | ||
| 2036 | } | ||
| 2037 | |||
| 2038 | if (rc != 0) { | ||
| 2039 | memMap->numRegionsUsed--; | ||
| 2040 | } | ||
| 2041 | |||
| 2042 | out: | ||
| 2043 | |||
| 2044 | DMA_MAP_PRINT("returning %d\n", rc); | ||
| 2045 | |||
| 2046 | up(&memMap->lock); | ||
| 2047 | |||
| 2048 | return rc; | ||
| 2049 | } | ||
| 2050 | |||
| 2051 | EXPORT_SYMBOL(dma_map_add_segment); | ||
| 2052 | |||
| 2053 | /****************************************************************************/ | ||
| 2054 | /** | ||
| 2055 | * Maps in a memory region such that it can be used for performing a DMA. | ||
| 2056 | * | ||
| 2057 | * @return 0 on success, error code otherwise. | ||
| 2058 | */ | ||
| 2059 | /****************************************************************************/ | ||
| 2060 | |||
| 2061 | int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */ | ||
| 2062 | void *mem, /* Virtual address that we want to get a map of */ | ||
| 2063 | size_t numBytes, /* Number of bytes being mapped */ | ||
| 2064 | enum dma_data_direction dir /* Direction that the mapping will be going */ | ||
| 2065 | ) { | ||
| 2066 | int rc; | ||
| 2067 | |||
| 2068 | rc = dma_map_start(memMap, dir); | ||
| 2069 | if (rc == 0) { | ||
| 2070 | rc = dma_map_add_region(memMap, mem, numBytes); | ||
| 2071 | if (rc < 0) { | ||
| 2072 | /* Since the add fails, this function will fail, and the caller won't */ | ||
| 2073 | /* call unmap, so we need to do it here. */ | ||
| 2074 | |||
| 2075 | dma_unmap(memMap, 0); | ||
| 2076 | } | ||
| 2077 | } | ||
| 2078 | |||
| 2079 | return rc; | ||
| 2080 | } | ||
| 2081 | |||
| 2082 | EXPORT_SYMBOL(dma_map_mem); | ||
| 2083 | |||
| 2084 | /****************************************************************************/ | ||
| 2085 | /** | ||
| 2086 | * Setup a descriptor ring for a given memory map. | ||
| 2087 | * | ||
| 2088 | * It is assumed that the descriptor ring has already been initialized, and | ||
| 2089 | * this routine will only reallocate a new descriptor ring if the existing | ||
| 2090 | * one is too small. | ||
| 2091 | * | ||
| 2092 | * @return 0 on success, error code otherwise. | ||
| 2093 | */ | ||
| 2094 | /****************************************************************************/ | ||
| 2095 | |||
| 2096 | int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */ | ||
| 2097 | DMA_MemMap_t *memMap, /* Memory map that will be used */ | ||
| 2098 | dma_addr_t devPhysAddr /* Physical address of device */ | ||
| 2099 | ) { | ||
| 2100 | int rc; | ||
| 2101 | int numDescriptors; | ||
| 2102 | DMA_DeviceAttribute_t *devAttr; | ||
| 2103 | DMA_Region_t *region; | ||
| 2104 | DMA_Segment_t *segment; | ||
| 2105 | dma_addr_t srcPhysAddr; | ||
| 2106 | dma_addr_t dstPhysAddr; | ||
| 2107 | int regionIdx; | ||
| 2108 | int segmentIdx; | ||
| 2109 | |||
| 2110 | devAttr = &DMA_gDeviceAttribute[dev]; | ||
| 2111 | |||
| 2112 | down(&memMap->lock); | ||
| 2113 | |||
| 2114 | /* Figure out how many descriptors we need */ | ||
| 2115 | |||
| 2116 | numDescriptors = 0; | ||
| 2117 | for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) { | ||
| 2118 | region = &memMap->region[regionIdx]; | ||
| 2119 | |||
| 2120 | for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed; | ||
| 2121 | segmentIdx++) { | ||
| 2122 | segment = ®ion->segment[segmentIdx]; | ||
| 2123 | |||
| 2124 | if (memMap->dir == DMA_TO_DEVICE) { | ||
| 2125 | srcPhysAddr = segment->physAddr; | ||
| 2126 | dstPhysAddr = devPhysAddr; | ||
| 2127 | } else { | ||
| 2128 | srcPhysAddr = devPhysAddr; | ||
| 2129 | dstPhysAddr = segment->physAddr; | ||
| 2130 | } | ||
| 2131 | |||
| 2132 | rc = | ||
| 2133 | dma_calculate_descriptor_count(dev, srcPhysAddr, | ||
| 2134 | dstPhysAddr, | ||
| 2135 | segment-> | ||
| 2136 | numBytes); | ||
| 2137 | if (rc < 0) { | ||
| 2138 | printk(KERN_ERR | ||
| 2139 | "%s: dma_calculate_descriptor_count failed: %d\n", | ||
| 2140 | __func__, rc); | ||
| 2141 | goto out; | ||
| 2142 | } | ||
| 2143 | numDescriptors += rc; | ||
| 2144 | } | ||
| 2145 | } | ||
| 2146 | |||
| 2147 | /* Adjust the size of the ring, if it isn't big enough */ | ||
| 2148 | |||
| 2149 | if (numDescriptors > devAttr->ring.descriptorsAllocated) { | ||
| 2150 | dma_free_descriptor_ring(&devAttr->ring); | ||
| 2151 | rc = | ||
| 2152 | dma_alloc_descriptor_ring(&devAttr->ring, | ||
| 2153 | numDescriptors); | ||
| 2154 | if (rc < 0) { | ||
| 2155 | printk(KERN_ERR | ||
| 2156 | "%s: dma_alloc_descriptor_ring failed: %d\n", | ||
| 2157 | __func__, rc); | ||
| 2158 | goto out; | ||
| 2159 | } | ||
| 2160 | } else { | ||
| 2161 | rc = | ||
| 2162 | dma_init_descriptor_ring(&devAttr->ring, | ||
| 2163 | numDescriptors); | ||
| 2164 | if (rc < 0) { | ||
| 2165 | printk(KERN_ERR | ||
| 2166 | "%s: dma_init_descriptor_ring failed: %d\n", | ||
| 2167 | __func__, rc); | ||
| 2168 | goto out; | ||
| 2169 | } | ||
| 2170 | } | ||
| 2171 | |||
| 2172 | /* Populate the descriptors */ | ||
| 2173 | |||
| 2174 | for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) { | ||
| 2175 | region = &memMap->region[regionIdx]; | ||
| 2176 | |||
| 2177 | for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed; | ||
| 2178 | segmentIdx++) { | ||
| 2179 | segment = ®ion->segment[segmentIdx]; | ||
| 2180 | |||
| 2181 | if (memMap->dir == DMA_TO_DEVICE) { | ||
| 2182 | srcPhysAddr = segment->physAddr; | ||
| 2183 | dstPhysAddr = devPhysAddr; | ||
| 2184 | } else { | ||
| 2185 | srcPhysAddr = devPhysAddr; | ||
| 2186 | dstPhysAddr = segment->physAddr; | ||
| 2187 | } | ||
| 2188 | |||
| 2189 | rc = | ||
| 2190 | dma_add_descriptors(&devAttr->ring, dev, | ||
| 2191 | srcPhysAddr, dstPhysAddr, | ||
| 2192 | segment->numBytes); | ||
| 2193 | if (rc < 0) { | ||
| 2194 | printk(KERN_ERR | ||
| 2195 | "%s: dma_add_descriptors failed: %d\n", | ||
| 2196 | __func__, rc); | ||
| 2197 | goto out; | ||
| 2198 | } | ||
| 2199 | } | ||
| 2200 | } | ||
| 2201 | |||
| 2202 | rc = 0; | ||
| 2203 | |||
| 2204 | out: | ||
| 2205 | |||
| 2206 | up(&memMap->lock); | ||
| 2207 | return rc; | ||
| 2208 | } | ||
| 2209 | |||
| 2210 | EXPORT_SYMBOL(dma_map_create_descriptor_ring); | ||
| 2211 | |||
| 2212 | /****************************************************************************/ | ||
| 2213 | /** | ||
| 2214 | * Maps in a memory region such that it can be used for performing a DMA. | ||
| 2215 | * | ||
| 2216 | * @return | ||
| 2217 | */ | ||
| 2218 | /****************************************************************************/ | ||
| 2219 | |||
| 2220 | int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ | ||
| 2221 | int dirtied /* non-zero if any of the pages were modified */ | ||
| 2222 | ) { | ||
| 2223 | int regionIdx; | ||
| 2224 | int segmentIdx; | ||
| 2225 | DMA_Region_t *region; | ||
| 2226 | DMA_Segment_t *segment; | ||
| 2227 | |||
| 2228 | for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) { | ||
| 2229 | region = &memMap->region[regionIdx]; | ||
| 2230 | |||
| 2231 | for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed; | ||
| 2232 | segmentIdx++) { | ||
| 2233 | segment = ®ion->segment[segmentIdx]; | ||
| 2234 | |||
| 2235 | switch (region->memType) { | ||
| 2236 | case DMA_MEM_TYPE_VMALLOC: | ||
| 2237 | { | ||
| 2238 | printk(KERN_ERR | ||
| 2239 | "%s: vmalloc'd pages are not yet supported\n", | ||
| 2240 | __func__); | ||
| 2241 | return -EINVAL; | ||
| 2242 | } | ||
| 2243 | |||
| 2244 | case DMA_MEM_TYPE_KMALLOC: | ||
| 2245 | { | ||
| 2246 | #if ALLOW_MAP_OF_KMALLOC_MEMORY | ||
| 2247 | dma_unmap_single(NULL, | ||
| 2248 | segment->physAddr, | ||
| 2249 | segment->numBytes, | ||
| 2250 | memMap->dir); | ||
| 2251 | #endif | ||
| 2252 | break; | ||
| 2253 | } | ||
| 2254 | |||
| 2255 | case DMA_MEM_TYPE_DMA: | ||
| 2256 | { | ||
| 2257 | dma_sync_single_for_cpu(NULL, | ||
| 2258 | segment-> | ||
| 2259 | physAddr, | ||
| 2260 | segment-> | ||
| 2261 | numBytes, | ||
| 2262 | memMap->dir); | ||
| 2263 | break; | ||
| 2264 | } | ||
| 2265 | |||
| 2266 | case DMA_MEM_TYPE_USER: | ||
| 2267 | { | ||
| 2268 | /* Nothing to do here. */ | ||
| 2269 | |||
| 2270 | break; | ||
| 2271 | } | ||
| 2272 | |||
| 2273 | default: | ||
| 2274 | { | ||
| 2275 | printk(KERN_ERR | ||
| 2276 | "%s: Unsupported memory type: %d\n", | ||
| 2277 | __func__, region->memType); | ||
| 2278 | return -EINVAL; | ||
| 2279 | } | ||
| 2280 | } | ||
| 2281 | |||
| 2282 | segment->virtAddr = NULL; | ||
| 2283 | segment->physAddr = 0; | ||
| 2284 | segment->numBytes = 0; | ||
| 2285 | } | ||
| 2286 | |||
| 2287 | if (region->numLockedPages > 0) { | ||
| 2288 | int pageIdx; | ||
| 2289 | |||
| 2290 | /* Some user pages were locked. We need to go and unlock them now. */ | ||
| 2291 | |||
| 2292 | for (pageIdx = 0; pageIdx < region->numLockedPages; | ||
| 2293 | pageIdx++) { | ||
| 2294 | struct page *page = | ||
| 2295 | region->lockedPages[pageIdx]; | ||
| 2296 | |||
| 2297 | if (memMap->dir == DMA_FROM_DEVICE) { | ||
| 2298 | SetPageDirty(page); | ||
| 2299 | } | ||
| 2300 | page_cache_release(page); | ||
| 2301 | } | ||
| 2302 | kfree(region->lockedPages); | ||
| 2303 | region->numLockedPages = 0; | ||
| 2304 | region->lockedPages = NULL; | ||
| 2305 | } | ||
| 2306 | |||
| 2307 | region->memType = DMA_MEM_TYPE_NONE; | ||
| 2308 | region->virtAddr = NULL; | ||
| 2309 | region->numBytes = 0; | ||
| 2310 | region->numSegmentsUsed = 0; | ||
| 2311 | } | ||
| 2312 | memMap->userTask = NULL; | ||
| 2313 | memMap->numRegionsUsed = 0; | ||
| 2314 | memMap->inUse = 0; | ||
| 2315 | |||
| 2316 | up(&memMap->lock); | ||
| 2317 | |||
| 2318 | return 0; | ||
| 2319 | } | ||
| 2320 | |||
| 2321 | EXPORT_SYMBOL(dma_unmap); | ||
diff --git a/arch/arm/mach-bcmring/dma_device.c b/arch/arm/mach-bcmring/dma_device.c new file mode 100644 index 000000000000..ca0ad736870b --- /dev/null +++ b/arch/arm/mach-bcmring/dma_device.c | |||
| @@ -0,0 +1,593 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file dma_device.c | ||
| 18 | * | ||
| 19 | * @brief private array of DMA_DeviceAttribute_t | ||
| 20 | */ | ||
| 21 | /****************************************************************************/ | ||
| 22 | |||
| 23 | DMA_DeviceAttribute_t DMA_gDeviceAttribute[DMA_NUM_DEVICE_ENTRIES] = { | ||
| 24 | [DMA_DEVICE_MEM_TO_MEM] = /* MEM 2 MEM */ | ||
| 25 | { | ||
| 26 | .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1, | ||
| 27 | .name = "mem-to-mem", | ||
| 28 | .config = { | ||
| 29 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 30 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 31 | .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM, | ||
| 32 | .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, | ||
| 33 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, | ||
| 34 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 35 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 36 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 37 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 38 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, | ||
| 39 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, | ||
| 40 | |||
| 41 | }, | ||
| 42 | }, | ||
| 43 | [DMA_DEVICE_VPM_MEM_TO_MEM] = /* VPM */ | ||
| 44 | { | ||
| 45 | .flags = DMA_DEVICE_FLAG_IS_DEDICATED | DMA_DEVICE_FLAG_NO_ISR, | ||
| 46 | .name = "vpm", | ||
| 47 | .dedicatedController = 0, | ||
| 48 | .dedicatedChannel = 0, | ||
| 49 | /* reserve DMA0:0 for VPM */ | ||
| 50 | }, | ||
| 51 | [DMA_DEVICE_NAND_MEM_TO_MEM] = /* NAND */ | ||
| 52 | { | ||
| 53 | .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1, | ||
| 54 | .name = "nand", | ||
| 55 | .config = { | ||
| 56 | .srcPeripheralPort = 0, | ||
| 57 | .dstPeripheralPort = 0, | ||
| 58 | .srcStatusRegisterAddress = 0x00000000, | ||
| 59 | .dstStatusRegisterAddress = 0x00000000, | ||
| 60 | .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM, | ||
| 61 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, | ||
| 62 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 63 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, | ||
| 64 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, | ||
| 65 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, | ||
| 66 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, | ||
| 67 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 68 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 69 | .channelPriority = dmacHw_CHANNEL_PRIORITY_6, | ||
| 70 | }, | ||
| 71 | }, | ||
| 72 | [DMA_DEVICE_PIF_MEM_TO_DEV] = /* PIF TX */ | ||
| 73 | { | ||
| 74 | .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1 | ||
| 75 | | DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO | ||
| 76 | | DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST | DMA_DEVICE_FLAG_PORT_PER_DMAC, | ||
| 77 | .name = "pif_tx", | ||
| 78 | .dmacPort = {14, 5}, | ||
| 79 | .config = { | ||
| 80 | .srcPeripheralPort = 0, /* SRC: memory */ | ||
| 81 | /* dstPeripheralPort = 5 or 14 */ | ||
| 82 | .srcStatusRegisterAddress = 0x00000000, | ||
| 83 | .dstStatusRegisterAddress = 0x00000000, | ||
| 84 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 85 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 86 | .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, | ||
| 87 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, | ||
| 88 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, | ||
| 89 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 90 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 91 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 92 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, | ||
| 93 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, | ||
| 94 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, | ||
| 95 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, | ||
| 96 | .maxDataPerBlock = 16256, | ||
| 97 | }, | ||
| 98 | }, | ||
| 99 | [DMA_DEVICE_PIF_DEV_TO_MEM] = /* PIF RX */ | ||
| 100 | { | ||
| 101 | .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1 | ||
| 102 | | DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO | ||
| 103 | /* DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST */ | ||
| 104 | | DMA_DEVICE_FLAG_PORT_PER_DMAC, | ||
| 105 | .name = "pif_rx", | ||
| 106 | .dmacPort = {14, 5}, | ||
| 107 | .config = { | ||
| 108 | /* srcPeripheralPort = 5 or 14 */ | ||
| 109 | .dstPeripheralPort = 0, /* DST: memory */ | ||
| 110 | .srcStatusRegisterAddress = 0x00000000, | ||
| 111 | .dstStatusRegisterAddress = 0x00000000, | ||
| 112 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 113 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 114 | .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, | ||
| 115 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, | ||
| 116 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 117 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 118 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 119 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 120 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, | ||
| 121 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, | ||
| 122 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, | ||
| 123 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, | ||
| 124 | .maxDataPerBlock = 16256, | ||
| 125 | }, | ||
| 126 | }, | ||
| 127 | [DMA_DEVICE_I2S0_DEV_TO_MEM] = /* I2S RX */ | ||
| 128 | { | ||
| 129 | .flags = DMA_DEVICE_FLAG_ON_DMA0, | ||
| 130 | .name = "i2s0_rx", | ||
| 131 | .config = { | ||
| 132 | .srcPeripheralPort = 0, /* SRC: I2S0 */ | ||
| 133 | .dstPeripheralPort = 0, /* DST: memory */ | ||
| 134 | .srcStatusRegisterAddress = 0, | ||
| 135 | .dstStatusRegisterAddress = 0, | ||
| 136 | .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, | ||
| 137 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, | ||
| 138 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 139 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_16, | ||
| 140 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, | ||
| 141 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, | ||
| 142 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0, | ||
| 143 | .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 144 | .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 145 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 146 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 147 | .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, | ||
| 148 | }, | ||
| 149 | }, | ||
| 150 | [DMA_DEVICE_I2S0_MEM_TO_DEV] = /* I2S TX */ | ||
| 151 | { | ||
| 152 | .flags = DMA_DEVICE_FLAG_ON_DMA0, | ||
| 153 | .name = "i2s0_tx", | ||
| 154 | .config = { | ||
| 155 | .srcPeripheralPort = 0, /* SRC: memory */ | ||
| 156 | .dstPeripheralPort = 1, /* DST: I2S0 */ | ||
| 157 | .srcStatusRegisterAddress = 0, | ||
| 158 | .dstStatusRegisterAddress = 0, | ||
| 159 | .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, | ||
| 160 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, | ||
| 161 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 162 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, | ||
| 163 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_16, | ||
| 164 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0, | ||
| 165 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, | ||
| 166 | .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 167 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 168 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 169 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 170 | .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, | ||
| 171 | }, | ||
| 172 | }, | ||
| 173 | [DMA_DEVICE_I2S1_DEV_TO_MEM] = /* I2S1 RX */ | ||
| 174 | { | ||
| 175 | .flags = DMA_DEVICE_FLAG_ON_DMA1, | ||
| 176 | .name = "i2s1_rx", | ||
| 177 | .config = { | ||
| 178 | .srcPeripheralPort = 2, /* SRC: I2S1 */ | ||
| 179 | .dstPeripheralPort = 0, /* DST: memory */ | ||
| 180 | .srcStatusRegisterAddress = 0, | ||
| 181 | .dstStatusRegisterAddress = 0, | ||
| 182 | .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, | ||
| 183 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, | ||
| 184 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 185 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_16, | ||
| 186 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, | ||
| 187 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, | ||
| 188 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0, | ||
| 189 | .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 190 | .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 191 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 192 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 193 | .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, | ||
| 194 | }, | ||
| 195 | }, | ||
| 196 | [DMA_DEVICE_I2S1_MEM_TO_DEV] = /* I2S1 TX */ | ||
| 197 | { | ||
| 198 | .flags = DMA_DEVICE_FLAG_ON_DMA1, | ||
| 199 | .name = "i2s1_tx", | ||
| 200 | .config = { | ||
| 201 | .srcPeripheralPort = 0, /* SRC: memory */ | ||
| 202 | .dstPeripheralPort = 3, /* DST: I2S1 */ | ||
| 203 | .srcStatusRegisterAddress = 0, | ||
| 204 | .dstStatusRegisterAddress = 0, | ||
| 205 | .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, | ||
| 206 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, | ||
| 207 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 208 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, | ||
| 209 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_16, | ||
| 210 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0, | ||
| 211 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, | ||
| 212 | .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 213 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 214 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 215 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 216 | .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, | ||
| 217 | }, | ||
| 218 | }, | ||
| 219 | [DMA_DEVICE_ESW_MEM_TO_DEV] = /* ESW TX */ | ||
| 220 | { | ||
| 221 | .name = "esw_tx", | ||
| 222 | .flags = DMA_DEVICE_FLAG_IS_DEDICATED, | ||
| 223 | .dedicatedController = 1, | ||
| 224 | .dedicatedChannel = 3, | ||
| 225 | .config = { | ||
| 226 | .srcPeripheralPort = 0, /* SRC: memory */ | ||
| 227 | .dstPeripheralPort = 1, /* DST: ESW (MTP) */ | ||
| 228 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 229 | .errorInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 230 | /* DMAx_AHB_SSTATARy */ | ||
| 231 | .srcStatusRegisterAddress = 0x00000000, | ||
| 232 | /* DMAx_AHB_DSTATARy */ | ||
| 233 | .dstStatusRegisterAddress = 0x30490010, | ||
| 234 | /* DMAx_AHB_CFGy */ | ||
| 235 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 236 | /* DMAx_AHB_CTLy */ | ||
| 237 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, | ||
| 238 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 239 | .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, | ||
| 240 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0, | ||
| 241 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, | ||
| 242 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 243 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 244 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, | ||
| 245 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, | ||
| 246 | }, | ||
| 247 | }, | ||
| 248 | [DMA_DEVICE_ESW_DEV_TO_MEM] = /* ESW RX */ | ||
| 249 | { | ||
| 250 | .name = "esw_rx", | ||
| 251 | .flags = DMA_DEVICE_FLAG_IS_DEDICATED, | ||
| 252 | .dedicatedController = 1, | ||
| 253 | .dedicatedChannel = 2, | ||
| 254 | .config = { | ||
| 255 | .srcPeripheralPort = 0, /* SRC: ESW (PTM) */ | ||
| 256 | .dstPeripheralPort = 0, /* DST: memory */ | ||
| 257 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 258 | .errorInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 259 | /* DMAx_AHB_SSTATARy */ | ||
| 260 | .srcStatusRegisterAddress = 0x30480010, | ||
| 261 | /* DMAx_AHB_DSTATARy */ | ||
| 262 | .dstStatusRegisterAddress = 0x00000000, | ||
| 263 | /* DMAx_AHB_CFGy */ | ||
| 264 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 265 | /* DMAx_AHB_CTLy */ | ||
| 266 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, | ||
| 267 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 268 | .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, | ||
| 269 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, | ||
| 270 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0, | ||
| 271 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 272 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 273 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, | ||
| 274 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, | ||
| 275 | }, | ||
| 276 | }, | ||
| 277 | [DMA_DEVICE_APM_CODEC_A_DEV_TO_MEM] = /* APM Codec A Ingress */ | ||
| 278 | { | ||
| 279 | .flags = DMA_DEVICE_FLAG_ON_DMA0, | ||
| 280 | .name = "apm_a_rx", | ||
| 281 | .config = { | ||
| 282 | .srcPeripheralPort = 2, /* SRC: Codec A Ingress FIFO */ | ||
| 283 | .dstPeripheralPort = 0, /* DST: memory */ | ||
| 284 | .srcStatusRegisterAddress = 0x00000000, | ||
| 285 | .dstStatusRegisterAddress = 0x00000000, | ||
| 286 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 287 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 288 | .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, | ||
| 289 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, | ||
| 290 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 291 | .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 292 | .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 293 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 294 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 295 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, | ||
| 296 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, | ||
| 297 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, | ||
| 298 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, | ||
| 299 | .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, | ||
| 300 | }, | ||
| 301 | }, | ||
| 302 | [DMA_DEVICE_APM_CODEC_A_MEM_TO_DEV] = /* APM Codec A Egress */ | ||
| 303 | { | ||
| 304 | .flags = DMA_DEVICE_FLAG_ON_DMA0, | ||
| 305 | .name = "apm_a_tx", | ||
| 306 | .config = { | ||
| 307 | .srcPeripheralPort = 0, /* SRC: memory */ | ||
| 308 | .dstPeripheralPort = 3, /* DST: Codec A Egress FIFO */ | ||
| 309 | .srcStatusRegisterAddress = 0x00000000, | ||
| 310 | .dstStatusRegisterAddress = 0x00000000, | ||
| 311 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 312 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 313 | .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, | ||
| 314 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, | ||
| 315 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, | ||
| 316 | .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 317 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 318 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 319 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 320 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, | ||
| 321 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, | ||
| 322 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, | ||
| 323 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, | ||
| 324 | .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, | ||
| 325 | }, | ||
| 326 | }, | ||
| 327 | [DMA_DEVICE_APM_CODEC_B_DEV_TO_MEM] = /* APM Codec B Ingress */ | ||
| 328 | { | ||
| 329 | .flags = DMA_DEVICE_FLAG_ON_DMA0, | ||
| 330 | .name = "apm_b_rx", | ||
| 331 | .config = { | ||
| 332 | .srcPeripheralPort = 4, /* SRC: Codec B Ingress FIFO */ | ||
| 333 | .dstPeripheralPort = 0, /* DST: memory */ | ||
| 334 | .srcStatusRegisterAddress = 0x00000000, | ||
| 335 | .dstStatusRegisterAddress = 0x00000000, | ||
| 336 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 337 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 338 | .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, | ||
| 339 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, | ||
| 340 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 341 | .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 342 | .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 343 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 344 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 345 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, | ||
| 346 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, | ||
| 347 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, | ||
| 348 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, | ||
| 349 | .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, | ||
| 350 | }, | ||
| 351 | }, | ||
| 352 | [DMA_DEVICE_APM_CODEC_B_MEM_TO_DEV] = /* APM Codec B Egress */ | ||
| 353 | { | ||
| 354 | .flags = DMA_DEVICE_FLAG_ON_DMA0, | ||
| 355 | .name = "apm_b_tx", | ||
| 356 | .config = { | ||
| 357 | .srcPeripheralPort = 0, /* SRC: memory */ | ||
| 358 | .dstPeripheralPort = 5, /* DST: Codec B Egress FIFO */ | ||
| 359 | .srcStatusRegisterAddress = 0x00000000, | ||
| 360 | .dstStatusRegisterAddress = 0x00000000, | ||
| 361 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 362 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 363 | .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, | ||
| 364 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, | ||
| 365 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, | ||
| 366 | .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 367 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 368 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 369 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 370 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, | ||
| 371 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, | ||
| 372 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, | ||
| 373 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, | ||
| 374 | .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, | ||
| 375 | }, | ||
| 376 | }, | ||
| 377 | [DMA_DEVICE_APM_CODEC_C_DEV_TO_MEM] = /* APM Codec C Ingress */ | ||
| 378 | { | ||
| 379 | .flags = DMA_DEVICE_FLAG_ON_DMA1, | ||
| 380 | .name = "apm_c_rx", | ||
| 381 | .config = { | ||
| 382 | .srcPeripheralPort = 4, /* SRC: Codec C Ingress FIFO */ | ||
| 383 | .dstPeripheralPort = 0, /* DST: memory */ | ||
| 384 | .srcStatusRegisterAddress = 0x00000000, | ||
| 385 | .dstStatusRegisterAddress = 0x00000000, | ||
| 386 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 387 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 388 | .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, | ||
| 389 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, | ||
| 390 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 391 | .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 392 | .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 393 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 394 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 395 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, | ||
| 396 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, | ||
| 397 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, | ||
| 398 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, | ||
| 399 | .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, | ||
| 400 | }, | ||
| 401 | }, | ||
| 402 | [DMA_DEVICE_APM_PCM0_DEV_TO_MEM] = /* PCM0 RX */ | ||
| 403 | { | ||
| 404 | .flags = DMA_DEVICE_FLAG_ON_DMA0, | ||
| 405 | .name = "pcm0_rx", | ||
| 406 | .config = { | ||
| 407 | .srcPeripheralPort = 12, /* SRC: PCM0 */ | ||
| 408 | .dstPeripheralPort = 0, /* DST: memory */ | ||
| 409 | .srcStatusRegisterAddress = 0, | ||
| 410 | .dstStatusRegisterAddress = 0, | ||
| 411 | .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, | ||
| 412 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, | ||
| 413 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 414 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, | ||
| 415 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, | ||
| 416 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, | ||
| 417 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, | ||
| 418 | .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 419 | .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 420 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 421 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 422 | .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, | ||
| 423 | }, | ||
| 424 | }, | ||
| 425 | [DMA_DEVICE_APM_PCM0_MEM_TO_DEV] = /* PCM0 TX */ | ||
| 426 | { | ||
| 427 | .flags = DMA_DEVICE_FLAG_ON_DMA0, | ||
| 428 | .name = "pcm0_tx", | ||
| 429 | .config = { | ||
| 430 | .srcPeripheralPort = 0, /* SRC: memory */ | ||
| 431 | .dstPeripheralPort = 13, /* DST: PCM0 */ | ||
| 432 | .srcStatusRegisterAddress = 0, | ||
| 433 | .dstStatusRegisterAddress = 0, | ||
| 434 | .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, | ||
| 435 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, | ||
| 436 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, | ||
| 437 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, | ||
| 438 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, | ||
| 439 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, | ||
| 440 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, | ||
| 441 | .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 442 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 443 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 444 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 445 | .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, | ||
| 446 | }, | ||
| 447 | }, | ||
| 448 | [DMA_DEVICE_APM_PCM1_DEV_TO_MEM] = /* PCM1 RX */ | ||
| 449 | { | ||
| 450 | .flags = DMA_DEVICE_FLAG_ON_DMA1, | ||
| 451 | .name = "pcm1_rx", | ||
| 452 | .config = { | ||
| 453 | .srcPeripheralPort = 14, /* SRC: PCM1 */ | ||
| 454 | .dstPeripheralPort = 0, /* DST: memory */ | ||
| 455 | .srcStatusRegisterAddress = 0, | ||
| 456 | .dstStatusRegisterAddress = 0, | ||
| 457 | .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, | ||
| 458 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, | ||
| 459 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 460 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, | ||
| 461 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, | ||
| 462 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, | ||
| 463 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, | ||
| 464 | .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 465 | .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 466 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 467 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 468 | .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, | ||
| 469 | }, | ||
| 470 | }, | ||
| 471 | [DMA_DEVICE_APM_PCM1_MEM_TO_DEV] = /* PCM1 TX */ | ||
| 472 | { | ||
| 473 | .flags = DMA_DEVICE_FLAG_ON_DMA1, | ||
| 474 | .name = "pcm1_tx", | ||
| 475 | .config = { | ||
| 476 | .srcPeripheralPort = 0, /* SRC: memory */ | ||
| 477 | .dstPeripheralPort = 15, /* DST: PCM1 */ | ||
| 478 | .srcStatusRegisterAddress = 0, | ||
| 479 | .dstStatusRegisterAddress = 0, | ||
| 480 | .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, | ||
| 481 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, | ||
| 482 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, | ||
| 483 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, | ||
| 484 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, | ||
| 485 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, | ||
| 486 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, | ||
| 487 | .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 488 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 489 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 490 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 491 | .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, | ||
| 492 | }, | ||
| 493 | }, | ||
| 494 | [DMA_DEVICE_SPUM_DEV_TO_MEM] = /* SPUM RX */ | ||
| 495 | { | ||
| 496 | .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1, | ||
| 497 | .name = "spum_rx", | ||
| 498 | .config = { | ||
| 499 | .srcPeripheralPort = 6, /* SRC: Codec A Ingress FIFO */ | ||
| 500 | .dstPeripheralPort = 0, /* DST: memory */ | ||
| 501 | .srcStatusRegisterAddress = 0x00000000, | ||
| 502 | .dstStatusRegisterAddress = 0x00000000, | ||
| 503 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 504 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 505 | .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, | ||
| 506 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, | ||
| 507 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 508 | .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 509 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 510 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 511 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 512 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, | ||
| 513 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, | ||
| 514 | /* Busrt size **MUST** be 16 for SPUM to work */ | ||
| 515 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_16, | ||
| 516 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_16, | ||
| 517 | .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, | ||
| 518 | /* on the RX side, SPU needs to be the flow controller */ | ||
| 519 | .flowControler = dmacHw_FLOW_CONTROL_PERIPHERAL, | ||
| 520 | }, | ||
| 521 | }, | ||
| 522 | [DMA_DEVICE_SPUM_MEM_TO_DEV] = /* SPUM TX */ | ||
| 523 | { | ||
| 524 | .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1, | ||
| 525 | .name = "spum_tx", | ||
| 526 | .config = { | ||
| 527 | .srcPeripheralPort = 0, /* SRC: memory */ | ||
| 528 | .dstPeripheralPort = 7, /* DST: SPUM */ | ||
| 529 | .srcStatusRegisterAddress = 0x00000000, | ||
| 530 | .dstStatusRegisterAddress = 0x00000000, | ||
| 531 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 532 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 533 | .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, | ||
| 534 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, | ||
| 535 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, | ||
| 536 | .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, | ||
| 537 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 538 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 539 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 540 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, | ||
| 541 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, | ||
| 542 | /* Busrt size **MUST** be 16 for SPUM to work */ | ||
| 543 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_16, | ||
| 544 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_16, | ||
| 545 | .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, | ||
| 546 | }, | ||
| 547 | }, | ||
| 548 | [DMA_DEVICE_MEM_TO_VRAM] = /* MEM 2 VRAM */ | ||
| 549 | { | ||
| 550 | .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1, | ||
| 551 | .name = "mem-to-vram", | ||
| 552 | .config = { | ||
| 553 | .srcPeripheralPort = 0, /* SRC: memory */ | ||
| 554 | .srcStatusRegisterAddress = 0x00000000, | ||
| 555 | .dstStatusRegisterAddress = 0x00000000, | ||
| 556 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 557 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 558 | .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM, | ||
| 559 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, | ||
| 560 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, | ||
| 561 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 562 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 563 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 564 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, | ||
| 565 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, | ||
| 566 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, | ||
| 567 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, | ||
| 568 | }, | ||
| 569 | }, | ||
| 570 | [DMA_DEVICE_VRAM_TO_MEM] = /* VRAM 2 MEM */ | ||
| 571 | { | ||
| 572 | .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1, | ||
| 573 | .name = "vram-to-mem", | ||
| 574 | .config = { | ||
| 575 | .dstPeripheralPort = 0, /* DST: memory */ | ||
| 576 | .srcStatusRegisterAddress = 0x00000000, | ||
| 577 | .dstStatusRegisterAddress = 0x00000000, | ||
| 578 | .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, | ||
| 579 | .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, | ||
| 580 | .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM, | ||
| 581 | .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, | ||
| 582 | .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, | ||
| 583 | .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 584 | .errorInterrupt = dmacHw_INTERRUPT_ENABLE, | ||
| 585 | .channelPriority = dmacHw_CHANNEL_PRIORITY_7, | ||
| 586 | .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, | ||
| 587 | .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, | ||
| 588 | .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, | ||
| 589 | .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, | ||
| 590 | }, | ||
| 591 | }, | ||
| 592 | }; | ||
| 593 | EXPORT_SYMBOL(DMA_gDeviceAttribute); /* primarily for dma-test.c */ | ||
diff --git a/arch/arm/mach-bcmring/include/cfg_global.h b/arch/arm/mach-bcmring/include/cfg_global.h new file mode 100644 index 000000000000..f01da877148e --- /dev/null +++ b/arch/arm/mach-bcmring/include/cfg_global.h | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | #ifndef _CFG_GLOBAL_H_ | ||
| 2 | #define _CFG_GLOBAL_H_ | ||
| 3 | |||
| 4 | #include <cfg_global_defines.h> | ||
| 5 | |||
| 6 | #define CFG_GLOBAL_CHIP BCM11107 | ||
| 7 | #define CFG_GLOBAL_CHIP_FAMILY CFG_GLOBAL_CHIP_FAMILY_BCMRING | ||
| 8 | #define CFG_GLOBAL_CHIP_REV 0xB0 | ||
| 9 | #define CFG_GLOBAL_RAM_SIZE 0x10000000 | ||
| 10 | #define CFG_GLOBAL_RAM_BASE 0x00000000 | ||
| 11 | #define CFG_GLOBAL_RAM_RESERVED_SIZE 0x000000 | ||
| 12 | |||
| 13 | #endif /* _CFG_GLOBAL_H_ */ | ||
diff --git a/arch/arm/mach-bcmring/include/cfg_global_defines.h b/arch/arm/mach-bcmring/include/cfg_global_defines.h new file mode 100644 index 000000000000..b5beb0b30734 --- /dev/null +++ b/arch/arm/mach-bcmring/include/cfg_global_defines.h | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2006 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #ifndef CFG_GLOBAL_DEFINES_H | ||
| 16 | #define CFG_GLOBAL_DEFINES_H | ||
| 17 | |||
| 18 | /* CHIP */ | ||
| 19 | #define BCM1103 1 | ||
| 20 | |||
| 21 | #define BCM1191 4 | ||
| 22 | #define BCM2153 5 | ||
| 23 | #define BCM2820 6 | ||
| 24 | |||
| 25 | #define BCM2826 8 | ||
| 26 | #define FPGA11107 9 | ||
| 27 | #define BCM11107 10 | ||
| 28 | #define BCM11109 11 | ||
| 29 | #define BCM11170 12 | ||
| 30 | #define BCM11110 13 | ||
| 31 | #define BCM11211 14 | ||
| 32 | |||
| 33 | /* CFG_GLOBAL_CHIP_FAMILY types */ | ||
| 34 | #define CFG_GLOBAL_CHIP_FAMILY_NONE 0 | ||
| 35 | #define CFG_GLOBAL_CHIP_FAMILY_BCM116X 2 | ||
| 36 | #define CFG_GLOBAL_CHIP_FAMILY_BCMRING 4 | ||
| 37 | #define CFG_GLOBAL_CHIP_FAMILY_BCM1103 8 | ||
| 38 | |||
| 39 | #define IMAGE_HEADER_SIZE_CHECKSUM 4 | ||
| 40 | #endif | ||
diff --git a/arch/arm/mach-bcmring/include/csp/cache.h b/arch/arm/mach-bcmring/include/csp/cache.h new file mode 100644 index 000000000000..caa20e59db99 --- /dev/null +++ b/arch/arm/mach-bcmring/include/csp/cache.h | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #ifndef CSP_CACHE_H | ||
| 16 | #define CSP_CACHE_H | ||
| 17 | |||
| 18 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 19 | |||
| 20 | #include <csp/stdint.h> | ||
| 21 | |||
| 22 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 23 | |||
| 24 | #if defined(__KERNEL__) && !defined(STANDALONE) | ||
| 25 | #include <asm/cacheflush.h> | ||
| 26 | |||
| 27 | #define CSP_CACHE_FLUSH_ALL flush_cache_all() | ||
| 28 | |||
| 29 | #else | ||
| 30 | |||
| 31 | #define CSP_CACHE_FLUSH_ALL | ||
| 32 | |||
| 33 | #endif | ||
| 34 | |||
| 35 | #endif /* CSP_CACHE_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/csp/delay.h b/arch/arm/mach-bcmring/include/csp/delay.h new file mode 100644 index 000000000000..8b3d80367293 --- /dev/null +++ b/arch/arm/mach-bcmring/include/csp/delay.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | |||
| 16 | #ifndef CSP_DELAY_H | ||
| 17 | #define CSP_DELAY_H | ||
| 18 | |||
| 19 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 20 | |||
| 21 | /* Some CSP routines require use of the following delay routines. Use the OS */ | ||
| 22 | /* version if available, otherwise use a CSP specific definition. */ | ||
| 23 | /* void udelay(unsigned long usecs); */ | ||
| 24 | /* void mdelay(unsigned long msecs); */ | ||
| 25 | |||
| 26 | #if defined(__KERNEL__) && !defined(STANDALONE) | ||
| 27 | #include <linux/delay.h> | ||
| 28 | #else | ||
| 29 | #include <mach/csp/delay.h> | ||
| 30 | #endif | ||
| 31 | |||
| 32 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 33 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 34 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 35 | |||
| 36 | #endif /* CSP_DELAY_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/csp/dmacHw.h b/arch/arm/mach-bcmring/include/csp/dmacHw.h new file mode 100644 index 000000000000..5d510130a25f --- /dev/null +++ b/arch/arm/mach-bcmring/include/csp/dmacHw.h | |||
| @@ -0,0 +1,596 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file dmacHw.h | ||
| 18 | * | ||
| 19 | * @brief API definitions for low level DMA controller driver | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | /****************************************************************************/ | ||
| 23 | #ifndef _DMACHW_H | ||
| 24 | #define _DMACHW_H | ||
| 25 | |||
| 26 | #include <stddef.h> | ||
| 27 | |||
| 28 | #include <csp/stdint.h> | ||
| 29 | #include <mach/csp/dmacHw_reg.h> | ||
| 30 | |||
| 31 | /* Define DMA Channel ID using DMA controller number (m) and channel number (c). | ||
| 32 | |||
| 33 | System specific channel ID should be defined as follows | ||
| 34 | |||
| 35 | For example: | ||
| 36 | |||
| 37 | #include <dmacHw.h> | ||
| 38 | ... | ||
| 39 | #define systemHw_LCD_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,5) | ||
| 40 | #define systemHw_SWITCH_RX_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,0) | ||
| 41 | #define systemHw_SWITCH_TX_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,1) | ||
| 42 | #define systemHw_APM_RX_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,3) | ||
| 43 | #define systemHw_APM_TX_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,4) | ||
| 44 | ... | ||
| 45 | #define systemHw_SHARED1_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(1,4) | ||
| 46 | #define systemHw_SHARED2_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(1,5) | ||
| 47 | #define systemHw_SHARED3_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,6) | ||
| 48 | ... | ||
| 49 | */ | ||
| 50 | #define dmacHw_MAKE_CHANNEL_ID(m, c) (m << 8 | c) | ||
| 51 | |||
| 52 | typedef enum { | ||
| 53 | dmacHw_CHANNEL_PRIORITY_0 = dmacHw_REG_CFG_LO_CH_PRIORITY_0, /* Channel priority 0. Lowest priority DMA channel */ | ||
| 54 | dmacHw_CHANNEL_PRIORITY_1 = dmacHw_REG_CFG_LO_CH_PRIORITY_1, /* Channel priority 1 */ | ||
| 55 | dmacHw_CHANNEL_PRIORITY_2 = dmacHw_REG_CFG_LO_CH_PRIORITY_2, /* Channel priority 2 */ | ||
| 56 | dmacHw_CHANNEL_PRIORITY_3 = dmacHw_REG_CFG_LO_CH_PRIORITY_3, /* Channel priority 3 */ | ||
| 57 | dmacHw_CHANNEL_PRIORITY_4 = dmacHw_REG_CFG_LO_CH_PRIORITY_4, /* Channel priority 4 */ | ||
| 58 | dmacHw_CHANNEL_PRIORITY_5 = dmacHw_REG_CFG_LO_CH_PRIORITY_5, /* Channel priority 5 */ | ||
| 59 | dmacHw_CHANNEL_PRIORITY_6 = dmacHw_REG_CFG_LO_CH_PRIORITY_6, /* Channel priority 6 */ | ||
| 60 | dmacHw_CHANNEL_PRIORITY_7 = dmacHw_REG_CFG_LO_CH_PRIORITY_7 /* Channel priority 7. Highest priority DMA channel */ | ||
| 61 | } dmacHw_CHANNEL_PRIORITY_e; | ||
| 62 | |||
| 63 | /* Source destination master interface */ | ||
| 64 | typedef enum { | ||
| 65 | dmacHw_SRC_MASTER_INTERFACE_1 = dmacHw_REG_CTL_SMS_1, /* Source DMA master interface 1 */ | ||
| 66 | dmacHw_SRC_MASTER_INTERFACE_2 = dmacHw_REG_CTL_SMS_2, /* Source DMA master interface 2 */ | ||
| 67 | dmacHw_DST_MASTER_INTERFACE_1 = dmacHw_REG_CTL_DMS_1, /* Destination DMA master interface 1 */ | ||
| 68 | dmacHw_DST_MASTER_INTERFACE_2 = dmacHw_REG_CTL_DMS_2 /* Destination DMA master interface 2 */ | ||
| 69 | } dmacHw_MASTER_INTERFACE_e; | ||
| 70 | |||
| 71 | typedef enum { | ||
| 72 | dmacHw_SRC_TRANSACTION_WIDTH_8 = dmacHw_REG_CTL_SRC_TR_WIDTH_8, /* Source 8 bit (1 byte) per transaction */ | ||
| 73 | dmacHw_SRC_TRANSACTION_WIDTH_16 = dmacHw_REG_CTL_SRC_TR_WIDTH_16, /* Source 16 bit (2 byte) per transaction */ | ||
| 74 | dmacHw_SRC_TRANSACTION_WIDTH_32 = dmacHw_REG_CTL_SRC_TR_WIDTH_32, /* Source 32 bit (4 byte) per transaction */ | ||
| 75 | dmacHw_SRC_TRANSACTION_WIDTH_64 = dmacHw_REG_CTL_SRC_TR_WIDTH_64, /* Source 64 bit (8 byte) per transaction */ | ||
| 76 | dmacHw_DST_TRANSACTION_WIDTH_8 = dmacHw_REG_CTL_DST_TR_WIDTH_8, /* Destination 8 bit (1 byte) per transaction */ | ||
| 77 | dmacHw_DST_TRANSACTION_WIDTH_16 = dmacHw_REG_CTL_DST_TR_WIDTH_16, /* Destination 16 bit (2 byte) per transaction */ | ||
| 78 | dmacHw_DST_TRANSACTION_WIDTH_32 = dmacHw_REG_CTL_DST_TR_WIDTH_32, /* Destination 32 bit (4 byte) per transaction */ | ||
| 79 | dmacHw_DST_TRANSACTION_WIDTH_64 = dmacHw_REG_CTL_DST_TR_WIDTH_64 /* Destination 64 bit (8 byte) per transaction */ | ||
| 80 | } dmacHw_TRANSACTION_WIDTH_e; | ||
| 81 | |||
| 82 | typedef enum { | ||
| 83 | dmacHw_SRC_BURST_WIDTH_0 = dmacHw_REG_CTL_SRC_MSIZE_0, /* Source No burst */ | ||
| 84 | dmacHw_SRC_BURST_WIDTH_4 = dmacHw_REG_CTL_SRC_MSIZE_4, /* Source 4 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */ | ||
| 85 | dmacHw_SRC_BURST_WIDTH_8 = dmacHw_REG_CTL_SRC_MSIZE_8, /* Source 8 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */ | ||
| 86 | dmacHw_SRC_BURST_WIDTH_16 = dmacHw_REG_CTL_SRC_MSIZE_16, /* Source 16 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */ | ||
| 87 | dmacHw_DST_BURST_WIDTH_0 = dmacHw_REG_CTL_DST_MSIZE_0, /* Destination No burst */ | ||
| 88 | dmacHw_DST_BURST_WIDTH_4 = dmacHw_REG_CTL_DST_MSIZE_4, /* Destination 4 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */ | ||
| 89 | dmacHw_DST_BURST_WIDTH_8 = dmacHw_REG_CTL_DST_MSIZE_8, /* Destination 8 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */ | ||
| 90 | dmacHw_DST_BURST_WIDTH_16 = dmacHw_REG_CTL_DST_MSIZE_16 /* Destination 16 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */ | ||
| 91 | } dmacHw_BURST_WIDTH_e; | ||
| 92 | |||
| 93 | typedef enum { | ||
| 94 | dmacHw_TRANSFER_TYPE_MEM_TO_MEM = dmacHw_REG_CTL_TTFC_MM_DMAC, /* Memory to memory transfer */ | ||
| 95 | dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM = dmacHw_REG_CTL_TTFC_PM_DMAC, /* Peripheral to memory transfer */ | ||
| 96 | dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL = dmacHw_REG_CTL_TTFC_MP_DMAC, /* Memory to peripheral transfer */ | ||
| 97 | dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL = dmacHw_REG_CTL_TTFC_PP_DMAC /* Peripheral to peripheral transfer */ | ||
| 98 | } dmacHw_TRANSFER_TYPE_e; | ||
| 99 | |||
| 100 | typedef enum { | ||
| 101 | dmacHw_TRANSFER_MODE_PERREQUEST, /* Block transfer per DMA request */ | ||
| 102 | dmacHw_TRANSFER_MODE_CONTINUOUS, /* Continuous transfer of streaming data */ | ||
| 103 | dmacHw_TRANSFER_MODE_PERIODIC /* Periodic transfer of streaming data */ | ||
| 104 | } dmacHw_TRANSFER_MODE_e; | ||
| 105 | |||
| 106 | typedef enum { | ||
| 107 | dmacHw_SRC_ADDRESS_UPDATE_MODE_INC = dmacHw_REG_CTL_SINC_INC, /* Increment source address after every transaction */ | ||
| 108 | dmacHw_SRC_ADDRESS_UPDATE_MODE_DEC = dmacHw_REG_CTL_SINC_DEC, /* Decrement source address after every transaction */ | ||
| 109 | dmacHw_DST_ADDRESS_UPDATE_MODE_INC = dmacHw_REG_CTL_DINC_INC, /* Increment destination address after every transaction */ | ||
| 110 | dmacHw_DST_ADDRESS_UPDATE_MODE_DEC = dmacHw_REG_CTL_DINC_DEC, /* Decrement destination address after every transaction */ | ||
| 111 | dmacHw_SRC_ADDRESS_UPDATE_MODE_NC = dmacHw_REG_CTL_SINC_NC, /* No change in source address after every transaction */ | ||
| 112 | dmacHw_DST_ADDRESS_UPDATE_MODE_NC = dmacHw_REG_CTL_DINC_NC /* No change in destination address after every transaction */ | ||
| 113 | } dmacHw_ADDRESS_UPDATE_MODE_e; | ||
| 114 | |||
| 115 | typedef enum { | ||
| 116 | dmacHw_FLOW_CONTROL_DMA, /* DMA working as flow controller (default) */ | ||
| 117 | dmacHw_FLOW_CONTROL_PERIPHERAL /* Peripheral working as flow controller */ | ||
| 118 | } dmacHw_FLOW_CONTROL_e; | ||
| 119 | |||
| 120 | typedef enum { | ||
| 121 | dmacHw_TRANSFER_STATUS_BUSY, /* DMA Transfer ongoing */ | ||
| 122 | dmacHw_TRANSFER_STATUS_DONE, /* DMA Transfer completed */ | ||
| 123 | dmacHw_TRANSFER_STATUS_ERROR /* DMA Transfer error */ | ||
| 124 | } dmacHw_TRANSFER_STATUS_e; | ||
| 125 | |||
| 126 | typedef enum { | ||
| 127 | dmacHw_INTERRUPT_DISABLE, /* Interrupt disable */ | ||
| 128 | dmacHw_INTERRUPT_ENABLE /* Interrupt enable */ | ||
| 129 | } dmacHw_INTERRUPT_e; | ||
| 130 | |||
| 131 | typedef enum { | ||
| 132 | dmacHw_INTERRUPT_STATUS_NONE = 0x0, /* No DMA interrupt */ | ||
| 133 | dmacHw_INTERRUPT_STATUS_TRANS = 0x1, /* End of DMA transfer interrupt */ | ||
| 134 | dmacHw_INTERRUPT_STATUS_BLOCK = 0x2, /* End of block transfer interrupt */ | ||
| 135 | dmacHw_INTERRUPT_STATUS_ERROR = 0x4 /* Error interrupt */ | ||
| 136 | } dmacHw_INTERRUPT_STATUS_e; | ||
| 137 | |||
| 138 | typedef enum { | ||
| 139 | dmacHw_CONTROLLER_ATTRIB_CHANNEL_NUM, /* Number of DMA channel */ | ||
| 140 | dmacHw_CONTROLLER_ATTRIB_CHANNEL_MAX_BLOCK_SIZE, /* Maximum channel burst size */ | ||
| 141 | dmacHw_CONTROLLER_ATTRIB_MASTER_INTF_NUM, /* Number of DMA master interface */ | ||
| 142 | dmacHw_CONTROLLER_ATTRIB_CHANNEL_BUS_WIDTH, /* Channel Data bus width */ | ||
| 143 | dmacHw_CONTROLLER_ATTRIB_CHANNEL_FIFO_SIZE /* Channel FIFO size */ | ||
| 144 | } dmacHw_CONTROLLER_ATTRIB_e; | ||
| 145 | |||
| 146 | typedef unsigned long dmacHw_HANDLE_t; /* DMA channel handle */ | ||
| 147 | typedef uint32_t dmacHw_ID_t; /* DMA channel Id. Must be created using | ||
| 148 | "dmacHw_MAKE_CHANNEL_ID" macro | ||
| 149 | */ | ||
| 150 | /* DMA channel configuration parameters */ | ||
| 151 | typedef struct { | ||
| 152 | uint32_t srcPeripheralPort; /* Source peripheral port */ | ||
| 153 | uint32_t dstPeripheralPort; /* Destination peripheral port */ | ||
| 154 | uint32_t srcStatusRegisterAddress; /* Source status register address */ | ||
| 155 | uint32_t dstStatusRegisterAddress; /* Destination status register address of type */ | ||
| 156 | |||
| 157 | uint32_t srcGatherWidth; /* Number of bytes gathered before successive gather opearation */ | ||
| 158 | uint32_t srcGatherJump; /* Number of bytes jumpped before successive gather opearation */ | ||
| 159 | uint32_t dstScatterWidth; /* Number of bytes sacattered before successive scatter opearation */ | ||
| 160 | uint32_t dstScatterJump; /* Number of bytes jumpped before successive scatter opearation */ | ||
| 161 | uint32_t maxDataPerBlock; /* Maximum number of bytes to be transferred per block/descrptor. | ||
| 162 | 0 = Maximum possible. | ||
| 163 | */ | ||
| 164 | |||
| 165 | dmacHw_ADDRESS_UPDATE_MODE_e srcUpdate; /* Source address update mode */ | ||
| 166 | dmacHw_ADDRESS_UPDATE_MODE_e dstUpdate; /* Destination address update mode */ | ||
| 167 | dmacHw_TRANSFER_TYPE_e transferType; /* DMA transfer type */ | ||
| 168 | dmacHw_TRANSFER_MODE_e transferMode; /* DMA transfer mode */ | ||
| 169 | dmacHw_MASTER_INTERFACE_e srcMasterInterface; /* DMA source interface */ | ||
| 170 | dmacHw_MASTER_INTERFACE_e dstMasterInterface; /* DMA destination interface */ | ||
| 171 | dmacHw_TRANSACTION_WIDTH_e srcMaxTransactionWidth; /* Source transaction width */ | ||
| 172 | dmacHw_TRANSACTION_WIDTH_e dstMaxTransactionWidth; /* Destination transaction width */ | ||
| 173 | dmacHw_BURST_WIDTH_e srcMaxBurstWidth; /* Source burst width */ | ||
| 174 | dmacHw_BURST_WIDTH_e dstMaxBurstWidth; /* Destination burst width */ | ||
| 175 | dmacHw_INTERRUPT_e blockTransferInterrupt; /* Block trsnafer interrupt */ | ||
| 176 | dmacHw_INTERRUPT_e completeTransferInterrupt; /* Complete DMA trsnafer interrupt */ | ||
| 177 | dmacHw_INTERRUPT_e errorInterrupt; /* Error interrupt */ | ||
| 178 | dmacHw_CHANNEL_PRIORITY_e channelPriority; /* Channel priority */ | ||
| 179 | dmacHw_FLOW_CONTROL_e flowControler; /* Data flow controller */ | ||
| 180 | } dmacHw_CONFIG_t; | ||
| 181 | |||
| 182 | /****************************************************************************/ | ||
| 183 | /** | ||
| 184 | * @brief Initializes DMA | ||
| 185 | * | ||
| 186 | * This function initializes DMA CSP driver | ||
| 187 | * | ||
| 188 | * @note | ||
| 189 | * Must be called before using any DMA channel | ||
| 190 | */ | ||
| 191 | /****************************************************************************/ | ||
| 192 | void dmacHw_initDma(void); | ||
| 193 | |||
| 194 | /****************************************************************************/ | ||
| 195 | /** | ||
| 196 | * @brief Exit function for DMA | ||
| 197 | * | ||
| 198 | * This function isolates DMA from the system | ||
| 199 | * | ||
| 200 | */ | ||
| 201 | /****************************************************************************/ | ||
| 202 | void dmacHw_exitDma(void); | ||
| 203 | |||
| 204 | /****************************************************************************/ | ||
| 205 | /** | ||
| 206 | * @brief Gets a handle to a DMA channel | ||
| 207 | * | ||
| 208 | * This function returns a handle, representing a control block of a particular DMA channel | ||
| 209 | * | ||
| 210 | * @return -1 - On Failure | ||
| 211 | * handle - On Success, representing a channel control block | ||
| 212 | * | ||
| 213 | * @note | ||
| 214 | * None Channel ID must be created using "dmacHw_MAKE_CHANNEL_ID" macro | ||
| 215 | */ | ||
| 216 | /****************************************************************************/ | ||
| 217 | dmacHw_HANDLE_t dmacHw_getChannelHandle(dmacHw_ID_t channelId /* [ IN ] DMA Channel Id */ | ||
| 218 | ); | ||
| 219 | |||
| 220 | /****************************************************************************/ | ||
| 221 | /** | ||
| 222 | * @brief Initializes a DMA channel for use | ||
| 223 | * | ||
| 224 | * This function initializes and resets a DMA channel for use | ||
| 225 | * | ||
| 226 | * @return -1 - On Failure | ||
| 227 | * 0 - On Success | ||
| 228 | * | ||
| 229 | * @note | ||
| 230 | * None | ||
| 231 | */ | ||
| 232 | /****************************************************************************/ | ||
| 233 | int dmacHw_initChannel(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */ | ||
| 234 | ); | ||
| 235 | |||
| 236 | /****************************************************************************/ | ||
| 237 | /** | ||
| 238 | * @brief Estimates number of descriptor needed to perform certain DMA transfer | ||
| 239 | * | ||
| 240 | * | ||
| 241 | * @return On failure : -1 | ||
| 242 | * On success : Number of descriptor count | ||
| 243 | * | ||
| 244 | * | ||
| 245 | */ | ||
| 246 | /****************************************************************************/ | ||
| 247 | int dmacHw_calculateDescriptorCount(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 248 | void *pSrcAddr, /* [ IN ] Source (Peripheral/Memory) address */ | ||
| 249 | void *pDstAddr, /* [ IN ] Destination (Peripheral/Memory) address */ | ||
| 250 | size_t dataLen /* [ IN ] Data length in bytes */ | ||
| 251 | ); | ||
| 252 | |||
| 253 | /****************************************************************************/ | ||
| 254 | /** | ||
| 255 | * @brief Initializes descriptor ring | ||
| 256 | * | ||
| 257 | * This function will initializes the descriptor ring of a DMA channel | ||
| 258 | * | ||
| 259 | * | ||
| 260 | * @return -1 - On failure | ||
| 261 | * 0 - On success | ||
| 262 | * @note | ||
| 263 | * - "len" parameter should be obtained from "dmacHw_descriptorLen" | ||
| 264 | * - Descriptor buffer MUST be 32 bit aligned and uncached as it | ||
| 265 | * is accessed by ARM and DMA | ||
| 266 | */ | ||
| 267 | /****************************************************************************/ | ||
| 268 | int dmacHw_initDescriptor(void *pDescriptorVirt, /* [ IN ] Virtual address of uncahced buffer allocated to form descriptor ring */ | ||
| 269 | uint32_t descriptorPhyAddr, /* [ IN ] Physical address of pDescriptorVirt (descriptor buffer) */ | ||
| 270 | uint32_t len, /* [ IN ] Size of the pBuf */ | ||
| 271 | uint32_t num /* [ IN ] Number of descriptor in the ring */ | ||
| 272 | ); | ||
| 273 | |||
| 274 | /****************************************************************************/ | ||
| 275 | /** | ||
| 276 | * @brief Finds amount of memory required to form a descriptor ring | ||
| 277 | * | ||
| 278 | * | ||
| 279 | * @return Number of bytes required to form a descriptor ring | ||
| 280 | * | ||
| 281 | * | ||
| 282 | * @note | ||
| 283 | * None | ||
| 284 | */ | ||
| 285 | /****************************************************************************/ | ||
| 286 | uint32_t dmacHw_descriptorLen(uint32_t descCnt /* [ IN ] Number of descriptor in the ring */ | ||
| 287 | ); | ||
| 288 | |||
| 289 | /****************************************************************************/ | ||
| 290 | /** | ||
| 291 | * @brief Configure DMA channel | ||
| 292 | * | ||
| 293 | * @return 0 : On success | ||
| 294 | * -1 : On failure | ||
| 295 | */ | ||
| 296 | /****************************************************************************/ | ||
| 297 | int dmacHw_configChannel(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 298 | dmacHw_CONFIG_t *pConfig /* [ IN ] Configuration settings */ | ||
| 299 | ); | ||
| 300 | |||
| 301 | /****************************************************************************/ | ||
| 302 | /** | ||
| 303 | * @brief Set descriptors for known data length | ||
| 304 | * | ||
| 305 | * When DMA has to work as a flow controller, this function prepares the | ||
| 306 | * descriptor chain to transfer data | ||
| 307 | * | ||
| 308 | * from: | ||
| 309 | * - Memory to memory | ||
| 310 | * - Peripheral to memory | ||
| 311 | * - Memory to Peripheral | ||
| 312 | * - Peripheral to Peripheral | ||
| 313 | * | ||
| 314 | * @return -1 - On failure | ||
| 315 | * 0 - On success | ||
| 316 | * | ||
| 317 | */ | ||
| 318 | /****************************************************************************/ | ||
| 319 | int dmacHw_setDataDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 320 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 321 | void *pSrcAddr, /* [ IN ] Source (Peripheral/Memory) address */ | ||
| 322 | void *pDstAddr, /* [ IN ] Destination (Peripheral/Memory) address */ | ||
| 323 | size_t dataLen /* [ IN ] Length in bytes */ | ||
| 324 | ); | ||
| 325 | |||
| 326 | /****************************************************************************/ | ||
| 327 | /** | ||
| 328 | * @brief Indicates whether DMA transfer is in progress or completed | ||
| 329 | * | ||
| 330 | * @return DMA transfer status | ||
| 331 | * dmacHw_TRANSFER_STATUS_BUSY: DMA Transfer ongoing | ||
| 332 | * dmacHw_TRANSFER_STATUS_DONE: DMA Transfer completed | ||
| 333 | * dmacHw_TRANSFER_STATUS_ERROR: DMA Transfer error | ||
| 334 | * | ||
| 335 | */ | ||
| 336 | /****************************************************************************/ | ||
| 337 | dmacHw_TRANSFER_STATUS_e dmacHw_transferCompleted(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */ | ||
| 338 | ); | ||
| 339 | |||
| 340 | /****************************************************************************/ | ||
| 341 | /** | ||
| 342 | * @brief Set descriptor carrying control information | ||
| 343 | * | ||
| 344 | * This function will be used to send specific control information to the device | ||
| 345 | * using the DMA channel | ||
| 346 | * | ||
| 347 | * | ||
| 348 | * @return -1 - On failure | ||
| 349 | * 0 - On success | ||
| 350 | * | ||
| 351 | * @note | ||
| 352 | * None | ||
| 353 | */ | ||
| 354 | /****************************************************************************/ | ||
| 355 | int dmacHw_setControlDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 356 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 357 | uint32_t ctlAddress, /* [ IN ] Address of the device control register */ | ||
| 358 | uint32_t control /* [ IN ] Device control information */ | ||
| 359 | ); | ||
| 360 | |||
| 361 | /****************************************************************************/ | ||
| 362 | /** | ||
| 363 | * @brief Read data DMA transferred to memory | ||
| 364 | * | ||
| 365 | * This function will read data that has been DMAed to memory while transfering from: | ||
| 366 | * - Memory to memory | ||
| 367 | * - Peripheral to memory | ||
| 368 | * | ||
| 369 | * @return 0 - No more data is available to read | ||
| 370 | * 1 - More data might be available to read | ||
| 371 | * | ||
| 372 | */ | ||
| 373 | /****************************************************************************/ | ||
| 374 | int dmacHw_readTransferredData(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 375 | dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 376 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 377 | void **ppBbuf, /* [ OUT ] Data received */ | ||
| 378 | size_t *pLlen /* [ OUT ] Length of the data received */ | ||
| 379 | ); | ||
| 380 | |||
| 381 | /****************************************************************************/ | ||
| 382 | /** | ||
| 383 | * @brief Prepares descriptor ring, when source peripheral working as a flow controller | ||
| 384 | * | ||
| 385 | * This function will form the descriptor ring by allocating buffers, when source peripheral | ||
| 386 | * has to work as a flow controller to transfer data from: | ||
| 387 | * - Peripheral to memory. | ||
| 388 | * | ||
| 389 | * @return -1 - On failure | ||
| 390 | * 0 - On success | ||
| 391 | * | ||
| 392 | * | ||
| 393 | * @note | ||
| 394 | * None | ||
| 395 | */ | ||
| 396 | /****************************************************************************/ | ||
| 397 | int dmacHw_setVariableDataDescriptor(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 398 | dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 399 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 400 | uint32_t srcAddr, /* [ IN ] Source peripheral address */ | ||
| 401 | void *(*fpAlloc) (int len), /* [ IN ] Function pointer that provides destination memory */ | ||
| 402 | int len, /* [ IN ] Number of bytes "fpAlloc" will allocate for destination */ | ||
| 403 | int num /* [ IN ] Number of descriptor to set */ | ||
| 404 | ); | ||
| 405 | |||
| 406 | /****************************************************************************/ | ||
| 407 | /** | ||
| 408 | * @brief Program channel register to initiate transfer | ||
| 409 | * | ||
| 410 | * @return void | ||
| 411 | * | ||
| 412 | * | ||
| 413 | * @note | ||
| 414 | * - Descriptor buffer MUST ALWAYS be flushed before calling this function | ||
| 415 | * - This function should also be called from ISR to program the channel with | ||
| 416 | * pending descriptors | ||
| 417 | */ | ||
| 418 | /****************************************************************************/ | ||
| 419 | void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 420 | dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 421 | void *pDescriptor /* [ IN ] Descriptor buffer */ | ||
| 422 | ); | ||
| 423 | |||
| 424 | /****************************************************************************/ | ||
| 425 | /** | ||
| 426 | * @brief Resets descriptor control information | ||
| 427 | * | ||
| 428 | * @return void | ||
| 429 | */ | ||
| 430 | /****************************************************************************/ | ||
| 431 | void dmacHw_resetDescriptorControl(void *pDescriptor /* [ IN ] Descriptor buffer */ | ||
| 432 | ); | ||
| 433 | |||
| 434 | /****************************************************************************/ | ||
| 435 | /** | ||
| 436 | * @brief Program channel register to stop transfer | ||
| 437 | * | ||
| 438 | * Ensures the channel is not doing any transfer after calling this function | ||
| 439 | * | ||
| 440 | * @return void | ||
| 441 | * | ||
| 442 | */ | ||
| 443 | /****************************************************************************/ | ||
| 444 | void dmacHw_stopTransfer(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */ | ||
| 445 | ); | ||
| 446 | |||
| 447 | /****************************************************************************/ | ||
| 448 | /** | ||
| 449 | * @brief Check the existance of pending descriptor | ||
| 450 | * | ||
| 451 | * This function confirmes if there is any pending descriptor in the chain | ||
| 452 | * to program the channel | ||
| 453 | * | ||
| 454 | * @return 1 : Channel need to be programmed with pending descriptor | ||
| 455 | * 0 : No more pending descriptor to programe the channel | ||
| 456 | * | ||
| 457 | * @note | ||
| 458 | * - This function should be called from ISR in case there are pending | ||
| 459 | * descriptor to program the channel. | ||
| 460 | * | ||
| 461 | * Example: | ||
| 462 | * | ||
| 463 | * dmac_isr () | ||
| 464 | * { | ||
| 465 | * ... | ||
| 466 | * if (dmacHw_descriptorPending (handle)) | ||
| 467 | * { | ||
| 468 | * dmacHw_initiateTransfer (handle); | ||
| 469 | * } | ||
| 470 | * } | ||
| 471 | * | ||
| 472 | */ | ||
| 473 | /****************************************************************************/ | ||
| 474 | uint32_t dmacHw_descriptorPending(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 475 | void *pDescriptor /* [ IN ] Descriptor buffer */ | ||
| 476 | ); | ||
| 477 | |||
| 478 | /****************************************************************************/ | ||
| 479 | /** | ||
| 480 | * @brief Deallocates source or destination memory, allocated | ||
| 481 | * | ||
| 482 | * This function can be called to deallocate data memory that was DMAed successfully | ||
| 483 | * | ||
| 484 | * @return -1 - On failure | ||
| 485 | * 0 - On success | ||
| 486 | * | ||
| 487 | * @note | ||
| 488 | * This function will be called ONLY, when source OR destination address is pointing | ||
| 489 | * to dynamic memory | ||
| 490 | */ | ||
| 491 | /****************************************************************************/ | ||
| 492 | int dmacHw_freeMem(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ | ||
| 493 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 494 | void (*fpFree) (void *) /* [ IN ] Function pointer to free data memory */ | ||
| 495 | ); | ||
| 496 | |||
| 497 | /****************************************************************************/ | ||
| 498 | /** | ||
| 499 | * @brief Clears the interrupt | ||
| 500 | * | ||
| 501 | * This function clears the DMA channel specific interrupt | ||
| 502 | * | ||
| 503 | * @return N/A | ||
| 504 | * | ||
| 505 | * @note | ||
| 506 | * Must be called under the context of ISR | ||
| 507 | */ | ||
| 508 | /****************************************************************************/ | ||
| 509 | void dmacHw_clearInterrupt(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */ | ||
| 510 | ); | ||
| 511 | |||
| 512 | /****************************************************************************/ | ||
| 513 | /** | ||
| 514 | * @brief Returns the cause of channel specific DMA interrupt | ||
| 515 | * | ||
| 516 | * This function returns the cause of interrupt | ||
| 517 | * | ||
| 518 | * @return Interrupt status, each bit representing a specific type of interrupt | ||
| 519 | * of type dmacHw_INTERRUPT_STATUS_e | ||
| 520 | * @note | ||
| 521 | * This function should be called under the context of ISR | ||
| 522 | */ | ||
| 523 | /****************************************************************************/ | ||
| 524 | dmacHw_INTERRUPT_STATUS_e dmacHw_getInterruptStatus(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */ | ||
| 525 | ); | ||
| 526 | |||
| 527 | /****************************************************************************/ | ||
| 528 | /** | ||
| 529 | * @brief Indentifies a DMA channel causing interrupt | ||
| 530 | * | ||
| 531 | * This functions returns a channel causing interrupt of type dmacHw_INTERRUPT_STATUS_e | ||
| 532 | * | ||
| 533 | * @return NULL : No channel causing DMA interrupt | ||
| 534 | * ! NULL : Handle to a channel causing DMA interrupt | ||
| 535 | * @note | ||
| 536 | * dmacHw_clearInterrupt() must be called with a valid handle after calling this function | ||
| 537 | */ | ||
| 538 | /****************************************************************************/ | ||
| 539 | dmacHw_HANDLE_t dmacHw_getInterruptSource(void); | ||
| 540 | |||
| 541 | /****************************************************************************/ | ||
| 542 | /** | ||
| 543 | * @brief Sets channel specific user data | ||
| 544 | * | ||
| 545 | * This function associates user data to a specif DMA channel | ||
| 546 | * | ||
| 547 | */ | ||
| 548 | /****************************************************************************/ | ||
| 549 | void dmacHw_setChannelUserData(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 550 | void *userData /* [ IN ] User data */ | ||
| 551 | ); | ||
| 552 | |||
| 553 | /****************************************************************************/ | ||
| 554 | /** | ||
| 555 | * @brief Gets channel specific user data | ||
| 556 | * | ||
| 557 | * This function returns user data specific to a DMA channel | ||
| 558 | * | ||
| 559 | * @return user data | ||
| 560 | */ | ||
| 561 | /****************************************************************************/ | ||
| 562 | void *dmacHw_getChannelUserData(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */ | ||
| 563 | ); | ||
| 564 | |||
| 565 | /****************************************************************************/ | ||
| 566 | /** | ||
| 567 | * @brief Displays channel specific registers and other control parameters | ||
| 568 | * | ||
| 569 | * | ||
| 570 | * @return void | ||
| 571 | * | ||
| 572 | * @note | ||
| 573 | * None | ||
| 574 | */ | ||
| 575 | /****************************************************************************/ | ||
| 576 | void dmacHw_printDebugInfo(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 577 | void *pDescriptor, /* [ IN ] Descriptor buffer */ | ||
| 578 | int (*fpPrint) (const char *, ...) /* [ IN ] Print callback function */ | ||
| 579 | ); | ||
| 580 | |||
| 581 | /****************************************************************************/ | ||
| 582 | /** | ||
| 583 | * @brief Provides DMA controller attributes | ||
| 584 | * | ||
| 585 | * | ||
| 586 | * @return DMA controller attributes | ||
| 587 | * | ||
| 588 | * @note | ||
| 589 | * None | ||
| 590 | */ | ||
| 591 | /****************************************************************************/ | ||
| 592 | uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ | ||
| 593 | dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controler attribute of type dmacHw_CONTROLLER_ATTRIB_e */ | ||
| 594 | ); | ||
| 595 | |||
| 596 | #endif /* _DMACHW_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/csp/errno.h b/arch/arm/mach-bcmring/include/csp/errno.h new file mode 100644 index 000000000000..51357dd5b666 --- /dev/null +++ b/arch/arm/mach-bcmring/include/csp/errno.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #ifndef CSP_ERRNO_H | ||
| 16 | #define CSP_ERRNO_H | ||
| 17 | |||
| 18 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 19 | |||
| 20 | #if defined(__KERNEL__) | ||
| 21 | #include <linux/errno.h> | ||
| 22 | #elif defined(CSP_SIMULATION) | ||
| 23 | #include <asm-generic/errno.h> | ||
| 24 | #else | ||
| 25 | #include <errno.h> | ||
| 26 | #endif | ||
| 27 | |||
| 28 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 29 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 30 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 31 | |||
| 32 | #endif /* CSP_ERRNO_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/csp/intcHw.h b/arch/arm/mach-bcmring/include/csp/intcHw.h new file mode 100644 index 000000000000..1c639c8ee08f --- /dev/null +++ b/arch/arm/mach-bcmring/include/csp/intcHw.h | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | |||
| 16 | /****************************************************************************/ | ||
| 17 | /** | ||
| 18 | * @file intcHw.h | ||
| 19 | * | ||
| 20 | * @brief generic interrupt controller API | ||
| 21 | * | ||
| 22 | * @note | ||
| 23 | * None | ||
| 24 | */ | ||
| 25 | /****************************************************************************/ | ||
| 26 | |||
| 27 | #ifndef _INTCHW_H | ||
| 28 | #define _INTCHW_H | ||
| 29 | |||
| 30 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 31 | #include <mach/csp/intcHw_reg.h> | ||
| 32 | |||
| 33 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 34 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 35 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 36 | static inline void intcHw_irq_disable(void *basep, uint32_t mask); | ||
| 37 | static inline void intcHw_irq_enable(void *basep, uint32_t mask); | ||
| 38 | |||
| 39 | #endif /* _INTCHW_H */ | ||
| 40 | |||
diff --git a/arch/arm/mach-bcmring/include/csp/module.h b/arch/arm/mach-bcmring/include/csp/module.h new file mode 100644 index 000000000000..c30d2a5975a6 --- /dev/null +++ b/arch/arm/mach-bcmring/include/csp/module.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | |||
| 16 | #ifndef CSP_MODULE_H | ||
| 17 | #define CSP_MODULE_H | ||
| 18 | |||
| 19 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 20 | |||
| 21 | #ifdef __KERNEL__ | ||
| 22 | #include <linux/module.h> | ||
| 23 | #else | ||
| 24 | #define EXPORT_SYMBOL(symbol) | ||
| 25 | #endif | ||
| 26 | |||
| 27 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 28 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 29 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 30 | |||
| 31 | |||
| 32 | #endif /* CSP_MODULE_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/csp/reg.h b/arch/arm/mach-bcmring/include/csp/reg.h new file mode 100644 index 000000000000..e5f60bf5a1f3 --- /dev/null +++ b/arch/arm/mach-bcmring/include/csp/reg.h | |||
| @@ -0,0 +1,114 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file reg.h | ||
| 18 | * | ||
| 19 | * @brief Generic register defintions used in CSP | ||
| 20 | */ | ||
| 21 | /****************************************************************************/ | ||
| 22 | |||
| 23 | #ifndef CSP_REG_H | ||
| 24 | #define CSP_REG_H | ||
| 25 | |||
| 26 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 27 | |||
| 28 | #include <csp/stdint.h> | ||
| 29 | |||
| 30 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 31 | |||
| 32 | #define __REG32(x) (*((volatile uint32_t *)(x))) | ||
| 33 | #define __REG16(x) (*((volatile uint16_t *)(x))) | ||
| 34 | #define __REG8(x) (*((volatile uint8_t *) (x))) | ||
| 35 | |||
| 36 | /* Macros used to define a sequence of reserved registers. The start / end */ | ||
| 37 | /* are byte offsets in the particular register definition, with the "end" */ | ||
| 38 | /* being the offset of the next un-reserved register. E.g. if offsets */ | ||
| 39 | /* 0x10 through to 0x1f are reserved, then this reserved area could be */ | ||
| 40 | /* specified as follows. */ | ||
| 41 | /* typedef struct */ | ||
| 42 | /* { */ | ||
| 43 | /* uint32_t reg1; offset 0x00 */ | ||
| 44 | /* uint32_t reg2; offset 0x04 */ | ||
| 45 | /* uint32_t reg3; offset 0x08 */ | ||
| 46 | /* uint32_t reg4; offset 0x0c */ | ||
| 47 | /* REG32_RSVD(0x10, 0x20); */ | ||
| 48 | /* uint32_t reg5; offset 0x20 */ | ||
| 49 | /* ... */ | ||
| 50 | /* } EXAMPLE_REG_t; */ | ||
| 51 | #define REG8_RSVD(start, end) uint8_t rsvd_##start[(end - start) / sizeof(uint8_t)] | ||
| 52 | #define REG16_RSVD(start, end) uint16_t rsvd_##start[(end - start) / sizeof(uint16_t)] | ||
| 53 | #define REG32_RSVD(start, end) uint32_t rsvd_##start[(end - start) / sizeof(uint32_t)] | ||
| 54 | |||
| 55 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 56 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 57 | |||
| 58 | /* Note: When protecting multiple statements, the REG_LOCAL_IRQ_SAVE and */ | ||
| 59 | /* REG_LOCAL_IRQ_RESTORE must be enclosed in { } to allow the */ | ||
| 60 | /* flags variable to be declared locally. */ | ||
| 61 | /* e.g. */ | ||
| 62 | /* statement1; */ | ||
| 63 | /* { */ | ||
| 64 | /* REG_LOCAL_IRQ_SAVE; */ | ||
| 65 | /* <multiple statements here> */ | ||
| 66 | /* REG_LOCAL_IRQ_RESTORE; */ | ||
| 67 | /* } */ | ||
| 68 | /* statement2; */ | ||
| 69 | /* */ | ||
| 70 | |||
| 71 | #if defined(__KERNEL__) && !defined(STANDALONE) | ||
| 72 | #include <mach/hardware.h> | ||
| 73 | #include <linux/interrupt.h> | ||
| 74 | |||
| 75 | #define REG_LOCAL_IRQ_SAVE HW_DECLARE_SPINLOCK(reg32) \ | ||
| 76 | unsigned long flags; HW_IRQ_SAVE(reg32, flags) | ||
| 77 | |||
| 78 | #define REG_LOCAL_IRQ_RESTORE HW_IRQ_RESTORE(reg32, flags) | ||
| 79 | |||
| 80 | #else | ||
| 81 | |||
| 82 | #define REG_LOCAL_IRQ_SAVE | ||
| 83 | #define REG_LOCAL_IRQ_RESTORE | ||
| 84 | |||
| 85 | #endif | ||
| 86 | |||
| 87 | static inline void reg32_modify_and(volatile uint32_t *reg, uint32_t value) | ||
| 88 | { | ||
| 89 | REG_LOCAL_IRQ_SAVE; | ||
| 90 | *reg &= value; | ||
| 91 | REG_LOCAL_IRQ_RESTORE; | ||
| 92 | } | ||
| 93 | |||
| 94 | static inline void reg32_modify_or(volatile uint32_t *reg, uint32_t value) | ||
| 95 | { | ||
| 96 | REG_LOCAL_IRQ_SAVE; | ||
| 97 | *reg |= value; | ||
| 98 | REG_LOCAL_IRQ_RESTORE; | ||
| 99 | } | ||
| 100 | |||
| 101 | static inline void reg32_modify_mask(volatile uint32_t *reg, uint32_t mask, | ||
| 102 | uint32_t value) | ||
| 103 | { | ||
| 104 | REG_LOCAL_IRQ_SAVE; | ||
| 105 | *reg = (*reg & mask) | value; | ||
| 106 | REG_LOCAL_IRQ_RESTORE; | ||
| 107 | } | ||
| 108 | |||
| 109 | static inline void reg32_write(volatile uint32_t *reg, uint32_t value) | ||
| 110 | { | ||
| 111 | *reg = value; | ||
| 112 | } | ||
| 113 | |||
| 114 | #endif /* CSP_REG_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/csp/secHw.h b/arch/arm/mach-bcmring/include/csp/secHw.h new file mode 100644 index 000000000000..b9d7e0732dfc --- /dev/null +++ b/arch/arm/mach-bcmring/include/csp/secHw.h | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file secHw.h | ||
| 18 | * | ||
| 19 | * @brief Definitions for accessing low level security features | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | /****************************************************************************/ | ||
| 23 | #ifndef SECHW_H | ||
| 24 | #define SECHW_H | ||
| 25 | |||
| 26 | typedef void (*secHw_FUNC_t) (void); | ||
| 27 | |||
| 28 | typedef enum { | ||
| 29 | secHw_MODE_SECURE = 0x0, /* Switches processor into secure mode */ | ||
| 30 | secHw_MODE_NONSECURE = 0x1 /* Switches processor into non-secure mode */ | ||
| 31 | } secHw_MODE; | ||
| 32 | |||
| 33 | /****************************************************************************/ | ||
| 34 | /** | ||
| 35 | * @brief Requesting to execute the function in secure mode | ||
| 36 | * | ||
| 37 | * This function requests the given function to run in secure mode | ||
| 38 | * | ||
| 39 | */ | ||
| 40 | /****************************************************************************/ | ||
| 41 | void secHw_RunSecure(secHw_FUNC_t /* Function to run in secure mode */ | ||
| 42 | ); | ||
| 43 | |||
| 44 | /****************************************************************************/ | ||
| 45 | /** | ||
| 46 | * @brief Sets the mode | ||
| 47 | * | ||
| 48 | * his function sets the processor mode (secure/non-secure) | ||
| 49 | * | ||
| 50 | */ | ||
| 51 | /****************************************************************************/ | ||
| 52 | void secHw_SetMode(secHw_MODE /* Processor mode */ | ||
| 53 | ); | ||
| 54 | |||
| 55 | /****************************************************************************/ | ||
| 56 | /** | ||
| 57 | * @brief Get the current mode | ||
| 58 | * | ||
| 59 | * This function retieves the processor mode (secure/non-secure) | ||
| 60 | * | ||
| 61 | */ | ||
| 62 | /****************************************************************************/ | ||
| 63 | void secHw_GetMode(secHw_MODE *); | ||
| 64 | |||
| 65 | #endif /* SECHW_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/csp/stdint.h b/arch/arm/mach-bcmring/include/csp/stdint.h new file mode 100644 index 000000000000..3a8718bbf700 --- /dev/null +++ b/arch/arm/mach-bcmring/include/csp/stdint.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #ifndef CSP_STDINT_H | ||
| 16 | #define CSP_STDINT_H | ||
| 17 | |||
| 18 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 19 | |||
| 20 | #ifdef __KERNEL__ | ||
| 21 | #include <linux/types.h> | ||
| 22 | #else | ||
| 23 | #include <stdint.h> | ||
| 24 | #endif | ||
| 25 | |||
| 26 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 27 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 28 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 29 | |||
| 30 | #endif /* CSP_STDINT_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/csp/string.h b/arch/arm/mach-bcmring/include/csp/string.h new file mode 100644 index 000000000000..ad9e4005f141 --- /dev/null +++ b/arch/arm/mach-bcmring/include/csp/string.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | |||
| 16 | |||
| 17 | #ifndef CSP_STRING_H | ||
| 18 | #define CSP_STRING_H | ||
| 19 | |||
| 20 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 21 | |||
| 22 | #ifdef __KERNEL__ | ||
| 23 | #include <linux/string.h> | ||
| 24 | #else | ||
| 25 | #include <string.h> | ||
| 26 | #endif | ||
| 27 | |||
| 28 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 29 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 30 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 31 | |||
| 32 | |||
| 33 | #endif /* CSP_STRING_H */ | ||
| 34 | |||
diff --git a/arch/arm/mach-bcmring/include/csp/tmrHw.h b/arch/arm/mach-bcmring/include/csp/tmrHw.h new file mode 100644 index 000000000000..f1236d00cb97 --- /dev/null +++ b/arch/arm/mach-bcmring/include/csp/tmrHw.h | |||
| @@ -0,0 +1,263 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file tmrHw.h | ||
| 18 | * | ||
| 19 | * @brief API definitions for low level Timer driver | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | /****************************************************************************/ | ||
| 23 | #ifndef _TMRHW_H | ||
| 24 | #define _TMRHW_H | ||
| 25 | |||
| 26 | #include <csp/stdint.h> | ||
| 27 | |||
| 28 | typedef uint32_t tmrHw_ID_t; /* Timer ID */ | ||
| 29 | typedef uint32_t tmrHw_COUNT_t; /* Timer count */ | ||
| 30 | typedef uint32_t tmrHw_INTERVAL_t; /* Timer interval */ | ||
| 31 | typedef uint32_t tmrHw_RATE_t; /* Timer event (count/interrupt) rate */ | ||
| 32 | |||
| 33 | typedef enum { | ||
| 34 | tmrHw_INTERRUPT_STATUS_SET, /* Interrupted */ | ||
| 35 | tmrHw_INTERRUPT_STATUS_UNSET /* No Interrupt */ | ||
| 36 | } tmrHw_INTERRUPT_STATUS_e; | ||
| 37 | |||
| 38 | typedef enum { | ||
| 39 | tmrHw_CAPABILITY_CLOCK, /* Clock speed in HHz */ | ||
| 40 | tmrHw_CAPABILITY_RESOLUTION /* Timer resolution in bits */ | ||
| 41 | } tmrHw_CAPABILITY_e; | ||
| 42 | |||
| 43 | /****************************************************************************/ | ||
| 44 | /** | ||
| 45 | * @brief Get timer capability | ||
| 46 | * | ||
| 47 | * This function returns various capabilities/attributes of a timer | ||
| 48 | * | ||
| 49 | * @return Numeric capability | ||
| 50 | * | ||
| 51 | */ | ||
| 52 | /****************************************************************************/ | ||
| 53 | uint32_t tmrHw_getTimerCapability(tmrHw_ID_t timerId, /* [ IN ] Timer Id */ | ||
| 54 | tmrHw_CAPABILITY_e capability /* [ IN ] Timer capability */ | ||
| 55 | ); | ||
| 56 | |||
| 57 | /****************************************************************************/ | ||
| 58 | /** | ||
| 59 | * @brief Configures a periodic timer in terms of timer interrupt rate | ||
| 60 | * | ||
| 61 | * This function initializes a periodic timer to generate specific number of | ||
| 62 | * timer interrupt per second | ||
| 63 | * | ||
| 64 | * @return On success: Effective timer frequency | ||
| 65 | * On failure: 0 | ||
| 66 | * | ||
| 67 | */ | ||
| 68 | /****************************************************************************/ | ||
| 69 | tmrHw_RATE_t tmrHw_setPeriodicTimerRate(tmrHw_ID_t timerId, /* [ IN ] Timer Id */ | ||
| 70 | tmrHw_RATE_t rate /* [ IN ] Number of timer interrupt per second */ | ||
| 71 | ); | ||
| 72 | |||
| 73 | /****************************************************************************/ | ||
| 74 | /** | ||
| 75 | * @brief Configures a periodic timer to generate timer interrupt after | ||
| 76 | * certain time interval | ||
| 77 | * | ||
| 78 | * This function initializes a periodic timer to generate timer interrupt | ||
| 79 | * after every time interval in milisecond | ||
| 80 | * | ||
| 81 | * @return On success: Effective interval set in mili-second | ||
| 82 | * On failure: 0 | ||
| 83 | * | ||
| 84 | */ | ||
| 85 | /****************************************************************************/ | ||
| 86 | tmrHw_INTERVAL_t tmrHw_setPeriodicTimerInterval(tmrHw_ID_t timerId, /* [ IN ] Timer Id */ | ||
| 87 | tmrHw_INTERVAL_t msec /* [ IN ] Interval in mili-second */ | ||
| 88 | ); | ||
| 89 | |||
| 90 | /****************************************************************************/ | ||
| 91 | /** | ||
| 92 | * @brief Configures a periodic timer to generate timer interrupt just once | ||
| 93 | * after certain time interval | ||
| 94 | * | ||
| 95 | * This function initializes a periodic timer to generate a single ticks after | ||
| 96 | * certain time interval in milisecond | ||
| 97 | * | ||
| 98 | * @return On success: Effective interval set in mili-second | ||
| 99 | * On failure: 0 | ||
| 100 | * | ||
| 101 | */ | ||
| 102 | /****************************************************************************/ | ||
| 103 | tmrHw_INTERVAL_t tmrHw_setOneshotTimerInterval(tmrHw_ID_t timerId, /* [ IN ] Timer Id */ | ||
| 104 | tmrHw_INTERVAL_t msec /* [ IN ] Interval in mili-second */ | ||
| 105 | ); | ||
| 106 | |||
| 107 | /****************************************************************************/ | ||
| 108 | /** | ||
| 109 | * @brief Configures a timer to run as a free running timer | ||
| 110 | * | ||
| 111 | * This function initializes a timer to run as a free running timer | ||
| 112 | * | ||
| 113 | * @return Timer resolution (count / sec) | ||
| 114 | * | ||
| 115 | */ | ||
| 116 | /****************************************************************************/ | ||
| 117 | tmrHw_RATE_t tmrHw_setFreeRunningTimer(tmrHw_ID_t timerId, /* [ IN ] Timer Id */ | ||
| 118 | uint32_t divider /* [ IN ] Dividing the clock frequency */ | ||
| 119 | ) __attribute__ ((section(".aramtext"))); | ||
| 120 | |||
| 121 | /****************************************************************************/ | ||
| 122 | /** | ||
| 123 | * @brief Starts a timer | ||
| 124 | * | ||
| 125 | * This function starts a preconfigured timer | ||
| 126 | * | ||
| 127 | * @return -1 - On Failure | ||
| 128 | * 0 - On Success | ||
| 129 | */ | ||
| 130 | /****************************************************************************/ | ||
| 131 | int tmrHw_startTimer(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 132 | ) __attribute__ ((section(".aramtext"))); | ||
| 133 | |||
| 134 | /****************************************************************************/ | ||
| 135 | /** | ||
| 136 | * @brief Stops a timer | ||
| 137 | * | ||
| 138 | * This function stops a running timer | ||
| 139 | * | ||
| 140 | * @return -1 - On Failure | ||
| 141 | * 0 - On Success | ||
| 142 | */ | ||
| 143 | /****************************************************************************/ | ||
| 144 | int tmrHw_stopTimer(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 145 | ); | ||
| 146 | |||
| 147 | /****************************************************************************/ | ||
| 148 | /** | ||
| 149 | * @brief Gets current timer count | ||
| 150 | * | ||
| 151 | * This function returns the current timer value | ||
| 152 | * | ||
| 153 | * @return Current downcounting timer value | ||
| 154 | * | ||
| 155 | */ | ||
| 156 | /****************************************************************************/ | ||
| 157 | tmrHw_COUNT_t tmrHw_GetCurrentCount(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 158 | ) __attribute__ ((section(".aramtext"))); | ||
| 159 | |||
| 160 | /****************************************************************************/ | ||
| 161 | /** | ||
| 162 | * @brief Gets timer count rate | ||
| 163 | * | ||
| 164 | * This function returns the number of counts per second | ||
| 165 | * | ||
| 166 | * @return Count rate | ||
| 167 | * | ||
| 168 | */ | ||
| 169 | /****************************************************************************/ | ||
| 170 | tmrHw_RATE_t tmrHw_getCountRate(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 171 | ) __attribute__ ((section(".aramtext"))); | ||
| 172 | |||
| 173 | /****************************************************************************/ | ||
| 174 | /** | ||
| 175 | * @brief Enables timer interrupt | ||
| 176 | * | ||
| 177 | * This function enables the timer interrupt | ||
| 178 | * | ||
| 179 | * @return N/A | ||
| 180 | * | ||
| 181 | */ | ||
| 182 | /****************************************************************************/ | ||
| 183 | void tmrHw_enableInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 184 | ); | ||
| 185 | |||
| 186 | /****************************************************************************/ | ||
| 187 | /** | ||
| 188 | * @brief Disables timer interrupt | ||
| 189 | * | ||
| 190 | * This function disable the timer interrupt | ||
| 191 | * | ||
| 192 | * @return N/A | ||
| 193 | */ | ||
| 194 | /****************************************************************************/ | ||
| 195 | void tmrHw_disableInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 196 | ); | ||
| 197 | |||
| 198 | /****************************************************************************/ | ||
| 199 | /** | ||
| 200 | * @brief Clears the interrupt | ||
| 201 | * | ||
| 202 | * This function clears the timer interrupt | ||
| 203 | * | ||
| 204 | * @return N/A | ||
| 205 | * | ||
| 206 | * @note | ||
| 207 | * Must be called under the context of ISR | ||
| 208 | */ | ||
| 209 | /****************************************************************************/ | ||
| 210 | void tmrHw_clearInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 211 | ); | ||
| 212 | |||
| 213 | /****************************************************************************/ | ||
| 214 | /** | ||
| 215 | * @brief Gets the interrupt status | ||
| 216 | * | ||
| 217 | * This function returns timer interrupt status | ||
| 218 | * | ||
| 219 | * @return Interrupt status | ||
| 220 | */ | ||
| 221 | /****************************************************************************/ | ||
| 222 | tmrHw_INTERRUPT_STATUS_e tmrHw_getInterruptStatus(tmrHw_ID_t timerId /* [ IN ] Timer id */ | ||
| 223 | ); | ||
| 224 | |||
| 225 | /****************************************************************************/ | ||
| 226 | /** | ||
| 227 | * @brief Indentifies a timer causing interrupt | ||
| 228 | * | ||
| 229 | * This functions returns a timer causing interrupt | ||
| 230 | * | ||
| 231 | * @return 0xFFFFFFFF : No timer causing an interrupt | ||
| 232 | * ! 0xFFFFFFFF : timer causing an interrupt | ||
| 233 | * @note | ||
| 234 | * tmrHw_clearIntrrupt() must be called with a valid timer id after calling this function | ||
| 235 | */ | ||
| 236 | /****************************************************************************/ | ||
| 237 | tmrHw_ID_t tmrHw_getInterruptSource(void); | ||
| 238 | |||
| 239 | /****************************************************************************/ | ||
| 240 | /** | ||
| 241 | * @brief Displays specific timer registers | ||
| 242 | * | ||
| 243 | * | ||
| 244 | * @return void | ||
| 245 | * | ||
| 246 | */ | ||
| 247 | /****************************************************************************/ | ||
| 248 | void tmrHw_printDebugInfo(tmrHw_ID_t timerId, /* [ IN ] Timer id */ | ||
| 249 | int (*fpPrint) (const char *, ...) /* [ IN ] Print callback function */ | ||
| 250 | ); | ||
| 251 | |||
| 252 | /****************************************************************************/ | ||
| 253 | /** | ||
| 254 | * @brief Use a timer to perform a busy wait delay for a number of usecs. | ||
| 255 | * | ||
| 256 | * @return N/A | ||
| 257 | */ | ||
| 258 | /****************************************************************************/ | ||
| 259 | void tmrHw_udelay(tmrHw_ID_t timerId, /* [ IN ] Timer id */ | ||
| 260 | unsigned long usecs /* [ IN ] usec to delay */ | ||
| 261 | ) __attribute__ ((section(".aramtext"))); | ||
| 262 | |||
| 263 | #endif /* _TMRHW_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/clkdev.h b/arch/arm/mach-bcmring/include/mach/clkdev.h new file mode 100644 index 000000000000..04b37a89801c --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/clkdev.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | #ifndef __ASM_MACH_CLKDEV_H | ||
| 2 | #define __ASM_MACH_CLKDEV_H | ||
| 3 | |||
| 4 | #define __clk_get(clk) ({ 1; }) | ||
| 5 | #define __clk_put(clk) do { } while (0) | ||
| 6 | |||
| 7 | #endif | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/cap.h b/arch/arm/mach-bcmring/include/mach/csp/cap.h new file mode 100644 index 000000000000..30fa2d540630 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/cap.h | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2009 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #ifndef CAP_H | ||
| 16 | #define CAP_H | ||
| 17 | |||
| 18 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 19 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 20 | typedef enum { | ||
| 21 | CAP_NOT_PRESENT = 0, | ||
| 22 | CAP_PRESENT | ||
| 23 | } CAP_RC_T; | ||
| 24 | |||
| 25 | typedef enum { | ||
| 26 | CAP_VPM, | ||
| 27 | CAP_ETH_PHY, | ||
| 28 | CAP_ETH_GMII, | ||
| 29 | CAP_ETH_SGMII, | ||
| 30 | CAP_USB, | ||
| 31 | CAP_TSC, | ||
| 32 | CAP_EHSS, | ||
| 33 | CAP_SDIO, | ||
| 34 | CAP_UARTB, | ||
| 35 | CAP_KEYPAD, | ||
| 36 | CAP_CLCD, | ||
| 37 | CAP_GE, | ||
| 38 | CAP_LEDM, | ||
| 39 | CAP_BBL, | ||
| 40 | CAP_VDEC, | ||
| 41 | CAP_PIF, | ||
| 42 | CAP_APM, | ||
| 43 | CAP_SPU, | ||
| 44 | CAP_PKA, | ||
| 45 | CAP_RNG, | ||
| 46 | } CAP_CAPABILITY_T; | ||
| 47 | |||
| 48 | typedef enum { | ||
| 49 | CAP_LCD_WVGA = 0, | ||
| 50 | CAP_LCD_VGA = 0x1, | ||
| 51 | CAP_LCD_WQVGA = 0x2, | ||
| 52 | CAP_LCD_QVGA = 0x3 | ||
| 53 | } CAP_LCD_RES_T; | ||
| 54 | |||
| 55 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 56 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 57 | |||
| 58 | static inline CAP_RC_T cap_isPresent(CAP_CAPABILITY_T capability, int index); | ||
| 59 | static inline uint32_t cap_getMaxArmSpeedHz(void); | ||
| 60 | static inline uint32_t cap_getMaxVpmSpeedHz(void); | ||
| 61 | static inline CAP_LCD_RES_T cap_getMaxLcdRes(void); | ||
| 62 | |||
| 63 | #endif | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/cap_inline.h b/arch/arm/mach-bcmring/include/mach/csp/cap_inline.h new file mode 100644 index 000000000000..933ce68ed90b --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/cap_inline.h | |||
| @@ -0,0 +1,409 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2009 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #ifndef CAP_INLINE_H | ||
| 16 | #define CAP_INLINE_H | ||
| 17 | |||
| 18 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 19 | #include <mach/csp/cap.h> | ||
| 20 | #include <cfg_global.h> | ||
| 21 | |||
| 22 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 23 | #define CAP_CONFIG0_VPM_DIS 0x00000001 | ||
| 24 | #define CAP_CONFIG0_ETH_PHY0_DIS 0x00000002 | ||
| 25 | #define CAP_CONFIG0_ETH_PHY1_DIS 0x00000004 | ||
| 26 | #define CAP_CONFIG0_ETH_GMII0_DIS 0x00000008 | ||
| 27 | #define CAP_CONFIG0_ETH_GMII1_DIS 0x00000010 | ||
| 28 | #define CAP_CONFIG0_ETH_SGMII0_DIS 0x00000020 | ||
| 29 | #define CAP_CONFIG0_ETH_SGMII1_DIS 0x00000040 | ||
| 30 | #define CAP_CONFIG0_USB0_DIS 0x00000080 | ||
| 31 | #define CAP_CONFIG0_USB1_DIS 0x00000100 | ||
| 32 | #define CAP_CONFIG0_TSC_DIS 0x00000200 | ||
| 33 | #define CAP_CONFIG0_EHSS0_DIS 0x00000400 | ||
| 34 | #define CAP_CONFIG0_EHSS1_DIS 0x00000800 | ||
| 35 | #define CAP_CONFIG0_SDIO0_DIS 0x00001000 | ||
| 36 | #define CAP_CONFIG0_SDIO1_DIS 0x00002000 | ||
| 37 | #define CAP_CONFIG0_UARTB_DIS 0x00004000 | ||
| 38 | #define CAP_CONFIG0_KEYPAD_DIS 0x00008000 | ||
| 39 | #define CAP_CONFIG0_CLCD_DIS 0x00010000 | ||
| 40 | #define CAP_CONFIG0_GE_DIS 0x00020000 | ||
| 41 | #define CAP_CONFIG0_LEDM_DIS 0x00040000 | ||
| 42 | #define CAP_CONFIG0_BBL_DIS 0x00080000 | ||
| 43 | #define CAP_CONFIG0_VDEC_DIS 0x00100000 | ||
| 44 | #define CAP_CONFIG0_PIF_DIS 0x00200000 | ||
| 45 | #define CAP_CONFIG0_RESERVED1_DIS 0x00400000 | ||
| 46 | #define CAP_CONFIG0_RESERVED2_DIS 0x00800000 | ||
| 47 | |||
| 48 | #define CAP_CONFIG1_APMA_DIS 0x00000001 | ||
| 49 | #define CAP_CONFIG1_APMB_DIS 0x00000002 | ||
| 50 | #define CAP_CONFIG1_APMC_DIS 0x00000004 | ||
| 51 | #define CAP_CONFIG1_CLCD_RES_MASK 0x00000600 | ||
| 52 | #define CAP_CONFIG1_CLCD_RES_SHIFT 9 | ||
| 53 | #define CAP_CONFIG1_CLCD_RES_WVGA (CAP_LCD_WVGA << CAP_CONFIG1_CLCD_RES_SHIFT) | ||
| 54 | #define CAP_CONFIG1_CLCD_RES_VGA (CAP_LCD_VGA << CAP_CONFIG1_CLCD_RES_SHIFT) | ||
| 55 | #define CAP_CONFIG1_CLCD_RES_WQVGA (CAP_LCD_WQVGA << CAP_CONFIG1_CLCD_RES_SHIFT) | ||
| 56 | #define CAP_CONFIG1_CLCD_RES_QVGA (CAP_LCD_QVGA << CAP_CONFIG1_CLCD_RES_SHIFT) | ||
| 57 | |||
| 58 | #define CAP_CONFIG2_SPU_DIS 0x00000010 | ||
| 59 | #define CAP_CONFIG2_PKA_DIS 0x00000020 | ||
| 60 | #define CAP_CONFIG2_RNG_DIS 0x00000080 | ||
| 61 | |||
| 62 | #if (CFG_GLOBAL_CHIP == BCM11107) | ||
| 63 | #define capConfig0 0 | ||
| 64 | #define capConfig1 CAP_CONFIG1_CLCD_RES_WVGA | ||
| 65 | #define capConfig2 0 | ||
| 66 | #define CAP_APM_MAX_NUM_CHANS 3 | ||
| 67 | #elif (CFG_GLOBAL_CHIP == FPGA11107) | ||
| 68 | #define capConfig0 0 | ||
| 69 | #define capConfig1 CAP_CONFIG1_CLCD_RES_WVGA | ||
| 70 | #define capConfig2 0 | ||
| 71 | #define CAP_APM_MAX_NUM_CHANS 3 | ||
| 72 | #elif (CFG_GLOBAL_CHIP == BCM11109) | ||
| 73 | #define capConfig0 (CAP_CONFIG0_USB1_DIS | CAP_CONFIG0_EHSS1_DIS | CAP_CONFIG0_SDIO1_DIS | CAP_CONFIG0_GE_DIS | CAP_CONFIG0_BBL_DIS | CAP_CONFIG0_VDEC_DIS) | ||
| 74 | #define capConfig1 (CAP_CONFIG1_APMC_DIS | CAP_CONFIG1_CLCD_RES_WQVGA) | ||
| 75 | #define capConfig2 (CAP_CONFIG2_SPU_DIS | CAP_CONFIG2_PKA_DIS) | ||
| 76 | #define CAP_APM_MAX_NUM_CHANS 2 | ||
| 77 | #elif (CFG_GLOBAL_CHIP == BCM11170) | ||
| 78 | #define capConfig0 (CAP_CONFIG0_ETH_GMII0_DIS | CAP_CONFIG0_ETH_GMII1_DIS | CAP_CONFIG0_USB0_DIS | CAP_CONFIG0_USB1_DIS | CAP_CONFIG0_TSC_DIS | CAP_CONFIG0_EHSS1_DIS | CAP_CONFIG0_SDIO0_DIS | CAP_CONFIG0_SDIO1_DIS | CAP_CONFIG0_UARTB_DIS | CAP_CONFIG0_CLCD_DIS | CAP_CONFIG0_GE_DIS | CAP_CONFIG0_BBL_DIS | CAP_CONFIG0_VDEC_DIS) | ||
| 79 | #define capConfig1 (CAP_CONFIG1_APMC_DIS | CAP_CONFIG1_CLCD_RES_WQVGA) | ||
| 80 | #define capConfig2 (CAP_CONFIG2_SPU_DIS | CAP_CONFIG2_PKA_DIS) | ||
| 81 | #define CAP_APM_MAX_NUM_CHANS 2 | ||
| 82 | #elif (CFG_GLOBAL_CHIP == BCM11110) | ||
| 83 | #define capConfig0 (CAP_CONFIG0_USB1_DIS | CAP_CONFIG0_TSC_DIS | CAP_CONFIG0_EHSS1_DIS | CAP_CONFIG0_SDIO0_DIS | CAP_CONFIG0_SDIO1_DIS | CAP_CONFIG0_UARTB_DIS | CAP_CONFIG0_GE_DIS | CAP_CONFIG0_BBL_DIS | CAP_CONFIG0_VDEC_DIS) | ||
| 84 | #define capConfig1 CAP_CONFIG1_APMC_DIS | ||
| 85 | #define capConfig2 (CAP_CONFIG2_SPU_DIS | CAP_CONFIG2_PKA_DIS) | ||
| 86 | #define CAP_APM_MAX_NUM_CHANS 2 | ||
| 87 | #elif (CFG_GLOBAL_CHIP == BCM11211) | ||
| 88 | #define capConfig0 (CAP_CONFIG0_ETH_PHY0_DIS | CAP_CONFIG0_ETH_GMII0_DIS | CAP_CONFIG0_ETH_GMII1_DIS | CAP_CONFIG0_ETH_SGMII0_DIS | CAP_CONFIG0_ETH_SGMII1_DIS | CAP_CONFIG0_CLCD_DIS) | ||
| 89 | #define capConfig1 CAP_CONFIG1_APMC_DIS | ||
| 90 | #define capConfig2 0 | ||
| 91 | #define CAP_APM_MAX_NUM_CHANS 2 | ||
| 92 | #else | ||
| 93 | #error CFG_GLOBAL_CHIP type capabilities not defined | ||
| 94 | #endif | ||
| 95 | |||
| 96 | #if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == FPGA11107)) | ||
| 97 | #define CAP_HW_CFG_ARM_CLK_HZ 500000000 | ||
| 98 | #elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110)) | ||
| 99 | #define CAP_HW_CFG_ARM_CLK_HZ 300000000 | ||
| 100 | #elif (CFG_GLOBAL_CHIP == BCM11211) | ||
| 101 | #define CAP_HW_CFG_ARM_CLK_HZ 666666666 | ||
| 102 | #else | ||
| 103 | #error CFG_GLOBAL_CHIP type capabilities not defined | ||
| 104 | #endif | ||
| 105 | |||
| 106 | #if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == BCM11211) || (CFG_GLOBAL_CHIP == FPGA11107)) | ||
| 107 | #define CAP_HW_CFG_VPM_CLK_HZ 333333333 | ||
| 108 | #elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110)) | ||
| 109 | #define CAP_HW_CFG_VPM_CLK_HZ 200000000 | ||
| 110 | #else | ||
| 111 | #error CFG_GLOBAL_CHIP type capabilities not defined | ||
| 112 | #endif | ||
| 113 | |||
| 114 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 115 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 116 | |||
| 117 | /**************************************************************************** | ||
| 118 | * cap_isPresent - | ||
| 119 | * | ||
| 120 | * PURPOSE: | ||
| 121 | * Determines if the chip has a certain capability present | ||
| 122 | * | ||
| 123 | * PARAMETERS: | ||
| 124 | * capability - type of capability to determine if present | ||
| 125 | * | ||
| 126 | * RETURNS: | ||
| 127 | * CAP_PRESENT or CAP_NOT_PRESENT | ||
| 128 | ****************************************************************************/ | ||
| 129 | static inline CAP_RC_T cap_isPresent(CAP_CAPABILITY_T capability, int index) | ||
| 130 | { | ||
| 131 | CAP_RC_T returnVal = CAP_NOT_PRESENT; | ||
| 132 | |||
| 133 | switch (capability) { | ||
| 134 | case CAP_VPM: | ||
| 135 | { | ||
| 136 | if (!(capConfig0 & CAP_CONFIG0_VPM_DIS)) { | ||
| 137 | returnVal = CAP_PRESENT; | ||
| 138 | } | ||
| 139 | } | ||
| 140 | break; | ||
| 141 | |||
| 142 | case CAP_ETH_PHY: | ||
| 143 | { | ||
| 144 | if ((index == 0) | ||
| 145 | && (!(capConfig0 & CAP_CONFIG0_ETH_PHY0_DIS))) { | ||
| 146 | returnVal = CAP_PRESENT; | ||
| 147 | } | ||
| 148 | if ((index == 1) | ||
| 149 | && (!(capConfig0 & CAP_CONFIG0_ETH_PHY1_DIS))) { | ||
| 150 | returnVal = CAP_PRESENT; | ||
| 151 | } | ||
| 152 | } | ||
| 153 | break; | ||
| 154 | |||
| 155 | case CAP_ETH_GMII: | ||
| 156 | { | ||
| 157 | if ((index == 0) | ||
| 158 | && (!(capConfig0 & CAP_CONFIG0_ETH_GMII0_DIS))) { | ||
| 159 | returnVal = CAP_PRESENT; | ||
| 160 | } | ||
| 161 | if ((index == 1) | ||
| 162 | && (!(capConfig0 & CAP_CONFIG0_ETH_GMII1_DIS))) { | ||
| 163 | returnVal = CAP_PRESENT; | ||
| 164 | } | ||
| 165 | } | ||
| 166 | break; | ||
| 167 | |||
| 168 | case CAP_ETH_SGMII: | ||
| 169 | { | ||
| 170 | if ((index == 0) | ||
| 171 | && (!(capConfig0 & CAP_CONFIG0_ETH_SGMII0_DIS))) { | ||
| 172 | returnVal = CAP_PRESENT; | ||
| 173 | } | ||
| 174 | if ((index == 1) | ||
| 175 | && (!(capConfig0 & CAP_CONFIG0_ETH_SGMII1_DIS))) { | ||
| 176 | returnVal = CAP_PRESENT; | ||
| 177 | } | ||
| 178 | } | ||
| 179 | break; | ||
| 180 | |||
| 181 | case CAP_USB: | ||
| 182 | { | ||
| 183 | if ((index == 0) | ||
| 184 | && (!(capConfig0 & CAP_CONFIG0_USB0_DIS))) { | ||
| 185 | returnVal = CAP_PRESENT; | ||
| 186 | } | ||
| 187 | if ((index == 1) | ||
| 188 | && (!(capConfig0 & CAP_CONFIG0_USB1_DIS))) { | ||
| 189 | returnVal = CAP_PRESENT; | ||
| 190 | } | ||
| 191 | } | ||
| 192 | break; | ||
| 193 | |||
| 194 | case CAP_TSC: | ||
| 195 | { | ||
| 196 | if (!(capConfig0 & CAP_CONFIG0_TSC_DIS)) { | ||
| 197 | returnVal = CAP_PRESENT; | ||
| 198 | } | ||
| 199 | } | ||
| 200 | break; | ||
| 201 | |||
| 202 | case CAP_EHSS: | ||
| 203 | { | ||
| 204 | if ((index == 0) | ||
| 205 | && (!(capConfig0 & CAP_CONFIG0_EHSS0_DIS))) { | ||
| 206 | returnVal = CAP_PRESENT; | ||
| 207 | } | ||
| 208 | if ((index == 1) | ||
| 209 | && (!(capConfig0 & CAP_CONFIG0_EHSS1_DIS))) { | ||
| 210 | returnVal = CAP_PRESENT; | ||
| 211 | } | ||
| 212 | } | ||
| 213 | break; | ||
| 214 | |||
| 215 | case CAP_SDIO: | ||
| 216 | { | ||
| 217 | if ((index == 0) | ||
| 218 | && (!(capConfig0 & CAP_CONFIG0_SDIO0_DIS))) { | ||
| 219 | returnVal = CAP_PRESENT; | ||
| 220 | } | ||
| 221 | if ((index == 1) | ||
| 222 | && (!(capConfig0 & CAP_CONFIG0_SDIO1_DIS))) { | ||
| 223 | returnVal = CAP_PRESENT; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | break; | ||
| 227 | |||
| 228 | case CAP_UARTB: | ||
| 229 | { | ||
| 230 | if (!(capConfig0 & CAP_CONFIG0_UARTB_DIS)) { | ||
| 231 | returnVal = CAP_PRESENT; | ||
| 232 | } | ||
| 233 | } | ||
| 234 | break; | ||
| 235 | |||
| 236 | case CAP_KEYPAD: | ||
| 237 | { | ||
| 238 | if (!(capConfig0 & CAP_CONFIG0_KEYPAD_DIS)) { | ||
| 239 | returnVal = CAP_PRESENT; | ||
| 240 | } | ||
| 241 | } | ||
| 242 | break; | ||
| 243 | |||
| 244 | case CAP_CLCD: | ||
| 245 | { | ||
| 246 | if (!(capConfig0 & CAP_CONFIG0_CLCD_DIS)) { | ||
| 247 | returnVal = CAP_PRESENT; | ||
| 248 | } | ||
| 249 | } | ||
| 250 | break; | ||
| 251 | |||
| 252 | case CAP_GE: | ||
| 253 | { | ||
| 254 | if (!(capConfig0 & CAP_CONFIG0_GE_DIS)) { | ||
| 255 | returnVal = CAP_PRESENT; | ||
| 256 | } | ||
| 257 | } | ||
| 258 | break; | ||
| 259 | |||
| 260 | case CAP_LEDM: | ||
| 261 | { | ||
| 262 | if (!(capConfig0 & CAP_CONFIG0_LEDM_DIS)) { | ||
| 263 | returnVal = CAP_PRESENT; | ||
| 264 | } | ||
| 265 | } | ||
| 266 | break; | ||
| 267 | |||
| 268 | case CAP_BBL: | ||
| 269 | { | ||
| 270 | if (!(capConfig0 & CAP_CONFIG0_BBL_DIS)) { | ||
| 271 | returnVal = CAP_PRESENT; | ||
| 272 | } | ||
| 273 | } | ||
| 274 | break; | ||
| 275 | |||
| 276 | case CAP_VDEC: | ||
| 277 | { | ||
| 278 | if (!(capConfig0 & CAP_CONFIG0_VDEC_DIS)) { | ||
| 279 | returnVal = CAP_PRESENT; | ||
| 280 | } | ||
| 281 | } | ||
| 282 | break; | ||
| 283 | |||
| 284 | case CAP_PIF: | ||
| 285 | { | ||
| 286 | if (!(capConfig0 & CAP_CONFIG0_PIF_DIS)) { | ||
| 287 | returnVal = CAP_PRESENT; | ||
| 288 | } | ||
| 289 | } | ||
| 290 | break; | ||
| 291 | |||
| 292 | case CAP_APM: | ||
| 293 | { | ||
| 294 | if ((index == 0) | ||
| 295 | && (!(capConfig1 & CAP_CONFIG1_APMA_DIS))) { | ||
| 296 | returnVal = CAP_PRESENT; | ||
| 297 | } | ||
| 298 | if ((index == 1) | ||
| 299 | && (!(capConfig1 & CAP_CONFIG1_APMB_DIS))) { | ||
| 300 | returnVal = CAP_PRESENT; | ||
| 301 | } | ||
| 302 | if ((index == 2) | ||
| 303 | && (!(capConfig1 & CAP_CONFIG1_APMC_DIS))) { | ||
| 304 | returnVal = CAP_PRESENT; | ||
| 305 | } | ||
| 306 | } | ||
| 307 | break; | ||
| 308 | |||
| 309 | case CAP_SPU: | ||
| 310 | { | ||
| 311 | if (!(capConfig2 & CAP_CONFIG2_SPU_DIS)) { | ||
| 312 | returnVal = CAP_PRESENT; | ||
| 313 | } | ||
| 314 | } | ||
| 315 | break; | ||
| 316 | |||
| 317 | case CAP_PKA: | ||
| 318 | { | ||
| 319 | if (!(capConfig2 & CAP_CONFIG2_PKA_DIS)) { | ||
| 320 | returnVal = CAP_PRESENT; | ||
| 321 | } | ||
| 322 | } | ||
| 323 | break; | ||
| 324 | |||
| 325 | case CAP_RNG: | ||
| 326 | { | ||
| 327 | if (!(capConfig2 & CAP_CONFIG2_RNG_DIS)) { | ||
| 328 | returnVal = CAP_PRESENT; | ||
| 329 | } | ||
| 330 | } | ||
| 331 | break; | ||
| 332 | |||
| 333 | default: | ||
| 334 | { | ||
| 335 | } | ||
| 336 | break; | ||
| 337 | } | ||
| 338 | return returnVal; | ||
| 339 | } | ||
| 340 | |||
| 341 | /**************************************************************************** | ||
| 342 | * cap_getMaxArmSpeedHz - | ||
| 343 | * | ||
| 344 | * PURPOSE: | ||
| 345 | * Determines the maximum speed of the ARM CPU | ||
| 346 | * | ||
| 347 | * PARAMETERS: | ||
| 348 | * none | ||
| 349 | * | ||
| 350 | * RETURNS: | ||
| 351 | * clock speed in Hz that the ARM processor is able to run at | ||
| 352 | ****************************************************************************/ | ||
| 353 | static inline uint32_t cap_getMaxArmSpeedHz(void) | ||
| 354 | { | ||
| 355 | #if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == FPGA11107)) | ||
| 356 | return 500000000; | ||
| 357 | #elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110)) | ||
| 358 | return 300000000; | ||
| 359 | #elif (CFG_GLOBAL_CHIP == BCM11211) | ||
| 360 | return 666666666; | ||
| 361 | #else | ||
| 362 | #error CFG_GLOBAL_CHIP type capabilities not defined | ||
| 363 | #endif | ||
| 364 | } | ||
| 365 | |||
| 366 | /**************************************************************************** | ||
| 367 | * cap_getMaxVpmSpeedHz - | ||
| 368 | * | ||
| 369 | * PURPOSE: | ||
| 370 | * Determines the maximum speed of the VPM | ||
| 371 | * | ||
| 372 | * PARAMETERS: | ||
| 373 | * none | ||
| 374 | * | ||
| 375 | * RETURNS: | ||
| 376 | * clock speed in Hz that the VPM is able to run at | ||
| 377 | ****************************************************************************/ | ||
| 378 | static inline uint32_t cap_getMaxVpmSpeedHz(void) | ||
| 379 | { | ||
| 380 | #if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == BCM11211) || (CFG_GLOBAL_CHIP == FPGA11107)) | ||
| 381 | return 333333333; | ||
| 382 | #elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110)) | ||
| 383 | return 200000000; | ||
| 384 | #else | ||
| 385 | #error CFG_GLOBAL_CHIP type capabilities not defined | ||
| 386 | #endif | ||
| 387 | } | ||
| 388 | |||
| 389 | /**************************************************************************** | ||
| 390 | * cap_getMaxLcdRes - | ||
| 391 | * | ||
| 392 | * PURPOSE: | ||
| 393 | * Determines the maximum LCD resolution capabilities | ||
| 394 | * | ||
| 395 | * PARAMETERS: | ||
| 396 | * none | ||
| 397 | * | ||
| 398 | * RETURNS: | ||
| 399 | * CAP_LCD_WVGA, CAP_LCD_VGA, CAP_LCD_WQVGA or CAP_LCD_QVGA | ||
| 400 | * | ||
| 401 | ****************************************************************************/ | ||
| 402 | static inline CAP_LCD_RES_T cap_getMaxLcdRes(void) | ||
| 403 | { | ||
| 404 | return (CAP_LCD_RES_T) | ||
| 405 | ((capConfig1 & CAP_CONFIG1_CLCD_RES_MASK) >> | ||
| 406 | CAP_CONFIG1_CLCD_RES_SHIFT); | ||
| 407 | } | ||
| 408 | |||
| 409 | #endif | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h new file mode 100644 index 000000000000..70eaea866cfe --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h | |||
| @@ -0,0 +1,1123 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #ifndef CHIPC_DEF_H | ||
| 16 | #define CHIPC_DEF_H | ||
| 17 | |||
| 18 | /* ---- Include Files ----------------------------------------------------- */ | ||
| 19 | |||
| 20 | #include <csp/stdint.h> | ||
| 21 | #include <csp/errno.h> | ||
| 22 | #include <csp/reg.h> | ||
| 23 | #include <mach/csp/chipcHw_reg.h> | ||
| 24 | |||
| 25 | /* ---- Public Constants and Types ---------------------------------------- */ | ||
| 26 | |||
| 27 | /* Set 1 to configure DDR/VPM phase alignment by HW */ | ||
| 28 | #define chipcHw_DDR_HW_PHASE_ALIGN 0 | ||
| 29 | #define chipcHw_VPM_HW_PHASE_ALIGN 0 | ||
| 30 | |||
| 31 | typedef uint32_t chipcHw_freq; | ||
| 32 | |||
| 33 | /* Configurable miscellaneous clocks */ | ||
| 34 | typedef enum { | ||
| 35 | chipcHw_CLOCK_DDR, /* DDR PHY Clock */ | ||
| 36 | chipcHw_CLOCK_ARM, /* ARM Clock */ | ||
| 37 | chipcHw_CLOCK_ESW, /* Ethernet Switch Clock */ | ||
| 38 | chipcHw_CLOCK_VPM, /* VPM Clock */ | ||
| 39 | chipcHw_CLOCK_ESW125, /* Ethernet MII Clock */ | ||
| 40 | chipcHw_CLOCK_UART, /* UART Clock */ | ||
| 41 | chipcHw_CLOCK_SDIO0, /* SDIO 0 Clock */ | ||
| 42 | chipcHw_CLOCK_SDIO1, /* SDIO 1 Clock */ | ||
| 43 | chipcHw_CLOCK_SPI, /* SPI Clock */ | ||
| 44 | chipcHw_CLOCK_ETM, /* ARM ETM Clock */ | ||
| 45 | |||
| 46 | chipcHw_CLOCK_BUS, /* BUS Clock */ | ||
| 47 | chipcHw_CLOCK_OTP, /* OTP Clock */ | ||
| 48 | chipcHw_CLOCK_I2C, /* I2C Host Clock */ | ||
| 49 | chipcHw_CLOCK_I2S0, /* I2S 0 Host Clock */ | ||
| 50 | chipcHw_CLOCK_RTBUS, /* DDR PHY Configuration Clock */ | ||
| 51 | chipcHw_CLOCK_APM100, /* APM100 Clock */ | ||
| 52 | chipcHw_CLOCK_TSC, /* Touch screen Clock */ | ||
| 53 | chipcHw_CLOCK_LED, /* LED Clock */ | ||
| 54 | |||
| 55 | chipcHw_CLOCK_USB, /* USB Clock */ | ||
| 56 | chipcHw_CLOCK_LCD, /* LCD CLock */ | ||
| 57 | chipcHw_CLOCK_APM, /* APM Clock */ | ||
| 58 | |||
| 59 | chipcHw_CLOCK_I2S1, /* I2S 1 Host Clock */ | ||
| 60 | } chipcHw_CLOCK_e; | ||
| 61 | |||
| 62 | /* System booting strap options */ | ||
| 63 | typedef enum { | ||
| 64 | chipcHw_BOOT_DEVICE_UART = chipcHw_STRAPS_BOOT_DEVICE_UART, | ||
| 65 | chipcHw_BOOT_DEVICE_SERIAL_FLASH = | ||
| 66 | chipcHw_STRAPS_BOOT_DEVICE_SERIAL_FLASH, | ||
| 67 | chipcHw_BOOT_DEVICE_NOR_FLASH_16 = | ||
| 68 | chipcHw_STRAPS_BOOT_DEVICE_NOR_FLASH_16, | ||
| 69 | chipcHw_BOOT_DEVICE_NAND_FLASH_8 = | ||
| 70 | chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_8, | ||
| 71 | chipcHw_BOOT_DEVICE_NAND_FLASH_16 = | ||
| 72 | chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_16 | ||
| 73 | } chipcHw_BOOT_DEVICE_e; | ||
| 74 | |||
| 75 | /* System booting modes */ | ||
| 76 | typedef enum { | ||
| 77 | chipcHw_BOOT_MODE_NORMAL = chipcHw_STRAPS_BOOT_MODE_NORMAL, | ||
| 78 | chipcHw_BOOT_MODE_DBG_SW = chipcHw_STRAPS_BOOT_MODE_DBG_SW, | ||
| 79 | chipcHw_BOOT_MODE_DBG_BOOT = chipcHw_STRAPS_BOOT_MODE_DBG_BOOT, | ||
| 80 | chipcHw_BOOT_MODE_NORMAL_QUIET = chipcHw_STRAPS_BOOT_MODE_NORMAL_QUIET | ||
| 81 | } chipcHw_BOOT_MODE_e; | ||
| 82 | |||
| 83 | /* NAND Flash page size strap options */ | ||
| 84 | typedef enum { | ||
| 85 | chipcHw_NAND_PAGESIZE_512 = chipcHw_STRAPS_NAND_PAGESIZE_512, | ||
| 86 | chipcHw_NAND_PAGESIZE_2048 = chipcHw_STRAPS_NAND_PAGESIZE_2048, | ||
| 87 | chipcHw_NAND_PAGESIZE_4096 = chipcHw_STRAPS_NAND_PAGESIZE_4096, | ||
| 88 | chipcHw_NAND_PAGESIZE_EXT = chipcHw_STRAPS_NAND_PAGESIZE_EXT | ||
| 89 | } chipcHw_NAND_PAGESIZE_e; | ||
| 90 | |||
| 91 | /* GPIO Pin function */ | ||
| 92 | typedef enum { | ||
| 93 | chipcHw_GPIO_FUNCTION_KEYPAD = chipcHw_REG_GPIO_MUX_KEYPAD, | ||
| 94 | chipcHw_GPIO_FUNCTION_I2CH = chipcHw_REG_GPIO_MUX_I2CH, | ||
| 95 | chipcHw_GPIO_FUNCTION_SPI = chipcHw_REG_GPIO_MUX_SPI, | ||
| 96 | chipcHw_GPIO_FUNCTION_UART = chipcHw_REG_GPIO_MUX_UART, | ||
| 97 | chipcHw_GPIO_FUNCTION_LEDMTXP = chipcHw_REG_GPIO_MUX_LEDMTXP, | ||
| 98 | chipcHw_GPIO_FUNCTION_LEDMTXS = chipcHw_REG_GPIO_MUX_LEDMTXS, | ||
| 99 | chipcHw_GPIO_FUNCTION_SDIO0 = chipcHw_REG_GPIO_MUX_SDIO0, | ||
| 100 | chipcHw_GPIO_FUNCTION_SDIO1 = chipcHw_REG_GPIO_MUX_SDIO1, | ||
| 101 | chipcHw_GPIO_FUNCTION_PCM = chipcHw_REG_GPIO_MUX_PCM, | ||
| 102 | chipcHw_GPIO_FUNCTION_I2S = chipcHw_REG_GPIO_MUX_I2S, | ||
| 103 | chipcHw_GPIO_FUNCTION_ETM = chipcHw_REG_GPIO_MUX_ETM, | ||
| 104 | chipcHw_GPIO_FUNCTION_DEBUG = chipcHw_REG_GPIO_MUX_DEBUG, | ||
| 105 | chipcHw_GPIO_FUNCTION_MISC = chipcHw_REG_GPIO_MUX_MISC, | ||
| 106 | chipcHw_GPIO_FUNCTION_GPIO = chipcHw_REG_GPIO_MUX_GPIO | ||
| 107 | } chipcHw_GPIO_FUNCTION_e; | ||
| 108 | |||
| 109 | /* PIN Output slew rate */ | ||
| 110 | typedef enum { | ||
| 111 | chipcHw_PIN_SLEW_RATE_HIGH = chipcHw_REG_SLEW_RATE_HIGH, | ||
| 112 | chipcHw_PIN_SLEW_RATE_NORMAL = chipcHw_REG_SLEW_RATE_NORMAL | ||
| 113 | } chipcHw_PIN_SLEW_RATE_e; | ||
| 114 | |||
| 115 | /* PIN Current drive strength */ | ||
| 116 | typedef enum { | ||
| 117 | chipcHw_PIN_CURRENT_STRENGTH_2mA = chipcHw_REG_CURRENT_STRENGTH_2mA, | ||
| 118 | chipcHw_PIN_CURRENT_STRENGTH_4mA = chipcHw_REG_CURRENT_STRENGTH_4mA, | ||
| 119 | chipcHw_PIN_CURRENT_STRENGTH_6mA = chipcHw_REG_CURRENT_STRENGTH_6mA, | ||
| 120 | chipcHw_PIN_CURRENT_STRENGTH_8mA = chipcHw_REG_CURRENT_STRENGTH_8mA, | ||
| 121 | chipcHw_PIN_CURRENT_STRENGTH_10mA = chipcHw_REG_CURRENT_STRENGTH_10mA, | ||
| 122 | chipcHw_PIN_CURRENT_STRENGTH_12mA = chipcHw_REG_CURRENT_STRENGTH_12mA | ||
| 123 | } chipcHw_PIN_CURRENT_STRENGTH_e; | ||
| 124 | |||
| 125 | /* PIN Pull up register settings */ | ||
| 126 | typedef enum { | ||
| 127 | chipcHw_PIN_PULL_NONE = chipcHw_REG_PULL_NONE, | ||
| 128 | chipcHw_PIN_PULL_UP = chipcHw_REG_PULL_UP, | ||
| 129 | chipcHw_PIN_PULL_DOWN = chipcHw_REG_PULL_DOWN | ||
| 130 | } chipcHw_PIN_PULL_e; | ||
| 131 | |||
| 132 | /* PIN input type settings */ | ||
| 133 | typedef enum { | ||
| 134 | chipcHw_PIN_INPUTTYPE_CMOS = chipcHw_REG_INPUTTYPE_CMOS, | ||
| 135 | chipcHw_PIN_INPUTTYPE_ST = chipcHw_REG_INPUTTYPE_ST | ||
| 136 | } chipcHw_PIN_INPUTTYPE_e; | ||
| 137 | |||
| 138 | /* Allow/Disalow the support of spread spectrum */ | ||
| 139 | typedef enum { | ||
| 140 | chipcHw_SPREAD_SPECTRUM_DISALLOW, /* Spread spectrum support is not allowed */ | ||
| 141 | chipcHw_SPREAD_SPECTRUM_ALLOW /* Spread spectrum support is allowed */ | ||
| 142 | } chipcHw_SPREAD_SPECTRUM_e; | ||
| 143 | |||
| 144 | typedef struct { | ||
| 145 | chipcHw_SPREAD_SPECTRUM_e ssSupport; /* Allow/Disalow to support spread spectrum. | ||
| 146 | If supported, call chipcHw_enableSpreadSpectrum () | ||
| 147 | to activate the spread spectrum with desired spread. */ | ||
| 148 | uint32_t pllVcoFreqHz; /* PLL VCO frequency in Hz */ | ||
| 149 | uint32_t pll2VcoFreqHz; /* PLL2 VCO frequency in Hz */ | ||
| 150 | uint32_t busClockFreqHz; /* Bus clock frequency in Hz */ | ||
| 151 | uint32_t armBusRatio; /* ARM clock : Bus clock */ | ||
| 152 | uint32_t vpmBusRatio; /* VPM clock : Bus clock */ | ||
| 153 | uint32_t ddrBusRatio; /* DDR clock : Bus clock */ | ||
| 154 | } chipcHw_INIT_PARAM_t; | ||
| 155 | |||
| 156 | /* CHIP revision number */ | ||
| 157 | typedef enum { | ||
| 158 | chipcHw_REV_NUMBER_A0 = chipcHw_REG_REV_A0, | ||
| 159 | chipcHw_REV_NUMBER_B0 = chipcHw_REG_REV_B0 | ||
| 160 | } chipcHw_REV_NUMBER_e; | ||
| 161 | |||
| 162 | typedef enum { | ||
| 163 | chipcHw_VPM_HW_PHASE_INTR_DISABLE = chipcHw_REG_VPM_INTR_DISABLE, | ||
| 164 | chipcHw_VPM_HW_PHASE_INTR_FAST = chipcHw_REG_VPM_INTR_FAST, | ||
| 165 | chipcHw_VPM_HW_PHASE_INTR_MEDIUM = chipcHw_REG_VPM_INTR_MEDIUM, | ||
| 166 | chipcHw_VPM_HW_PHASE_INTR_SLOW = chipcHw_REG_VPM_INTR_SLOW | ||
| 167 | } chipcHw_VPM_HW_PHASE_INTR_e; | ||
| 168 | |||
| 169 | typedef enum { | ||
| 170 | chipcHw_DDR_HW_PHASE_MARGIN_STRICT, /* Strict margin for DDR phase align condition */ | ||
| 171 | chipcHw_DDR_HW_PHASE_MARGIN_MEDIUM, /* Medium margin for DDR phase align condition */ | ||
| 172 | chipcHw_DDR_HW_PHASE_MARGIN_WIDE /* Wider margin for DDR phase align condition */ | ||
| 173 | } chipcHw_DDR_HW_PHASE_MARGIN_e; | ||
| 174 | |||
| 175 | typedef enum { | ||
| 176 | chipcHw_VPM_HW_PHASE_MARGIN_STRICT, /* Strict margin for VPM phase align condition */ | ||
| 177 | chipcHw_VPM_HW_PHASE_MARGIN_MEDIUM, /* Medium margin for VPM phase align condition */ | ||
| 178 | chipcHw_VPM_HW_PHASE_MARGIN_WIDE /* Wider margin for VPM phase align condition */ | ||
| 179 | } chipcHw_VPM_HW_PHASE_MARGIN_e; | ||
| 180 | |||
| 181 | #define chipcHw_XTAL_FREQ_Hz 25000000 /* Reference clock frequency in Hz */ | ||
| 182 | |||
| 183 | /* Programable pin defines */ | ||
| 184 | #define chipcHw_PIN_GPIO(n) ((((n) >= 0) && ((n) < (chipcHw_GPIO_COUNT))) ? (n) : 0xFFFFFFFF) | ||
| 185 | /* GPIO pin 0 - 60 */ | ||
| 186 | #define chipcHw_PIN_UARTTXD (chipcHw_GPIO_COUNT + 0) /* UART Transmit */ | ||
| 187 | #define chipcHw_PIN_NVI_A (chipcHw_GPIO_COUNT + 1) /* NVI Interface */ | ||
| 188 | #define chipcHw_PIN_NVI_D (chipcHw_GPIO_COUNT + 2) /* NVI Interface */ | ||
| 189 | #define chipcHw_PIN_NVI_OEB (chipcHw_GPIO_COUNT + 3) /* NVI Interface */ | ||
| 190 | #define chipcHw_PIN_NVI_WEB (chipcHw_GPIO_COUNT + 4) /* NVI Interface */ | ||
| 191 | #define chipcHw_PIN_NVI_CS (chipcHw_GPIO_COUNT + 5) /* NVI Interface */ | ||
| 192 | #define chipcHw_PIN_NVI_NAND_CSB (chipcHw_GPIO_COUNT + 6) /* NVI Interface */ | ||
| 193 | #define chipcHw_PIN_NVI_FLASHWP (chipcHw_GPIO_COUNT + 7) /* NVI Interface */ | ||
| 194 | #define chipcHw_PIN_NVI_NAND_RDYB (chipcHw_GPIO_COUNT + 8) /* NVI Interface */ | ||
| 195 | #define chipcHw_PIN_CL_DATA_0_17 (chipcHw_GPIO_COUNT + 9) /* LCD Data 0 - 17 */ | ||
| 196 | #define chipcHw_PIN_CL_DATA_18_20 (chipcHw_GPIO_COUNT + 10) /* LCD Data 18 - 20 */ | ||
| 197 | #define chipcHw_PIN_CL_DATA_21_23 (chipcHw_GPIO_COUNT + 11) /* LCD Data 21 - 23 */ | ||
| 198 | #define chipcHw_PIN_CL_POWER (chipcHw_GPIO_COUNT + 12) /* LCD Power */ | ||
| 199 | #define chipcHw_PIN_CL_ACK (chipcHw_GPIO_COUNT + 13) /* LCD Ack */ | ||
| 200 | #define chipcHw_PIN_CL_FP (chipcHw_GPIO_COUNT + 14) /* LCD FP */ | ||
| 201 | #define chipcHw_PIN_CL_LP (chipcHw_GPIO_COUNT + 15) /* LCD LP */ | ||
| 202 | #define chipcHw_PIN_UARTRXD (chipcHw_GPIO_COUNT + 16) /* UART Receive */ | ||
| 203 | |||
| 204 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 205 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 206 | |||
| 207 | /****************************************************************************/ | ||
| 208 | /** | ||
| 209 | * @brief Initializes the clock module | ||
| 210 | * | ||
| 211 | */ | ||
| 212 | /****************************************************************************/ | ||
| 213 | void chipcHw_Init(chipcHw_INIT_PARAM_t *initParam /* [ IN ] Misc chip initialization parameter */ | ||
| 214 | ) __attribute__ ((section(".aramtext"))); | ||
| 215 | |||
| 216 | /****************************************************************************/ | ||
| 217 | /** | ||
| 218 | * @brief Enables the PLL1 | ||
| 219 | * | ||
| 220 | * This function enables the PLL1 | ||
| 221 | * | ||
| 222 | */ | ||
| 223 | /****************************************************************************/ | ||
| 224 | void chipcHw_pll1Enable(uint32_t vcoFreqHz, /* [ IN ] VCO frequency in Hz */ | ||
| 225 | chipcHw_SPREAD_SPECTRUM_e ssSupport /* [ IN ] SS status */ | ||
| 226 | ) __attribute__ ((section(".aramtext"))); | ||
| 227 | |||
| 228 | /****************************************************************************/ | ||
| 229 | /** | ||
| 230 | * @brief Enables the PLL2 | ||
| 231 | * | ||
| 232 | * This function enables the PLL2 | ||
| 233 | * | ||
| 234 | */ | ||
| 235 | /****************************************************************************/ | ||
| 236 | void chipcHw_pll2Enable(uint32_t vcoFreqHz /* [ IN ] VCO frequency in Hz */ | ||
| 237 | ) __attribute__ ((section(".aramtext"))); | ||
| 238 | |||
| 239 | /****************************************************************************/ | ||
| 240 | /** | ||
| 241 | * @brief Disable the PLL1 | ||
| 242 | * | ||
| 243 | */ | ||
| 244 | /****************************************************************************/ | ||
| 245 | static inline void chipcHw_pll1Disable(void); | ||
| 246 | |||
| 247 | /****************************************************************************/ | ||
| 248 | /** | ||
| 249 | * @brief Disable the PLL2 | ||
| 250 | * | ||
| 251 | */ | ||
| 252 | /****************************************************************************/ | ||
| 253 | static inline void chipcHw_pll2Disable(void); | ||
| 254 | |||
| 255 | /****************************************************************************/ | ||
| 256 | /** | ||
| 257 | * @brief Set clock fequency for miscellaneous configurable clocks | ||
| 258 | * | ||
| 259 | * This function sets clock frequency | ||
| 260 | * | ||
| 261 | * @return Configured clock frequency in KHz | ||
| 262 | * | ||
| 263 | */ | ||
| 264 | /****************************************************************************/ | ||
| 265 | chipcHw_freq chipcHw_getClockFrequency(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */ | ||
| 266 | ) __attribute__ ((section(".aramtext"))); | ||
| 267 | |||
| 268 | /****************************************************************************/ | ||
| 269 | /** | ||
| 270 | * @brief Set clock fequency for miscellaneous configurable clocks | ||
| 271 | * | ||
| 272 | * This function sets clock frequency | ||
| 273 | * | ||
| 274 | * @return Configured clock frequency in Hz | ||
| 275 | * | ||
| 276 | */ | ||
| 277 | /****************************************************************************/ | ||
| 278 | chipcHw_freq chipcHw_setClockFrequency(chipcHw_CLOCK_e clock, /* [ IN ] Configurable clock */ | ||
| 279 | uint32_t freq /* [ IN ] Clock frequency in Hz */ | ||
| 280 | ) __attribute__ ((section(".aramtext"))); | ||
| 281 | |||
| 282 | /****************************************************************************/ | ||
| 283 | /** | ||
| 284 | * @brief Set VPM clock in sync with BUS clock | ||
| 285 | * | ||
| 286 | * This function does the phase adjustment between VPM and BUS clock | ||
| 287 | * | ||
| 288 | * @return >= 0 : On success ( # of adjustment required ) | ||
| 289 | * -1 : On failure | ||
| 290 | */ | ||
| 291 | /****************************************************************************/ | ||
| 292 | int chipcHw_vpmPhaseAlign(void); | ||
| 293 | |||
| 294 | /****************************************************************************/ | ||
| 295 | /** | ||
| 296 | * @brief Enables core a clock of a certain device | ||
| 297 | * | ||
| 298 | * This function enables a core clock | ||
| 299 | * | ||
| 300 | * @return void | ||
| 301 | * | ||
| 302 | * @note Doesnot affect the bus interface clock | ||
| 303 | */ | ||
| 304 | /****************************************************************************/ | ||
| 305 | static inline void chipcHw_setClockEnable(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */ | ||
| 306 | ); | ||
| 307 | |||
| 308 | /****************************************************************************/ | ||
| 309 | /** | ||
| 310 | * @brief Disabled a core clock of a certain device | ||
| 311 | * | ||
| 312 | * This function disables a core clock | ||
| 313 | * | ||
| 314 | * @return void | ||
| 315 | * | ||
| 316 | * @note Doesnot affect the bus interface clock | ||
| 317 | */ | ||
| 318 | /****************************************************************************/ | ||
| 319 | static inline void chipcHw_setClockDisable(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */ | ||
| 320 | ); | ||
| 321 | |||
| 322 | /****************************************************************************/ | ||
| 323 | /** | ||
| 324 | * @brief Enables bypass clock of a certain device | ||
| 325 | * | ||
| 326 | * This function enables bypass clock | ||
| 327 | * | ||
| 328 | * @note Doesnot affect the bus interface clock | ||
| 329 | */ | ||
| 330 | /****************************************************************************/ | ||
| 331 | static inline void chipcHw_bypassClockEnable(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */ | ||
| 332 | ); | ||
| 333 | |||
| 334 | /****************************************************************************/ | ||
| 335 | /** | ||
| 336 | * @brief Disabled bypass clock of a certain device | ||
| 337 | * | ||
| 338 | * This function disables bypass clock | ||
| 339 | * | ||
| 340 | * @note Doesnot affect the bus interface clock | ||
| 341 | */ | ||
| 342 | /****************************************************************************/ | ||
| 343 | static inline void chipcHw_bypassClockDisable(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */ | ||
| 344 | ); | ||
| 345 | |||
| 346 | /****************************************************************************/ | ||
| 347 | /** | ||
| 348 | * @brief Get Numeric Chip ID | ||
| 349 | * | ||
| 350 | * This function returns Chip ID that includes the revison number | ||
| 351 | * | ||
| 352 | * @return Complete numeric Chip ID | ||
| 353 | * | ||
| 354 | */ | ||
| 355 | /****************************************************************************/ | ||
| 356 | static inline uint32_t chipcHw_getChipId(void); | ||
| 357 | |||
| 358 | /****************************************************************************/ | ||
| 359 | /** | ||
| 360 | * @brief Get Chip Product ID | ||
| 361 | * | ||
| 362 | * This function returns Chip Product ID | ||
| 363 | * | ||
| 364 | * @return Chip Product ID | ||
| 365 | */ | ||
| 366 | /****************************************************************************/ | ||
| 367 | static inline uint32_t chipcHw_getChipProductId(void); | ||
| 368 | |||
| 369 | /****************************************************************************/ | ||
| 370 | /** | ||
| 371 | * @brief Get revision number | ||
| 372 | * | ||
| 373 | * This function returns revision number of the chip | ||
| 374 | * | ||
| 375 | * @return Revision number | ||
| 376 | */ | ||
| 377 | /****************************************************************************/ | ||
| 378 | static inline chipcHw_REV_NUMBER_e chipcHw_getChipRevisionNumber(void); | ||
| 379 | |||
| 380 | /****************************************************************************/ | ||
| 381 | /** | ||
| 382 | * @brief Enables bus interface clock | ||
| 383 | * | ||
| 384 | * Enables bus interface clock of various device | ||
| 385 | * | ||
| 386 | * @return void | ||
| 387 | * | ||
| 388 | * @note use chipcHw_REG_BUS_CLOCK_XXXX | ||
| 389 | */ | ||
| 390 | /****************************************************************************/ | ||
| 391 | static inline void chipcHw_busInterfaceClockEnable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_BUS_CLOCK_XXXXX */ | ||
| 392 | ); | ||
| 393 | |||
| 394 | /****************************************************************************/ | ||
| 395 | /** | ||
| 396 | * @brief Disables bus interface clock | ||
| 397 | * | ||
| 398 | * Disables bus interface clock of various device | ||
| 399 | * | ||
| 400 | * @return void | ||
| 401 | * | ||
| 402 | * @note use chipcHw_REG_BUS_CLOCK_XXXX | ||
| 403 | */ | ||
| 404 | /****************************************************************************/ | ||
| 405 | static inline void chipcHw_busInterfaceClockDisable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_BUS_CLOCK_XXXXX */ | ||
| 406 | ); | ||
| 407 | |||
| 408 | /****************************************************************************/ | ||
| 409 | /** | ||
| 410 | * @brief Enables various audio channels | ||
| 411 | * | ||
| 412 | * Enables audio channel | ||
| 413 | * | ||
| 414 | * @return void | ||
| 415 | * | ||
| 416 | * @note use chipcHw_REG_AUDIO_CHANNEL_XXXXXX | ||
| 417 | */ | ||
| 418 | /****************************************************************************/ | ||
| 419 | static inline void chipcHw_audioChannelEnable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_AUDIO_CHANNEL_XXXXXX */ | ||
| 420 | ); | ||
| 421 | |||
| 422 | /****************************************************************************/ | ||
| 423 | /** | ||
| 424 | * @brief Disables various audio channels | ||
| 425 | * | ||
| 426 | * Disables audio channel | ||
| 427 | * | ||
| 428 | * @return void | ||
| 429 | * | ||
| 430 | * @note use chipcHw_REG_AUDIO_CHANNEL_XXXXXX | ||
| 431 | */ | ||
| 432 | /****************************************************************************/ | ||
| 433 | static inline void chipcHw_audioChannelDisable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_AUDIO_CHANNEL_XXXXXX */ | ||
| 434 | ); | ||
| 435 | |||
| 436 | /****************************************************************************/ | ||
| 437 | /** | ||
| 438 | * @brief Soft resets devices | ||
| 439 | * | ||
| 440 | * Soft resets various devices | ||
| 441 | * | ||
| 442 | * @return void | ||
| 443 | * | ||
| 444 | * @note use chipcHw_REG_SOFT_RESET_XXXXXX defines | ||
| 445 | */ | ||
| 446 | /****************************************************************************/ | ||
| 447 | static inline void chipcHw_softReset(uint64_t mask /* [ IN ] Bit map of type chipcHw_REG_SOFT_RESET_XXXXXX */ | ||
| 448 | ); | ||
| 449 | |||
| 450 | static inline void chipcHw_softResetDisable(uint64_t mask /* [ IN ] Bit map of type chipcHw_REG_SOFT_RESET_XXXXXX */ | ||
| 451 | ); | ||
| 452 | |||
| 453 | static inline void chipcHw_softResetEnable(uint64_t mask /* [ IN ] Bit map of type chipcHw_REG_SOFT_RESET_XXXXXX */ | ||
| 454 | ); | ||
| 455 | |||
| 456 | /****************************************************************************/ | ||
| 457 | /** | ||
| 458 | * @brief Configures misc CHIP functionality | ||
| 459 | * | ||
| 460 | * Configures CHIP functionality | ||
| 461 | * | ||
| 462 | * @return void | ||
| 463 | * | ||
| 464 | * @note use chipcHw_REG_MISC_CTRL_XXXXXX | ||
| 465 | */ | ||
| 466 | /****************************************************************************/ | ||
| 467 | static inline void chipcHw_miscControl(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_MISC_CTRL_XXXXXX */ | ||
| 468 | ); | ||
| 469 | |||
| 470 | static inline void chipcHw_miscControlDisable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_MISC_CTRL_XXXXXX */ | ||
| 471 | ); | ||
| 472 | |||
| 473 | static inline void chipcHw_miscControlEnable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_MISC_CTRL_XXXXXX */ | ||
| 474 | ); | ||
| 475 | |||
| 476 | /****************************************************************************/ | ||
| 477 | /** | ||
| 478 | * @brief Set OTP options | ||
| 479 | * | ||
| 480 | * Set OTP options | ||
| 481 | * | ||
| 482 | * @return void | ||
| 483 | * | ||
| 484 | * @note use chipcHw_REG_OTP_XXXXXX | ||
| 485 | */ | ||
| 486 | /****************************************************************************/ | ||
| 487 | static inline void chipcHw_setOTPOption(uint64_t mask /* [ IN ] Bit map of type chipcHw_REG_OTP_XXXXXX */ | ||
| 488 | ); | ||
| 489 | |||
| 490 | /****************************************************************************/ | ||
| 491 | /** | ||
| 492 | * @brief Get sticky bits | ||
| 493 | * | ||
| 494 | * @return Sticky bit options of type chipcHw_REG_STICKY_XXXXXX | ||
| 495 | * | ||
| 496 | */ | ||
| 497 | /****************************************************************************/ | ||
| 498 | static inline uint32_t chipcHw_getStickyBits(void); | ||
| 499 | |||
| 500 | /****************************************************************************/ | ||
| 501 | /** | ||
| 502 | * @brief Set sticky bits | ||
| 503 | * | ||
| 504 | * @return void | ||
| 505 | * | ||
| 506 | * @note use chipcHw_REG_STICKY_XXXXXX | ||
| 507 | */ | ||
| 508 | /****************************************************************************/ | ||
| 509 | static inline void chipcHw_setStickyBits(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_STICKY_XXXXXX */ | ||
| 510 | ); | ||
| 511 | |||
| 512 | /****************************************************************************/ | ||
| 513 | /** | ||
| 514 | * @brief Clear sticky bits | ||
| 515 | * | ||
| 516 | * @return void | ||
| 517 | * | ||
| 518 | * @note use chipcHw_REG_STICKY_XXXXXX | ||
| 519 | */ | ||
| 520 | /****************************************************************************/ | ||
| 521 | static inline void chipcHw_clearStickyBits(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_STICKY_XXXXXX */ | ||
| 522 | ); | ||
| 523 | |||
| 524 | /****************************************************************************/ | ||
| 525 | /** | ||
| 526 | * @brief Get software override strap options | ||
| 527 | * | ||
| 528 | * Retrieves software override strap options | ||
| 529 | * | ||
| 530 | * @return Software override strap value | ||
| 531 | * | ||
| 532 | */ | ||
| 533 | /****************************************************************************/ | ||
| 534 | static inline uint32_t chipcHw_getSoftStraps(void); | ||
| 535 | |||
| 536 | /****************************************************************************/ | ||
| 537 | /** | ||
| 538 | * @brief Set software override strap options | ||
| 539 | * | ||
| 540 | * set software override strap options | ||
| 541 | * | ||
| 542 | * @return nothing | ||
| 543 | * | ||
| 544 | */ | ||
| 545 | /****************************************************************************/ | ||
| 546 | static inline void chipcHw_setSoftStraps(uint32_t strapOptions); | ||
| 547 | |||
| 548 | /****************************************************************************/ | ||
| 549 | /** | ||
| 550 | * @brief Get pin strap options | ||
| 551 | * | ||
| 552 | * Retrieves pin strap options | ||
| 553 | * | ||
| 554 | * @return Pin strap value | ||
| 555 | * | ||
| 556 | */ | ||
| 557 | /****************************************************************************/ | ||
| 558 | static inline uint32_t chipcHw_getPinStraps(void); | ||
| 559 | |||
| 560 | /****************************************************************************/ | ||
| 561 | /** | ||
| 562 | * @brief Get valid pin strap options | ||
| 563 | * | ||
| 564 | * Retrieves valid pin strap options | ||
| 565 | * | ||
| 566 | * @return valid Pin strap value | ||
| 567 | * | ||
| 568 | */ | ||
| 569 | /****************************************************************************/ | ||
| 570 | static inline uint32_t chipcHw_getValidStraps(void); | ||
| 571 | |||
| 572 | /****************************************************************************/ | ||
| 573 | /** | ||
| 574 | * @brief Initialize valid pin strap options | ||
| 575 | * | ||
| 576 | * Retrieves valid pin strap options by copying HW strap options to soft register | ||
| 577 | * (if chipcHw_STRAPS_SOFT_OVERRIDE not set) | ||
| 578 | * | ||
| 579 | * @return nothing | ||
| 580 | * | ||
| 581 | */ | ||
| 582 | /****************************************************************************/ | ||
| 583 | static inline void chipcHw_initValidStraps(void); | ||
| 584 | |||
| 585 | /****************************************************************************/ | ||
| 586 | /** | ||
| 587 | * @brief Get status (enabled/disabled) of bus interface clock | ||
| 588 | * | ||
| 589 | * This function returns the status of devices' bus interface clock | ||
| 590 | * | ||
| 591 | * @return Bus interface clock | ||
| 592 | * | ||
| 593 | */ | ||
| 594 | /****************************************************************************/ | ||
| 595 | static inline uint32_t chipcHw_getBusInterfaceClockStatus(void); | ||
| 596 | |||
| 597 | /****************************************************************************/ | ||
| 598 | /** | ||
| 599 | * @brief Get boot device | ||
| 600 | * | ||
| 601 | * This function returns the device type used in booting the system | ||
| 602 | * | ||
| 603 | * @return Boot device of type chipcHw_BOOT_DEVICE_e | ||
| 604 | * | ||
| 605 | */ | ||
| 606 | /****************************************************************************/ | ||
| 607 | static inline chipcHw_BOOT_DEVICE_e chipcHw_getBootDevice(void); | ||
| 608 | |||
| 609 | /****************************************************************************/ | ||
| 610 | /** | ||
| 611 | * @brief Get boot mode | ||
| 612 | * | ||
| 613 | * This function returns the way the system was booted | ||
| 614 | * | ||
| 615 | * @return Boot mode of type chipcHw_BOOT_MODE_e | ||
| 616 | * | ||
| 617 | */ | ||
| 618 | /****************************************************************************/ | ||
| 619 | static inline chipcHw_BOOT_MODE_e chipcHw_getBootMode(void); | ||
| 620 | |||
| 621 | /****************************************************************************/ | ||
| 622 | /** | ||
| 623 | * @brief Get NAND flash page size | ||
| 624 | * | ||
| 625 | * This function returns the NAND device page size | ||
| 626 | * | ||
| 627 | * @return Boot NAND device page size | ||
| 628 | * | ||
| 629 | */ | ||
| 630 | /****************************************************************************/ | ||
| 631 | static inline chipcHw_NAND_PAGESIZE_e chipcHw_getNandPageSize(void); | ||
| 632 | |||
| 633 | /****************************************************************************/ | ||
| 634 | /** | ||
| 635 | * @brief Get NAND flash address cycle configuration | ||
| 636 | * | ||
| 637 | * This function returns the NAND flash address cycle configuration | ||
| 638 | * | ||
| 639 | * @return 0 = Do not extra address cycle, 1 = Add extra cycle | ||
| 640 | * | ||
| 641 | */ | ||
| 642 | /****************************************************************************/ | ||
| 643 | static inline int chipcHw_getNandExtraCycle(void); | ||
| 644 | |||
| 645 | /****************************************************************************/ | ||
| 646 | /** | ||
| 647 | * @brief Activates PIF interface | ||
| 648 | * | ||
| 649 | * This function activates PIF interface by taking control of LCD pins | ||
| 650 | * | ||
| 651 | * @note | ||
| 652 | * When activated, LCD pins will be defined as follows for PIF operation | ||
| 653 | * | ||
| 654 | * CLD[17:0] = pif_data[17:0] | ||
| 655 | * CLD[23:18] = pif_address[5:0] | ||
| 656 | * CLPOWER = pif_wr_str | ||
| 657 | * CLCP = pif_rd_str | ||
| 658 | * CLAC = pif_hat1 | ||
| 659 | * CLFP = pif_hrdy1 | ||
| 660 | * CLLP = pif_hat2 | ||
| 661 | * GPIO[42] = pif_hrdy2 | ||
| 662 | * | ||
| 663 | * In PIF mode, "pif_hrdy2" overrides other shared function for GPIO[42] pin | ||
| 664 | * | ||
| 665 | */ | ||
| 666 | /****************************************************************************/ | ||
| 667 | static inline void chipcHw_activatePifInterface(void); | ||
| 668 | |||
| 669 | /****************************************************************************/ | ||
| 670 | /** | ||
| 671 | * @brief Activates LCD interface | ||
| 672 | * | ||
| 673 | * This function activates LCD interface | ||
| 674 | * | ||
| 675 | * @note | ||
| 676 | * When activated, LCD pins will be defined as follows | ||
| 677 | * | ||
| 678 | * CLD[17:0] = LCD data | ||
| 679 | * CLD[23:18] = LCD data | ||
| 680 | * CLPOWER = LCD power | ||
| 681 | * CLCP = | ||
| 682 | * CLAC = LCD ack | ||
| 683 | * CLFP = | ||
| 684 | * CLLP = | ||
| 685 | */ | ||
| 686 | /****************************************************************************/ | ||
| 687 | static inline void chipcHw_activateLcdInterface(void); | ||
| 688 | |||
| 689 | /****************************************************************************/ | ||
| 690 | /** | ||
| 691 | * @brief Deactivates PIF/LCD interface | ||
| 692 | * | ||
| 693 | * This function deactivates PIF/LCD interface | ||
| 694 | * | ||
| 695 | * @note | ||
| 696 | * When deactivated LCD pins will be in rti-stated | ||
| 697 | * | ||
| 698 | */ | ||
| 699 | /****************************************************************************/ | ||
| 700 | static inline void chipcHw_deactivatePifLcdInterface(void); | ||
| 701 | |||
| 702 | /****************************************************************************/ | ||
| 703 | /** | ||
| 704 | * @brief Get to know the configuration of GPIO pin | ||
| 705 | * | ||
| 706 | */ | ||
| 707 | /****************************************************************************/ | ||
| 708 | static inline chipcHw_GPIO_FUNCTION_e chipcHw_getGpioPinFunction(int pin /* GPIO Pin number */ | ||
| 709 | ); | ||
| 710 | |||
| 711 | /****************************************************************************/ | ||
| 712 | /** | ||
| 713 | * @brief Configure GPIO pin function | ||
| 714 | * | ||
| 715 | */ | ||
| 716 | /****************************************************************************/ | ||
| 717 | static inline void chipcHw_setGpioPinFunction(int pin, /* GPIO Pin number */ | ||
| 718 | chipcHw_GPIO_FUNCTION_e func /* Configuration function */ | ||
| 719 | ); | ||
| 720 | |||
| 721 | /****************************************************************************/ | ||
| 722 | /** | ||
| 723 | * @brief Set Pin slew rate | ||
| 724 | * | ||
| 725 | * This function sets the slew of individual pin | ||
| 726 | * | ||
| 727 | */ | ||
| 728 | /****************************************************************************/ | ||
| 729 | static inline void chipcHw_setPinSlewRate(uint32_t pin, /* Pin of type chipcHw_PIN_XXXXX */ | ||
| 730 | chipcHw_PIN_SLEW_RATE_e slewRate /* Pin slew rate */ | ||
| 731 | ); | ||
| 732 | |||
| 733 | /****************************************************************************/ | ||
| 734 | /** | ||
| 735 | * @brief Set Pin output drive current | ||
| 736 | * | ||
| 737 | * This function sets output drive current of individual pin | ||
| 738 | * | ||
| 739 | * Note: Avoid the use of the word 'current' since linux headers define this | ||
| 740 | * to be the current task. | ||
| 741 | */ | ||
| 742 | /****************************************************************************/ | ||
| 743 | static inline void chipcHw_setPinOutputCurrent(uint32_t pin, /* Pin of type chipcHw_PIN_XXXXX */ | ||
| 744 | chipcHw_PIN_CURRENT_STRENGTH_e curr /* Pin current rating */ | ||
| 745 | ); | ||
| 746 | |||
| 747 | /****************************************************************************/ | ||
| 748 | /** | ||
| 749 | * @brief Set Pin pullup register | ||
| 750 | * | ||
| 751 | * This function sets pullup register of individual pin | ||
| 752 | * | ||
| 753 | */ | ||
| 754 | /****************************************************************************/ | ||
| 755 | static inline void chipcHw_setPinPullup(uint32_t pin, /* Pin of type chipcHw_PIN_XXXXX */ | ||
| 756 | chipcHw_PIN_PULL_e pullup /* Pullup register settings */ | ||
| 757 | ); | ||
| 758 | |||
| 759 | /****************************************************************************/ | ||
| 760 | /** | ||
| 761 | * @brief Set Pin input type | ||
| 762 | * | ||
| 763 | * This function sets input type of individual Pin | ||
| 764 | * | ||
| 765 | */ | ||
| 766 | /****************************************************************************/ | ||
| 767 | static inline void chipcHw_setPinInputType(uint32_t pin, /* Pin of type chipcHw_PIN_XXXXX */ | ||
| 768 | chipcHw_PIN_INPUTTYPE_e inputType /* Pin input type */ | ||
| 769 | ); | ||
| 770 | |||
| 771 | /****************************************************************************/ | ||
| 772 | /** | ||
| 773 | * @brief Retrieves a string representation of the mux setting for a pin. | ||
| 774 | * | ||
| 775 | * @return Pointer to a character string. | ||
| 776 | */ | ||
| 777 | /****************************************************************************/ | ||
| 778 | |||
| 779 | const char *chipcHw_getGpioPinFunctionStr(int pin); | ||
| 780 | |||
| 781 | /****************************************************************************/ | ||
| 782 | /** @brief issue warmReset | ||
| 783 | */ | ||
| 784 | /****************************************************************************/ | ||
| 785 | void chipcHw_reset(uint32_t mask); | ||
| 786 | |||
| 787 | /****************************************************************************/ | ||
| 788 | /** @brief clock reconfigure | ||
| 789 | */ | ||
| 790 | /****************************************************************************/ | ||
| 791 | void chipcHw_clockReconfig(uint32_t busHz, uint32_t armRatio, uint32_t vpmRatio, | ||
| 792 | uint32_t ddrRatio); | ||
| 793 | |||
| 794 | /****************************************************************************/ | ||
| 795 | /** | ||
| 796 | * @brief Enable Spread Spectrum | ||
| 797 | * | ||
| 798 | * @note chipcHw_Init() must be called earlier | ||
| 799 | */ | ||
| 800 | /****************************************************************************/ | ||
| 801 | static inline void chipcHw_enableSpreadSpectrum(void); | ||
| 802 | |||
| 803 | /****************************************************************************/ | ||
| 804 | /** | ||
| 805 | * @brief Disable Spread Spectrum | ||
| 806 | * | ||
| 807 | */ | ||
| 808 | /****************************************************************************/ | ||
| 809 | static inline void chipcHw_disableSpreadSpectrum(void); | ||
| 810 | |||
| 811 | /****************************************************************************/ | ||
| 812 | /** @brief Checks if software strap is enabled | ||
| 813 | * | ||
| 814 | * @return 1 : When enable | ||
| 815 | * 0 : When disable | ||
| 816 | */ | ||
| 817 | /****************************************************************************/ | ||
| 818 | static inline int chipcHw_isSoftwareStrapsEnable(void); | ||
| 819 | |||
| 820 | /****************************************************************************/ | ||
| 821 | /** @brief Enable software strap | ||
| 822 | */ | ||
| 823 | /****************************************************************************/ | ||
| 824 | static inline void chipcHw_softwareStrapsEnable(void); | ||
| 825 | |||
| 826 | /****************************************************************************/ | ||
| 827 | /** @brief Disable software strap | ||
| 828 | */ | ||
| 829 | /****************************************************************************/ | ||
| 830 | static inline void chipcHw_softwareStrapsDisable(void); | ||
| 831 | |||
| 832 | /****************************************************************************/ | ||
| 833 | /** @brief PLL test enable | ||
| 834 | */ | ||
| 835 | /****************************************************************************/ | ||
| 836 | static inline void chipcHw_pllTestEnable(void); | ||
| 837 | |||
| 838 | /****************************************************************************/ | ||
| 839 | /** @brief PLL2 test enable | ||
| 840 | */ | ||
| 841 | /****************************************************************************/ | ||
| 842 | static inline void chipcHw_pll2TestEnable(void); | ||
| 843 | |||
| 844 | /****************************************************************************/ | ||
| 845 | /** @brief PLL test disable | ||
| 846 | */ | ||
| 847 | /****************************************************************************/ | ||
| 848 | static inline void chipcHw_pllTestDisable(void); | ||
| 849 | |||
| 850 | /****************************************************************************/ | ||
| 851 | /** @brief PLL2 test disable | ||
| 852 | */ | ||
| 853 | /****************************************************************************/ | ||
| 854 | static inline void chipcHw_pll2TestDisable(void); | ||
| 855 | |||
| 856 | /****************************************************************************/ | ||
| 857 | /** @brief Get PLL test status | ||
| 858 | */ | ||
| 859 | /****************************************************************************/ | ||
| 860 | static inline int chipcHw_isPllTestEnable(void); | ||
| 861 | |||
| 862 | /****************************************************************************/ | ||
| 863 | /** @brief Get PLL2 test status | ||
| 864 | */ | ||
| 865 | /****************************************************************************/ | ||
| 866 | static inline int chipcHw_isPll2TestEnable(void); | ||
| 867 | |||
| 868 | /****************************************************************************/ | ||
| 869 | /** @brief PLL test select | ||
| 870 | */ | ||
| 871 | /****************************************************************************/ | ||
| 872 | static inline void chipcHw_pllTestSelect(uint32_t val); | ||
| 873 | |||
| 874 | /****************************************************************************/ | ||
| 875 | /** @brief PLL2 test select | ||
| 876 | */ | ||
| 877 | /****************************************************************************/ | ||
| 878 | static inline void chipcHw_pll2TestSelect(uint32_t val); | ||
| 879 | |||
| 880 | /****************************************************************************/ | ||
| 881 | /** @brief Get PLL test selected option | ||
| 882 | */ | ||
| 883 | /****************************************************************************/ | ||
| 884 | static inline uint8_t chipcHw_getPllTestSelected(void); | ||
| 885 | |||
| 886 | /****************************************************************************/ | ||
| 887 | /** @brief Get PLL2 test selected option | ||
| 888 | */ | ||
| 889 | /****************************************************************************/ | ||
| 890 | static inline uint8_t chipcHw_getPll2TestSelected(void); | ||
| 891 | |||
| 892 | /****************************************************************************/ | ||
| 893 | /** | ||
| 894 | * @brief Enables DDR SW phase alignment interrupt | ||
| 895 | */ | ||
| 896 | /****************************************************************************/ | ||
| 897 | static inline void chipcHw_ddrPhaseAlignInterruptEnable(void); | ||
| 898 | |||
| 899 | /****************************************************************************/ | ||
| 900 | /** | ||
| 901 | * @brief Disables DDR SW phase alignment interrupt | ||
| 902 | */ | ||
| 903 | /****************************************************************************/ | ||
| 904 | static inline void chipcHw_ddrPhaseAlignInterruptDisable(void); | ||
| 905 | |||
| 906 | /****************************************************************************/ | ||
| 907 | /** | ||
| 908 | * @brief Set VPM SW phase alignment interrupt mode | ||
| 909 | * | ||
| 910 | * This function sets VPM phase alignment interrupt | ||
| 911 | * | ||
| 912 | */ | ||
| 913 | /****************************************************************************/ | ||
| 914 | static inline void | ||
| 915 | chipcHw_vpmPhaseAlignInterruptMode(chipcHw_VPM_HW_PHASE_INTR_e mode); | ||
| 916 | |||
| 917 | /****************************************************************************/ | ||
| 918 | /** | ||
| 919 | * @brief Enable DDR phase alignment in software | ||
| 920 | * | ||
| 921 | */ | ||
| 922 | /****************************************************************************/ | ||
| 923 | static inline void chipcHw_ddrSwPhaseAlignEnable(void); | ||
| 924 | |||
| 925 | /****************************************************************************/ | ||
| 926 | /** | ||
| 927 | * @brief Disable DDR phase alignment in software | ||
| 928 | * | ||
| 929 | */ | ||
| 930 | /****************************************************************************/ | ||
| 931 | static inline void chipcHw_ddrSwPhaseAlignDisable(void); | ||
| 932 | |||
| 933 | /****************************************************************************/ | ||
| 934 | /** | ||
| 935 | * @brief Enable DDR phase alignment in hardware | ||
| 936 | * | ||
| 937 | */ | ||
| 938 | /****************************************************************************/ | ||
| 939 | static inline void chipcHw_ddrHwPhaseAlignEnable(void); | ||
| 940 | |||
| 941 | /****************************************************************************/ | ||
| 942 | /** | ||
| 943 | * @brief Disable DDR phase alignment in hardware | ||
| 944 | * | ||
| 945 | */ | ||
| 946 | /****************************************************************************/ | ||
| 947 | static inline void chipcHw_ddrHwPhaseAlignDisable(void); | ||
| 948 | |||
| 949 | /****************************************************************************/ | ||
| 950 | /** | ||
| 951 | * @brief Enable VPM phase alignment in software | ||
| 952 | * | ||
| 953 | */ | ||
| 954 | /****************************************************************************/ | ||
| 955 | static inline void chipcHw_vpmSwPhaseAlignEnable(void); | ||
| 956 | |||
| 957 | /****************************************************************************/ | ||
| 958 | /** | ||
| 959 | * @brief Disable VPM phase alignment in software | ||
| 960 | * | ||
| 961 | */ | ||
| 962 | /****************************************************************************/ | ||
| 963 | static inline void chipcHw_vpmSwPhaseAlignDisable(void); | ||
| 964 | |||
| 965 | /****************************************************************************/ | ||
| 966 | /** | ||
| 967 | * @brief Enable VPM phase alignment in hardware | ||
| 968 | * | ||
| 969 | */ | ||
| 970 | /****************************************************************************/ | ||
| 971 | static inline void chipcHw_vpmHwPhaseAlignEnable(void); | ||
| 972 | |||
| 973 | /****************************************************************************/ | ||
| 974 | /** | ||
| 975 | * @brief Disable VPM phase alignment in hardware | ||
| 976 | * | ||
| 977 | */ | ||
| 978 | /****************************************************************************/ | ||
| 979 | static inline void chipcHw_vpmHwPhaseAlignDisable(void); | ||
| 980 | |||
| 981 | /****************************************************************************/ | ||
| 982 | /** | ||
| 983 | * @brief Set DDR phase alignment margin in hardware | ||
| 984 | * | ||
| 985 | */ | ||
| 986 | /****************************************************************************/ | ||
| 987 | static inline void chipcHw_setDdrHwPhaseAlignMargin(chipcHw_DDR_HW_PHASE_MARGIN_e margin /* Margin alinging DDR phase */ | ||
| 988 | ); | ||
| 989 | |||
| 990 | /****************************************************************************/ | ||
| 991 | /** | ||
| 992 | * @brief Set VPM phase alignment margin in hardware | ||
| 993 | * | ||
| 994 | */ | ||
| 995 | /****************************************************************************/ | ||
| 996 | static inline void chipcHw_setVpmHwPhaseAlignMargin(chipcHw_VPM_HW_PHASE_MARGIN_e margin /* Margin alinging VPM phase */ | ||
| 997 | ); | ||
| 998 | |||
| 999 | /****************************************************************************/ | ||
| 1000 | /** | ||
| 1001 | * @brief Checks DDR phase aligned status done by HW | ||
| 1002 | * | ||
| 1003 | * @return 1: When aligned | ||
| 1004 | * 0: When not aligned | ||
| 1005 | */ | ||
| 1006 | /****************************************************************************/ | ||
| 1007 | static inline uint32_t chipcHw_isDdrHwPhaseAligned(void); | ||
| 1008 | |||
| 1009 | /****************************************************************************/ | ||
| 1010 | /** | ||
| 1011 | * @brief Checks VPM phase aligned status done by HW | ||
| 1012 | * | ||
| 1013 | * @return 1: When aligned | ||
| 1014 | * 0: When not aligned | ||
| 1015 | */ | ||
| 1016 | /****************************************************************************/ | ||
| 1017 | static inline uint32_t chipcHw_isVpmHwPhaseAligned(void); | ||
| 1018 | |||
| 1019 | /****************************************************************************/ | ||
| 1020 | /** | ||
| 1021 | * @brief Get DDR phase aligned status done by HW | ||
| 1022 | * | ||
| 1023 | */ | ||
| 1024 | /****************************************************************************/ | ||
| 1025 | static inline uint32_t chipcHw_getDdrHwPhaseAlignStatus(void); | ||
| 1026 | |||
| 1027 | /****************************************************************************/ | ||
| 1028 | /** | ||
| 1029 | * @brief Get VPM phase aligned status done by HW | ||
| 1030 | * | ||
| 1031 | */ | ||
| 1032 | /****************************************************************************/ | ||
| 1033 | static inline uint32_t chipcHw_getVpmHwPhaseAlignStatus(void); | ||
| 1034 | |||
| 1035 | /****************************************************************************/ | ||
| 1036 | /** | ||
| 1037 | * @brief Get DDR phase control value | ||
| 1038 | * | ||
| 1039 | */ | ||
| 1040 | /****************************************************************************/ | ||
| 1041 | static inline uint32_t chipcHw_getDdrPhaseControl(void); | ||
| 1042 | |||
| 1043 | /****************************************************************************/ | ||
| 1044 | /** | ||
| 1045 | * @brief Get VPM phase control value | ||
| 1046 | * | ||
| 1047 | */ | ||
| 1048 | /****************************************************************************/ | ||
| 1049 | static inline uint32_t chipcHw_getVpmPhaseControl(void); | ||
| 1050 | |||
| 1051 | /****************************************************************************/ | ||
| 1052 | /** | ||
| 1053 | * @brief DDR phase alignment timeout count | ||
| 1054 | * | ||
| 1055 | * @note If HW fails to perform the phase alignment, it will trigger | ||
| 1056 | * a DDR phase alignment timeout interrupt. | ||
| 1057 | */ | ||
| 1058 | /****************************************************************************/ | ||
| 1059 | static inline void chipcHw_ddrHwPhaseAlignTimeout(uint32_t busCycle /* Timeout in bus cycle */ | ||
| 1060 | ); | ||
| 1061 | |||
| 1062 | /****************************************************************************/ | ||
| 1063 | /** | ||
| 1064 | * @brief VPM phase alignment timeout count | ||
| 1065 | * | ||
| 1066 | * @note If HW fails to perform the phase alignment, it will trigger | ||
| 1067 | * a VPM phase alignment timeout interrupt. | ||
| 1068 | */ | ||
| 1069 | /****************************************************************************/ | ||
| 1070 | static inline void chipcHw_vpmHwPhaseAlignTimeout(uint32_t busCycle /* Timeout in bus cycle */ | ||
| 1071 | ); | ||
| 1072 | |||
| 1073 | /****************************************************************************/ | ||
| 1074 | /** | ||
| 1075 | * @brief DDR phase alignment timeout interrupt enable | ||
| 1076 | * | ||
| 1077 | */ | ||
| 1078 | /****************************************************************************/ | ||
| 1079 | static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptEnable(void); | ||
| 1080 | |||
| 1081 | /****************************************************************************/ | ||
| 1082 | /** | ||
| 1083 | * @brief VPM phase alignment timeout interrupt enable | ||
| 1084 | * | ||
| 1085 | */ | ||
| 1086 | /****************************************************************************/ | ||
| 1087 | static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptEnable(void); | ||
| 1088 | |||
| 1089 | /****************************************************************************/ | ||
| 1090 | /** | ||
| 1091 | * @brief DDR phase alignment timeout interrupt disable | ||
| 1092 | * | ||
| 1093 | */ | ||
| 1094 | /****************************************************************************/ | ||
| 1095 | static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptDisable(void); | ||
| 1096 | |||
| 1097 | /****************************************************************************/ | ||
| 1098 | /** | ||
| 1099 | * @brief VPM phase alignment timeout interrupt disable | ||
| 1100 | * | ||
| 1101 | */ | ||
| 1102 | /****************************************************************************/ | ||
| 1103 | static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptDisable(void); | ||
| 1104 | |||
| 1105 | /****************************************************************************/ | ||
| 1106 | /** | ||
| 1107 | * @brief Clear DDR phase alignment timeout interrupt | ||
| 1108 | * | ||
| 1109 | */ | ||
| 1110 | /****************************************************************************/ | ||
| 1111 | static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptClear(void); | ||
| 1112 | |||
| 1113 | /****************************************************************************/ | ||
| 1114 | /** | ||
| 1115 | * @brief Clear VPM phase alignment timeout interrupt | ||
| 1116 | * | ||
| 1117 | */ | ||
| 1118 | /****************************************************************************/ | ||
| 1119 | static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptClear(void); | ||
| 1120 | |||
| 1121 | /* ---- Private Constants and Types -------------------------------------- */ | ||
| 1122 | |||
| 1123 | #endif /* CHIPC_DEF_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h new file mode 100644 index 000000000000..c78833acb37a --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h | |||
| @@ -0,0 +1,1673 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #ifndef CHIPC_INLINE_H | ||
| 16 | #define CHIPC_INLINE_H | ||
| 17 | |||
| 18 | /* ---- Include Files ----------------------------------------------------- */ | ||
| 19 | |||
| 20 | #include <csp/errno.h> | ||
| 21 | #include <csp/reg.h> | ||
| 22 | #include <mach/csp/chipcHw_reg.h> | ||
| 23 | #include <mach/csp/chipcHw_def.h> | ||
| 24 | |||
| 25 | /* ---- Private Constants and Types --------------------------------------- */ | ||
| 26 | typedef enum { | ||
| 27 | chipcHw_OPTYPE_BYPASS, /* Bypass operation */ | ||
| 28 | chipcHw_OPTYPE_OUTPUT /* Output operation */ | ||
| 29 | } chipcHw_OPTYPE_e; | ||
| 30 | |||
| 31 | /* ---- Public Constants and Types ---------------------------------------- */ | ||
| 32 | /* ---- Public Variable Externs ------------------------------------------- */ | ||
| 33 | /* ---- Public Function Prototypes ---------------------------------------- */ | ||
| 34 | /* ---- Private Function Prototypes --------------------------------------- */ | ||
| 35 | static inline void chipcHw_setClock(chipcHw_CLOCK_e clock, | ||
| 36 | chipcHw_OPTYPE_e type, int mode); | ||
| 37 | |||
| 38 | /****************************************************************************/ | ||
| 39 | /** | ||
| 40 | * @brief Get Numeric Chip ID | ||
| 41 | * | ||
| 42 | * This function returns Chip ID that includes the revison number | ||
| 43 | * | ||
| 44 | * @return Complete numeric Chip ID | ||
| 45 | * | ||
| 46 | */ | ||
| 47 | /****************************************************************************/ | ||
| 48 | static inline uint32_t chipcHw_getChipId(void) | ||
| 49 | { | ||
| 50 | return pChipcHw->ChipId; | ||
| 51 | } | ||
| 52 | |||
| 53 | /****************************************************************************/ | ||
| 54 | /** | ||
| 55 | * @brief Enable Spread Spectrum | ||
| 56 | * | ||
| 57 | * @note chipcHw_Init() must be called earlier | ||
| 58 | */ | ||
| 59 | /****************************************************************************/ | ||
| 60 | static inline void chipcHw_enableSpreadSpectrum(void) | ||
| 61 | { | ||
| 62 | if ((pChipcHw-> | ||
| 63 | PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) != | ||
| 64 | chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) { | ||
| 65 | ddrcReg_PHY_ADDR_CTL_REGP->ssCfg = | ||
| 66 | (0xFFFF << ddrcReg_PHY_ADDR_SS_CFG_NDIV_AMPLITUDE_SHIFT) | | ||
| 67 | (ddrcReg_PHY_ADDR_SS_CFG_MIN_CYCLE_PER_TICK << | ||
| 68 | ddrcReg_PHY_ADDR_SS_CFG_CYCLE_PER_TICK_SHIFT); | ||
| 69 | ddrcReg_PHY_ADDR_CTL_REGP->ssCtl |= | ||
| 70 | ddrcReg_PHY_ADDR_SS_CTRL_ENABLE; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | /****************************************************************************/ | ||
| 75 | /** | ||
| 76 | * @brief Disable Spread Spectrum | ||
| 77 | * | ||
| 78 | */ | ||
| 79 | /****************************************************************************/ | ||
| 80 | static inline void chipcHw_disableSpreadSpectrum(void) | ||
| 81 | { | ||
| 82 | ddrcReg_PHY_ADDR_CTL_REGP->ssCtl &= ~ddrcReg_PHY_ADDR_SS_CTRL_ENABLE; | ||
| 83 | } | ||
| 84 | |||
| 85 | /****************************************************************************/ | ||
| 86 | /** | ||
| 87 | * @brief Get Chip Product ID | ||
| 88 | * | ||
| 89 | * This function returns Chip Product ID | ||
| 90 | * | ||
| 91 | * @return Chip Product ID | ||
| 92 | */ | ||
| 93 | /****************************************************************************/ | ||
| 94 | static inline uint32_t chipcHw_getChipProductId(void) | ||
| 95 | { | ||
| 96 | return (pChipcHw-> | ||
| 97 | ChipId & chipcHw_REG_CHIPID_BASE_MASK) >> | ||
| 98 | chipcHw_REG_CHIPID_BASE_SHIFT; | ||
| 99 | } | ||
| 100 | |||
| 101 | /****************************************************************************/ | ||
| 102 | /** | ||
| 103 | * @brief Get revision number | ||
| 104 | * | ||
| 105 | * This function returns revision number of the chip | ||
| 106 | * | ||
| 107 | * @return Revision number | ||
| 108 | */ | ||
| 109 | /****************************************************************************/ | ||
| 110 | static inline chipcHw_REV_NUMBER_e chipcHw_getChipRevisionNumber(void) | ||
| 111 | { | ||
| 112 | return pChipcHw->ChipId & chipcHw_REG_CHIPID_REV_MASK; | ||
| 113 | } | ||
| 114 | |||
| 115 | /****************************************************************************/ | ||
| 116 | /** | ||
| 117 | * @brief Enables bus interface clock | ||
| 118 | * | ||
| 119 | * Enables bus interface clock of various device | ||
| 120 | * | ||
| 121 | * @return void | ||
| 122 | * | ||
| 123 | * @note use chipcHw_REG_BUS_CLOCK_XXXX for mask | ||
| 124 | */ | ||
| 125 | /****************************************************************************/ | ||
| 126 | static inline void chipcHw_busInterfaceClockEnable(uint32_t mask) | ||
| 127 | { | ||
| 128 | reg32_modify_or(&pChipcHw->BusIntfClock, mask); | ||
| 129 | } | ||
| 130 | |||
| 131 | /****************************************************************************/ | ||
| 132 | /** | ||
| 133 | * @brief Disables bus interface clock | ||
| 134 | * | ||
| 135 | * Disables bus interface clock of various device | ||
| 136 | * | ||
| 137 | * @return void | ||
| 138 | * | ||
| 139 | * @note use chipcHw_REG_BUS_CLOCK_XXXX | ||
| 140 | */ | ||
| 141 | /****************************************************************************/ | ||
| 142 | static inline void chipcHw_busInterfaceClockDisable(uint32_t mask) | ||
| 143 | { | ||
| 144 | reg32_modify_and(&pChipcHw->BusIntfClock, ~mask); | ||
| 145 | } | ||
| 146 | |||
| 147 | /****************************************************************************/ | ||
| 148 | /** | ||
| 149 | * @brief Get status (enabled/disabled) of bus interface clock | ||
| 150 | * | ||
| 151 | * This function returns the status of devices' bus interface clock | ||
| 152 | * | ||
| 153 | * @return Bus interface clock | ||
| 154 | * | ||
| 155 | */ | ||
| 156 | /****************************************************************************/ | ||
| 157 | static inline uint32_t chipcHw_getBusInterfaceClockStatus(void) | ||
| 158 | { | ||
| 159 | return pChipcHw->BusIntfClock; | ||
| 160 | } | ||
| 161 | |||
| 162 | /****************************************************************************/ | ||
| 163 | /** | ||
| 164 | * @brief Enables various audio channels | ||
| 165 | * | ||
| 166 | * Enables audio channel | ||
| 167 | * | ||
| 168 | * @return void | ||
| 169 | * | ||
| 170 | * @note use chipcHw_REG_AUDIO_CHANNEL_XXXXXX | ||
| 171 | */ | ||
| 172 | /****************************************************************************/ | ||
| 173 | static inline void chipcHw_audioChannelEnable(uint32_t mask) | ||
| 174 | { | ||
| 175 | reg32_modify_or(&pChipcHw->AudioEnable, mask); | ||
| 176 | } | ||
| 177 | |||
| 178 | /****************************************************************************/ | ||
| 179 | /** | ||
| 180 | * @brief Disables various audio channels | ||
| 181 | * | ||
| 182 | * Disables audio channel | ||
| 183 | * | ||
| 184 | * @return void | ||
| 185 | * | ||
| 186 | * @note use chipcHw_REG_AUDIO_CHANNEL_XXXXXX | ||
| 187 | */ | ||
| 188 | /****************************************************************************/ | ||
| 189 | static inline void chipcHw_audioChannelDisable(uint32_t mask) | ||
| 190 | { | ||
| 191 | reg32_modify_and(&pChipcHw->AudioEnable, ~mask); | ||
| 192 | } | ||
| 193 | |||
| 194 | /****************************************************************************/ | ||
| 195 | /** | ||
| 196 | * @brief Soft resets devices | ||
| 197 | * | ||
| 198 | * Soft resets various devices | ||
| 199 | * | ||
| 200 | * @return void | ||
| 201 | * | ||
| 202 | * @note use chipcHw_REG_SOFT_RESET_XXXXXX defines | ||
| 203 | */ | ||
| 204 | /****************************************************************************/ | ||
| 205 | static inline void chipcHw_softReset(uint64_t mask) | ||
| 206 | { | ||
| 207 | chipcHw_softResetEnable(mask); | ||
| 208 | chipcHw_softResetDisable(mask); | ||
| 209 | } | ||
| 210 | |||
| 211 | static inline void chipcHw_softResetDisable(uint64_t mask) | ||
| 212 | { | ||
| 213 | uint32_t ctrl1 = (uint32_t) mask; | ||
| 214 | uint32_t ctrl2 = (uint32_t) (mask >> 32); | ||
| 215 | |||
| 216 | /* Deassert module soft reset */ | ||
| 217 | REG_LOCAL_IRQ_SAVE; | ||
| 218 | pChipcHw->SoftReset1 ^= ctrl1; | ||
| 219 | pChipcHw->SoftReset2 ^= (ctrl2 & (~chipcHw_REG_SOFT_RESET_UNHOLD_MASK)); | ||
| 220 | REG_LOCAL_IRQ_RESTORE; | ||
| 221 | } | ||
| 222 | |||
| 223 | static inline void chipcHw_softResetEnable(uint64_t mask) | ||
| 224 | { | ||
| 225 | uint32_t ctrl1 = (uint32_t) mask; | ||
| 226 | uint32_t ctrl2 = (uint32_t) (mask >> 32); | ||
| 227 | uint32_t unhold = 0; | ||
| 228 | |||
| 229 | REG_LOCAL_IRQ_SAVE; | ||
| 230 | pChipcHw->SoftReset1 |= ctrl1; | ||
| 231 | /* Mask out unhold request bits */ | ||
| 232 | pChipcHw->SoftReset2 |= (ctrl2 & (~chipcHw_REG_SOFT_RESET_UNHOLD_MASK)); | ||
| 233 | |||
| 234 | /* Process unhold requests */ | ||
| 235 | if (ctrl2 & chipcHw_REG_SOFT_RESET_VPM_GLOBAL_UNHOLD) { | ||
| 236 | unhold = chipcHw_REG_SOFT_RESET_VPM_GLOBAL_HOLD; | ||
| 237 | } | ||
| 238 | |||
| 239 | if (ctrl2 & chipcHw_REG_SOFT_RESET_VPM_UNHOLD) { | ||
| 240 | unhold |= chipcHw_REG_SOFT_RESET_VPM_HOLD; | ||
| 241 | } | ||
| 242 | |||
| 243 | if (ctrl2 & chipcHw_REG_SOFT_RESET_ARM_UNHOLD) { | ||
| 244 | unhold |= chipcHw_REG_SOFT_RESET_ARM_HOLD; | ||
| 245 | } | ||
| 246 | |||
| 247 | if (unhold) { | ||
| 248 | /* Make sure unhold request is effective */ | ||
| 249 | pChipcHw->SoftReset1 &= ~unhold; | ||
| 250 | } | ||
| 251 | REG_LOCAL_IRQ_RESTORE; | ||
| 252 | } | ||
| 253 | |||
| 254 | /****************************************************************************/ | ||
| 255 | /** | ||
| 256 | * @brief Configures misc CHIP functionality | ||
| 257 | * | ||
| 258 | * Configures CHIP functionality | ||
| 259 | * | ||
| 260 | * @return void | ||
| 261 | * | ||
| 262 | * @note use chipcHw_REG_MISC_CTRL_XXXXXX | ||
| 263 | */ | ||
| 264 | /****************************************************************************/ | ||
| 265 | static inline void chipcHw_miscControl(uint32_t mask) | ||
| 266 | { | ||
| 267 | reg32_write(&pChipcHw->MiscCtrl, mask); | ||
| 268 | } | ||
| 269 | |||
| 270 | static inline void chipcHw_miscControlDisable(uint32_t mask) | ||
| 271 | { | ||
| 272 | reg32_modify_and(&pChipcHw->MiscCtrl, ~mask); | ||
| 273 | } | ||
| 274 | |||
| 275 | static inline void chipcHw_miscControlEnable(uint32_t mask) | ||
| 276 | { | ||
| 277 | reg32_modify_or(&pChipcHw->MiscCtrl, mask); | ||
| 278 | } | ||
| 279 | |||
| 280 | /****************************************************************************/ | ||
| 281 | /** | ||
| 282 | * @brief Set OTP options | ||
| 283 | * | ||
| 284 | * Set OTP options | ||
| 285 | * | ||
| 286 | * @return void | ||
| 287 | * | ||
| 288 | * @note use chipcHw_REG_OTP_XXXXXX | ||
| 289 | */ | ||
| 290 | /****************************************************************************/ | ||
| 291 | static inline void chipcHw_setOTPOption(uint64_t mask) | ||
| 292 | { | ||
| 293 | uint32_t ctrl1 = (uint32_t) mask; | ||
| 294 | uint32_t ctrl2 = (uint32_t) (mask >> 32); | ||
| 295 | |||
| 296 | reg32_modify_or(&pChipcHw->SoftOTP1, ctrl1); | ||
| 297 | reg32_modify_or(&pChipcHw->SoftOTP2, ctrl2); | ||
| 298 | } | ||
| 299 | |||
| 300 | /****************************************************************************/ | ||
| 301 | /** | ||
| 302 | * @brief Get sticky bits | ||
| 303 | * | ||
| 304 | * @return Sticky bit options of type chipcHw_REG_STICKY_XXXXXX | ||
| 305 | * | ||
| 306 | */ | ||
| 307 | /****************************************************************************/ | ||
| 308 | static inline uint32_t chipcHw_getStickyBits(void) | ||
| 309 | { | ||
| 310 | return pChipcHw->Sticky; | ||
| 311 | } | ||
| 312 | |||
| 313 | /****************************************************************************/ | ||
| 314 | /** | ||
| 315 | * @brief Set sticky bits | ||
| 316 | * | ||
| 317 | * @return void | ||
| 318 | * | ||
| 319 | * @note use chipcHw_REG_STICKY_XXXXXX | ||
| 320 | */ | ||
| 321 | /****************************************************************************/ | ||
| 322 | static inline void chipcHw_setStickyBits(uint32_t mask) | ||
| 323 | { | ||
| 324 | uint32_t bits = 0; | ||
| 325 | |||
| 326 | REG_LOCAL_IRQ_SAVE; | ||
| 327 | if (mask & chipcHw_REG_STICKY_POR_BROM) { | ||
| 328 | bits |= chipcHw_REG_STICKY_POR_BROM; | ||
| 329 | } else { | ||
| 330 | uint32_t sticky; | ||
| 331 | sticky = pChipcHw->Sticky; | ||
| 332 | |||
| 333 | if ((mask & chipcHw_REG_STICKY_BOOT_DONE) | ||
| 334 | && (sticky & chipcHw_REG_STICKY_BOOT_DONE) == 0) { | ||
| 335 | bits |= chipcHw_REG_STICKY_BOOT_DONE; | ||
| 336 | } | ||
| 337 | if ((mask & chipcHw_REG_STICKY_GENERAL_1) | ||
| 338 | && (sticky & chipcHw_REG_STICKY_GENERAL_1) == 0) { | ||
| 339 | bits |= chipcHw_REG_STICKY_GENERAL_1; | ||
| 340 | } | ||
| 341 | if ((mask & chipcHw_REG_STICKY_GENERAL_2) | ||
| 342 | && (sticky & chipcHw_REG_STICKY_GENERAL_2) == 0) { | ||
| 343 | bits |= chipcHw_REG_STICKY_GENERAL_2; | ||
| 344 | } | ||
| 345 | if ((mask & chipcHw_REG_STICKY_GENERAL_3) | ||
| 346 | && (sticky & chipcHw_REG_STICKY_GENERAL_3) == 0) { | ||
| 347 | bits |= chipcHw_REG_STICKY_GENERAL_3; | ||
| 348 | } | ||
| 349 | if ((mask & chipcHw_REG_STICKY_GENERAL_4) | ||
| 350 | && (sticky & chipcHw_REG_STICKY_GENERAL_4) == 0) { | ||
| 351 | bits |= chipcHw_REG_STICKY_GENERAL_4; | ||
| 352 | } | ||
| 353 | if ((mask & chipcHw_REG_STICKY_GENERAL_5) | ||
| 354 | && (sticky & chipcHw_REG_STICKY_GENERAL_5) == 0) { | ||
| 355 | bits |= chipcHw_REG_STICKY_GENERAL_5; | ||
| 356 | } | ||
| 357 | } | ||
| 358 | pChipcHw->Sticky = bits; | ||
| 359 | REG_LOCAL_IRQ_RESTORE; | ||
| 360 | } | ||
| 361 | |||
| 362 | /****************************************************************************/ | ||
| 363 | /** | ||
| 364 | * @brief Clear sticky bits | ||
| 365 | * | ||
| 366 | * @return void | ||
| 367 | * | ||
| 368 | * @note use chipcHw_REG_STICKY_XXXXXX | ||
| 369 | */ | ||
| 370 | /****************************************************************************/ | ||
| 371 | static inline void chipcHw_clearStickyBits(uint32_t mask) | ||
| 372 | { | ||
| 373 | uint32_t bits = 0; | ||
| 374 | |||
| 375 | REG_LOCAL_IRQ_SAVE; | ||
| 376 | if (mask & | ||
| 377 | (chipcHw_REG_STICKY_BOOT_DONE | chipcHw_REG_STICKY_GENERAL_1 | | ||
| 378 | chipcHw_REG_STICKY_GENERAL_2 | chipcHw_REG_STICKY_GENERAL_3 | | ||
| 379 | chipcHw_REG_STICKY_GENERAL_4 | chipcHw_REG_STICKY_GENERAL_5)) { | ||
| 380 | uint32_t sticky = pChipcHw->Sticky; | ||
| 381 | |||
| 382 | if ((mask & chipcHw_REG_STICKY_BOOT_DONE) | ||
| 383 | && (sticky & chipcHw_REG_STICKY_BOOT_DONE)) { | ||
| 384 | bits = chipcHw_REG_STICKY_BOOT_DONE; | ||
| 385 | mask &= ~chipcHw_REG_STICKY_BOOT_DONE; | ||
| 386 | } | ||
| 387 | if ((mask & chipcHw_REG_STICKY_GENERAL_1) | ||
| 388 | && (sticky & chipcHw_REG_STICKY_GENERAL_1)) { | ||
| 389 | bits |= chipcHw_REG_STICKY_GENERAL_1; | ||
| 390 | mask &= ~chipcHw_REG_STICKY_GENERAL_1; | ||
| 391 | } | ||
| 392 | if ((mask & chipcHw_REG_STICKY_GENERAL_2) | ||
| 393 | && (sticky & chipcHw_REG_STICKY_GENERAL_2)) { | ||
| 394 | bits |= chipcHw_REG_STICKY_GENERAL_2; | ||
| 395 | mask &= ~chipcHw_REG_STICKY_GENERAL_2; | ||
| 396 | } | ||
| 397 | if ((mask & chipcHw_REG_STICKY_GENERAL_3) | ||
| 398 | && (sticky & chipcHw_REG_STICKY_GENERAL_3)) { | ||
| 399 | bits |= chipcHw_REG_STICKY_GENERAL_3; | ||
| 400 | mask &= ~chipcHw_REG_STICKY_GENERAL_3; | ||
| 401 | } | ||
| 402 | if ((mask & chipcHw_REG_STICKY_GENERAL_4) | ||
| 403 | && (sticky & chipcHw_REG_STICKY_GENERAL_4)) { | ||
| 404 | bits |= chipcHw_REG_STICKY_GENERAL_4; | ||
| 405 | mask &= ~chipcHw_REG_STICKY_GENERAL_4; | ||
| 406 | } | ||
| 407 | if ((mask & chipcHw_REG_STICKY_GENERAL_5) | ||
| 408 | && (sticky & chipcHw_REG_STICKY_GENERAL_5)) { | ||
| 409 | bits |= chipcHw_REG_STICKY_GENERAL_5; | ||
| 410 | mask &= ~chipcHw_REG_STICKY_GENERAL_5; | ||
| 411 | } | ||
| 412 | } | ||
| 413 | pChipcHw->Sticky = bits | mask; | ||
| 414 | REG_LOCAL_IRQ_RESTORE; | ||
| 415 | } | ||
| 416 | |||
| 417 | /****************************************************************************/ | ||
| 418 | /** | ||
| 419 | * @brief Get software strap value | ||
| 420 | * | ||
| 421 | * Retrieves software strap value | ||
| 422 | * | ||
| 423 | * @return Software strap value | ||
| 424 | * | ||
| 425 | */ | ||
| 426 | /****************************************************************************/ | ||
| 427 | static inline uint32_t chipcHw_getSoftStraps(void) | ||
| 428 | { | ||
| 429 | return pChipcHw->SoftStraps; | ||
| 430 | } | ||
| 431 | |||
| 432 | /****************************************************************************/ | ||
| 433 | /** | ||
| 434 | * @brief Set software override strap options | ||
| 435 | * | ||
| 436 | * set software override strap options | ||
| 437 | * | ||
| 438 | * @return nothing | ||
| 439 | * | ||
| 440 | */ | ||
| 441 | /****************************************************************************/ | ||
| 442 | static inline void chipcHw_setSoftStraps(uint32_t strapOptions) | ||
| 443 | { | ||
| 444 | reg32_write(&pChipcHw->SoftStraps, strapOptions); | ||
| 445 | } | ||
| 446 | |||
| 447 | /****************************************************************************/ | ||
| 448 | /** | ||
| 449 | * @brief Get Pin Strap Options | ||
| 450 | * | ||
| 451 | * This function returns the raw boot strap options | ||
| 452 | * | ||
| 453 | * @return strap options | ||
| 454 | * | ||
| 455 | */ | ||
| 456 | /****************************************************************************/ | ||
| 457 | static inline uint32_t chipcHw_getPinStraps(void) | ||
| 458 | { | ||
| 459 | return pChipcHw->PinStraps; | ||
| 460 | } | ||
| 461 | |||
| 462 | /****************************************************************************/ | ||
| 463 | /** | ||
| 464 | * @brief Get Valid Strap Options | ||
| 465 | * | ||
| 466 | * This function returns the valid raw boot strap options | ||
| 467 | * | ||
| 468 | * @return strap options | ||
| 469 | * | ||
| 470 | */ | ||
| 471 | /****************************************************************************/ | ||
| 472 | static inline uint32_t chipcHw_getValidStraps(void) | ||
| 473 | { | ||
| 474 | uint32_t softStraps; | ||
| 475 | |||
| 476 | /* | ||
| 477 | ** Always return the SoftStraps - bootROM calls chipcHw_initValidStraps | ||
| 478 | ** which copies HW straps to soft straps if there is no override | ||
| 479 | */ | ||
| 480 | softStraps = chipcHw_getSoftStraps(); | ||
| 481 | |||
| 482 | return softStraps; | ||
| 483 | } | ||
| 484 | |||
| 485 | /****************************************************************************/ | ||
| 486 | /** | ||
| 487 | * @brief Initialize valid pin strap options | ||
| 488 | * | ||
| 489 | * Retrieves valid pin strap options by copying HW strap options to soft register | ||
| 490 | * (if chipcHw_STRAPS_SOFT_OVERRIDE not set) | ||
| 491 | * | ||
| 492 | * @return nothing | ||
| 493 | * | ||
| 494 | */ | ||
| 495 | /****************************************************************************/ | ||
| 496 | static inline void chipcHw_initValidStraps(void) | ||
| 497 | { | ||
| 498 | uint32_t softStraps; | ||
| 499 | |||
| 500 | REG_LOCAL_IRQ_SAVE; | ||
| 501 | softStraps = chipcHw_getSoftStraps(); | ||
| 502 | |||
| 503 | if ((softStraps & chipcHw_STRAPS_SOFT_OVERRIDE) == 0) { | ||
| 504 | /* Copy HW straps to software straps */ | ||
| 505 | chipcHw_setSoftStraps(chipcHw_getPinStraps()); | ||
| 506 | } | ||
| 507 | REG_LOCAL_IRQ_RESTORE; | ||
| 508 | } | ||
| 509 | |||
| 510 | /****************************************************************************/ | ||
| 511 | /** | ||
| 512 | * @brief Get boot device | ||
| 513 | * | ||
| 514 | * This function returns the device type used in booting the system | ||
| 515 | * | ||
| 516 | * @return Boot device of type chipcHw_BOOT_DEVICE | ||
| 517 | * | ||
| 518 | */ | ||
| 519 | /****************************************************************************/ | ||
| 520 | static inline chipcHw_BOOT_DEVICE_e chipcHw_getBootDevice(void) | ||
| 521 | { | ||
| 522 | return chipcHw_getValidStraps() & chipcHw_STRAPS_BOOT_DEVICE_MASK; | ||
| 523 | } | ||
| 524 | |||
| 525 | /****************************************************************************/ | ||
| 526 | /** | ||
| 527 | * @brief Get boot mode | ||
| 528 | * | ||
| 529 | * This function returns the way the system was booted | ||
| 530 | * | ||
| 531 | * @return Boot mode of type chipcHw_BOOT_MODE | ||
| 532 | * | ||
| 533 | */ | ||
| 534 | /****************************************************************************/ | ||
| 535 | static inline chipcHw_BOOT_MODE_e chipcHw_getBootMode(void) | ||
| 536 | { | ||
| 537 | return chipcHw_getValidStraps() & chipcHw_STRAPS_BOOT_MODE_MASK; | ||
| 538 | } | ||
| 539 | |||
| 540 | /****************************************************************************/ | ||
| 541 | /** | ||
| 542 | * @brief Get NAND flash page size | ||
| 543 | * | ||
| 544 | * This function returns the NAND device page size | ||
| 545 | * | ||
| 546 | * @return Boot NAND device page size | ||
| 547 | * | ||
| 548 | */ | ||
| 549 | /****************************************************************************/ | ||
| 550 | static inline chipcHw_NAND_PAGESIZE_e chipcHw_getNandPageSize(void) | ||
| 551 | { | ||
| 552 | return chipcHw_getValidStraps() & chipcHw_STRAPS_NAND_PAGESIZE_MASK; | ||
| 553 | } | ||
| 554 | |||
| 555 | /****************************************************************************/ | ||
| 556 | /** | ||
| 557 | * @brief Get NAND flash address cycle configuration | ||
| 558 | * | ||
| 559 | * This function returns the NAND flash address cycle configuration | ||
| 560 | * | ||
| 561 | * @return 0 = Do not extra address cycle, 1 = Add extra cycle | ||
| 562 | * | ||
| 563 | */ | ||
| 564 | /****************************************************************************/ | ||
| 565 | static inline int chipcHw_getNandExtraCycle(void) | ||
| 566 | { | ||
| 567 | if (chipcHw_getValidStraps() & chipcHw_STRAPS_NAND_EXTRA_CYCLE) { | ||
| 568 | return 1; | ||
| 569 | } else { | ||
| 570 | return 0; | ||
| 571 | } | ||
| 572 | } | ||
| 573 | |||
| 574 | /****************************************************************************/ | ||
| 575 | /** | ||
| 576 | * @brief Activates PIF interface | ||
| 577 | * | ||
| 578 | * This function activates PIF interface by taking control of LCD pins | ||
| 579 | * | ||
| 580 | * @note | ||
| 581 | * When activated, LCD pins will be defined as follows for PIF operation | ||
| 582 | * | ||
| 583 | * CLD[17:0] = pif_data[17:0] | ||
| 584 | * CLD[23:18] = pif_address[5:0] | ||
| 585 | * CLPOWER = pif_wr_str | ||
| 586 | * CLCP = pif_rd_str | ||
| 587 | * CLAC = pif_hat1 | ||
| 588 | * CLFP = pif_hrdy1 | ||
| 589 | * CLLP = pif_hat2 | ||
| 590 | * GPIO[42] = pif_hrdy2 | ||
| 591 | * | ||
| 592 | * In PIF mode, "pif_hrdy2" overrides other shared function for GPIO[42] pin | ||
| 593 | * | ||
| 594 | */ | ||
| 595 | /****************************************************************************/ | ||
| 596 | static inline void chipcHw_activatePifInterface(void) | ||
| 597 | { | ||
| 598 | reg32_write(&pChipcHw->LcdPifMode, chipcHw_REG_PIF_PIN_ENABLE); | ||
| 599 | } | ||
| 600 | |||
| 601 | /****************************************************************************/ | ||
| 602 | /** | ||
| 603 | * @brief Activates LCD interface | ||
| 604 | * | ||
| 605 | * This function activates LCD interface | ||
| 606 | * | ||
| 607 | * @note | ||
| 608 | * When activated, LCD pins will be defined as follows | ||
| 609 | * | ||
| 610 | * CLD[17:0] = LCD data | ||
| 611 | * CLD[23:18] = LCD data | ||
| 612 | * CLPOWER = LCD power | ||
| 613 | * CLCP = | ||
| 614 | * CLAC = LCD ack | ||
| 615 | * CLFP = | ||
| 616 | * CLLP = | ||
| 617 | */ | ||
| 618 | /****************************************************************************/ | ||
| 619 | static inline void chipcHw_activateLcdInterface(void) | ||
| 620 | { | ||
| 621 | reg32_write(&pChipcHw->LcdPifMode, chipcHw_REG_LCD_PIN_ENABLE); | ||
| 622 | } | ||
| 623 | |||
| 624 | /****************************************************************************/ | ||
| 625 | /** | ||
| 626 | * @brief Deactivates PIF/LCD interface | ||
| 627 | * | ||
| 628 | * This function deactivates PIF/LCD interface | ||
| 629 | * | ||
| 630 | * @note | ||
| 631 | * When deactivated LCD pins will be in rti-stated | ||
| 632 | * | ||
| 633 | */ | ||
| 634 | /****************************************************************************/ | ||
| 635 | static inline void chipcHw_deactivatePifLcdInterface(void) | ||
| 636 | { | ||
| 637 | reg32_write(&pChipcHw->LcdPifMode, 0); | ||
| 638 | } | ||
| 639 | |||
| 640 | /****************************************************************************/ | ||
| 641 | /** | ||
| 642 | * @brief Select GE2 | ||
| 643 | * | ||
| 644 | * This function select GE2 as the graphic engine | ||
| 645 | * | ||
| 646 | */ | ||
| 647 | /****************************************************************************/ | ||
| 648 | static inline void chipcHw_selectGE2(void) | ||
| 649 | { | ||
| 650 | reg32_modify_and(&pChipcHw->MiscCtrl, ~chipcHw_REG_MISC_CTRL_GE_SEL); | ||
| 651 | } | ||
| 652 | |||
| 653 | /****************************************************************************/ | ||
| 654 | /** | ||
| 655 | * @brief Select GE3 | ||
| 656 | * | ||
| 657 | * This function select GE3 as the graphic engine | ||
| 658 | * | ||
| 659 | */ | ||
| 660 | /****************************************************************************/ | ||
| 661 | static inline void chipcHw_selectGE3(void) | ||
| 662 | { | ||
| 663 | reg32_modify_or(&pChipcHw->MiscCtrl, chipcHw_REG_MISC_CTRL_GE_SEL); | ||
| 664 | } | ||
| 665 | |||
| 666 | /****************************************************************************/ | ||
| 667 | /** | ||
| 668 | * @brief Get to know the configuration of GPIO pin | ||
| 669 | * | ||
| 670 | */ | ||
| 671 | /****************************************************************************/ | ||
| 672 | static inline chipcHw_GPIO_FUNCTION_e chipcHw_getGpioPinFunction(int pin) | ||
| 673 | { | ||
| 674 | return (*((uint32_t *) chipcHw_REG_GPIO_MUX(pin)) & | ||
| 675 | (chipcHw_REG_GPIO_MUX_MASK << | ||
| 676 | chipcHw_REG_GPIO_MUX_POSITION(pin))) >> | ||
| 677 | chipcHw_REG_GPIO_MUX_POSITION(pin); | ||
| 678 | } | ||
| 679 | |||
| 680 | /****************************************************************************/ | ||
| 681 | /** | ||
| 682 | * @brief Configure GPIO pin function | ||
| 683 | * | ||
| 684 | */ | ||
| 685 | /****************************************************************************/ | ||
| 686 | static inline void chipcHw_setGpioPinFunction(int pin, | ||
| 687 | chipcHw_GPIO_FUNCTION_e func) | ||
| 688 | { | ||
| 689 | REG_LOCAL_IRQ_SAVE; | ||
| 690 | *((uint32_t *) chipcHw_REG_GPIO_MUX(pin)) &= | ||
| 691 | ~(chipcHw_REG_GPIO_MUX_MASK << chipcHw_REG_GPIO_MUX_POSITION(pin)); | ||
| 692 | *((uint32_t *) chipcHw_REG_GPIO_MUX(pin)) |= | ||
| 693 | func << chipcHw_REG_GPIO_MUX_POSITION(pin); | ||
| 694 | REG_LOCAL_IRQ_RESTORE; | ||
| 695 | } | ||
| 696 | |||
| 697 | /****************************************************************************/ | ||
| 698 | /** | ||
| 699 | * @brief Set Pin slew rate | ||
| 700 | * | ||
| 701 | * This function sets the slew of individual pin | ||
| 702 | * | ||
| 703 | */ | ||
| 704 | /****************************************************************************/ | ||
| 705 | static inline void chipcHw_setPinSlewRate(uint32_t pin, | ||
| 706 | chipcHw_PIN_SLEW_RATE_e slewRate) | ||
| 707 | { | ||
| 708 | REG_LOCAL_IRQ_SAVE; | ||
| 709 | *((uint32_t *) chipcHw_REG_SLEW_RATE(pin)) &= | ||
| 710 | ~(chipcHw_REG_SLEW_RATE_MASK << | ||
| 711 | chipcHw_REG_SLEW_RATE_POSITION(pin)); | ||
| 712 | *((uint32_t *) chipcHw_REG_SLEW_RATE(pin)) |= | ||
| 713 | (uint32_t) slewRate << chipcHw_REG_SLEW_RATE_POSITION(pin); | ||
| 714 | REG_LOCAL_IRQ_RESTORE; | ||
| 715 | } | ||
| 716 | |||
| 717 | /****************************************************************************/ | ||
| 718 | /** | ||
| 719 | * @brief Set Pin output drive current | ||
| 720 | * | ||
| 721 | * This function sets output drive current of individual pin | ||
| 722 | * | ||
| 723 | * Note: Avoid the use of the word 'current' since linux headers define this | ||
| 724 | * to be the current task. | ||
| 725 | */ | ||
| 726 | /****************************************************************************/ | ||
| 727 | static inline void chipcHw_setPinOutputCurrent(uint32_t pin, | ||
| 728 | chipcHw_PIN_CURRENT_STRENGTH_e | ||
| 729 | curr) | ||
| 730 | { | ||
| 731 | REG_LOCAL_IRQ_SAVE; | ||
| 732 | *((uint32_t *) chipcHw_REG_CURRENT(pin)) &= | ||
| 733 | ~(chipcHw_REG_CURRENT_MASK << chipcHw_REG_CURRENT_POSITION(pin)); | ||
| 734 | *((uint32_t *) chipcHw_REG_CURRENT(pin)) |= | ||
| 735 | (uint32_t) curr << chipcHw_REG_CURRENT_POSITION(pin); | ||
| 736 | REG_LOCAL_IRQ_RESTORE; | ||
| 737 | } | ||
| 738 | |||
| 739 | /****************************************************************************/ | ||
| 740 | /** | ||
| 741 | * @brief Set Pin pullup register | ||
| 742 | * | ||
| 743 | * This function sets pullup register of individual pin | ||
| 744 | * | ||
| 745 | */ | ||
| 746 | /****************************************************************************/ | ||
| 747 | static inline void chipcHw_setPinPullup(uint32_t pin, chipcHw_PIN_PULL_e pullup) | ||
| 748 | { | ||
| 749 | REG_LOCAL_IRQ_SAVE; | ||
| 750 | *((uint32_t *) chipcHw_REG_PULLUP(pin)) &= | ||
| 751 | ~(chipcHw_REG_PULLUP_MASK << chipcHw_REG_PULLUP_POSITION(pin)); | ||
| 752 | *((uint32_t *) chipcHw_REG_PULLUP(pin)) |= | ||
| 753 | (uint32_t) pullup << chipcHw_REG_PULLUP_POSITION(pin); | ||
| 754 | REG_LOCAL_IRQ_RESTORE; | ||
| 755 | } | ||
| 756 | |||
| 757 | /****************************************************************************/ | ||
| 758 | /** | ||
| 759 | * @brief Set Pin input type | ||
| 760 | * | ||
| 761 | * This function sets input type of individual pin | ||
| 762 | * | ||
| 763 | */ | ||
| 764 | /****************************************************************************/ | ||
| 765 | static inline void chipcHw_setPinInputType(uint32_t pin, | ||
| 766 | chipcHw_PIN_INPUTTYPE_e inputType) | ||
| 767 | { | ||
| 768 | REG_LOCAL_IRQ_SAVE; | ||
| 769 | *((uint32_t *) chipcHw_REG_INPUTTYPE(pin)) &= | ||
| 770 | ~(chipcHw_REG_INPUTTYPE_MASK << | ||
| 771 | chipcHw_REG_INPUTTYPE_POSITION(pin)); | ||
| 772 | *((uint32_t *) chipcHw_REG_INPUTTYPE(pin)) |= | ||
| 773 | (uint32_t) inputType << chipcHw_REG_INPUTTYPE_POSITION(pin); | ||
| 774 | REG_LOCAL_IRQ_RESTORE; | ||
| 775 | } | ||
| 776 | |||
| 777 | /****************************************************************************/ | ||
| 778 | /** | ||
| 779 | * @brief Power up the USB PHY | ||
| 780 | * | ||
| 781 | * This function powers up the USB PHY | ||
| 782 | * | ||
| 783 | */ | ||
| 784 | /****************************************************************************/ | ||
| 785 | static inline void chipcHw_powerUpUsbPhy(void) | ||
| 786 | { | ||
| 787 | reg32_modify_and(&pChipcHw->MiscCtrl, | ||
| 788 | chipcHw_REG_MISC_CTRL_USB_POWERON); | ||
| 789 | } | ||
| 790 | |||
| 791 | /****************************************************************************/ | ||
| 792 | /** | ||
| 793 | * @brief Power down the USB PHY | ||
| 794 | * | ||
| 795 | * This function powers down the USB PHY | ||
| 796 | * | ||
| 797 | */ | ||
| 798 | /****************************************************************************/ | ||
| 799 | static inline void chipcHw_powerDownUsbPhy(void) | ||
| 800 | { | ||
| 801 | reg32_modify_or(&pChipcHw->MiscCtrl, | ||
| 802 | chipcHw_REG_MISC_CTRL_USB_POWEROFF); | ||
| 803 | } | ||
| 804 | |||
| 805 | /****************************************************************************/ | ||
| 806 | /** | ||
| 807 | * @brief Set the 2nd USB as host | ||
| 808 | * | ||
| 809 | * This function sets the 2nd USB as host | ||
| 810 | * | ||
| 811 | */ | ||
| 812 | /****************************************************************************/ | ||
| 813 | static inline void chipcHw_setUsbHost(void) | ||
| 814 | { | ||
| 815 | reg32_modify_or(&pChipcHw->MiscCtrl, | ||
| 816 | chipcHw_REG_MISC_CTRL_USB_MODE_HOST); | ||
| 817 | } | ||
| 818 | |||
| 819 | /****************************************************************************/ | ||
| 820 | /** | ||
| 821 | * @brief Set the 2nd USB as device | ||
| 822 | * | ||
| 823 | * This function sets the 2nd USB as device | ||
| 824 | * | ||
| 825 | */ | ||
| 826 | /****************************************************************************/ | ||
| 827 | static inline void chipcHw_setUsbDevice(void) | ||
| 828 | { | ||
| 829 | reg32_modify_and(&pChipcHw->MiscCtrl, | ||
| 830 | chipcHw_REG_MISC_CTRL_USB_MODE_DEVICE); | ||
| 831 | } | ||
| 832 | |||
| 833 | /****************************************************************************/ | ||
| 834 | /** | ||
| 835 | * @brief Lower layer funtion to enable/disable a clock of a certain device | ||
| 836 | * | ||
| 837 | * This function enables/disables a core clock | ||
| 838 | * | ||
| 839 | */ | ||
| 840 | /****************************************************************************/ | ||
| 841 | static inline void chipcHw_setClock(chipcHw_CLOCK_e clock, | ||
| 842 | chipcHw_OPTYPE_e type, int mode) | ||
| 843 | { | ||
| 844 | volatile uint32_t *pPLLReg = (uint32_t *) 0x0; | ||
| 845 | volatile uint32_t *pClockCtrl = (uint32_t *) 0x0; | ||
| 846 | |||
| 847 | switch (clock) { | ||
| 848 | case chipcHw_CLOCK_DDR: | ||
| 849 | pPLLReg = &pChipcHw->DDRClock; | ||
| 850 | break; | ||
| 851 | case chipcHw_CLOCK_ARM: | ||
| 852 | pPLLReg = &pChipcHw->ARMClock; | ||
| 853 | break; | ||
| 854 | case chipcHw_CLOCK_ESW: | ||
| 855 | pPLLReg = &pChipcHw->ESWClock; | ||
| 856 | break; | ||
| 857 | case chipcHw_CLOCK_VPM: | ||
| 858 | pPLLReg = &pChipcHw->VPMClock; | ||
| 859 | break; | ||
| 860 | case chipcHw_CLOCK_ESW125: | ||
| 861 | pPLLReg = &pChipcHw->ESW125Clock; | ||
| 862 | break; | ||
| 863 | case chipcHw_CLOCK_UART: | ||
| 864 | pPLLReg = &pChipcHw->UARTClock; | ||
| 865 | break; | ||
| 866 | case chipcHw_CLOCK_SDIO0: | ||
| 867 | pPLLReg = &pChipcHw->SDIO0Clock; | ||
| 868 | break; | ||
| 869 | case chipcHw_CLOCK_SDIO1: | ||
| 870 | pPLLReg = &pChipcHw->SDIO1Clock; | ||
| 871 | break; | ||
| 872 | case chipcHw_CLOCK_SPI: | ||
| 873 | pPLLReg = &pChipcHw->SPIClock; | ||
| 874 | break; | ||
| 875 | case chipcHw_CLOCK_ETM: | ||
| 876 | pPLLReg = &pChipcHw->ETMClock; | ||
| 877 | break; | ||
| 878 | case chipcHw_CLOCK_USB: | ||
| 879 | pPLLReg = &pChipcHw->USBClock; | ||
| 880 | if (type == chipcHw_OPTYPE_OUTPUT) { | ||
| 881 | if (mode) { | ||
| 882 | reg32_modify_and(pPLLReg, | ||
| 883 | ~chipcHw_REG_PLL_CLOCK_POWER_DOWN); | ||
| 884 | } else { | ||
| 885 | reg32_modify_or(pPLLReg, | ||
| 886 | chipcHw_REG_PLL_CLOCK_POWER_DOWN); | ||
| 887 | } | ||
| 888 | } | ||
| 889 | break; | ||
| 890 | case chipcHw_CLOCK_LCD: | ||
| 891 | pPLLReg = &pChipcHw->LCDClock; | ||
| 892 | if (type == chipcHw_OPTYPE_OUTPUT) { | ||
| 893 | if (mode) { | ||
| 894 | reg32_modify_and(pPLLReg, | ||
| 895 | ~chipcHw_REG_PLL_CLOCK_POWER_DOWN); | ||
| 896 | } else { | ||
| 897 | reg32_modify_or(pPLLReg, | ||
| 898 | chipcHw_REG_PLL_CLOCK_POWER_DOWN); | ||
| 899 | } | ||
| 900 | } | ||
| 901 | break; | ||
| 902 | case chipcHw_CLOCK_APM: | ||
| 903 | pPLLReg = &pChipcHw->APMClock; | ||
| 904 | if (type == chipcHw_OPTYPE_OUTPUT) { | ||
| 905 | if (mode) { | ||
| 906 | reg32_modify_and(pPLLReg, | ||
| 907 | ~chipcHw_REG_PLL_CLOCK_POWER_DOWN); | ||
| 908 | } else { | ||
| 909 | reg32_modify_or(pPLLReg, | ||
| 910 | chipcHw_REG_PLL_CLOCK_POWER_DOWN); | ||
| 911 | } | ||
| 912 | } | ||
| 913 | break; | ||
| 914 | case chipcHw_CLOCK_BUS: | ||
| 915 | pClockCtrl = &pChipcHw->ACLKClock; | ||
| 916 | break; | ||
| 917 | case chipcHw_CLOCK_OTP: | ||
| 918 | pClockCtrl = &pChipcHw->OTPClock; | ||
| 919 | break; | ||
| 920 | case chipcHw_CLOCK_I2C: | ||
| 921 | pClockCtrl = &pChipcHw->I2CClock; | ||
| 922 | break; | ||
| 923 | case chipcHw_CLOCK_I2S0: | ||
| 924 | pClockCtrl = &pChipcHw->I2S0Clock; | ||
| 925 | break; | ||
| 926 | case chipcHw_CLOCK_RTBUS: | ||
| 927 | pClockCtrl = &pChipcHw->RTBUSClock; | ||
| 928 | break; | ||
| 929 | case chipcHw_CLOCK_APM100: | ||
| 930 | pClockCtrl = &pChipcHw->APM100Clock; | ||
| 931 | break; | ||
| 932 | case chipcHw_CLOCK_TSC: | ||
| 933 | pClockCtrl = &pChipcHw->TSCClock; | ||
| 934 | break; | ||
| 935 | case chipcHw_CLOCK_LED: | ||
| 936 | pClockCtrl = &pChipcHw->LEDClock; | ||
| 937 | break; | ||
| 938 | case chipcHw_CLOCK_I2S1: | ||
| 939 | pClockCtrl = &pChipcHw->I2S1Clock; | ||
| 940 | break; | ||
| 941 | } | ||
| 942 | |||
| 943 | if (pPLLReg) { | ||
| 944 | switch (type) { | ||
| 945 | case chipcHw_OPTYPE_OUTPUT: | ||
| 946 | /* PLL clock output enable/disable */ | ||
| 947 | if (mode) { | ||
| 948 | if (clock == chipcHw_CLOCK_DDR) { | ||
| 949 | /* DDR clock enable is inverted */ | ||
| 950 | reg32_modify_and(pPLLReg, | ||
| 951 | ~chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE); | ||
| 952 | } else { | ||
| 953 | reg32_modify_or(pPLLReg, | ||
| 954 | chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE); | ||
| 955 | } | ||
| 956 | } else { | ||
| 957 | if (clock == chipcHw_CLOCK_DDR) { | ||
| 958 | /* DDR clock disable is inverted */ | ||
| 959 | reg32_modify_or(pPLLReg, | ||
| 960 | chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE); | ||
| 961 | } else { | ||
| 962 | reg32_modify_and(pPLLReg, | ||
| 963 | ~chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE); | ||
| 964 | } | ||
| 965 | } | ||
| 966 | break; | ||
| 967 | case chipcHw_OPTYPE_BYPASS: | ||
| 968 | /* PLL clock bypass enable/disable */ | ||
| 969 | if (mode) { | ||
| 970 | reg32_modify_or(pPLLReg, | ||
| 971 | chipcHw_REG_PLL_CLOCK_BYPASS_SELECT); | ||
| 972 | } else { | ||
| 973 | reg32_modify_and(pPLLReg, | ||
| 974 | ~chipcHw_REG_PLL_CLOCK_BYPASS_SELECT); | ||
| 975 | } | ||
| 976 | break; | ||
| 977 | } | ||
| 978 | } else if (pClockCtrl) { | ||
| 979 | switch (type) { | ||
| 980 | case chipcHw_OPTYPE_OUTPUT: | ||
| 981 | if (mode) { | ||
| 982 | reg32_modify_or(pClockCtrl, | ||
| 983 | chipcHw_REG_DIV_CLOCK_OUTPUT_ENABLE); | ||
| 984 | } else { | ||
| 985 | reg32_modify_and(pClockCtrl, | ||
| 986 | ~chipcHw_REG_DIV_CLOCK_OUTPUT_ENABLE); | ||
| 987 | } | ||
| 988 | break; | ||
| 989 | case chipcHw_OPTYPE_BYPASS: | ||
| 990 | if (mode) { | ||
| 991 | reg32_modify_or(pClockCtrl, | ||
| 992 | chipcHw_REG_DIV_CLOCK_BYPASS_SELECT); | ||
| 993 | } else { | ||
| 994 | reg32_modify_and(pClockCtrl, | ||
| 995 | ~chipcHw_REG_DIV_CLOCK_BYPASS_SELECT); | ||
| 996 | } | ||
| 997 | break; | ||
| 998 | } | ||
| 999 | } | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | /****************************************************************************/ | ||
| 1003 | /** | ||
| 1004 | * @brief Disables a core clock of a certain device | ||
| 1005 | * | ||
| 1006 | * This function disables a core clock | ||
| 1007 | * | ||
| 1008 | * @note no change in power consumption | ||
| 1009 | */ | ||
| 1010 | /****************************************************************************/ | ||
| 1011 | static inline void chipcHw_setClockDisable(chipcHw_CLOCK_e clock) | ||
| 1012 | { | ||
| 1013 | |||
| 1014 | /* Disable output of the clock */ | ||
| 1015 | chipcHw_setClock(clock, chipcHw_OPTYPE_OUTPUT, 0); | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | /****************************************************************************/ | ||
| 1019 | /** | ||
| 1020 | * @brief Enable a core clock of a certain device | ||
| 1021 | * | ||
| 1022 | * This function enables a core clock | ||
| 1023 | * | ||
| 1024 | * @note no change in power consumption | ||
| 1025 | */ | ||
| 1026 | /****************************************************************************/ | ||
| 1027 | static inline void chipcHw_setClockEnable(chipcHw_CLOCK_e clock) | ||
| 1028 | { | ||
| 1029 | |||
| 1030 | /* Enable output of the clock */ | ||
| 1031 | chipcHw_setClock(clock, chipcHw_OPTYPE_OUTPUT, 1); | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | /****************************************************************************/ | ||
| 1035 | /** | ||
| 1036 | * @brief Enables bypass clock of a certain device | ||
| 1037 | * | ||
| 1038 | * This function enables bypass clock | ||
| 1039 | * | ||
| 1040 | * @note Doesnot affect the bus interface clock | ||
| 1041 | */ | ||
| 1042 | /****************************************************************************/ | ||
| 1043 | static inline void chipcHw_bypassClockEnable(chipcHw_CLOCK_e clock) | ||
| 1044 | { | ||
| 1045 | /* Enable bypass clock */ | ||
| 1046 | chipcHw_setClock(clock, chipcHw_OPTYPE_BYPASS, 1); | ||
| 1047 | } | ||
| 1048 | |||
| 1049 | /****************************************************************************/ | ||
| 1050 | /** | ||
| 1051 | * @brief Disabled bypass clock of a certain device | ||
| 1052 | * | ||
| 1053 | * This function disables bypass clock | ||
| 1054 | * | ||
| 1055 | * @note Doesnot affect the bus interface clock | ||
| 1056 | */ | ||
| 1057 | /****************************************************************************/ | ||
| 1058 | static inline void chipcHw_bypassClockDisable(chipcHw_CLOCK_e clock) | ||
| 1059 | { | ||
| 1060 | /* Disable bypass clock */ | ||
| 1061 | chipcHw_setClock(clock, chipcHw_OPTYPE_BYPASS, 0); | ||
| 1062 | |||
| 1063 | } | ||
| 1064 | |||
| 1065 | /****************************************************************************/ | ||
| 1066 | /** @brief Checks if software strap is enabled | ||
| 1067 | * | ||
| 1068 | * @return 1 : When enable | ||
| 1069 | * 0 : When disable | ||
| 1070 | */ | ||
| 1071 | /****************************************************************************/ | ||
| 1072 | static inline int chipcHw_isSoftwareStrapsEnable(void) | ||
| 1073 | { | ||
| 1074 | return pChipcHw->SoftStraps & 0x00000001; | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | /****************************************************************************/ | ||
| 1078 | /** @brief Enable software strap | ||
| 1079 | */ | ||
| 1080 | /****************************************************************************/ | ||
| 1081 | static inline void chipcHw_softwareStrapsEnable(void) | ||
| 1082 | { | ||
| 1083 | reg32_modify_or(&pChipcHw->SoftStraps, 0x00000001); | ||
| 1084 | } | ||
| 1085 | |||
| 1086 | /****************************************************************************/ | ||
| 1087 | /** @brief Disable software strap | ||
| 1088 | */ | ||
| 1089 | /****************************************************************************/ | ||
| 1090 | static inline void chipcHw_softwareStrapsDisable(void) | ||
| 1091 | { | ||
| 1092 | reg32_modify_and(&pChipcHw->SoftStraps, (~0x00000001)); | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | /****************************************************************************/ | ||
| 1096 | /** @brief PLL test enable | ||
| 1097 | */ | ||
| 1098 | /****************************************************************************/ | ||
| 1099 | static inline void chipcHw_pllTestEnable(void) | ||
| 1100 | { | ||
| 1101 | reg32_modify_or(&pChipcHw->PLLConfig, | ||
| 1102 | chipcHw_REG_PLL_CONFIG_TEST_ENABLE); | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | /****************************************************************************/ | ||
| 1106 | /** @brief PLL2 test enable | ||
| 1107 | */ | ||
| 1108 | /****************************************************************************/ | ||
| 1109 | static inline void chipcHw_pll2TestEnable(void) | ||
| 1110 | { | ||
| 1111 | reg32_modify_or(&pChipcHw->PLLConfig2, | ||
| 1112 | chipcHw_REG_PLL_CONFIG_TEST_ENABLE); | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | /****************************************************************************/ | ||
| 1116 | /** @brief PLL test disable | ||
| 1117 | */ | ||
| 1118 | /****************************************************************************/ | ||
| 1119 | static inline void chipcHw_pllTestDisable(void) | ||
| 1120 | { | ||
| 1121 | reg32_modify_and(&pChipcHw->PLLConfig, | ||
| 1122 | ~chipcHw_REG_PLL_CONFIG_TEST_ENABLE); | ||
| 1123 | } | ||
| 1124 | |||
| 1125 | /****************************************************************************/ | ||
| 1126 | /** @brief PLL2 test disable | ||
| 1127 | */ | ||
| 1128 | /****************************************************************************/ | ||
| 1129 | static inline void chipcHw_pll2TestDisable(void) | ||
| 1130 | { | ||
| 1131 | reg32_modify_and(&pChipcHw->PLLConfig2, | ||
| 1132 | ~chipcHw_REG_PLL_CONFIG_TEST_ENABLE); | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | /****************************************************************************/ | ||
| 1136 | /** @brief Get PLL test status | ||
| 1137 | */ | ||
| 1138 | /****************************************************************************/ | ||
| 1139 | static inline int chipcHw_isPllTestEnable(void) | ||
| 1140 | { | ||
| 1141 | return pChipcHw->PLLConfig & chipcHw_REG_PLL_CONFIG_TEST_ENABLE; | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | /****************************************************************************/ | ||
| 1145 | /** @brief Get PLL2 test status | ||
| 1146 | */ | ||
| 1147 | /****************************************************************************/ | ||
| 1148 | static inline int chipcHw_isPll2TestEnable(void) | ||
| 1149 | { | ||
| 1150 | return pChipcHw->PLLConfig2 & chipcHw_REG_PLL_CONFIG_TEST_ENABLE; | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | /****************************************************************************/ | ||
| 1154 | /** @brief PLL test select | ||
| 1155 | */ | ||
| 1156 | /****************************************************************************/ | ||
| 1157 | static inline void chipcHw_pllTestSelect(uint32_t val) | ||
| 1158 | { | ||
| 1159 | REG_LOCAL_IRQ_SAVE; | ||
| 1160 | pChipcHw->PLLConfig &= ~chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK; | ||
| 1161 | pChipcHw->PLLConfig |= | ||
| 1162 | (val) << chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT; | ||
| 1163 | REG_LOCAL_IRQ_RESTORE; | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | /****************************************************************************/ | ||
| 1167 | /** @brief PLL2 test select | ||
| 1168 | */ | ||
| 1169 | /****************************************************************************/ | ||
| 1170 | static inline void chipcHw_pll2TestSelect(uint32_t val) | ||
| 1171 | { | ||
| 1172 | |||
| 1173 | REG_LOCAL_IRQ_SAVE; | ||
| 1174 | pChipcHw->PLLConfig2 &= ~chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK; | ||
| 1175 | pChipcHw->PLLConfig2 |= | ||
| 1176 | (val) << chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT; | ||
| 1177 | REG_LOCAL_IRQ_RESTORE; | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | /****************************************************************************/ | ||
| 1181 | /** @brief Get PLL test selected option | ||
| 1182 | */ | ||
| 1183 | /****************************************************************************/ | ||
| 1184 | static inline uint8_t chipcHw_getPllTestSelected(void) | ||
| 1185 | { | ||
| 1186 | return (uint8_t) ((pChipcHw-> | ||
| 1187 | PLLConfig & chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK) | ||
| 1188 | >> chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT); | ||
| 1189 | } | ||
| 1190 | |||
| 1191 | /****************************************************************************/ | ||
| 1192 | /** @brief Get PLL2 test selected option | ||
| 1193 | */ | ||
| 1194 | /****************************************************************************/ | ||
| 1195 | static inline uint8_t chipcHw_getPll2TestSelected(void) | ||
| 1196 | { | ||
| 1197 | return (uint8_t) ((pChipcHw-> | ||
| 1198 | PLLConfig2 & chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK) | ||
| 1199 | >> chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT); | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | /****************************************************************************/ | ||
| 1203 | /** | ||
| 1204 | * @brief Disable the PLL1 | ||
| 1205 | * | ||
| 1206 | */ | ||
| 1207 | /****************************************************************************/ | ||
| 1208 | static inline void chipcHw_pll1Disable(void) | ||
| 1209 | { | ||
| 1210 | REG_LOCAL_IRQ_SAVE; | ||
| 1211 | pChipcHw->PLLConfig |= chipcHw_REG_PLL_CONFIG_POWER_DOWN; | ||
| 1212 | REG_LOCAL_IRQ_RESTORE; | ||
| 1213 | } | ||
| 1214 | |||
| 1215 | /****************************************************************************/ | ||
| 1216 | /** | ||
| 1217 | * @brief Disable the PLL2 | ||
| 1218 | * | ||
| 1219 | */ | ||
| 1220 | /****************************************************************************/ | ||
| 1221 | static inline void chipcHw_pll2Disable(void) | ||
| 1222 | { | ||
| 1223 | REG_LOCAL_IRQ_SAVE; | ||
| 1224 | pChipcHw->PLLConfig2 |= chipcHw_REG_PLL_CONFIG_POWER_DOWN; | ||
| 1225 | REG_LOCAL_IRQ_RESTORE; | ||
| 1226 | } | ||
| 1227 | |||
| 1228 | /****************************************************************************/ | ||
| 1229 | /** | ||
| 1230 | * @brief Enables DDR SW phase alignment interrupt | ||
| 1231 | */ | ||
| 1232 | /****************************************************************************/ | ||
| 1233 | static inline void chipcHw_ddrPhaseAlignInterruptEnable(void) | ||
| 1234 | { | ||
| 1235 | REG_LOCAL_IRQ_SAVE; | ||
| 1236 | pChipcHw->Spare1 |= chipcHw_REG_SPARE1_DDR_PHASE_INTR_ENABLE; | ||
| 1237 | REG_LOCAL_IRQ_RESTORE; | ||
| 1238 | } | ||
| 1239 | |||
| 1240 | /****************************************************************************/ | ||
| 1241 | /** | ||
| 1242 | * @brief Disables DDR SW phase alignment interrupt | ||
| 1243 | */ | ||
| 1244 | /****************************************************************************/ | ||
| 1245 | static inline void chipcHw_ddrPhaseAlignInterruptDisable(void) | ||
| 1246 | { | ||
| 1247 | REG_LOCAL_IRQ_SAVE; | ||
| 1248 | pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_DDR_PHASE_INTR_ENABLE; | ||
| 1249 | REG_LOCAL_IRQ_RESTORE; | ||
| 1250 | } | ||
| 1251 | |||
| 1252 | /****************************************************************************/ | ||
| 1253 | /** | ||
| 1254 | * @brief Set VPM SW phase alignment interrupt mode | ||
| 1255 | * | ||
| 1256 | * This function sets VPM phase alignment interrupt | ||
| 1257 | */ | ||
| 1258 | /****************************************************************************/ | ||
| 1259 | static inline void | ||
| 1260 | chipcHw_vpmPhaseAlignInterruptMode(chipcHw_VPM_HW_PHASE_INTR_e mode) | ||
| 1261 | { | ||
| 1262 | REG_LOCAL_IRQ_SAVE; | ||
| 1263 | if (mode == chipcHw_VPM_HW_PHASE_INTR_DISABLE) { | ||
| 1264 | pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_PHASE_INTR_ENABLE; | ||
| 1265 | } else { | ||
| 1266 | pChipcHw->Spare1 |= chipcHw_REG_SPARE1_VPM_PHASE_INTR_ENABLE; | ||
| 1267 | } | ||
| 1268 | pChipcHw->VPMPhaseCtrl2 = | ||
| 1269 | (pChipcHw-> | ||
| 1270 | VPMPhaseCtrl2 & ~(chipcHw_REG_VPM_INTR_SELECT_MASK << | ||
| 1271 | chipcHw_REG_VPM_INTR_SELECT_SHIFT)) | mode; | ||
| 1272 | REG_LOCAL_IRQ_RESTORE; | ||
| 1273 | } | ||
| 1274 | |||
| 1275 | /****************************************************************************/ | ||
| 1276 | /** | ||
| 1277 | * @brief Enable DDR phase alignment in software | ||
| 1278 | * | ||
| 1279 | */ | ||
| 1280 | /****************************************************************************/ | ||
| 1281 | static inline void chipcHw_ddrSwPhaseAlignEnable(void) | ||
| 1282 | { | ||
| 1283 | REG_LOCAL_IRQ_SAVE; | ||
| 1284 | pChipcHw->DDRPhaseCtrl1 |= chipcHw_REG_DDR_SW_PHASE_CTRL_ENABLE; | ||
| 1285 | REG_LOCAL_IRQ_RESTORE; | ||
| 1286 | } | ||
| 1287 | |||
| 1288 | /****************************************************************************/ | ||
| 1289 | /** | ||
| 1290 | * @brief Disable DDR phase alignment in software | ||
| 1291 | * | ||
| 1292 | */ | ||
| 1293 | /****************************************************************************/ | ||
| 1294 | static inline void chipcHw_ddrSwPhaseAlignDisable(void) | ||
| 1295 | { | ||
| 1296 | REG_LOCAL_IRQ_SAVE; | ||
| 1297 | pChipcHw->DDRPhaseCtrl1 &= ~chipcHw_REG_DDR_SW_PHASE_CTRL_ENABLE; | ||
| 1298 | REG_LOCAL_IRQ_RESTORE; | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | /****************************************************************************/ | ||
| 1302 | /** | ||
| 1303 | * @brief Enable DDR phase alignment in hardware | ||
| 1304 | * | ||
| 1305 | */ | ||
| 1306 | /****************************************************************************/ | ||
| 1307 | static inline void chipcHw_ddrHwPhaseAlignEnable(void) | ||
| 1308 | { | ||
| 1309 | REG_LOCAL_IRQ_SAVE; | ||
| 1310 | pChipcHw->DDRPhaseCtrl1 |= chipcHw_REG_DDR_HW_PHASE_CTRL_ENABLE; | ||
| 1311 | REG_LOCAL_IRQ_RESTORE; | ||
| 1312 | } | ||
| 1313 | |||
| 1314 | /****************************************************************************/ | ||
| 1315 | /** | ||
| 1316 | * @brief Disable DDR phase alignment in hardware | ||
| 1317 | * | ||
| 1318 | */ | ||
| 1319 | /****************************************************************************/ | ||
| 1320 | static inline void chipcHw_ddrHwPhaseAlignDisable(void) | ||
| 1321 | { | ||
| 1322 | REG_LOCAL_IRQ_SAVE; | ||
| 1323 | pChipcHw->DDRPhaseCtrl1 &= ~chipcHw_REG_DDR_HW_PHASE_CTRL_ENABLE; | ||
| 1324 | REG_LOCAL_IRQ_RESTORE; | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | /****************************************************************************/ | ||
| 1328 | /** | ||
| 1329 | * @brief Enable VPM phase alignment in software | ||
| 1330 | * | ||
| 1331 | */ | ||
| 1332 | /****************************************************************************/ | ||
| 1333 | static inline void chipcHw_vpmSwPhaseAlignEnable(void) | ||
| 1334 | { | ||
| 1335 | REG_LOCAL_IRQ_SAVE; | ||
| 1336 | pChipcHw->VPMPhaseCtrl1 |= chipcHw_REG_VPM_SW_PHASE_CTRL_ENABLE; | ||
| 1337 | REG_LOCAL_IRQ_RESTORE; | ||
| 1338 | } | ||
| 1339 | |||
| 1340 | /****************************************************************************/ | ||
| 1341 | /** | ||
| 1342 | * @brief Disable VPM phase alignment in software | ||
| 1343 | * | ||
| 1344 | */ | ||
| 1345 | /****************************************************************************/ | ||
| 1346 | static inline void chipcHw_vpmSwPhaseAlignDisable(void) | ||
| 1347 | { | ||
| 1348 | REG_LOCAL_IRQ_SAVE; | ||
| 1349 | pChipcHw->VPMPhaseCtrl1 &= ~chipcHw_REG_VPM_SW_PHASE_CTRL_ENABLE; | ||
| 1350 | REG_LOCAL_IRQ_RESTORE; | ||
| 1351 | } | ||
| 1352 | |||
| 1353 | /****************************************************************************/ | ||
| 1354 | /** | ||
| 1355 | * @brief Enable VPM phase alignment in hardware | ||
| 1356 | * | ||
| 1357 | */ | ||
| 1358 | /****************************************************************************/ | ||
| 1359 | static inline void chipcHw_vpmHwPhaseAlignEnable(void) | ||
| 1360 | { | ||
| 1361 | REG_LOCAL_IRQ_SAVE; | ||
| 1362 | pChipcHw->VPMPhaseCtrl1 |= chipcHw_REG_VPM_HW_PHASE_CTRL_ENABLE; | ||
| 1363 | REG_LOCAL_IRQ_RESTORE; | ||
| 1364 | } | ||
| 1365 | |||
| 1366 | /****************************************************************************/ | ||
| 1367 | /** | ||
| 1368 | * @brief Disable VPM phase alignment in hardware | ||
| 1369 | * | ||
| 1370 | */ | ||
| 1371 | /****************************************************************************/ | ||
| 1372 | static inline void chipcHw_vpmHwPhaseAlignDisable(void) | ||
| 1373 | { | ||
| 1374 | REG_LOCAL_IRQ_SAVE; | ||
| 1375 | pChipcHw->VPMPhaseCtrl1 &= ~chipcHw_REG_VPM_HW_PHASE_CTRL_ENABLE; | ||
| 1376 | REG_LOCAL_IRQ_RESTORE; | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | /****************************************************************************/ | ||
| 1380 | /** | ||
| 1381 | * @brief Set DDR phase alignment margin in hardware | ||
| 1382 | * | ||
| 1383 | */ | ||
| 1384 | /****************************************************************************/ | ||
| 1385 | static inline void | ||
| 1386 | chipcHw_setDdrHwPhaseAlignMargin(chipcHw_DDR_HW_PHASE_MARGIN_e margin) | ||
| 1387 | { | ||
| 1388 | uint32_t ge = 0; | ||
| 1389 | uint32_t le = 0; | ||
| 1390 | |||
| 1391 | switch (margin) { | ||
| 1392 | case chipcHw_DDR_HW_PHASE_MARGIN_STRICT: | ||
| 1393 | ge = 0x0F; | ||
| 1394 | le = 0x0F; | ||
| 1395 | break; | ||
| 1396 | case chipcHw_DDR_HW_PHASE_MARGIN_MEDIUM: | ||
| 1397 | ge = 0x03; | ||
| 1398 | le = 0x3F; | ||
| 1399 | break; | ||
| 1400 | case chipcHw_DDR_HW_PHASE_MARGIN_WIDE: | ||
| 1401 | ge = 0x01; | ||
| 1402 | le = 0x7F; | ||
| 1403 | break; | ||
| 1404 | } | ||
| 1405 | |||
| 1406 | { | ||
| 1407 | REG_LOCAL_IRQ_SAVE; | ||
| 1408 | |||
| 1409 | pChipcHw->DDRPhaseCtrl1 &= | ||
| 1410 | ~((chipcHw_REG_DDR_PHASE_VALUE_GE_MASK << | ||
| 1411 | chipcHw_REG_DDR_PHASE_VALUE_GE_SHIFT) | ||
| 1412 | || (chipcHw_REG_DDR_PHASE_VALUE_LE_MASK << | ||
| 1413 | chipcHw_REG_DDR_PHASE_VALUE_LE_SHIFT)); | ||
| 1414 | |||
| 1415 | pChipcHw->DDRPhaseCtrl1 |= | ||
| 1416 | ((ge << chipcHw_REG_DDR_PHASE_VALUE_GE_SHIFT) | ||
| 1417 | || (le << chipcHw_REG_DDR_PHASE_VALUE_LE_SHIFT)); | ||
| 1418 | |||
| 1419 | REG_LOCAL_IRQ_RESTORE; | ||
| 1420 | } | ||
| 1421 | } | ||
| 1422 | |||
| 1423 | /****************************************************************************/ | ||
| 1424 | /** | ||
| 1425 | * @brief Set VPM phase alignment margin in hardware | ||
| 1426 | * | ||
| 1427 | */ | ||
| 1428 | /****************************************************************************/ | ||
| 1429 | static inline void | ||
| 1430 | chipcHw_setVpmHwPhaseAlignMargin(chipcHw_VPM_HW_PHASE_MARGIN_e margin) | ||
| 1431 | { | ||
| 1432 | uint32_t ge = 0; | ||
| 1433 | uint32_t le = 0; | ||
| 1434 | |||
| 1435 | switch (margin) { | ||
| 1436 | case chipcHw_VPM_HW_PHASE_MARGIN_STRICT: | ||
| 1437 | ge = 0x0F; | ||
| 1438 | le = 0x0F; | ||
| 1439 | break; | ||
| 1440 | case chipcHw_VPM_HW_PHASE_MARGIN_MEDIUM: | ||
| 1441 | ge = 0x03; | ||
| 1442 | le = 0x3F; | ||
| 1443 | break; | ||
| 1444 | case chipcHw_VPM_HW_PHASE_MARGIN_WIDE: | ||
| 1445 | ge = 0x01; | ||
| 1446 | le = 0x7F; | ||
| 1447 | break; | ||
| 1448 | } | ||
| 1449 | |||
| 1450 | { | ||
| 1451 | REG_LOCAL_IRQ_SAVE; | ||
| 1452 | |||
| 1453 | pChipcHw->VPMPhaseCtrl1 &= | ||
| 1454 | ~((chipcHw_REG_VPM_PHASE_VALUE_GE_MASK << | ||
| 1455 | chipcHw_REG_VPM_PHASE_VALUE_GE_SHIFT) | ||
| 1456 | || (chipcHw_REG_VPM_PHASE_VALUE_LE_MASK << | ||
| 1457 | chipcHw_REG_VPM_PHASE_VALUE_LE_SHIFT)); | ||
| 1458 | |||
| 1459 | pChipcHw->VPMPhaseCtrl1 |= | ||
| 1460 | ((ge << chipcHw_REG_VPM_PHASE_VALUE_GE_SHIFT) | ||
| 1461 | || (le << chipcHw_REG_VPM_PHASE_VALUE_LE_SHIFT)); | ||
| 1462 | |||
| 1463 | REG_LOCAL_IRQ_RESTORE; | ||
| 1464 | } | ||
| 1465 | } | ||
| 1466 | |||
| 1467 | /****************************************************************************/ | ||
| 1468 | /** | ||
| 1469 | * @brief Checks DDR phase aligned status done by HW | ||
| 1470 | * | ||
| 1471 | * @return 1: When aligned | ||
| 1472 | * 0: When not aligned | ||
| 1473 | */ | ||
| 1474 | /****************************************************************************/ | ||
| 1475 | static inline uint32_t chipcHw_isDdrHwPhaseAligned(void) | ||
| 1476 | { | ||
| 1477 | return (pChipcHw-> | ||
| 1478 | PhaseAlignStatus & chipcHw_REG_DDR_PHASE_ALIGNED) ? 1 : 0; | ||
| 1479 | } | ||
| 1480 | |||
| 1481 | /****************************************************************************/ | ||
| 1482 | /** | ||
| 1483 | * @brief Checks VPM phase aligned status done by HW | ||
| 1484 | * | ||
| 1485 | * @return 1: When aligned | ||
| 1486 | * 0: When not aligned | ||
| 1487 | */ | ||
| 1488 | /****************************************************************************/ | ||
| 1489 | static inline uint32_t chipcHw_isVpmHwPhaseAligned(void) | ||
| 1490 | { | ||
| 1491 | return (pChipcHw-> | ||
| 1492 | PhaseAlignStatus & chipcHw_REG_VPM_PHASE_ALIGNED) ? 1 : 0; | ||
| 1493 | } | ||
| 1494 | |||
| 1495 | /****************************************************************************/ | ||
| 1496 | /** | ||
| 1497 | * @brief Get DDR phase aligned status done by HW | ||
| 1498 | * | ||
| 1499 | */ | ||
| 1500 | /****************************************************************************/ | ||
| 1501 | static inline uint32_t chipcHw_getDdrHwPhaseAlignStatus(void) | ||
| 1502 | { | ||
| 1503 | return (pChipcHw-> | ||
| 1504 | PhaseAlignStatus & chipcHw_REG_DDR_PHASE_STATUS_MASK) >> | ||
| 1505 | chipcHw_REG_DDR_PHASE_STATUS_SHIFT; | ||
| 1506 | } | ||
| 1507 | |||
| 1508 | /****************************************************************************/ | ||
| 1509 | /** | ||
| 1510 | * @brief Get VPM phase aligned status done by HW | ||
| 1511 | * | ||
| 1512 | */ | ||
| 1513 | /****************************************************************************/ | ||
| 1514 | static inline uint32_t chipcHw_getVpmHwPhaseAlignStatus(void) | ||
| 1515 | { | ||
| 1516 | return (pChipcHw-> | ||
| 1517 | PhaseAlignStatus & chipcHw_REG_VPM_PHASE_STATUS_MASK) >> | ||
| 1518 | chipcHw_REG_VPM_PHASE_STATUS_SHIFT; | ||
| 1519 | } | ||
| 1520 | |||
| 1521 | /****************************************************************************/ | ||
| 1522 | /** | ||
| 1523 | * @brief Get DDR phase control value | ||
| 1524 | * | ||
| 1525 | */ | ||
| 1526 | /****************************************************************************/ | ||
| 1527 | static inline uint32_t chipcHw_getDdrPhaseControl(void) | ||
| 1528 | { | ||
| 1529 | return (pChipcHw-> | ||
| 1530 | PhaseAlignStatus & chipcHw_REG_DDR_PHASE_CTRL_MASK) >> | ||
| 1531 | chipcHw_REG_DDR_PHASE_CTRL_SHIFT; | ||
| 1532 | } | ||
| 1533 | |||
| 1534 | /****************************************************************************/ | ||
| 1535 | /** | ||
| 1536 | * @brief Get VPM phase control value | ||
| 1537 | * | ||
| 1538 | */ | ||
| 1539 | /****************************************************************************/ | ||
| 1540 | static inline uint32_t chipcHw_getVpmPhaseControl(void) | ||
| 1541 | { | ||
| 1542 | return (pChipcHw-> | ||
| 1543 | PhaseAlignStatus & chipcHw_REG_VPM_PHASE_CTRL_MASK) >> | ||
| 1544 | chipcHw_REG_VPM_PHASE_CTRL_SHIFT; | ||
| 1545 | } | ||
| 1546 | |||
| 1547 | /****************************************************************************/ | ||
| 1548 | /** | ||
| 1549 | * @brief DDR phase alignment timeout count | ||
| 1550 | * | ||
| 1551 | * @note If HW fails to perform the phase alignment, it will trigger | ||
| 1552 | * a DDR phase alignment timeout interrupt. | ||
| 1553 | */ | ||
| 1554 | /****************************************************************************/ | ||
| 1555 | static inline void chipcHw_ddrHwPhaseAlignTimeout(uint32_t busCycle) | ||
| 1556 | { | ||
| 1557 | REG_LOCAL_IRQ_SAVE; | ||
| 1558 | pChipcHw->DDRPhaseCtrl2 &= | ||
| 1559 | ~(chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_MASK << | ||
| 1560 | chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_SHIFT); | ||
| 1561 | pChipcHw->DDRPhaseCtrl2 |= | ||
| 1562 | (busCycle & chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_MASK) << | ||
| 1563 | chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_SHIFT; | ||
| 1564 | REG_LOCAL_IRQ_RESTORE; | ||
| 1565 | } | ||
| 1566 | |||
| 1567 | /****************************************************************************/ | ||
| 1568 | /** | ||
| 1569 | * @brief VPM phase alignment timeout count | ||
| 1570 | * | ||
| 1571 | * @note If HW fails to perform the phase alignment, it will trigger | ||
| 1572 | * a VPM phase alignment timeout interrupt. | ||
| 1573 | */ | ||
| 1574 | /****************************************************************************/ | ||
| 1575 | static inline void chipcHw_vpmHwPhaseAlignTimeout(uint32_t busCycle) | ||
| 1576 | { | ||
| 1577 | REG_LOCAL_IRQ_SAVE; | ||
| 1578 | pChipcHw->VPMPhaseCtrl2 &= | ||
| 1579 | ~(chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_MASK << | ||
| 1580 | chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_SHIFT); | ||
| 1581 | pChipcHw->VPMPhaseCtrl2 |= | ||
| 1582 | (busCycle & chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_MASK) << | ||
| 1583 | chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_SHIFT; | ||
| 1584 | REG_LOCAL_IRQ_RESTORE; | ||
| 1585 | } | ||
| 1586 | |||
| 1587 | /****************************************************************************/ | ||
| 1588 | /** | ||
| 1589 | * @brief Clear DDR phase alignment timeout interrupt | ||
| 1590 | * | ||
| 1591 | */ | ||
| 1592 | /****************************************************************************/ | ||
| 1593 | static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptClear(void) | ||
| 1594 | { | ||
| 1595 | REG_LOCAL_IRQ_SAVE; | ||
| 1596 | /* Clear timeout interrupt service bit */ | ||
| 1597 | pChipcHw->DDRPhaseCtrl2 |= chipcHw_REG_DDR_INTR_SERVICED; | ||
| 1598 | pChipcHw->DDRPhaseCtrl2 &= ~chipcHw_REG_DDR_INTR_SERVICED; | ||
| 1599 | REG_LOCAL_IRQ_RESTORE; | ||
| 1600 | } | ||
| 1601 | |||
| 1602 | /****************************************************************************/ | ||
| 1603 | /** | ||
| 1604 | * @brief Clear VPM phase alignment timeout interrupt | ||
| 1605 | * | ||
| 1606 | */ | ||
| 1607 | /****************************************************************************/ | ||
| 1608 | static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptClear(void) | ||
| 1609 | { | ||
| 1610 | REG_LOCAL_IRQ_SAVE; | ||
| 1611 | /* Clear timeout interrupt service bit */ | ||
| 1612 | pChipcHw->VPMPhaseCtrl2 |= chipcHw_REG_VPM_INTR_SERVICED; | ||
| 1613 | pChipcHw->VPMPhaseCtrl2 &= ~chipcHw_REG_VPM_INTR_SERVICED; | ||
| 1614 | REG_LOCAL_IRQ_RESTORE; | ||
| 1615 | } | ||
| 1616 | |||
| 1617 | /****************************************************************************/ | ||
| 1618 | /** | ||
| 1619 | * @brief DDR phase alignment timeout interrupt enable | ||
| 1620 | * | ||
| 1621 | */ | ||
| 1622 | /****************************************************************************/ | ||
| 1623 | static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptEnable(void) | ||
| 1624 | { | ||
| 1625 | REG_LOCAL_IRQ_SAVE; | ||
| 1626 | chipcHw_ddrHwPhaseAlignTimeoutInterruptClear(); /* Recommended */ | ||
| 1627 | /* Enable timeout interrupt */ | ||
| 1628 | pChipcHw->DDRPhaseCtrl2 |= chipcHw_REG_DDR_TIMEOUT_INTR_ENABLE; | ||
| 1629 | REG_LOCAL_IRQ_RESTORE; | ||
| 1630 | } | ||
| 1631 | |||
| 1632 | /****************************************************************************/ | ||
| 1633 | /** | ||
| 1634 | * @brief VPM phase alignment timeout interrupt enable | ||
| 1635 | * | ||
| 1636 | */ | ||
| 1637 | /****************************************************************************/ | ||
| 1638 | static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptEnable(void) | ||
| 1639 | { | ||
| 1640 | REG_LOCAL_IRQ_SAVE; | ||
| 1641 | chipcHw_vpmHwPhaseAlignTimeoutInterruptClear(); /* Recommended */ | ||
| 1642 | /* Enable timeout interrupt */ | ||
| 1643 | pChipcHw->VPMPhaseCtrl2 |= chipcHw_REG_VPM_TIMEOUT_INTR_ENABLE; | ||
| 1644 | REG_LOCAL_IRQ_RESTORE; | ||
| 1645 | } | ||
| 1646 | |||
| 1647 | /****************************************************************************/ | ||
| 1648 | /** | ||
| 1649 | * @brief DDR phase alignment timeout interrupt disable | ||
| 1650 | * | ||
| 1651 | */ | ||
| 1652 | /****************************************************************************/ | ||
| 1653 | static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptDisable(void) | ||
| 1654 | { | ||
| 1655 | REG_LOCAL_IRQ_SAVE; | ||
| 1656 | pChipcHw->DDRPhaseCtrl2 &= ~chipcHw_REG_DDR_TIMEOUT_INTR_ENABLE; | ||
| 1657 | REG_LOCAL_IRQ_RESTORE; | ||
| 1658 | } | ||
| 1659 | |||
| 1660 | /****************************************************************************/ | ||
| 1661 | /** | ||
| 1662 | * @brief VPM phase alignment timeout interrupt disable | ||
| 1663 | * | ||
| 1664 | */ | ||
| 1665 | /****************************************************************************/ | ||
| 1666 | static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptDisable(void) | ||
| 1667 | { | ||
| 1668 | REG_LOCAL_IRQ_SAVE; | ||
| 1669 | pChipcHw->VPMPhaseCtrl2 &= ~chipcHw_REG_VPM_TIMEOUT_INTR_ENABLE; | ||
| 1670 | REG_LOCAL_IRQ_RESTORE; | ||
| 1671 | } | ||
| 1672 | |||
| 1673 | #endif /* CHIPC_INLINE_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h new file mode 100644 index 000000000000..b162448f613c --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h | |||
| @@ -0,0 +1,530 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file chipcHw_reg.h | ||
| 18 | * | ||
| 19 | * @brief Definitions for low level chip control registers | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | /****************************************************************************/ | ||
| 23 | #ifndef CHIPCHW_REG_H | ||
| 24 | #define CHIPCHW_REG_H | ||
| 25 | |||
| 26 | #include <mach/csp/mm_io.h> | ||
| 27 | #include <csp/reg.h> | ||
| 28 | #include <mach/csp/ddrcReg.h> | ||
| 29 | |||
| 30 | #define chipcHw_BASE_ADDRESS MM_IO_BASE_CHIPC | ||
| 31 | |||
| 32 | typedef struct { | ||
| 33 | uint32_t ChipId; /* Chip ID */ | ||
| 34 | uint32_t DDRClock; /* PLL1 Channel 1 for DDR clock */ | ||
| 35 | uint32_t ARMClock; /* PLL1 Channel 2 for ARM clock */ | ||
| 36 | uint32_t ESWClock; /* PLL1 Channel 3 for ESW system clock */ | ||
| 37 | uint32_t VPMClock; /* PLL1 Channel 4 for VPM clock */ | ||
| 38 | uint32_t ESW125Clock; /* PLL1 Channel 5 for ESW 125MHz clock */ | ||
| 39 | uint32_t UARTClock; /* PLL1 Channel 6 for UART clock */ | ||
| 40 | uint32_t SDIO0Clock; /* PLL1 Channel 7 for SDIO 0 clock */ | ||
| 41 | uint32_t SDIO1Clock; /* PLL1 Channel 8 for SDIO 1 clock */ | ||
| 42 | uint32_t SPIClock; /* PLL1 Channel 9 for SPI master Clock */ | ||
| 43 | uint32_t ETMClock; /* PLL1 Channel 10 for ARM ETM Clock */ | ||
| 44 | |||
| 45 | uint32_t ACLKClock; /* ACLK Clock (Divider) */ | ||
| 46 | uint32_t OTPClock; /* OTP Clock (Divider) */ | ||
| 47 | uint32_t I2CClock; /* I2C Clock (CK_13m) (Divider) */ | ||
| 48 | uint32_t I2S0Clock; /* I2S0 Clock (Divider) */ | ||
| 49 | uint32_t RTBUSClock; /* RTBUS (DDR PHY Config.) Clock (Divider) */ | ||
| 50 | uint32_t pad1; | ||
| 51 | uint32_t APM100Clock; /* APM 100MHz CLK Clock (Divider) */ | ||
| 52 | uint32_t TSCClock; /* TSC Clock (Divider) */ | ||
| 53 | uint32_t LEDClock; /* LED Clock (Divider) */ | ||
| 54 | |||
| 55 | uint32_t USBClock; /* PLL2 Channel 1 for USB clock */ | ||
| 56 | uint32_t LCDClock; /* PLL2 Channel 2 for LCD clock */ | ||
| 57 | uint32_t APMClock; /* PLL2 Channel 3 for APM 200 MHz clock */ | ||
| 58 | |||
| 59 | uint32_t BusIntfClock; /* Bus interface clock */ | ||
| 60 | |||
| 61 | uint32_t PLLStatus; /* PLL status register (PLL1) */ | ||
| 62 | uint32_t PLLConfig; /* PLL configuration register (PLL1) */ | ||
| 63 | uint32_t PLLPreDivider; /* PLL pre-divider control register (PLL1) */ | ||
| 64 | uint32_t PLLDivider; /* PLL divider control register (PLL1) */ | ||
| 65 | uint32_t PLLControl1; /* PLL analog control register #1 (PLL1) */ | ||
| 66 | uint32_t PLLControl2; /* PLL analog control register #2 (PLL1) */ | ||
| 67 | |||
| 68 | uint32_t I2S1Clock; /* I2S1 Clock */ | ||
| 69 | uint32_t AudioEnable; /* Enable/ disable audio channel */ | ||
| 70 | uint32_t SoftReset1; /* Reset blocks */ | ||
| 71 | uint32_t SoftReset2; /* Reset blocks */ | ||
| 72 | uint32_t Spare1; /* Phase align interrupts */ | ||
| 73 | uint32_t Sticky; /* Sticky bits */ | ||
| 74 | uint32_t MiscCtrl; /* Misc. control */ | ||
| 75 | uint32_t pad3[3]; | ||
| 76 | |||
| 77 | uint32_t PLLStatus2; /* PLL status register (PLL2) */ | ||
| 78 | uint32_t PLLConfig2; /* PLL configuration register (PLL2) */ | ||
| 79 | uint32_t PLLPreDivider2; /* PLL pre-divider control register (PLL2) */ | ||
| 80 | uint32_t PLLDivider2; /* PLL divider control register (PLL2) */ | ||
| 81 | uint32_t PLLControl12; /* PLL analog control register #1 (PLL2) */ | ||
| 82 | uint32_t PLLControl22; /* PLL analog control register #2 (PLL2) */ | ||
| 83 | |||
| 84 | uint32_t DDRPhaseCtrl1; /* DDR Clock Phase Alignment control1 */ | ||
| 85 | uint32_t VPMPhaseCtrl1; /* VPM Clock Phase Alignment control1 */ | ||
| 86 | uint32_t PhaseAlignStatus; /* DDR/VPM Clock Phase Alignment Status */ | ||
| 87 | uint32_t PhaseCtrlStatus; /* DDR/VPM Clock HW DDR/VPM ph_ctrl and load_ch Status */ | ||
| 88 | uint32_t DDRPhaseCtrl2; /* DDR Clock Phase Alignment control2 */ | ||
| 89 | uint32_t VPMPhaseCtrl2; /* VPM Clock Phase Alignment control2 */ | ||
| 90 | uint32_t pad4[9]; | ||
| 91 | |||
| 92 | uint32_t SoftOTP1; /* Software OTP control */ | ||
| 93 | uint32_t SoftOTP2; /* Software OTP control */ | ||
| 94 | uint32_t SoftStraps; /* Software strap */ | ||
| 95 | uint32_t PinStraps; /* Pin Straps */ | ||
| 96 | uint32_t DiffOscCtrl; /* Diff oscillator control */ | ||
| 97 | uint32_t DiagsCtrl; /* Diagnostic control */ | ||
| 98 | uint32_t DiagsOutputCtrl; /* Diagnostic output enable */ | ||
| 99 | uint32_t DiagsReadBackCtrl; /* Diagnostic read back control */ | ||
| 100 | |||
| 101 | uint32_t LcdPifMode; /* LCD/PIF Pin Sharing MUX Mode */ | ||
| 102 | |||
| 103 | uint32_t GpioMux_0_7; /* Pin Sharing MUX0 Control */ | ||
| 104 | uint32_t GpioMux_8_15; /* Pin Sharing MUX1 Control */ | ||
| 105 | uint32_t GpioMux_16_23; /* Pin Sharing MUX2 Control */ | ||
| 106 | uint32_t GpioMux_24_31; /* Pin Sharing MUX3 Control */ | ||
| 107 | uint32_t GpioMux_32_39; /* Pin Sharing MUX4 Control */ | ||
| 108 | uint32_t GpioMux_40_47; /* Pin Sharing MUX5 Control */ | ||
| 109 | uint32_t GpioMux_48_55; /* Pin Sharing MUX6 Control */ | ||
| 110 | uint32_t GpioMux_56_63; /* Pin Sharing MUX7 Control */ | ||
| 111 | |||
| 112 | uint32_t GpioSR_0_7; /* Slew rate for GPIO 0 - 7 */ | ||
| 113 | uint32_t GpioSR_8_15; /* Slew rate for GPIO 8 - 15 */ | ||
| 114 | uint32_t GpioSR_16_23; /* Slew rate for GPIO 16 - 23 */ | ||
| 115 | uint32_t GpioSR_24_31; /* Slew rate for GPIO 24 - 31 */ | ||
| 116 | uint32_t GpioSR_32_39; /* Slew rate for GPIO 32 - 39 */ | ||
| 117 | uint32_t GpioSR_40_47; /* Slew rate for GPIO 40 - 47 */ | ||
| 118 | uint32_t GpioSR_48_55; /* Slew rate for GPIO 48 - 55 */ | ||
| 119 | uint32_t GpioSR_56_63; /* Slew rate for GPIO 56 - 63 */ | ||
| 120 | uint32_t MiscSR_0_7; /* Slew rate for MISC 0 - 7 */ | ||
| 121 | uint32_t MiscSR_8_15; /* Slew rate for MISC 8 - 15 */ | ||
| 122 | |||
| 123 | uint32_t GpioPull_0_15; /* Pull up registers for GPIO 0 - 15 */ | ||
| 124 | uint32_t GpioPull_16_31; /* Pull up registers for GPIO 16 - 31 */ | ||
| 125 | uint32_t GpioPull_32_47; /* Pull up registers for GPIO 32 - 47 */ | ||
| 126 | uint32_t GpioPull_48_63; /* Pull up registers for GPIO 48 - 63 */ | ||
| 127 | uint32_t MiscPull_0_15; /* Pull up registers for MISC 0 - 15 */ | ||
| 128 | |||
| 129 | uint32_t GpioInput_0_31; /* Input type for GPIO 0 - 31 */ | ||
| 130 | uint32_t GpioInput_32_63; /* Input type for GPIO 32 - 63 */ | ||
| 131 | uint32_t MiscInput_0_15; /* Input type for MISC 0 - 16 */ | ||
| 132 | } chipcHw_REG_t; | ||
| 133 | |||
| 134 | #define pChipcHw ((volatile chipcHw_REG_t *) chipcHw_BASE_ADDRESS) | ||
| 135 | #define pChipcPhysical ((volatile chipcHw_REG_t *) MM_ADDR_IO_CHIPC) | ||
| 136 | |||
| 137 | #define chipcHw_REG_CHIPID_BASE_MASK 0xFFFFF000 | ||
| 138 | #define chipcHw_REG_CHIPID_BASE_SHIFT 12 | ||
| 139 | #define chipcHw_REG_CHIPID_REV_MASK 0x00000FFF | ||
| 140 | #define chipcHw_REG_REV_A0 0xA00 | ||
| 141 | #define chipcHw_REG_REV_B0 0x0B0 | ||
| 142 | |||
| 143 | #define chipcHw_REG_PLL_STATUS_CONTROL_ENABLE 0x80000000 /* Allow controlling PLL registers */ | ||
| 144 | #define chipcHw_REG_PLL_STATUS_LOCKED 0x00000001 /* PLL is settled */ | ||
| 145 | #define chipcHw_REG_PLL_CONFIG_D_RESET 0x00000008 /* Digital reset */ | ||
| 146 | #define chipcHw_REG_PLL_CONFIG_A_RESET 0x00000004 /* Analog reset */ | ||
| 147 | #define chipcHw_REG_PLL_CONFIG_BYPASS_ENABLE 0x00000020 /* Bypass enable */ | ||
| 148 | #define chipcHw_REG_PLL_CONFIG_OUTPUT_ENABLE 0x00000010 /* Output enable */ | ||
| 149 | #define chipcHw_REG_PLL_CONFIG_POWER_DOWN 0x00000001 /* Power down */ | ||
| 150 | #define chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ 1600000000 /* 1.6GHz VCO split frequency */ | ||
| 151 | #define chipcHw_REG_PLL_CONFIG_VCO_800_1600 0x00000000 /* VCO range 800-1600 MHz */ | ||
| 152 | #define chipcHw_REG_PLL_CONFIG_VCO_1601_3200 0x00000080 /* VCO range 1601-3200 MHz */ | ||
| 153 | #define chipcHw_REG_PLL_CONFIG_TEST_ENABLE 0x00010000 /* PLL test output enable */ | ||
| 154 | #define chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK 0x003E0000 /* Mask to set test values */ | ||
| 155 | #define chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT 17 | ||
| 156 | |||
| 157 | #define chipcHw_REG_PLL_CLOCK_PHASE_COMP 0x00800000 /* Phase comparator output */ | ||
| 158 | #define chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK 0x00300000 /* Clock to bus ratio mask */ | ||
| 159 | #define chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT 20 /* Number of bits to be shifted */ | ||
| 160 | #define chipcHw_REG_PLL_CLOCK_POWER_DOWN 0x00080000 /* PLL channel power down */ | ||
| 161 | #define chipcHw_REG_PLL_CLOCK_SOURCE_GPIO 0x00040000 /* Use GPIO as source */ | ||
| 162 | #define chipcHw_REG_PLL_CLOCK_BYPASS_SELECT 0x00020000 /* Select bypass clock */ | ||
| 163 | #define chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE 0x00010000 /* Clock gated ON */ | ||
| 164 | #define chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE 0x00008000 /* Clock phase update enable */ | ||
| 165 | #define chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT 8 /* Number of bits to be shifted */ | ||
| 166 | #define chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK 0x00003F00 /* Phase control mask */ | ||
| 167 | #define chipcHw_REG_PLL_CLOCK_MDIV_MASK 0x000000FF /* Clock post divider mask | ||
| 168 | |||
| 169 | 00000000 = divide-by-256 | ||
| 170 | 00000001 = divide-by-1 | ||
| 171 | 00000010 = divide-by-2 | ||
| 172 | 00000011 = divide-by-3 | ||
| 173 | 00000100 = divide-by-4 | ||
| 174 | 00000101 = divide-by-5 | ||
| 175 | 00000110 = divide-by-6 | ||
| 176 | . | ||
| 177 | . | ||
| 178 | 11111011 = divide-by-251 | ||
| 179 | 11111100 = divide-by-252 | ||
| 180 | 11111101 = divide-by-253 | ||
| 181 | 11111110 = divide-by-254 | ||
| 182 | */ | ||
| 183 | |||
| 184 | #define chipcHw_REG_DIV_CLOCK_SOURCE_OTHER 0x00040000 /* NON-PLL clock source select */ | ||
| 185 | #define chipcHw_REG_DIV_CLOCK_BYPASS_SELECT 0x00020000 /* NON-PLL clock bypass enable */ | ||
| 186 | #define chipcHw_REG_DIV_CLOCK_OUTPUT_ENABLE 0x00010000 /* NON-PLL clock output enable */ | ||
| 187 | #define chipcHw_REG_DIV_CLOCK_DIV_MASK 0x000000FF /* NON-PLL clock post-divide mask */ | ||
| 188 | #define chipcHw_REG_DIV_CLOCK_DIV_256 0x00000000 /* NON-PLL clock post-divide by 256 */ | ||
| 189 | |||
| 190 | #define chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT 0 | ||
| 191 | #define chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT 4 | ||
| 192 | #define chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT 8 | ||
| 193 | #define chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK 0x0001FF00 | ||
| 194 | #define chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN 0x02000000 | ||
| 195 | #define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK 0x00700000 /* Divider mask */ | ||
| 196 | #define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER 0x00000000 /* Integer-N Mode */ | ||
| 197 | #define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_UNIT 0x00100000 /* MASH Sigma-Delta Modulator Unit Mode */ | ||
| 198 | #define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MFB_UNIT 0x00200000 /* MFB Sigma-Delta Modulator Unit Mode */ | ||
| 199 | #define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_1_8 0x00300000 /* MASH Sigma-Delta Modulator 1/8 Mode */ | ||
| 200 | #define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MFB_1_8 0x00400000 /* MFB Sigma-Delta Modulator 1/8 Mode */ | ||
| 201 | |||
| 202 | #define chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vco) ((vco) / chipcHw_XTAL_FREQ_Hz) | ||
| 203 | #define chipcHw_REG_PLL_PREDIVIDER_P1 1 | ||
| 204 | #define chipcHw_REG_PLL_PREDIVIDER_P2 1 | ||
| 205 | |||
| 206 | #define chipcHw_REG_PLL_DIVIDER_M1DIV 0x03000000 | ||
| 207 | #define chipcHw_REG_PLL_DIVIDER_FRAC 0x00FFFFFF /* Fractional divider */ | ||
| 208 | |||
| 209 | #define chipcHw_REG_PLL_DIVIDER_NDIV_f_SS (0x00FFFFFF) /* To attain spread with max frequency */ | ||
| 210 | |||
| 211 | #define chipcHw_REG_PLL_DIVIDER_NDIV_f 0 /* ndiv_frac = chipcHw_REG_PLL_DIVIDER_NDIV_f / | ||
| 212 | chipcHw_REG_PLL_DIVIDER_FRAC | ||
| 213 | = 0, when SS is disable | ||
| 214 | */ | ||
| 215 | |||
| 216 | #define chipcHw_REG_PLL_DIVIDER_MDIV(vco, Hz) ((chipcHw_divide((vco), (Hz)) > 255) ? 0 : chipcHw_divide((vco), (Hz))) | ||
| 217 | |||
| 218 | #define chipcHw_REG_ACLKClock_CLK_DIV_MASK 0x3 | ||
| 219 | |||
| 220 | /* System booting strap options */ | ||
| 221 | #define chipcHw_STRAPS_SOFT_OVERRIDE 0x00000001 /* Software Strap Override */ | ||
| 222 | |||
| 223 | #define chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_8 0x00000000 /* 8 bit NAND FLASH Boot */ | ||
| 224 | #define chipcHw_STRAPS_BOOT_DEVICE_NOR_FLASH_16 0x00000002 /* 16 bit NOR FLASH Boot */ | ||
| 225 | #define chipcHw_STRAPS_BOOT_DEVICE_SERIAL_FLASH 0x00000004 /* Serial FLASH Boot */ | ||
| 226 | #define chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_16 0x00000006 /* 16 bit NAND FLASH Boot */ | ||
| 227 | #define chipcHw_STRAPS_BOOT_DEVICE_UART 0x00000008 /* UART Boot */ | ||
| 228 | #define chipcHw_STRAPS_BOOT_DEVICE_MASK 0x0000000E /* Mask */ | ||
| 229 | |||
| 230 | /* System boot option */ | ||
| 231 | #define chipcHw_STRAPS_BOOT_OPTION_BROM 0x00000000 /* Boot from Boot ROM */ | ||
| 232 | #define chipcHw_STRAPS_BOOT_OPTION_ARAM 0x00000020 /* Boot from ARAM */ | ||
| 233 | #define chipcHw_STRAPS_BOOT_OPTION_NOR 0x00000030 /* Boot from NOR flash */ | ||
| 234 | |||
| 235 | /* NAND Flash page size strap options */ | ||
| 236 | #define chipcHw_STRAPS_NAND_PAGESIZE_512 0x00000000 /* NAND FLASH page size of 512 bytes */ | ||
| 237 | #define chipcHw_STRAPS_NAND_PAGESIZE_2048 0x00000040 /* NAND FLASH page size of 2048 bytes */ | ||
| 238 | #define chipcHw_STRAPS_NAND_PAGESIZE_4096 0x00000080 /* NAND FLASH page size of 4096 bytes */ | ||
| 239 | #define chipcHw_STRAPS_NAND_PAGESIZE_EXT 0x000000C0 /* NAND FLASH page of extened size */ | ||
| 240 | #define chipcHw_STRAPS_NAND_PAGESIZE_MASK 0x000000C0 /* Mask */ | ||
| 241 | |||
| 242 | #define chipcHw_STRAPS_NAND_EXTRA_CYCLE 0x00000400 /* NAND FLASH address cycle configuration */ | ||
| 243 | #define chipcHw_STRAPS_REBOOT_TO_UART 0x00000800 /* Reboot to UART on error */ | ||
| 244 | |||
| 245 | /* Secure boot mode strap options */ | ||
| 246 | #define chipcHw_STRAPS_BOOT_MODE_NORMAL 0x00000000 /* Normal Boot */ | ||
| 247 | #define chipcHw_STRAPS_BOOT_MODE_DBG_SW 0x00000100 /* Software debugging Boot */ | ||
| 248 | #define chipcHw_STRAPS_BOOT_MODE_DBG_BOOT 0x00000200 /* Boot rom debugging Boot */ | ||
| 249 | #define chipcHw_STRAPS_BOOT_MODE_NORMAL_QUIET 0x00000300 /* Normal Boot (Quiet BootRom) */ | ||
| 250 | #define chipcHw_STRAPS_BOOT_MODE_MASK 0x00000300 /* Mask */ | ||
| 251 | |||
| 252 | /* Slave Mode straps */ | ||
| 253 | #define chipcHw_STRAPS_I2CS 0x02000000 /* I2C Slave */ | ||
| 254 | #define chipcHw_STRAPS_SPIS 0x01000000 /* SPI Slave */ | ||
| 255 | |||
| 256 | /* Strap pin options */ | ||
| 257 | #define chipcHw_REG_SW_STRAPS ((pChipcHw->PinStraps & 0x0000FC00) >> 10) | ||
| 258 | |||
| 259 | /* PIF/LCD pin sharing defines */ | ||
| 260 | #define chipcHw_REG_LCD_PIN_ENABLE 0x00000001 /* LCD Controller is used and the pins have LCD functions */ | ||
| 261 | #define chipcHw_REG_PIF_PIN_ENABLE 0x00000002 /* LCD pins are used to perform PIF functions */ | ||
| 262 | |||
| 263 | #define chipcHw_GPIO_COUNT 61 /* Number of GPIO pin accessible thorugh CHIPC */ | ||
| 264 | |||
| 265 | /* NOTE: Any changes to these constants will require a corresponding change to chipcHw_str.c */ | ||
| 266 | #define chipcHw_REG_GPIO_MUX_KEYPAD 0x00000001 /* GPIO mux for Keypad */ | ||
| 267 | #define chipcHw_REG_GPIO_MUX_I2CH 0x00000002 /* GPIO mux for I2CH */ | ||
| 268 | #define chipcHw_REG_GPIO_MUX_SPI 0x00000003 /* GPIO mux for SPI */ | ||
| 269 | #define chipcHw_REG_GPIO_MUX_UART 0x00000004 /* GPIO mux for UART */ | ||
| 270 | #define chipcHw_REG_GPIO_MUX_LEDMTXP 0x00000005 /* GPIO mux for LEDMTXP */ | ||
| 271 | #define chipcHw_REG_GPIO_MUX_LEDMTXS 0x00000006 /* GPIO mux for LEDMTXS */ | ||
| 272 | #define chipcHw_REG_GPIO_MUX_SDIO0 0x00000007 /* GPIO mux for SDIO0 */ | ||
| 273 | #define chipcHw_REG_GPIO_MUX_SDIO1 0x00000008 /* GPIO mux for SDIO1 */ | ||
| 274 | #define chipcHw_REG_GPIO_MUX_PCM 0x00000009 /* GPIO mux for PCM */ | ||
| 275 | #define chipcHw_REG_GPIO_MUX_I2S 0x0000000A /* GPIO mux for I2S */ | ||
| 276 | #define chipcHw_REG_GPIO_MUX_ETM 0x0000000B /* GPIO mux for ETM */ | ||
| 277 | #define chipcHw_REG_GPIO_MUX_DEBUG 0x0000000C /* GPIO mux for DEBUG */ | ||
| 278 | #define chipcHw_REG_GPIO_MUX_MISC 0x0000000D /* GPIO mux for MISC */ | ||
| 279 | #define chipcHw_REG_GPIO_MUX_GPIO 0x00000000 /* GPIO mux for GPIO */ | ||
| 280 | #define chipcHw_REG_GPIO_MUX(pin) (&pChipcHw->GpioMux_0_7 + ((pin) >> 3)) | ||
| 281 | #define chipcHw_REG_GPIO_MUX_POSITION(pin) (((pin) & 0x00000007) << 2) | ||
| 282 | #define chipcHw_REG_GPIO_MUX_MASK 0x0000000F /* Mask */ | ||
| 283 | |||
| 284 | #define chipcHw_REG_SLEW_RATE_HIGH 0x00000000 /* High speed slew rate */ | ||
| 285 | #define chipcHw_REG_SLEW_RATE_NORMAL 0x00000008 /* Normal slew rate */ | ||
| 286 | /* Pins beyond 42 are defined by skipping 8 bits within the register */ | ||
| 287 | #define chipcHw_REG_SLEW_RATE(pin) (((pin) > 42) ? (&pChipcHw->GpioSR_0_7 + (((pin) + 2) >> 3)) : (&pChipcHw->GpioSR_0_7 + ((pin) >> 3))) | ||
| 288 | #define chipcHw_REG_SLEW_RATE_POSITION(pin) (((pin) > 42) ? ((((pin) + 2) & 0x00000007) << 2) : (((pin) & 0x00000007) << 2)) | ||
| 289 | #define chipcHw_REG_SLEW_RATE_MASK 0x00000008 /* Mask */ | ||
| 290 | |||
| 291 | #define chipcHw_REG_CURRENT_STRENGTH_2mA 0x00000001 /* Current driving strength 2 milli ampere */ | ||
| 292 | #define chipcHw_REG_CURRENT_STRENGTH_4mA 0x00000002 /* Current driving strength 4 milli ampere */ | ||
| 293 | #define chipcHw_REG_CURRENT_STRENGTH_6mA 0x00000004 /* Current driving strength 6 milli ampere */ | ||
| 294 | #define chipcHw_REG_CURRENT_STRENGTH_8mA 0x00000005 /* Current driving strength 8 milli ampere */ | ||
| 295 | #define chipcHw_REG_CURRENT_STRENGTH_10mA 0x00000006 /* Current driving strength 10 milli ampere */ | ||
| 296 | #define chipcHw_REG_CURRENT_STRENGTH_12mA 0x00000007 /* Current driving strength 12 milli ampere */ | ||
| 297 | #define chipcHw_REG_CURRENT_MASK 0x00000007 /* Mask */ | ||
| 298 | /* Pins beyond 42 are defined by skipping 8 bits */ | ||
| 299 | #define chipcHw_REG_CURRENT(pin) (((pin) > 42) ? (&pChipcHw->GpioSR_0_7 + (((pin) + 2) >> 3)) : (&pChipcHw->GpioSR_0_7 + ((pin) >> 3))) | ||
| 300 | #define chipcHw_REG_CURRENT_POSITION(pin) (((pin) > 42) ? ((((pin) + 2) & 0x00000007) << 2) : (((pin) & 0x00000007) << 2)) | ||
| 301 | |||
| 302 | #define chipcHw_REG_PULL_NONE 0x00000000 /* No pull up register */ | ||
| 303 | #define chipcHw_REG_PULL_UP 0x00000001 /* Pull up register enable */ | ||
| 304 | #define chipcHw_REG_PULL_DOWN 0x00000002 /* Pull down register enable */ | ||
| 305 | #define chipcHw_REG_PULLUP_MASK 0x00000003 /* Mask */ | ||
| 306 | /* Pins beyond 42 are defined by skipping 4 bits */ | ||
| 307 | #define chipcHw_REG_PULLUP(pin) (((pin) > 42) ? (&pChipcHw->GpioPull_0_15 + (((pin) + 2) >> 4)) : (&pChipcHw->GpioPull_0_15 + ((pin) >> 4))) | ||
| 308 | #define chipcHw_REG_PULLUP_POSITION(pin) (((pin) > 42) ? ((((pin) + 2) & 0x0000000F) << 1) : (((pin) & 0x0000000F) << 1)) | ||
| 309 | |||
| 310 | #define chipcHw_REG_INPUTTYPE_CMOS 0x00000000 /* Normal CMOS logic */ | ||
| 311 | #define chipcHw_REG_INPUTTYPE_ST 0x00000001 /* High speed Schmitt Trigger */ | ||
| 312 | #define chipcHw_REG_INPUTTYPE_MASK 0x00000001 /* Mask */ | ||
| 313 | /* Pins beyond 42 are defined by skipping 2 bits */ | ||
| 314 | #define chipcHw_REG_INPUTTYPE(pin) (((pin) > 42) ? (&pChipcHw->GpioInput_0_31 + (((pin) + 2) >> 5)) : (&pChipcHw->GpioInput_0_31 + ((pin) >> 5))) | ||
| 315 | #define chipcHw_REG_INPUTTYPE_POSITION(pin) (((pin) > 42) ? ((((pin) + 2) & 0x0000001F)) : (((pin) & 0x0000001F))) | ||
| 316 | |||
| 317 | /* Device connected to the bus clock */ | ||
| 318 | #define chipcHw_REG_BUS_CLOCK_ARM 0x00000001 /* Bus interface clock for ARM */ | ||
| 319 | #define chipcHw_REG_BUS_CLOCK_VDEC 0x00000002 /* Bus interface clock for VDEC */ | ||
| 320 | #define chipcHw_REG_BUS_CLOCK_ARAM 0x00000004 /* Bus interface clock for ARAM */ | ||
| 321 | #define chipcHw_REG_BUS_CLOCK_HPM 0x00000008 /* Bus interface clock for HPM */ | ||
| 322 | #define chipcHw_REG_BUS_CLOCK_DDRC 0x00000010 /* Bus interface clock for DDRC */ | ||
| 323 | #define chipcHw_REG_BUS_CLOCK_DMAC0 0x00000020 /* Bus interface clock for DMAC0 */ | ||
| 324 | #define chipcHw_REG_BUS_CLOCK_DMAC1 0x00000040 /* Bus interface clock for DMAC1 */ | ||
| 325 | #define chipcHw_REG_BUS_CLOCK_NVI 0x00000080 /* Bus interface clock for NVI */ | ||
| 326 | #define chipcHw_REG_BUS_CLOCK_ESW 0x00000100 /* Bus interface clock for ESW */ | ||
| 327 | #define chipcHw_REG_BUS_CLOCK_GE 0x00000200 /* Bus interface clock for GE */ | ||
| 328 | #define chipcHw_REG_BUS_CLOCK_I2CH 0x00000400 /* Bus interface clock for I2CH */ | ||
| 329 | #define chipcHw_REG_BUS_CLOCK_I2S0 0x00000800 /* Bus interface clock for I2S0 */ | ||
| 330 | #define chipcHw_REG_BUS_CLOCK_I2S1 0x00001000 /* Bus interface clock for I2S1 */ | ||
| 331 | #define chipcHw_REG_BUS_CLOCK_VRAM 0x00002000 /* Bus interface clock for VRAM */ | ||
| 332 | #define chipcHw_REG_BUS_CLOCK_CLCD 0x00004000 /* Bus interface clock for CLCD */ | ||
| 333 | #define chipcHw_REG_BUS_CLOCK_LDK 0x00008000 /* Bus interface clock for LDK */ | ||
| 334 | #define chipcHw_REG_BUS_CLOCK_LED 0x00010000 /* Bus interface clock for LED */ | ||
| 335 | #define chipcHw_REG_BUS_CLOCK_OTP 0x00020000 /* Bus interface clock for OTP */ | ||
| 336 | #define chipcHw_REG_BUS_CLOCK_PIF 0x00040000 /* Bus interface clock for PIF */ | ||
| 337 | #define chipcHw_REG_BUS_CLOCK_SPU 0x00080000 /* Bus interface clock for SPU */ | ||
| 338 | #define chipcHw_REG_BUS_CLOCK_SDIO0 0x00100000 /* Bus interface clock for SDIO0 */ | ||
| 339 | #define chipcHw_REG_BUS_CLOCK_SDIO1 0x00200000 /* Bus interface clock for SDIO1 */ | ||
| 340 | #define chipcHw_REG_BUS_CLOCK_SPIH 0x00400000 /* Bus interface clock for SPIH */ | ||
| 341 | #define chipcHw_REG_BUS_CLOCK_SPIS 0x00800000 /* Bus interface clock for SPIS */ | ||
| 342 | #define chipcHw_REG_BUS_CLOCK_UART0 0x01000000 /* Bus interface clock for UART0 */ | ||
| 343 | #define chipcHw_REG_BUS_CLOCK_UART1 0x02000000 /* Bus interface clock for UART1 */ | ||
| 344 | #define chipcHw_REG_BUS_CLOCK_BBL 0x04000000 /* Bus interface clock for BBL */ | ||
| 345 | #define chipcHw_REG_BUS_CLOCK_I2CS 0x08000000 /* Bus interface clock for I2CS */ | ||
| 346 | #define chipcHw_REG_BUS_CLOCK_USBH 0x10000000 /* Bus interface clock for USB Host */ | ||
| 347 | #define chipcHw_REG_BUS_CLOCK_USBD 0x20000000 /* Bus interface clock for USB Device */ | ||
| 348 | #define chipcHw_REG_BUS_CLOCK_BROM 0x40000000 /* Bus interface clock for Boot ROM */ | ||
| 349 | #define chipcHw_REG_BUS_CLOCK_TSC 0x80000000 /* Bus interface clock for Touch screen */ | ||
| 350 | |||
| 351 | /* Software resets defines */ | ||
| 352 | #define chipcHw_REG_SOFT_RESET_VPM_GLOBAL_HOLD 0x0000000080000000ULL /* Reset Global VPM and hold */ | ||
| 353 | #define chipcHw_REG_SOFT_RESET_VPM_HOLD 0x0000000040000000ULL /* Reset VPM and hold */ | ||
| 354 | #define chipcHw_REG_SOFT_RESET_VPM_GLOBAL 0x0000000020000000ULL /* Reset Global VPM */ | ||
| 355 | #define chipcHw_REG_SOFT_RESET_VPM 0x0000000010000000ULL /* Reset VPM */ | ||
| 356 | #define chipcHw_REG_SOFT_RESET_KEYPAD 0x0000000008000000ULL /* Reset Key pad */ | ||
| 357 | #define chipcHw_REG_SOFT_RESET_LED 0x0000000004000000ULL /* Reset LED */ | ||
| 358 | #define chipcHw_REG_SOFT_RESET_SPU 0x0000000002000000ULL /* Reset SPU */ | ||
| 359 | #define chipcHw_REG_SOFT_RESET_RNG 0x0000000001000000ULL /* Reset RNG */ | ||
| 360 | #define chipcHw_REG_SOFT_RESET_PKA 0x0000000000800000ULL /* Reset PKA */ | ||
| 361 | #define chipcHw_REG_SOFT_RESET_LCD 0x0000000000400000ULL /* Reset LCD */ | ||
| 362 | #define chipcHw_REG_SOFT_RESET_PIF 0x0000000000200000ULL /* Reset PIF */ | ||
| 363 | #define chipcHw_REG_SOFT_RESET_I2CS 0x0000000000100000ULL /* Reset I2C Slave */ | ||
| 364 | #define chipcHw_REG_SOFT_RESET_I2CH 0x0000000000080000ULL /* Reset I2C Host */ | ||
| 365 | #define chipcHw_REG_SOFT_RESET_SDIO1 0x0000000000040000ULL /* Reset SDIO 1 */ | ||
| 366 | #define chipcHw_REG_SOFT_RESET_SDIO0 0x0000000000020000ULL /* Reset SDIO 0 */ | ||
| 367 | #define chipcHw_REG_SOFT_RESET_BBL 0x0000000000010000ULL /* Reset BBL */ | ||
| 368 | #define chipcHw_REG_SOFT_RESET_I2S1 0x0000000000008000ULL /* Reset I2S1 */ | ||
| 369 | #define chipcHw_REG_SOFT_RESET_I2S0 0x0000000000004000ULL /* Reset I2S0 */ | ||
| 370 | #define chipcHw_REG_SOFT_RESET_SPIS 0x0000000000002000ULL /* Reset SPI Slave */ | ||
| 371 | #define chipcHw_REG_SOFT_RESET_SPIH 0x0000000000001000ULL /* Reset SPI Host */ | ||
| 372 | #define chipcHw_REG_SOFT_RESET_GPIO1 0x0000000000000800ULL /* Reset GPIO block 1 */ | ||
| 373 | #define chipcHw_REG_SOFT_RESET_GPIO0 0x0000000000000400ULL /* Reset GPIO block 0 */ | ||
| 374 | #define chipcHw_REG_SOFT_RESET_UART1 0x0000000000000200ULL /* Reset UART 1 */ | ||
| 375 | #define chipcHw_REG_SOFT_RESET_UART0 0x0000000000000100ULL /* Reset UART 0 */ | ||
| 376 | #define chipcHw_REG_SOFT_RESET_NVI 0x0000000000000080ULL /* Reset NVI */ | ||
| 377 | #define chipcHw_REG_SOFT_RESET_WDOG 0x0000000000000040ULL /* Reset Watch dog */ | ||
| 378 | #define chipcHw_REG_SOFT_RESET_TMR 0x0000000000000020ULL /* Reset Timer */ | ||
| 379 | #define chipcHw_REG_SOFT_RESET_ETM 0x0000000000000010ULL /* Reset ETM */ | ||
| 380 | #define chipcHw_REG_SOFT_RESET_ARM_HOLD 0x0000000000000008ULL /* Reset ARM and HOLD */ | ||
| 381 | #define chipcHw_REG_SOFT_RESET_ARM 0x0000000000000004ULL /* Reset ARM */ | ||
| 382 | #define chipcHw_REG_SOFT_RESET_CHIP_WARM 0x0000000000000002ULL /* Chip warm reset */ | ||
| 383 | #define chipcHw_REG_SOFT_RESET_CHIP_SOFT 0x0000000000000001ULL /* Chip soft reset */ | ||
| 384 | #define chipcHw_REG_SOFT_RESET_VDEC 0x0000100000000000ULL /* Video decoder */ | ||
| 385 | #define chipcHw_REG_SOFT_RESET_GE 0x0000080000000000ULL /* Graphics engine */ | ||
| 386 | #define chipcHw_REG_SOFT_RESET_OTP 0x0000040000000000ULL /* Reset OTP */ | ||
| 387 | #define chipcHw_REG_SOFT_RESET_USB2 0x0000020000000000ULL /* Reset USB2 */ | ||
| 388 | #define chipcHw_REG_SOFT_RESET_USB1 0x0000010000000000ULL /* Reset USB 1 */ | ||
| 389 | #define chipcHw_REG_SOFT_RESET_USB 0x0000008000000000ULL /* Reset USB 1 and USB2 soft reset */ | ||
| 390 | #define chipcHw_REG_SOFT_RESET_ESW 0x0000004000000000ULL /* Reset Ethernet switch */ | ||
| 391 | #define chipcHw_REG_SOFT_RESET_ESWCLK 0x0000002000000000ULL /* Reset Ethernet switch clock */ | ||
| 392 | #define chipcHw_REG_SOFT_RESET_DDRPHY 0x0000001000000000ULL /* Reset DDR Physical */ | ||
| 393 | #define chipcHw_REG_SOFT_RESET_DDR 0x0000000800000000ULL /* Reset DDR Controller */ | ||
| 394 | #define chipcHw_REG_SOFT_RESET_TSC 0x0000000400000000ULL /* Reset Touch screen */ | ||
| 395 | #define chipcHw_REG_SOFT_RESET_PCM 0x0000000200000000ULL /* Reset PCM device */ | ||
| 396 | #define chipcHw_REG_SOFT_RESET_APM 0x0000200100000000ULL /* Reset APM device */ | ||
| 397 | |||
| 398 | #define chipcHw_REG_SOFT_RESET_VPM_GLOBAL_UNHOLD 0x8000000000000000ULL /* Unhold Global VPM */ | ||
| 399 | #define chipcHw_REG_SOFT_RESET_VPM_UNHOLD 0x4000000000000000ULL /* Unhold VPM */ | ||
| 400 | #define chipcHw_REG_SOFT_RESET_ARM_UNHOLD 0x2000000000000000ULL /* Unhold ARM reset */ | ||
| 401 | #define chipcHw_REG_SOFT_RESET_UNHOLD_MASK 0xF000000000000000ULL /* Mask to handle unhold request */ | ||
| 402 | |||
| 403 | /* Audio channel control defines */ | ||
| 404 | #define chipcHw_REG_AUDIO_CHANNEL_ENABLE_ALL 0x00000001 /* Enable all audio channel */ | ||
| 405 | #define chipcHw_REG_AUDIO_CHANNEL_ENABLE_A 0x00000002 /* Enable channel A */ | ||
| 406 | #define chipcHw_REG_AUDIO_CHANNEL_ENABLE_B 0x00000004 /* Enable channel B */ | ||
| 407 | #define chipcHw_REG_AUDIO_CHANNEL_ENABLE_C 0x00000008 /* Enable channel C */ | ||
| 408 | #define chipcHw_REG_AUDIO_CHANNEL_ENABLE_NTP_CLOCK 0x00000010 /* Enable NTP clock */ | ||
| 409 | #define chipcHw_REG_AUDIO_CHANNEL_ENABLE_PCM0_CLOCK 0x00000020 /* Enable PCM0 clock */ | ||
| 410 | #define chipcHw_REG_AUDIO_CHANNEL_ENABLE_PCM1_CLOCK 0x00000040 /* Enable PCM1 clock */ | ||
| 411 | #define chipcHw_REG_AUDIO_CHANNEL_ENABLE_APM_CLOCK 0x00000080 /* Enable APM clock */ | ||
| 412 | |||
| 413 | /* Misc. chip control defines */ | ||
| 414 | #define chipcHw_REG_MISC_CTRL_GE_SEL 0x00040000 /* Select GE2/GE3 */ | ||
| 415 | #define chipcHw_REG_MISC_CTRL_I2S1_CLOCK_ONCHIP 0x00000000 /* Use on chip clock for I2S1 */ | ||
| 416 | #define chipcHw_REG_MISC_CTRL_I2S1_CLOCK_GPIO 0x00020000 /* Use external clock via GPIO pin 26 for I2S1 */ | ||
| 417 | #define chipcHw_REG_MISC_CTRL_I2S0_CLOCK_ONCHIP 0x00000000 /* Use on chip clock for I2S0 */ | ||
| 418 | #define chipcHw_REG_MISC_CTRL_I2S0_CLOCK_GPIO 0x00010000 /* Use external clock via GPIO pin 45 for I2S0 */ | ||
| 419 | #define chipcHw_REG_MISC_CTRL_ARM_CP15_DISABLE 0x00008000 /* Disable ARM CP15 bit */ | ||
| 420 | #define chipcHw_REG_MISC_CTRL_RTC_DISABLE 0x00000008 /* Disable RTC registers */ | ||
| 421 | #define chipcHw_REG_MISC_CTRL_BBRAM_DISABLE 0x00000004 /* Disable Battery Backed RAM */ | ||
| 422 | #define chipcHw_REG_MISC_CTRL_USB_MODE_HOST 0x00000002 /* Set USB as host */ | ||
| 423 | #define chipcHw_REG_MISC_CTRL_USB_MODE_DEVICE 0xFFFFFFFD /* Set USB as device */ | ||
| 424 | #define chipcHw_REG_MISC_CTRL_USB_POWERON 0xFFFFFFFE /* Power up USB */ | ||
| 425 | #define chipcHw_REG_MISC_CTRL_USB_POWEROFF 0x00000001 /* Power down USB */ | ||
| 426 | |||
| 427 | /* OTP configuration defines */ | ||
| 428 | #define chipcHw_REG_OTP_SECURITY_OFF 0x0000020000000000ULL /* Security support is OFF */ | ||
| 429 | #define chipcHw_REG_OTP_SPU_SLOW 0x0000010000000000ULL /* Limited SPU throughput */ | ||
| 430 | #define chipcHw_REG_OTP_LCD_SPEED 0x0000000600000000ULL /* Set VPM speed one */ | ||
| 431 | #define chipcHw_REG_OTP_VPM_SPEED_1 0x0000000100000000ULL /* Set VPM speed one */ | ||
| 432 | #define chipcHw_REG_OTP_VPM_SPEED_0 0x0000000080000000ULL /* Set VPM speed zero */ | ||
| 433 | #define chipcHw_REG_OTP_AXI_SPEED 0x0000000060000000ULL /* Set maximum AXI bus speed */ | ||
| 434 | #define chipcHw_REG_OTP_APM_DISABLE 0x000000001F000000ULL /* Disable APM */ | ||
| 435 | #define chipcHw_REG_OTP_PIF_DISABLE 0x0000000000200000ULL /* Disable PIF */ | ||
| 436 | #define chipcHw_REG_OTP_VDEC_DISABLE 0x0000000000100000ULL /* Disable Video decoder */ | ||
| 437 | #define chipcHw_REG_OTP_BBL_DISABLE 0x0000000000080000ULL /* Disable RTC and BBRAM */ | ||
| 438 | #define chipcHw_REG_OTP_LED_DISABLE 0x0000000000040000ULL /* Disable LED */ | ||
| 439 | #define chipcHw_REG_OTP_GE_DISABLE 0x0000000000020000ULL /* Disable Graphics Engine */ | ||
| 440 | #define chipcHw_REG_OTP_LCD_DISABLE 0x0000000000010000ULL /* Disable LCD */ | ||
| 441 | #define chipcHw_REG_OTP_KEYPAD_DISABLE 0x0000000000008000ULL /* Disable keypad */ | ||
| 442 | #define chipcHw_REG_OTP_UART_DISABLE 0x0000000000004000ULL /* Disable UART */ | ||
| 443 | #define chipcHw_REG_OTP_SDIOH_DISABLE 0x0000000000003000ULL /* Disable SDIO host */ | ||
| 444 | #define chipcHw_REG_OTP_HSS_DISABLE 0x0000000000000C00ULL /* Disable HSS */ | ||
| 445 | #define chipcHw_REG_OTP_TSC_DISABLE 0x0000000000000200ULL /* Disable touch screen */ | ||
| 446 | #define chipcHw_REG_OTP_USB_DISABLE 0x0000000000000180ULL /* Disable USB */ | ||
| 447 | #define chipcHw_REG_OTP_SGMII_DISABLE 0x0000000000000060ULL /* Disable SGMII */ | ||
| 448 | #define chipcHw_REG_OTP_ETH_DISABLE 0x0000000000000018ULL /* Disable gigabit ethernet */ | ||
| 449 | #define chipcHw_REG_OTP_ETH_PHY_DISABLE 0x0000000000000006ULL /* Disable ethernet PHY */ | ||
| 450 | #define chipcHw_REG_OTP_VPM_DISABLE 0x0000000000000001ULL /* Disable VPM */ | ||
| 451 | |||
| 452 | /* Sticky bit defines */ | ||
| 453 | #define chipcHw_REG_STICKY_BOOT_DONE 0x00000001 /* Boot done */ | ||
| 454 | #define chipcHw_REG_STICKY_SOFT_RESET 0x00000002 /* ARM soft reset */ | ||
| 455 | #define chipcHw_REG_STICKY_GENERAL_1 0x00000004 /* General purpose bit 1 */ | ||
| 456 | #define chipcHw_REG_STICKY_GENERAL_2 0x00000008 /* General purpose bit 2 */ | ||
| 457 | #define chipcHw_REG_STICKY_GENERAL_3 0x00000010 /* General purpose bit 3 */ | ||
| 458 | #define chipcHw_REG_STICKY_GENERAL_4 0x00000020 /* General purpose bit 4 */ | ||
| 459 | #define chipcHw_REG_STICKY_GENERAL_5 0x00000040 /* General purpose bit 5 */ | ||
| 460 | #define chipcHw_REG_STICKY_POR_BROM 0x00000080 /* Special sticky bit for security - set in BROM to avoid other modes being entered */ | ||
| 461 | #define chipcHw_REG_STICKY_ARM_RESET 0x00000100 /* ARM reset */ | ||
| 462 | #define chipcHw_REG_STICKY_CHIP_SOFT_RESET 0x00000200 /* Chip soft reset */ | ||
| 463 | #define chipcHw_REG_STICKY_CHIP_WARM_RESET 0x00000400 /* Chip warm reset */ | ||
| 464 | #define chipcHw_REG_STICKY_WDOG_RESET 0x00000800 /* Watchdog reset */ | ||
| 465 | #define chipcHw_REG_STICKY_OTP_RESET 0x00001000 /* OTP reset */ | ||
| 466 | |||
| 467 | /* HW phase alignment defines *//* Spare1 register definitions */ | ||
| 468 | #define chipcHw_REG_SPARE1_DDR_PHASE_INTR_ENABLE 0x80000000 /* Enable DDR phase align panic interrupt */ | ||
| 469 | #define chipcHw_REG_SPARE1_VPM_PHASE_INTR_ENABLE 0x40000000 /* Enable VPM phase align panic interrupt */ | ||
| 470 | #define chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE 0x00000002 /* Enable access to VPM using system BUS */ | ||
| 471 | #define chipcHw_REG_SPARE1_DDR_BUS_ACCESS_ENABLE 0x00000001 /* Enable access to DDR using system BUS */ | ||
| 472 | /* DDRPhaseCtrl1 register definitions */ | ||
| 473 | #define chipcHw_REG_DDR_SW_PHASE_CTRL_ENABLE 0x80000000 /* Enable DDR SW phase alignment */ | ||
| 474 | #define chipcHw_REG_DDR_HW_PHASE_CTRL_ENABLE 0x40000000 /* Enable DDR HW phase alignment */ | ||
| 475 | #define chipcHw_REG_DDR_PHASE_VALUE_GE_MASK 0x0000007F /* DDR lower threshold for phase alignment */ | ||
| 476 | #define chipcHw_REG_DDR_PHASE_VALUE_GE_SHIFT 23 | ||
| 477 | #define chipcHw_REG_DDR_PHASE_VALUE_LE_MASK 0x0000007F /* DDR upper threshold for phase alignment */ | ||
| 478 | #define chipcHw_REG_DDR_PHASE_VALUE_LE_SHIFT 16 | ||
| 479 | #define chipcHw_REG_DDR_PHASE_ALIGN_WAIT_CYCLE_MASK 0x0000FFFF /* BUS Cycle to wait to run next DDR phase alignment */ | ||
| 480 | #define chipcHw_REG_DDR_PHASE_ALIGN_WAIT_CYCLE_SHIFT 0 | ||
| 481 | /* VPMPhaseCtrl1 register definitions */ | ||
| 482 | #define chipcHw_REG_VPM_SW_PHASE_CTRL_ENABLE 0x80000000 /* Enable VPM SW phase alignment */ | ||
| 483 | #define chipcHw_REG_VPM_HW_PHASE_CTRL_ENABLE 0x40000000 /* Enable VPM HW phase alignment */ | ||
| 484 | #define chipcHw_REG_VPM_PHASE_VALUE_GE_MASK 0x0000007F /* VPM lower threshold for phase alignment */ | ||
| 485 | #define chipcHw_REG_VPM_PHASE_VALUE_GE_SHIFT 23 | ||
| 486 | #define chipcHw_REG_VPM_PHASE_VALUE_LE_MASK 0x0000007F /* VPM upper threshold for phase alignment */ | ||
| 487 | #define chipcHw_REG_VPM_PHASE_VALUE_LE_SHIFT 16 | ||
| 488 | #define chipcHw_REG_VPM_PHASE_ALIGN_WAIT_CYCLE_MASK 0x0000FFFF /* BUS Cycle to wait to complete the VPM phase alignment */ | ||
| 489 | #define chipcHw_REG_VPM_PHASE_ALIGN_WAIT_CYCLE_SHIFT 0 | ||
| 490 | /* PhaseAlignStatus register definitions */ | ||
| 491 | #define chipcHw_REG_DDR_TIMEOUT_INTR_STATUS 0x80000000 /* DDR time out interrupt status */ | ||
| 492 | #define chipcHw_REG_DDR_PHASE_STATUS_MASK 0x0000007F /* DDR phase status value */ | ||
| 493 | #define chipcHw_REG_DDR_PHASE_STATUS_SHIFT 24 | ||
| 494 | #define chipcHw_REG_DDR_PHASE_ALIGNED 0x00800000 /* DDR Phase aligned status */ | ||
| 495 | #define chipcHw_REG_DDR_LOAD 0x00400000 /* Load DDR phase status */ | ||
| 496 | #define chipcHw_REG_DDR_PHASE_CTRL_MASK 0x0000003F /* DDR phase control value */ | ||
| 497 | #define chipcHw_REG_DDR_PHASE_CTRL_SHIFT 16 | ||
| 498 | #define chipcHw_REG_VPM_TIMEOUT_INTR_STATUS 0x80000000 /* VPM time out interrupt status */ | ||
| 499 | #define chipcHw_REG_VPM_PHASE_STATUS_MASK 0x0000007F /* VPM phase status value */ | ||
| 500 | #define chipcHw_REG_VPM_PHASE_STATUS_SHIFT 8 | ||
| 501 | #define chipcHw_REG_VPM_PHASE_ALIGNED 0x00000080 /* VPM Phase aligned status */ | ||
| 502 | #define chipcHw_REG_VPM_LOAD 0x00000040 /* Load VPM phase status */ | ||
| 503 | #define chipcHw_REG_VPM_PHASE_CTRL_MASK 0x0000003F /* VPM phase control value */ | ||
| 504 | #define chipcHw_REG_VPM_PHASE_CTRL_SHIFT 0 | ||
| 505 | /* DDRPhaseCtrl2 register definitions */ | ||
| 506 | #define chipcHw_REG_DDR_INTR_SERVICED 0x02000000 /* Acknowledge that interrupt was serviced */ | ||
| 507 | #define chipcHw_REG_DDR_TIMEOUT_INTR_ENABLE 0x01000000 /* Enable time out interrupt */ | ||
| 508 | #define chipcHw_REG_DDR_LOAD_COUNT_PHASE_CTRL_MASK 0x0000000F /* Wait before toggling load_ch */ | ||
| 509 | #define chipcHw_REG_DDR_LOAD_COUNT_PHASE_CTRL_SHIFT 20 | ||
| 510 | #define chipcHw_REG_DDR_TOTAL_LOAD_COUNT_CTRL_MASK 0x0000000F /* Total wait to settle ph_ctrl and load_ch */ | ||
| 511 | #define chipcHw_REG_DDR_TOTAL_LOAD_COUNT_CTRL_SHIFT 16 | ||
| 512 | #define chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_MASK 0x0000FFFF /* Time out value for DDR HW phase alignment */ | ||
| 513 | #define chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_SHIFT 0 | ||
| 514 | /* VPMPhaseCtrl2 register definitions */ | ||
| 515 | #define chipcHw_REG_VPM_INTR_SELECT_MASK 0x00000003 /* Interrupt select */ | ||
| 516 | #define chipcHw_REG_VPM_INTR_SELECT_SHIFT 26 | ||
| 517 | #define chipcHw_REG_VPM_INTR_DISABLE 0x00000000 | ||
| 518 | #define chipcHw_REG_VPM_INTR_FAST (0x1 << chipcHw_REG_VPM_INTR_SELECT_SHIFT) | ||
| 519 | #define chipcHw_REG_VPM_INTR_MEDIUM (0x2 << chipcHw_REG_VPM_INTR_SELECT_SHIFT) | ||
| 520 | #define chipcHw_REG_VPM_INTR_SLOW (0x3 << chipcHw_REG_VPM_INTR_SELECT_SHIFT) | ||
| 521 | #define chipcHw_REG_VPM_INTR_SERVICED 0x02000000 /* Acknowledge that interrupt was serviced */ | ||
| 522 | #define chipcHw_REG_VPM_TIMEOUT_INTR_ENABLE 0x01000000 /* Enable time out interrupt */ | ||
| 523 | #define chipcHw_REG_VPM_LOAD_COUNT_PHASE_CTRL_MASK 0x0000000F /* Wait before toggling load_ch */ | ||
| 524 | #define chipcHw_REG_VPM_LOAD_COUNT_PHASE_CTRL_SHIFT 20 | ||
| 525 | #define chipcHw_REG_VPM_TOTAL_LOAD_COUNT_CTRL_MASK 0x0000000F /* Total wait cycle to settle ph_ctrl and load_ch */ | ||
| 526 | #define chipcHw_REG_VPM_TOTAL_LOAD_COUNT_CTRL_SHIFT 16 | ||
| 527 | #define chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_MASK 0x0000FFFF /* Time out value for VPM HW phase alignment */ | ||
| 528 | #define chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_SHIFT 0 | ||
| 529 | |||
| 530 | #endif /* CHIPCHW_REG_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h b/arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h new file mode 100644 index 000000000000..f1b68e26fa6d --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h | |||
| @@ -0,0 +1,872 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file ddrcReg.h | ||
| 18 | * | ||
| 19 | * @brief Register definitions for BCMRING DDR2 Controller and PHY | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | /****************************************************************************/ | ||
| 23 | |||
| 24 | #ifndef DDRC_REG_H | ||
| 25 | #define DDRC_REG_H | ||
| 26 | |||
| 27 | #ifdef __cplusplus | ||
| 28 | extern "C" { | ||
| 29 | #endif | ||
| 30 | |||
| 31 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 32 | |||
| 33 | #include <csp/reg.h> | ||
| 34 | #include <csp/stdint.h> | ||
| 35 | |||
| 36 | #include <mach/csp/mm_io.h> | ||
| 37 | |||
| 38 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 39 | |||
| 40 | /*********************************************************************/ | ||
| 41 | /* DDR2 Controller (ARM PL341) register definitions */ | ||
| 42 | /*********************************************************************/ | ||
| 43 | |||
| 44 | /* -------------------------------------------------------------------- */ | ||
| 45 | /* -------------------------------------------------------------------- */ | ||
| 46 | /* ARM PL341 DDR2 configuration registers, offset 0x000 */ | ||
| 47 | /* -------------------------------------------------------------------- */ | ||
| 48 | /* -------------------------------------------------------------------- */ | ||
| 49 | |||
| 50 | typedef struct { | ||
| 51 | uint32_t memcStatus; | ||
| 52 | uint32_t memcCmd; | ||
| 53 | uint32_t directCmd; | ||
| 54 | uint32_t memoryCfg; | ||
| 55 | uint32_t refreshPrd; | ||
| 56 | uint32_t casLatency; | ||
| 57 | uint32_t writeLatency; | ||
| 58 | uint32_t tMrd; | ||
| 59 | uint32_t tRas; | ||
| 60 | uint32_t tRc; | ||
| 61 | uint32_t tRcd; | ||
| 62 | uint32_t tRfc; | ||
| 63 | uint32_t tRp; | ||
| 64 | uint32_t tRrd; | ||
| 65 | uint32_t tWr; | ||
| 66 | uint32_t tWtr; | ||
| 67 | uint32_t tXp; | ||
| 68 | uint32_t tXsr; | ||
| 69 | uint32_t tEsr; | ||
| 70 | uint32_t memoryCfg2; | ||
| 71 | uint32_t memoryCfg3; | ||
| 72 | uint32_t tFaw; | ||
| 73 | } ddrcReg_CTLR_MEMC_REG_t; | ||
| 74 | |||
| 75 | #define ddrcReg_CTLR_MEMC_REG_OFFSET 0x0000 | ||
| 76 | #define ddrcReg_CTLR_MEMC_REGP ((volatile ddrcReg_CTLR_MEMC_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_MEMC_REG_OFFSET)) | ||
| 77 | |||
| 78 | /* ----------------------------------------------------- */ | ||
| 79 | |||
| 80 | #define ddrcReg_CTLR_MEMC_STATUS_BANKS_MASK (0x3 << 12) | ||
| 81 | #define ddrcReg_CTLR_MEMC_STATUS_BANKS_4 (0x0 << 12) | ||
| 82 | #define ddrcReg_CTLR_MEMC_STATUS_BANKS_8 (0x3 << 12) | ||
| 83 | |||
| 84 | #define ddrcReg_CTLR_MEMC_STATUS_MONITORS_MASK (0x3 << 10) | ||
| 85 | #define ddrcReg_CTLR_MEMC_STATUS_MONITORS_0 (0x0 << 10) | ||
| 86 | #define ddrcReg_CTLR_MEMC_STATUS_MONITORS_1 (0x1 << 10) | ||
| 87 | #define ddrcReg_CTLR_MEMC_STATUS_MONITORS_2 (0x2 << 10) | ||
| 88 | #define ddrcReg_CTLR_MEMC_STATUS_MONITORS_4 (0x3 << 10) | ||
| 89 | |||
| 90 | #define ddrcReg_CTLR_MEMC_STATUS_CHIPS_MASK (0x3 << 7) | ||
| 91 | #define ddrcReg_CTLR_MEMC_STATUS_CHIPS_1 (0x0 << 7) | ||
| 92 | #define ddrcReg_CTLR_MEMC_STATUS_CHIPS_2 (0x1 << 7) | ||
| 93 | #define ddrcReg_CTLR_MEMC_STATUS_CHIPS_3 (0x2 << 7) | ||
| 94 | #define ddrcReg_CTLR_MEMC_STATUS_CHIPS_4 (0x3 << 7) | ||
| 95 | |||
| 96 | #define ddrcReg_CTLR_MEMC_STATUS_TYPE_MASK (0x7 << 4) | ||
| 97 | #define ddrcReg_CTLR_MEMC_STATUS_TYPE_DDR2 (0x5 << 4) | ||
| 98 | |||
| 99 | #define ddrcReg_CTLR_MEMC_STATUS_WIDTH_MASK (0x3 << 2) | ||
| 100 | #define ddrcReg_CTLR_MEMC_STATUS_WIDTH_16 (0x0 << 2) | ||
| 101 | #define ddrcReg_CTLR_MEMC_STATUS_WIDTH_32 (0x1 << 2) | ||
| 102 | #define ddrcReg_CTLR_MEMC_STATUS_WIDTH_64 (0x2 << 2) | ||
| 103 | #define ddrcReg_CTLR_MEMC_STATUS_WIDTH_128 (0x3 << 2) | ||
| 104 | |||
| 105 | #define ddrcReg_CTLR_MEMC_STATUS_STATE_MASK (0x3 << 0) | ||
| 106 | #define ddrcReg_CTLR_MEMC_STATUS_STATE_CONFIG (0x0 << 0) | ||
| 107 | #define ddrcReg_CTLR_MEMC_STATUS_STATE_READY (0x1 << 0) | ||
| 108 | #define ddrcReg_CTLR_MEMC_STATUS_STATE_PAUSED (0x2 << 0) | ||
| 109 | #define ddrcReg_CTLR_MEMC_STATUS_STATE_LOWPWR (0x3 << 0) | ||
| 110 | |||
| 111 | /* ----------------------------------------------------- */ | ||
| 112 | |||
| 113 | #define ddrcReg_CTLR_MEMC_CMD_MASK (0x7 << 0) | ||
| 114 | #define ddrcReg_CTLR_MEMC_CMD_GO (0x0 << 0) | ||
| 115 | #define ddrcReg_CTLR_MEMC_CMD_SLEEP (0x1 << 0) | ||
| 116 | #define ddrcReg_CTLR_MEMC_CMD_WAKEUP (0x2 << 0) | ||
| 117 | #define ddrcReg_CTLR_MEMC_CMD_PAUSE (0x3 << 0) | ||
| 118 | #define ddrcReg_CTLR_MEMC_CMD_CONFIGURE (0x4 << 0) | ||
| 119 | #define ddrcReg_CTLR_MEMC_CMD_ACTIVE_PAUSE (0x7 << 0) | ||
| 120 | |||
| 121 | /* ----------------------------------------------------- */ | ||
| 122 | |||
| 123 | #define ddrcReg_CTLR_DIRECT_CMD_CHIP_SHIFT 20 | ||
| 124 | #define ddrcReg_CTLR_DIRECT_CMD_CHIP_MASK (0x3 << ddrcReg_CTLR_DIRECT_CMD_CHIP_SHIFT) | ||
| 125 | |||
| 126 | #define ddrcReg_CTLR_DIRECT_CMD_TYPE_PRECHARGEALL (0x0 << 18) | ||
| 127 | #define ddrcReg_CTLR_DIRECT_CMD_TYPE_AUTOREFRESH (0x1 << 18) | ||
| 128 | #define ddrcReg_CTLR_DIRECT_CMD_TYPE_MODEREG (0x2 << 18) | ||
| 129 | #define ddrcReg_CTLR_DIRECT_CMD_TYPE_NOP (0x3 << 18) | ||
| 130 | |||
| 131 | #define ddrcReg_CTLR_DIRECT_CMD_BANK_SHIFT 16 | ||
| 132 | #define ddrcReg_CTLR_DIRECT_CMD_BANK_MASK (0x3 << ddrcReg_CTLR_DIRECT_CMD_BANK_SHIFT) | ||
| 133 | |||
| 134 | #define ddrcReg_CTLR_DIRECT_CMD_ADDR_SHIFT 0 | ||
| 135 | #define ddrcReg_CTLR_DIRECT_CMD_ADDR_MASK (0x1ffff << ddrcReg_CTLR_DIRECT_CMD_ADDR_SHIFT) | ||
| 136 | |||
| 137 | /* ----------------------------------------------------- */ | ||
| 138 | |||
| 139 | #define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_MASK (0x3 << 21) | ||
| 140 | #define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_1 (0x0 << 21) | ||
| 141 | #define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_2 (0x1 << 21) | ||
| 142 | #define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_3 (0x2 << 21) | ||
| 143 | #define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_4 (0x3 << 21) | ||
| 144 | |||
| 145 | #define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_MASK (0x7 << 18) | ||
| 146 | #define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_3_0 (0x0 << 18) | ||
| 147 | #define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_4_1 (0x1 << 18) | ||
| 148 | #define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_5_2 (0x2 << 18) | ||
| 149 | #define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_6_3 (0x3 << 18) | ||
| 150 | #define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_7_4 (0x4 << 18) | ||
| 151 | #define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_8_5 (0x5 << 18) | ||
| 152 | #define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_9_6 (0x6 << 18) | ||
| 153 | #define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_10_7 (0x7 << 18) | ||
| 154 | |||
| 155 | #define ddrcReg_CTLR_MEMORY_CFG_BURST_LEN_MASK (0x7 << 15) | ||
| 156 | #define ddrcReg_CTLR_MEMORY_CFG_BURST_LEN_4 (0x2 << 15) | ||
| 157 | #define ddrcReg_CTLR_MEMORY_CFG_BURST_LEN_8 (0x3 << 15) /* @note Not supported in PL341 */ | ||
| 158 | |||
| 159 | #define ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_ENABLE (0x1 << 13) | ||
| 160 | |||
| 161 | #define ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_CYCLES_SHIFT 7 | ||
| 162 | #define ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_CYCLES_MASK (0x3f << ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_CYCLES_SHIFT) | ||
| 163 | |||
| 164 | #define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_MASK (0x7 << 3) | ||
| 165 | #define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_11 (0x0 << 3) | ||
| 166 | #define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_12 (0x1 << 3) | ||
| 167 | #define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_13 (0x2 << 3) | ||
| 168 | #define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_14 (0x3 << 3) | ||
| 169 | #define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_15 (0x4 << 3) | ||
| 170 | #define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_16 (0x5 << 3) | ||
| 171 | |||
| 172 | #define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_MASK (0x7 << 0) | ||
| 173 | #define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_9 (0x1 << 0) | ||
| 174 | #define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_10 (0x2 << 0) | ||
| 175 | #define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_11 (0x3 << 0) | ||
| 176 | |||
| 177 | /* ----------------------------------------------------- */ | ||
| 178 | |||
| 179 | #define ddrcReg_CTLR_REFRESH_PRD_SHIFT 0 | ||
| 180 | #define ddrcReg_CTLR_REFRESH_PRD_MASK (0x7fff << ddrcReg_CTLR_REFRESH_PRD_SHIFT) | ||
| 181 | |||
| 182 | /* ----------------------------------------------------- */ | ||
| 183 | |||
| 184 | #define ddrcReg_CTLR_CAS_LATENCY_SHIFT 1 | ||
| 185 | #define ddrcReg_CTLR_CAS_LATENCY_MASK (0x7 << ddrcReg_CTLR_CAS_LATENCY_SHIFT) | ||
| 186 | |||
| 187 | /* ----------------------------------------------------- */ | ||
| 188 | |||
| 189 | #define ddrcReg_CTLR_WRITE_LATENCY_SHIFT 0 | ||
| 190 | #define ddrcReg_CTLR_WRITE_LATENCY_MASK (0x7 << ddrcReg_CTLR_WRITE_LATENCY_SHIFT) | ||
| 191 | |||
| 192 | /* ----------------------------------------------------- */ | ||
| 193 | |||
| 194 | #define ddrcReg_CTLR_T_MRD_SHIFT 0 | ||
| 195 | #define ddrcReg_CTLR_T_MRD_MASK (0x7f << ddrcReg_CTLR_T_MRD_SHIFT) | ||
| 196 | |||
| 197 | /* ----------------------------------------------------- */ | ||
| 198 | |||
| 199 | #define ddrcReg_CTLR_T_RAS_SHIFT 0 | ||
| 200 | #define ddrcReg_CTLR_T_RAS_MASK (0x1f << ddrcReg_CTLR_T_RAS_SHIFT) | ||
| 201 | |||
| 202 | /* ----------------------------------------------------- */ | ||
| 203 | |||
| 204 | #define ddrcReg_CTLR_T_RC_SHIFT 0 | ||
| 205 | #define ddrcReg_CTLR_T_RC_MASK (0x1f << ddrcReg_CTLR_T_RC_SHIFT) | ||
| 206 | |||
| 207 | /* ----------------------------------------------------- */ | ||
| 208 | |||
| 209 | #define ddrcReg_CTLR_T_RCD_SCHEDULE_DELAY_SHIFT 8 | ||
| 210 | #define ddrcReg_CTLR_T_RCD_SCHEDULE_DELAY_MASK (0x7 << ddrcReg_CTLR_T_RCD_SCHEDULE_DELAY_SHIFT) | ||
| 211 | |||
| 212 | #define ddrcReg_CTLR_T_RCD_SHIFT 0 | ||
| 213 | #define ddrcReg_CTLR_T_RCD_MASK (0x7 << ddrcReg_CTLR_T_RCD_SHIFT) | ||
| 214 | |||
| 215 | /* ----------------------------------------------------- */ | ||
| 216 | |||
| 217 | #define ddrcReg_CTLR_T_RFC_SCHEDULE_DELAY_SHIFT 8 | ||
| 218 | #define ddrcReg_CTLR_T_RFC_SCHEDULE_DELAY_MASK (0x7f << ddrcReg_CTLR_T_RFC_SCHEDULE_DELAY_SHIFT) | ||
| 219 | |||
| 220 | #define ddrcReg_CTLR_T_RFC_SHIFT 0 | ||
| 221 | #define ddrcReg_CTLR_T_RFC_MASK (0x7f << ddrcReg_CTLR_T_RFC_SHIFT) | ||
| 222 | |||
| 223 | /* ----------------------------------------------------- */ | ||
| 224 | |||
| 225 | #define ddrcReg_CTLR_T_RP_SCHEDULE_DELAY_SHIFT 8 | ||
| 226 | #define ddrcReg_CTLR_T_RP_SCHEDULE_DELAY_MASK (0x7 << ddrcReg_CTLR_T_RP_SCHEDULE_DELAY_SHIFT) | ||
| 227 | |||
| 228 | #define ddrcReg_CTLR_T_RP_SHIFT 0 | ||
| 229 | #define ddrcReg_CTLR_T_RP_MASK (0xf << ddrcReg_CTLR_T_RP_SHIFT) | ||
| 230 | |||
| 231 | /* ----------------------------------------------------- */ | ||
| 232 | |||
| 233 | #define ddrcReg_CTLR_T_RRD_SHIFT 0 | ||
| 234 | #define ddrcReg_CTLR_T_RRD_MASK (0xf << ddrcReg_CTLR_T_RRD_SHIFT) | ||
| 235 | |||
| 236 | /* ----------------------------------------------------- */ | ||
| 237 | |||
| 238 | #define ddrcReg_CTLR_T_WR_SHIFT 0 | ||
| 239 | #define ddrcReg_CTLR_T_WR_MASK (0x7 << ddrcReg_CTLR_T_WR_SHIFT) | ||
| 240 | |||
| 241 | /* ----------------------------------------------------- */ | ||
| 242 | |||
| 243 | #define ddrcReg_CTLR_T_WTR_SHIFT 0 | ||
| 244 | #define ddrcReg_CTLR_T_WTR_MASK (0x7 << ddrcReg_CTLR_T_WTR_SHIFT) | ||
| 245 | |||
| 246 | /* ----------------------------------------------------- */ | ||
| 247 | |||
| 248 | #define ddrcReg_CTLR_T_XP_SHIFT 0 | ||
| 249 | #define ddrcReg_CTLR_T_XP_MASK (0xff << ddrcReg_CTLR_T_XP_SHIFT) | ||
| 250 | |||
| 251 | /* ----------------------------------------------------- */ | ||
| 252 | |||
| 253 | #define ddrcReg_CTLR_T_XSR_SHIFT 0 | ||
| 254 | #define ddrcReg_CTLR_T_XSR_MASK (0xff << ddrcReg_CTLR_T_XSR_SHIFT) | ||
| 255 | |||
| 256 | /* ----------------------------------------------------- */ | ||
| 257 | |||
| 258 | #define ddrcReg_CTLR_T_ESR_SHIFT 0 | ||
| 259 | #define ddrcReg_CTLR_T_ESR_MASK (0xff << ddrcReg_CTLR_T_ESR_SHIFT) | ||
| 260 | |||
| 261 | /* ----------------------------------------------------- */ | ||
| 262 | |||
| 263 | #define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_MASK (0x3 << 6) | ||
| 264 | #define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_16BITS (0 << 6) | ||
| 265 | #define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_32BITS (1 << 6) | ||
| 266 | #define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_64BITS (2 << 6) | ||
| 267 | |||
| 268 | #define ddrcReg_CTLR_MEMORY_CFG2_AXI_BANK_BITS_MASK (0x3 << 4) | ||
| 269 | #define ddrcReg_CTLR_MEMORY_CFG2_AXI_BANK_BITS_2 (0 << 4) | ||
| 270 | #define ddrcReg_CTLR_MEMORY_CFG2_AXI_BANK_BITS_3 (3 << 4) | ||
| 271 | |||
| 272 | #define ddrcReg_CTLR_MEMORY_CFG2_CKE_INIT_STATE_LOW (0 << 3) | ||
| 273 | #define ddrcReg_CTLR_MEMORY_CFG2_CKE_INIT_STATE_HIGH (1 << 3) | ||
| 274 | |||
| 275 | #define ddrcReg_CTLR_MEMORY_CFG2_DQM_INIT_STATE_LOW (0 << 2) | ||
| 276 | #define ddrcReg_CTLR_MEMORY_CFG2_DQM_INIT_STATE_HIGH (1 << 2) | ||
| 277 | |||
| 278 | #define ddrcReg_CTLR_MEMORY_CFG2_CLK_MASK (0x3 << 0) | ||
| 279 | #define ddrcReg_CTLR_MEMORY_CFG2_CLK_ASYNC (0 << 0) | ||
| 280 | #define ddrcReg_CTLR_MEMORY_CFG2_CLK_SYNC_A_LE_M (1 << 0) | ||
| 281 | #define ddrcReg_CTLR_MEMORY_CFG2_CLK_SYNC_A_GT_M (3 << 0) | ||
| 282 | |||
| 283 | /* ----------------------------------------------------- */ | ||
| 284 | |||
| 285 | #define ddrcReg_CTLR_MEMORY_CFG3_REFRESH_TO_SHIFT 0 | ||
| 286 | #define ddrcReg_CTLR_MEMORY_CFG3_REFRESH_TO_MASK (0x7 << ddrcReg_CTLR_MEMORY_CFG3_REFRESH_TO_SHIFT) | ||
| 287 | |||
| 288 | /* ----------------------------------------------------- */ | ||
| 289 | |||
| 290 | #define ddrcReg_CTLR_T_FAW_SCHEDULE_DELAY_SHIFT 8 | ||
| 291 | #define ddrcReg_CTLR_T_FAW_SCHEDULE_DELAY_MASK (0x1f << ddrcReg_CTLR_T_FAW_SCHEDULE_DELAY_SHIFT) | ||
| 292 | |||
| 293 | #define ddrcReg_CTLR_T_FAW_PERIOD_SHIFT 0 | ||
| 294 | #define ddrcReg_CTLR_T_FAW_PERIOD_MASK (0x1f << ddrcReg_CTLR_T_FAW_PERIOD_SHIFT) | ||
| 295 | |||
| 296 | /* -------------------------------------------------------------------- */ | ||
| 297 | /* -------------------------------------------------------------------- */ | ||
| 298 | /* ARM PL341 AXI ID QOS configuration registers, offset 0x100 */ | ||
| 299 | /* -------------------------------------------------------------------- */ | ||
| 300 | /* -------------------------------------------------------------------- */ | ||
| 301 | |||
| 302 | #define ddrcReg_CTLR_QOS_CNT 16 | ||
| 303 | #define ddrcReg_CTLR_QOS_MAX (ddrcReg_CTLR_QOS_CNT - 1) | ||
| 304 | |||
| 305 | typedef struct { | ||
| 306 | uint32_t cfg[ddrcReg_CTLR_QOS_CNT]; | ||
| 307 | } ddrcReg_CTLR_QOS_REG_t; | ||
| 308 | |||
| 309 | #define ddrcReg_CTLR_QOS_REG_OFFSET 0x100 | ||
| 310 | #define ddrcReg_CTLR_QOS_REGP ((volatile ddrcReg_CTLR_QOS_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_QOS_REG_OFFSET)) | ||
| 311 | |||
| 312 | /* ----------------------------------------------------- */ | ||
| 313 | |||
| 314 | #define ddrcReg_CTLR_QOS_CFG_MAX_SHIFT 2 | ||
| 315 | #define ddrcReg_CTLR_QOS_CFG_MAX_MASK (0xff << ddrcReg_CTLR_QOS_CFG_MAX_SHIFT) | ||
| 316 | |||
| 317 | #define ddrcReg_CTLR_QOS_CFG_MIN_SHIFT 1 | ||
| 318 | #define ddrcReg_CTLR_QOS_CFG_MIN_MASK (1 << ddrcReg_CTLR_QOS_CFG_MIN_SHIFT) | ||
| 319 | |||
| 320 | #define ddrcReg_CTLR_QOS_CFG_ENABLE (1 << 0) | ||
| 321 | |||
| 322 | /* -------------------------------------------------------------------- */ | ||
| 323 | /* -------------------------------------------------------------------- */ | ||
| 324 | /* ARM PL341 Memory chip configuration registers, offset 0x200 */ | ||
| 325 | /* -------------------------------------------------------------------- */ | ||
| 326 | /* -------------------------------------------------------------------- */ | ||
| 327 | |||
| 328 | #define ddrcReg_CTLR_CHIP_CNT 4 | ||
| 329 | #define ddrcReg_CTLR_CHIP_MAX (ddrcReg_CTLR_CHIP_CNT - 1) | ||
| 330 | |||
| 331 | typedef struct { | ||
| 332 | uint32_t cfg[ddrcReg_CTLR_CHIP_CNT]; | ||
| 333 | } ddrcReg_CTLR_CHIP_REG_t; | ||
| 334 | |||
| 335 | #define ddrcReg_CTLR_CHIP_REG_OFFSET 0x200 | ||
| 336 | #define ddrcReg_CTLR_CHIP_REGP ((volatile ddrcReg_CTLR_CHIP_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_CHIP_REG_OFFSET)) | ||
| 337 | |||
| 338 | /* ----------------------------------------------------- */ | ||
| 339 | |||
| 340 | #define ddrcReg_CTLR_CHIP_CFG_MEM_ORG_MASK (1 << 16) | ||
| 341 | #define ddrcReg_CTLR_CHIP_CFG_MEM_ORG_ROW_BANK_COL (0 << 16) | ||
| 342 | #define ddrcReg_CTLR_CHIP_CFG_MEM_ORG_BANK_ROW_COL (1 << 16) | ||
| 343 | |||
| 344 | #define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MATCH_SHIFT 8 | ||
| 345 | #define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MATCH_MASK (0xff << ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MATCH_SHIFT) | ||
| 346 | |||
| 347 | #define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MASK_SHIFT 0 | ||
| 348 | #define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MASK_MASK (0xff << ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MASK_SHIFT) | ||
| 349 | |||
| 350 | /* -------------------------------------------------------------------- */ | ||
| 351 | /* -------------------------------------------------------------------- */ | ||
| 352 | /* ARM PL341 User configuration registers, offset 0x300 */ | ||
| 353 | /* -------------------------------------------------------------------- */ | ||
| 354 | /* -------------------------------------------------------------------- */ | ||
| 355 | |||
| 356 | #define ddrcReg_CTLR_USER_OUTPUT_CNT 2 | ||
| 357 | |||
| 358 | typedef struct { | ||
| 359 | uint32_t input; | ||
| 360 | uint32_t output[ddrcReg_CTLR_USER_OUTPUT_CNT]; | ||
| 361 | uint32_t feature; | ||
| 362 | } ddrcReg_CTLR_USER_REG_t; | ||
| 363 | |||
| 364 | #define ddrcReg_CTLR_USER_REG_OFFSET 0x300 | ||
| 365 | #define ddrcReg_CTLR_USER_REGP ((volatile ddrcReg_CTLR_USER_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_USER_REG_OFFSET)) | ||
| 366 | |||
| 367 | /* ----------------------------------------------------- */ | ||
| 368 | |||
| 369 | #define ddrcReg_CTLR_USER_INPUT_STATUS_SHIFT 0 | ||
| 370 | #define ddrcReg_CTLR_USER_INPUT_STATUS_MASK (0xff << ddrcReg_CTLR_USER_INPUT_STATUS_SHIFT) | ||
| 371 | |||
| 372 | /* ----------------------------------------------------- */ | ||
| 373 | |||
| 374 | #define ddrcReg_CTLR_USER_OUTPUT_CFG_SHIFT 0 | ||
| 375 | #define ddrcReg_CTLR_USER_OUTPUT_CFG_MASK (0xff << ddrcReg_CTLR_USER_OUTPUT_CFG_SHIFT) | ||
| 376 | |||
| 377 | #define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT 1 | ||
| 378 | #define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_MASK (1 << ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT) | ||
| 379 | #define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_BP134 (0 << ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT) | ||
| 380 | #define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_PL301 (1 << ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT) | ||
| 381 | #define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_REGISTERED ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_PL301 | ||
| 382 | |||
| 383 | /* ----------------------------------------------------- */ | ||
| 384 | |||
| 385 | #define ddrcReg_CTLR_FEATURE_WRITE_BLOCK_DISABLE (1 << 2) | ||
| 386 | #define ddrcReg_CTLR_FEATURE_EARLY_BURST_RSP_DISABLE (1 << 0) | ||
| 387 | |||
| 388 | /*********************************************************************/ | ||
| 389 | /* Broadcom DDR23 PHY register definitions */ | ||
| 390 | /*********************************************************************/ | ||
| 391 | |||
| 392 | /* -------------------------------------------------------------------- */ | ||
| 393 | /* -------------------------------------------------------------------- */ | ||
| 394 | /* Broadcom DDR23 PHY Address and Control register definitions */ | ||
| 395 | /* -------------------------------------------------------------------- */ | ||
| 396 | /* -------------------------------------------------------------------- */ | ||
| 397 | |||
| 398 | typedef struct { | ||
| 399 | uint32_t revision; | ||
| 400 | uint32_t pmCtl; | ||
| 401 | REG32_RSVD(0x0008, 0x0010); | ||
| 402 | uint32_t pllStatus; | ||
| 403 | uint32_t pllCfg; | ||
| 404 | uint32_t pllPreDiv; | ||
| 405 | uint32_t pllDiv; | ||
| 406 | uint32_t pllCtl1; | ||
| 407 | uint32_t pllCtl2; | ||
| 408 | uint32_t ssCtl; | ||
| 409 | uint32_t ssCfg; | ||
| 410 | uint32_t vdlStatic; | ||
| 411 | uint32_t vdlDynamic; | ||
| 412 | uint32_t padIdle; | ||
| 413 | uint32_t pvtComp; | ||
| 414 | uint32_t padDrive; | ||
| 415 | uint32_t clkRgltrCtl; | ||
| 416 | } ddrcReg_PHY_ADDR_CTL_REG_t; | ||
| 417 | |||
| 418 | #define ddrcReg_PHY_ADDR_CTL_REG_OFFSET 0x0400 | ||
| 419 | #define ddrcReg_PHY_ADDR_CTL_REGP ((volatile ddrcReg_PHY_ADDR_CTL_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_PHY_ADDR_CTL_REG_OFFSET)) | ||
| 420 | |||
| 421 | /* @todo These SS definitions are duplicates of ones below */ | ||
| 422 | |||
| 423 | #define ddrcReg_PHY_ADDR_SS_CTRL_ENABLE 0x00000001 | ||
| 424 | #define ddrcReg_PHY_ADDR_SS_CFG_CYCLE_PER_TICK_MASK 0xFFFF0000 | ||
| 425 | #define ddrcReg_PHY_ADDR_SS_CFG_CYCLE_PER_TICK_SHIFT 16 | ||
| 426 | #define ddrcReg_PHY_ADDR_SS_CFG_MIN_CYCLE_PER_TICK 10 /* Higher the value, lower the SS modulation frequency */ | ||
| 427 | #define ddrcReg_PHY_ADDR_SS_CFG_NDIV_AMPLITUDE_MASK 0x0000FFFF | ||
| 428 | #define ddrcReg_PHY_ADDR_SS_CFG_NDIV_AMPLITUDE_SHIFT 0 | ||
| 429 | |||
| 430 | /* ----------------------------------------------------- */ | ||
| 431 | |||
| 432 | #define ddrcReg_PHY_ADDR_CTL_REVISION_MAJOR_SHIFT 8 | ||
| 433 | #define ddrcReg_PHY_ADDR_CTL_REVISION_MAJOR_MASK (0xff << ddrcReg_PHY_ADDR_CTL_REVISION_MAJOR_SHIFT) | ||
| 434 | |||
| 435 | #define ddrcReg_PHY_ADDR_CTL_REVISION_MINOR_SHIFT 0 | ||
| 436 | #define ddrcReg_PHY_ADDR_CTL_REVISION_MINOR_MASK (0xff << ddrcReg_PHY_ADDR_CTL_REVISION_MINOR_SHIFT) | ||
| 437 | |||
| 438 | /* ----------------------------------------------------- */ | ||
| 439 | |||
| 440 | #define ddrcReg_PHY_ADDR_CTL_CLK_PM_CTL_DDR_CLK_DISABLE (1 << 0) | ||
| 441 | |||
| 442 | /* ----------------------------------------------------- */ | ||
| 443 | |||
| 444 | #define ddrcReg_PHY_ADDR_CTL_PLL_STATUS_LOCKED (1 << 0) | ||
| 445 | |||
| 446 | /* ----------------------------------------------------- */ | ||
| 447 | |||
| 448 | #define ddrcReg_PHY_ADDR_CTL_PLL_CFG_DIV2_CLK_RESET (1 << 31) | ||
| 449 | |||
| 450 | #define ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_SEL_SHIFT 17 | ||
| 451 | #define ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_SEL_MASK (0x1f << ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_SEL_SHIFT) | ||
| 452 | |||
| 453 | #define ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_ENABLE (1 << 16) | ||
| 454 | |||
| 455 | #define ddrcReg_PHY_ADDR_CTL_PLL_CFG_BGAP_ADJ_SHIFT 12 | ||
| 456 | #define ddrcReg_PHY_ADDR_CTL_PLL_CFG_BGAP_ADJ_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PLL_CFG_BGAP_ADJ_SHIFT) | ||
| 457 | |||
| 458 | #define ddrcReg_PHY_ADDR_CTL_PLL_CFG_VCO_RNG (1 << 7) | ||
| 459 | #define ddrcReg_PHY_ADDR_CTL_PLL_CFG_CH1_PWRDWN (1 << 6) | ||
| 460 | #define ddrcReg_PHY_ADDR_CTL_PLL_CFG_BYPASS_ENABLE (1 << 5) | ||
| 461 | #define ddrcReg_PHY_ADDR_CTL_PLL_CFG_CLKOUT_ENABLE (1 << 4) | ||
| 462 | #define ddrcReg_PHY_ADDR_CTL_PLL_CFG_D_RESET (1 << 3) | ||
| 463 | #define ddrcReg_PHY_ADDR_CTL_PLL_CFG_A_RESET (1 << 2) | ||
| 464 | #define ddrcReg_PHY_ADDR_CTL_PLL_CFG_PWRDWN (1 << 0) | ||
| 465 | |||
| 466 | /* ----------------------------------------------------- */ | ||
| 467 | |||
| 468 | #define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_DITHER_MFB (1 << 26) | ||
| 469 | #define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_PWRDWN (1 << 25) | ||
| 470 | |||
| 471 | #define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_MODE_SHIFT 20 | ||
| 472 | #define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_MODE_MASK (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_MODE_SHIFT) | ||
| 473 | |||
| 474 | #define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_INT_SHIFT 8 | ||
| 475 | #define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_INT_MASK (0x1ff << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_INT_SHIFT) | ||
| 476 | |||
| 477 | #define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P2_SHIFT 4 | ||
| 478 | #define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P2_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P2_SHIFT) | ||
| 479 | |||
| 480 | #define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P1_SHIFT 0 | ||
| 481 | #define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P1_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P1_SHIFT) | ||
| 482 | |||
| 483 | /* ----------------------------------------------------- */ | ||
| 484 | |||
| 485 | #define ddrcReg_PHY_ADDR_CTL_PLL_DIV_M1_SHIFT 24 | ||
| 486 | #define ddrcReg_PHY_ADDR_CTL_PLL_DIV_M1_MASK (0xff << ddrcReg_PHY_ADDR_CTL_PLL_DIV_M1_SHIFT) | ||
| 487 | |||
| 488 | #define ddrcReg_PHY_ADDR_CTL_PLL_DIV_FRAC_SHIFT 0 | ||
| 489 | #define ddrcReg_PHY_ADDR_CTL_PLL_DIV_FRAC_MASK (0xffffff << ddrcReg_PHY_ADDR_CTL_PLL_DIV_FRAC_SHIFT) | ||
| 490 | |||
| 491 | /* ----------------------------------------------------- */ | ||
| 492 | |||
| 493 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_TESTA_SHIFT 30 | ||
| 494 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_TESTA_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_TESTA_SHIFT) | ||
| 495 | |||
| 496 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XS_SHIFT 27 | ||
| 497 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XS_MASK (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XS_SHIFT) | ||
| 498 | |||
| 499 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XF_SHIFT 24 | ||
| 500 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XF_MASK (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XF_SHIFT) | ||
| 501 | |||
| 502 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LPF_BW_SHIFT 22 | ||
| 503 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LPF_BW_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LPF_BW_SHIFT) | ||
| 504 | |||
| 505 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LF_ORDER (0x1 << 21) | ||
| 506 | |||
| 507 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CN_SHIFT 19 | ||
| 508 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CN_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CN_SHIFT) | ||
| 509 | |||
| 510 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RN_SHIFT 17 | ||
| 511 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RN_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RN_SHIFT) | ||
| 512 | |||
| 513 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CP_SHIFT 15 | ||
| 514 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CP_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CP_SHIFT) | ||
| 515 | |||
| 516 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CZ_SHIFT 13 | ||
| 517 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CZ_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CZ_SHIFT) | ||
| 518 | |||
| 519 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RZ_SHIFT 10 | ||
| 520 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RZ_MASK (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RZ_SHIFT) | ||
| 521 | |||
| 522 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICPX_SHIFT 5 | ||
| 523 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICPX_MASK (0x1f << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICPX_SHIFT) | ||
| 524 | |||
| 525 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICP_OFF_SHIFT 0 | ||
| 526 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICP_OFF_MASK (0x1f << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICP_OFF_SHIFT) | ||
| 527 | |||
| 528 | /* ----------------------------------------------------- */ | ||
| 529 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_PTAP_ADJ_SHIFT 4 | ||
| 530 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_PTAP_ADJ_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL2_PTAP_ADJ_SHIFT) | ||
| 531 | |||
| 532 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_CTAP_ADJ_SHIFT 2 | ||
| 533 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_CTAP_ADJ_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL2_CTAP_ADJ_SHIFT) | ||
| 534 | |||
| 535 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_LOWCUR_ENABLE (0x1 << 1) | ||
| 536 | #define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_BIASIN_ENABLE (0x1 << 0) | ||
| 537 | |||
| 538 | /* ----------------------------------------------------- */ | ||
| 539 | |||
| 540 | #define ddrcReg_PHY_ADDR_CTL_PLL_SS_EN_ENABLE (0x1 << 0) | ||
| 541 | |||
| 542 | /* ----------------------------------------------------- */ | ||
| 543 | |||
| 544 | #define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_CYC_PER_TICK_SHIFT 16 | ||
| 545 | #define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_CYC_PER_TICK_MASK (0xffff << ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_CYC_PER_TICK_SHIFT) | ||
| 546 | |||
| 547 | #define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_NDIV_AMP_SHIFT 0 | ||
| 548 | #define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_NDIV_AMP_MASK (0xffff << ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_NDIV_AMP_SHIFT) | ||
| 549 | |||
| 550 | /* ----------------------------------------------------- */ | ||
| 551 | |||
| 552 | #define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FORCE (1 << 20) | ||
| 553 | #define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_ENABLE (1 << 16) | ||
| 554 | |||
| 555 | #define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FALL_SHIFT 12 | ||
| 556 | #define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FALL_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FALL_SHIFT) | ||
| 557 | |||
| 558 | #define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_RISE_SHIFT 8 | ||
| 559 | #define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_RISE_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_RISE_SHIFT) | ||
| 560 | |||
| 561 | #define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_STEP_SHIFT 0 | ||
| 562 | #define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_STEP_MASK (0x3f << ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_STEP_SHIFT) | ||
| 563 | |||
| 564 | /* ----------------------------------------------------- */ | ||
| 565 | |||
| 566 | #define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_ENABLE (1 << 16) | ||
| 567 | |||
| 568 | #define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_FALL_SHIFT 12 | ||
| 569 | #define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_FALL_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_FALL_SHIFT) | ||
| 570 | |||
| 571 | #define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_RISE_SHIFT 8 | ||
| 572 | #define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_RISE_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_RISE_SHIFT) | ||
| 573 | |||
| 574 | #define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_STEP_SHIFT 0 | ||
| 575 | #define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_STEP_MASK (0x3f << ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_STEP_SHIFT) | ||
| 576 | |||
| 577 | /* ----------------------------------------------------- */ | ||
| 578 | |||
| 579 | #define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_ENABLE (1u << 31) | ||
| 580 | #define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_RXENB_DISABLE (1 << 8) | ||
| 581 | #define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CTL_IDDQ_DISABLE (1 << 6) | ||
| 582 | #define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CTL_REB_DISABLE (1 << 5) | ||
| 583 | #define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CTL_OEB_DISABLE (1 << 4) | ||
| 584 | #define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CKE_IDDQ_DISABLE (1 << 2) | ||
| 585 | #define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CKE_REB_DISABLE (1 << 1) | ||
| 586 | #define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CKE_OEB_DISABLE (1 << 0) | ||
| 587 | |||
| 588 | /* ----------------------------------------------------- */ | ||
| 589 | |||
| 590 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_DONE (1 << 30) | ||
| 591 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_DONE (1 << 29) | ||
| 592 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_SAMPLE_DONE (1 << 28) | ||
| 593 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_SAMPLE_AUTO_ENABLE (1 << 27) | ||
| 594 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_SAMPLE_ENABLE (1 << 26) | ||
| 595 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_OVR_ENABLE (1 << 25) | ||
| 596 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_OVR_ENABLE (1 << 24) | ||
| 597 | |||
| 598 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_SHIFT 20 | ||
| 599 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_SHIFT) | ||
| 600 | |||
| 601 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_SHIFT 16 | ||
| 602 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_SHIFT) | ||
| 603 | |||
| 604 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_PD_SHIFT 12 | ||
| 605 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_PD_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_PD_SHIFT) | ||
| 606 | |||
| 607 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_ND_SHIFT 8 | ||
| 608 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_ND_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_ND_SHIFT) | ||
| 609 | |||
| 610 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_PD_SHIFT 4 | ||
| 611 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_PD_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_PD_SHIFT) | ||
| 612 | |||
| 613 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_ND_SHIFT 0 | ||
| 614 | #define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_ND_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_ND_SHIFT) | ||
| 615 | |||
| 616 | /* ----------------------------------------------------- */ | ||
| 617 | |||
| 618 | #define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_RT60B (1 << 4) | ||
| 619 | #define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SEL_SSTL18 (1 << 3) | ||
| 620 | #define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SELTXDRV_CI (1 << 2) | ||
| 621 | #define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SELRXDRV (1 << 1) | ||
| 622 | #define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SLEW (1 << 0) | ||
| 623 | |||
| 624 | /* ----------------------------------------------------- */ | ||
| 625 | |||
| 626 | #define ddrcReg_PHY_ADDR_CTL_CLK_RGLTR_CTL_PWR_HALF (1 << 1) | ||
| 627 | #define ddrcReg_PHY_ADDR_CTL_CLK_RGLTR_CTL_PWR_OFF (1 << 0) | ||
| 628 | |||
| 629 | /* -------------------------------------------------------------------- */ | ||
| 630 | /* -------------------------------------------------------------------- */ | ||
| 631 | /* Broadcom DDR23 PHY Byte Lane register definitions */ | ||
| 632 | /* -------------------------------------------------------------------- */ | ||
| 633 | /* -------------------------------------------------------------------- */ | ||
| 634 | |||
| 635 | #define ddrcReg_PHY_BYTE_LANE_CNT 2 | ||
| 636 | #define ddrcReg_PHY_BYTE_LANE_MAX (ddrcReg_CTLR_BYTE_LANE_CNT - 1) | ||
| 637 | |||
| 638 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_CNT 8 | ||
| 639 | |||
| 640 | typedef struct { | ||
| 641 | uint32_t revision; | ||
| 642 | uint32_t vdlCalibrate; | ||
| 643 | uint32_t vdlStatus; | ||
| 644 | REG32_RSVD(0x000c, 0x0010); | ||
| 645 | uint32_t vdlOverride[ddrcReg_PHY_BYTE_LANE_VDL_OVR_CNT]; | ||
| 646 | uint32_t readCtl; | ||
| 647 | uint32_t readStatus; | ||
| 648 | uint32_t readClear; | ||
| 649 | uint32_t padIdleCtl; | ||
| 650 | uint32_t padDriveCtl; | ||
| 651 | uint32_t padClkCtl; | ||
| 652 | uint32_t writeCtl; | ||
| 653 | uint32_t clkRegCtl; | ||
| 654 | } ddrcReg_PHY_BYTE_LANE_REG_t; | ||
| 655 | |||
| 656 | /* There are 2 instances of the byte Lane registers, one for each byte lane. */ | ||
| 657 | #define ddrcReg_PHY_BYTE_LANE_1_REG_OFFSET 0x0500 | ||
| 658 | #define ddrcReg_PHY_BYTE_LANE_2_REG_OFFSET 0x0600 | ||
| 659 | |||
| 660 | #define ddrcReg_PHY_BYTE_LANE_1_REGP ((volatile ddrcReg_PHY_BYTE_LANE_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_PHY_BYTE_LANE_1_REG_OFFSET)) | ||
| 661 | #define ddrcReg_PHY_BYTE_LANE_2_REGP ((volatile ddrcReg_PHY_BYTE_LANE_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_PHY_BYTE_LANE_2_REG_OFFSET)) | ||
| 662 | |||
| 663 | /* ----------------------------------------------------- */ | ||
| 664 | |||
| 665 | #define ddrcReg_PHY_BYTE_LANE_REVISION_MAJOR_SHIFT 8 | ||
| 666 | #define ddrcReg_PHY_BYTE_LANE_REVISION_MAJOR_MASK (0xff << ddrcReg_PHY_BYTE_LANE_REVISION_MAJOR_SHIFT) | ||
| 667 | |||
| 668 | #define ddrcReg_PHY_BYTE_LANE_REVISION_MINOR_SHIFT 0 | ||
| 669 | #define ddrcReg_PHY_BYTE_LANE_REVISION_MINOR_MASK (0xff << ddrcReg_PHY_BYTE_LANE_REVISION_MINOR_SHIFT) | ||
| 670 | |||
| 671 | /* ----------------------------------------------------- */ | ||
| 672 | |||
| 673 | #define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_CLK_2CYCLE (1 << 4) | ||
| 674 | #define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_CLK_1CYCLE (0 << 4) | ||
| 675 | |||
| 676 | #define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_TEST (1 << 3) | ||
| 677 | #define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_ALWAYS (1 << 2) | ||
| 678 | #define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_ONCE (1 << 1) | ||
| 679 | #define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_FAST (1 << 0) | ||
| 680 | |||
| 681 | /* ----------------------------------------------------- */ | ||
| 682 | |||
| 683 | /* The byte lane VDL status calibTotal[9:0] is comprised of [9:4] step value, [3:2] fine fall */ | ||
| 684 | /* and [1:0] fine rise. Note that calibTotal[9:0] is located at bit 4 in the VDL status */ | ||
| 685 | /* register. The fine rise and fall are no longer used, so add some definitions for just */ | ||
| 686 | /* the step setting to simplify things. */ | ||
| 687 | |||
| 688 | #define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_STEP_SHIFT 8 | ||
| 689 | #define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_STEP_MASK (0x3f << ddrcReg_PHY_BYTE_LANE_VDL_STATUS_STEP_SHIFT) | ||
| 690 | |||
| 691 | #define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_TOTAL_SHIFT 4 | ||
| 692 | #define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_TOTAL_MASK (0x3ff << ddrcReg_PHY_BYTE_LANE_VDL_STATUS_TOTAL_SHIFT) | ||
| 693 | |||
| 694 | #define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_LOCK (1 << 1) | ||
| 695 | #define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_IDLE (1 << 0) | ||
| 696 | |||
| 697 | /* ----------------------------------------------------- */ | ||
| 698 | |||
| 699 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_ENABLE (1 << 16) | ||
| 700 | |||
| 701 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_FALL_SHIFT 12 | ||
| 702 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_FALL_MASK (0x3 << ddrcReg_PHY_BYTE_LANE_VDL_OVR_FALL_SHIFT) | ||
| 703 | |||
| 704 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_RISE_SHIFT 8 | ||
| 705 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_RISE_MASK (0x3 << ddrcReg_PHY_BYTE_LANE_VDL_OVR_RISE_SHIFT) | ||
| 706 | |||
| 707 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_STEP_SHIFT 0 | ||
| 708 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_STEP_MASK (0x3f << ddrcReg_PHY_BYTE_LANE_VDL_OVR_STEP_SHIFT) | ||
| 709 | |||
| 710 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_READ_DQS_P 0 | ||
| 711 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_READ_DQS_N 1 | ||
| 712 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_READ_EN 2 | ||
| 713 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_WRITE_DQ_DQM 3 | ||
| 714 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_READ_DQS_P 4 | ||
| 715 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_READ_DQS_N 5 | ||
| 716 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_READ_EN 6 | ||
| 717 | #define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_WRITE_DQ_DQM 7 | ||
| 718 | |||
| 719 | /* ----------------------------------------------------- */ | ||
| 720 | |||
| 721 | #define ddrcReg_PHY_BYTE_LANE_READ_CTL_DELAY_SHIFT 8 | ||
| 722 | #define ddrcReg_PHY_BYTE_LANE_READ_CTL_DELAY_MASK (0x3 << ddrcReg_PHY_BYTE_LANE_READ_CTL_DELAY_SHIFT) | ||
| 723 | |||
| 724 | #define ddrcReg_PHY_BYTE_LANE_READ_CTL_DQ_ODT_ENABLE (1 << 3) | ||
| 725 | #define ddrcReg_PHY_BYTE_LANE_READ_CTL_DQ_ODT_ADJUST (1 << 2) | ||
| 726 | #define ddrcReg_PHY_BYTE_LANE_READ_CTL_RD_ODT_ENABLE (1 << 1) | ||
| 727 | #define ddrcReg_PHY_BYTE_LANE_READ_CTL_RD_ODT_ADJUST (1 << 0) | ||
| 728 | |||
| 729 | /* ----------------------------------------------------- */ | ||
| 730 | |||
| 731 | #define ddrcReg_PHY_BYTE_LANE_READ_STATUS_ERROR_SHIFT 0 | ||
| 732 | #define ddrcReg_PHY_BYTE_LANE_READ_STATUS_ERROR_MASK (0xf << ddrcReg_PHY_BYTE_LANE_READ_STATUS_ERROR_SHIFT) | ||
| 733 | |||
| 734 | /* ----------------------------------------------------- */ | ||
| 735 | |||
| 736 | #define ddrcReg_PHY_BYTE_LANE_READ_CLEAR_STATUS (1 << 0) | ||
| 737 | |||
| 738 | /* ----------------------------------------------------- */ | ||
| 739 | |||
| 740 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_ENABLE (1u << 31) | ||
| 741 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_RXENB_DISABLE (1 << 19) | ||
| 742 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_IDDQ_DISABLE (1 << 18) | ||
| 743 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_REB_DISABLE (1 << 17) | ||
| 744 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_OEB_DISABLE (1 << 16) | ||
| 745 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_RXENB_DISABLE (1 << 15) | ||
| 746 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_IDDQ_DISABLE (1 << 14) | ||
| 747 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_REB_DISABLE (1 << 13) | ||
| 748 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_OEB_DISABLE (1 << 12) | ||
| 749 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_RXENB_DISABLE (1 << 11) | ||
| 750 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_IDDQ_DISABLE (1 << 10) | ||
| 751 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_REB_DISABLE (1 << 9) | ||
| 752 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_OEB_DISABLE (1 << 8) | ||
| 753 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_RXENB_DISABLE (1 << 7) | ||
| 754 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_IDDQ_DISABLE (1 << 6) | ||
| 755 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_REB_DISABLE (1 << 5) | ||
| 756 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_OEB_DISABLE (1 << 4) | ||
| 757 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_RXENB_DISABLE (1 << 3) | ||
| 758 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_IDDQ_DISABLE (1 << 2) | ||
| 759 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_REB_DISABLE (1 << 1) | ||
| 760 | #define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_OEB_DISABLE (1 << 0) | ||
| 761 | |||
| 762 | /* ----------------------------------------------------- */ | ||
| 763 | |||
| 764 | #define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_RT60B_DDR_READ_ENB (1 << 5) | ||
| 765 | #define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_RT60B (1 << 4) | ||
| 766 | #define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SEL_SSTL18 (1 << 3) | ||
| 767 | #define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SELTXDRV_CI (1 << 2) | ||
| 768 | #define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SELRXDRV (1 << 1) | ||
| 769 | #define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SLEW (1 << 0) | ||
| 770 | |||
| 771 | /* ----------------------------------------------------- */ | ||
| 772 | |||
| 773 | #define ddrcReg_PHY_BYTE_LANE_PAD_CLK_CTL_DISABLE (1 << 0) | ||
| 774 | |||
| 775 | /* ----------------------------------------------------- */ | ||
| 776 | |||
| 777 | #define ddrcReg_PHY_BYTE_LANE_WRITE_CTL_PREAMBLE_DDR3 (1 << 0) | ||
| 778 | |||
| 779 | /* ----------------------------------------------------- */ | ||
| 780 | |||
| 781 | #define ddrcReg_PHY_BYTE_LANE_CLK_REG_CTL_PWR_HALF (1 << 1) | ||
| 782 | #define ddrcReg_PHY_BYTE_LANE_CLK_REG_CTL_PWR_OFF (1 << 0) | ||
| 783 | |||
| 784 | /*********************************************************************/ | ||
| 785 | /* ARM PL341 DDRC to Broadcom DDR23 PHY glue register definitions */ | ||
| 786 | /*********************************************************************/ | ||
| 787 | |||
| 788 | typedef struct { | ||
| 789 | uint32_t cfg; | ||
| 790 | uint32_t actMonCnt; | ||
| 791 | uint32_t ctl; | ||
| 792 | uint32_t lbistCtl; | ||
| 793 | uint32_t lbistSeed; | ||
| 794 | uint32_t lbistStatus; | ||
| 795 | uint32_t tieOff; | ||
| 796 | uint32_t actMonClear; | ||
| 797 | uint32_t status; | ||
| 798 | uint32_t user; | ||
| 799 | } ddrcReg_CTLR_PHY_GLUE_REG_t; | ||
| 800 | |||
| 801 | #define ddrcReg_CTLR_PHY_GLUE_OFFSET 0x0700 | ||
| 802 | #define ddrcReg_CTLR_PHY_GLUE_REGP ((volatile ddrcReg_CTLR_PHY_GLUE_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_PHY_GLUE_OFFSET)) | ||
| 803 | |||
| 804 | /* ----------------------------------------------------- */ | ||
| 805 | |||
| 806 | /* DDR2 / AXI block phase alignment interrupt control */ | ||
| 807 | #define ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT 18 | ||
| 808 | #define ddrcReg_CTLR_PHY_GLUE_CFG_INT_MASK (0x3 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT) | ||
| 809 | #define ddrcReg_CTLR_PHY_GLUE_CFG_INT_OFF (0 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT) | ||
| 810 | #define ddrcReg_CTLR_PHY_GLUE_CFG_INT_ON_TIGHT (1 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT) | ||
| 811 | #define ddrcReg_CTLR_PHY_GLUE_CFG_INT_ON_MEDIUM (2 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT) | ||
| 812 | #define ddrcReg_CTLR_PHY_GLUE_CFG_INT_ON_LOOSE (3 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT) | ||
| 813 | |||
| 814 | #define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT 17 | ||
| 815 | #define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_MASK (1 << ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT) | ||
| 816 | #define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_DIFFERENTIAL (0 << ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT) | ||
| 817 | #define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_CMOS (1 << ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT) | ||
| 818 | |||
| 819 | #define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT 16 | ||
| 820 | #define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_MASK (1 << ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT) | ||
| 821 | #define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_DEEP (0 << ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT) | ||
| 822 | #define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHALLOW (1 << ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT) | ||
| 823 | #define ddrcReg_CTLR_PHY_GLUE_CFG_HW_FIXED_ALIGNMENT_DISABLED ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHALLOW | ||
| 824 | |||
| 825 | #define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT 15 | ||
| 826 | #define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_MASK (1 << ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT) | ||
| 827 | #define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_BP134 (0 << ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT) | ||
| 828 | #define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_PL301 (1 << ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT) | ||
| 829 | #define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_REGISTERED ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_PL301 | ||
| 830 | |||
| 831 | /* Software control of PHY VDL updates from control register settings. Bit 13 enables the use of Bit 14. */ | ||
| 832 | /* If software control is not enabled, then updates occur when a refresh command is issued by the hardware */ | ||
| 833 | /* controller. If 2 chips selects are being used, then software control must be enabled. */ | ||
| 834 | #define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_VDL_UPDATE_SW_CTL_LOAD (1 << 14) | ||
| 835 | #define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_VDL_UPDATE_SW_CTL_ENABLE (1 << 13) | ||
| 836 | |||
| 837 | /* Use these to bypass a pipeline stage. By default the ADDR is off but the BYTE LANE in / out are on. */ | ||
| 838 | #define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_ADDR_CTL_IN_BYPASS_PIPELINE_STAGE (1 << 12) | ||
| 839 | #define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_BYTE_LANE_IN_BYPASS_PIPELINE_STAGE (1 << 11) | ||
| 840 | #define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_BYTE_LANE_OUT_BYPASS_PIPELINE_STAGE (1 << 10) | ||
| 841 | |||
| 842 | /* Chip select count */ | ||
| 843 | #define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT 9 | ||
| 844 | #define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_MASK (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT) | ||
| 845 | #define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_1 (0 << ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT) | ||
| 846 | #define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_2 (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT) | ||
| 847 | |||
| 848 | #define ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SHIFT 8 | ||
| 849 | #define ddrcReg_CTLR_PHY_GLUE_CFG_CLK_ASYNC (0 << ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SHIFT) | ||
| 850 | #define ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SYNC (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SHIFT) | ||
| 851 | |||
| 852 | #define ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_SHIFT 7 | ||
| 853 | #define ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_LOW (0 << ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_SHIFT) | ||
| 854 | #define ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_HIGH (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_SHIFT) | ||
| 855 | |||
| 856 | #define ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_SHIFT 6 | ||
| 857 | #define ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_LOW (0 << ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_SHIFT) | ||
| 858 | #define ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_HIGH (1 << ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_SHIFT) | ||
| 859 | |||
| 860 | #define ddrcReg_CTLR_PHY_GLUE_CFG_CAS_LATENCY_SHIFT 0 | ||
| 861 | #define ddrcReg_CTLR_PHY_GLUE_CFG_CAS_LATENCY_MASK (0x7 << ddrcReg_CTLR_PHY_GLUE_CFG_CAS_LATENCY_SHIFT) | ||
| 862 | |||
| 863 | /* ----------------------------------------------------- */ | ||
| 864 | #define ddrcReg_CTLR_PHY_GLUE_STATUS_PHASE_SHIFT 0 | ||
| 865 | #define ddrcReg_CTLR_PHY_GLUE_STATUS_PHASE_MASK (0x7f << ddrcReg_CTLR_PHY_GLUE_STATUS_PHASE_SHIFT) | ||
| 866 | |||
| 867 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 868 | |||
| 869 | #ifdef __cplusplus | ||
| 870 | } /* end extern "C" */ | ||
| 871 | #endif | ||
| 872 | #endif /* DDRC_REG_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h new file mode 100644 index 000000000000..375066ad0186 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h | |||
| @@ -0,0 +1,145 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file dmacHw_priv.h | ||
| 18 | * | ||
| 19 | * @brief Private Definitions for low level DMA driver | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | /****************************************************************************/ | ||
| 23 | |||
| 24 | #ifndef _DMACHW_PRIV_H | ||
| 25 | #define _DMACHW_PRIV_H | ||
| 26 | |||
| 27 | #include <csp/stdint.h> | ||
| 28 | |||
| 29 | /* Data type for DMA Link List Item */ | ||
| 30 | typedef struct { | ||
| 31 | uint32_t sar; /* Source Adress Register. | ||
| 32 | Address must be aligned to CTLx.SRC_TR_WIDTH. */ | ||
| 33 | uint32_t dar; /* Destination Address Register. | ||
| 34 | Address must be aligned to CTLx.DST_TR_WIDTH. */ | ||
| 35 | uint32_t llpPhy; /* LLP contains the physical address of the next descriptor for block chaining using linked lists. | ||
| 36 | Address MUST be aligned to a 32-bit boundary. */ | ||
| 37 | dmacHw_REG64_t ctl; /* Control Register. 64 bits */ | ||
| 38 | uint32_t sstat; /* Source Status Register */ | ||
| 39 | uint32_t dstat; /* Destination Status Register */ | ||
| 40 | uint32_t devCtl; /* Device specific control information */ | ||
| 41 | uint32_t llp; /* LLP contains the virtual address of the next descriptor for block chaining using linked lists. */ | ||
| 42 | } dmacHw_DESC_t; | ||
| 43 | |||
| 44 | /* | ||
| 45 | * Descriptor ring pointers | ||
| 46 | */ | ||
| 47 | typedef struct { | ||
| 48 | int num; /* Number of link items */ | ||
| 49 | dmacHw_DESC_t *pHead; /* Head of descriptor ring (for writing) */ | ||
| 50 | dmacHw_DESC_t *pTail; /* Tail of descriptor ring (for reading) */ | ||
| 51 | dmacHw_DESC_t *pProg; /* Descriptor to program the channel (for programming the channel register) */ | ||
| 52 | dmacHw_DESC_t *pEnd; /* End of current descriptor chain */ | ||
| 53 | dmacHw_DESC_t *pFree; /* Descriptor to free memory (freeing dynamic memory) */ | ||
| 54 | uint32_t virt2PhyOffset; /* Virtual to physical address offset for the descriptor ring */ | ||
| 55 | } dmacHw_DESC_RING_t; | ||
| 56 | |||
| 57 | /* | ||
| 58 | * DMA channel control block | ||
| 59 | */ | ||
| 60 | typedef struct { | ||
| 61 | uint32_t module; /* DMA controller module (0-1) */ | ||
| 62 | uint32_t channel; /* DMA channel (0-7) */ | ||
| 63 | volatile uint32_t varDataStarted; /* Flag indicating variable data channel is enabled */ | ||
| 64 | volatile uint32_t descUpdated; /* Flag to indicate descriptor update is complete */ | ||
| 65 | void *userData; /* Channel specifc user data */ | ||
| 66 | } dmacHw_CBLK_t; | ||
| 67 | |||
| 68 | #define dmacHw_ASSERT(a) if (!(a)) while (1) | ||
| 69 | #define dmacHw_MAX_CHANNEL_COUNT 16 | ||
| 70 | #define dmacHw_FREE_USER_MEMORY 0xFFFFFFFF | ||
| 71 | #define dmacHw_DESC_FREE dmacHw_REG_CTL_DONE | ||
| 72 | #define dmacHw_DESC_INIT ((dmacHw_DESC_t *) 0xFFFFFFFF) | ||
| 73 | #define dmacHw_MAX_BLOCKSIZE 4064 | ||
| 74 | #define dmacHw_GET_DESC_RING(addr) (dmacHw_DESC_RING_t *)(addr) | ||
| 75 | #define dmacHw_ADDRESS_MASK(byte) ((byte) - 1) | ||
| 76 | #define dmacHw_NEXT_DESC(rp, dp) ((rp)->dp = (dmacHw_DESC_t *)(rp)->dp->llp) | ||
| 77 | #define dmacHw_HANDLE_TO_CBLK(handle) ((dmacHw_CBLK_t *) (handle)) | ||
| 78 | #define dmacHw_CBLK_TO_HANDLE(cblkp) ((dmacHw_HANDLE_t) (cblkp)) | ||
| 79 | #define dmacHw_DST_IS_MEMORY(tt) (((tt) == dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM) || ((tt) == dmacHw_TRANSFER_TYPE_MEM_TO_MEM)) ? 1 : 0 | ||
| 80 | |||
| 81 | /****************************************************************************/ | ||
| 82 | /** | ||
| 83 | * @brief Get next available transaction width | ||
| 84 | * | ||
| 85 | * | ||
| 86 | * @return On sucess : Next avail able transaction width | ||
| 87 | * On failure : dmacHw_TRANSACTION_WIDTH_8 | ||
| 88 | * | ||
| 89 | * @note | ||
| 90 | * None | ||
| 91 | */ | ||
| 92 | /****************************************************************************/ | ||
| 93 | static inline dmacHw_TRANSACTION_WIDTH_e dmacHw_GetNextTrWidth(dmacHw_TRANSACTION_WIDTH_e tw /* [ IN ] Current transaction width */ | ||
| 94 | ) { | ||
| 95 | if (tw & dmacHw_REG_CTL_SRC_TR_WIDTH_MASK) { | ||
| 96 | return ((tw >> dmacHw_REG_CTL_SRC_TR_WIDTH_SHIFT) - | ||
| 97 | 1) << dmacHw_REG_CTL_SRC_TR_WIDTH_SHIFT; | ||
| 98 | } else if (tw & dmacHw_REG_CTL_DST_TR_WIDTH_MASK) { | ||
| 99 | return ((tw >> dmacHw_REG_CTL_DST_TR_WIDTH_SHIFT) - | ||
| 100 | 1) << dmacHw_REG_CTL_DST_TR_WIDTH_SHIFT; | ||
| 101 | } | ||
| 102 | |||
| 103 | /* Default return */ | ||
| 104 | return dmacHw_SRC_TRANSACTION_WIDTH_8; | ||
| 105 | } | ||
| 106 | |||
| 107 | /****************************************************************************/ | ||
| 108 | /** | ||
| 109 | * @brief Get number of bytes per transaction | ||
| 110 | * | ||
| 111 | * @return Number of bytes per transaction | ||
| 112 | * | ||
| 113 | * | ||
| 114 | * @note | ||
| 115 | * None | ||
| 116 | */ | ||
| 117 | /****************************************************************************/ | ||
| 118 | static inline int dmacHw_GetTrWidthInBytes(dmacHw_TRANSACTION_WIDTH_e tw /* [ IN ] Transaction width */ | ||
| 119 | ) { | ||
| 120 | int width = 1; | ||
| 121 | switch (tw) { | ||
| 122 | case dmacHw_SRC_TRANSACTION_WIDTH_8: | ||
| 123 | width = 1; | ||
| 124 | break; | ||
| 125 | case dmacHw_SRC_TRANSACTION_WIDTH_16: | ||
| 126 | case dmacHw_DST_TRANSACTION_WIDTH_16: | ||
| 127 | width = 2; | ||
| 128 | break; | ||
| 129 | case dmacHw_SRC_TRANSACTION_WIDTH_32: | ||
| 130 | case dmacHw_DST_TRANSACTION_WIDTH_32: | ||
| 131 | width = 4; | ||
| 132 | break; | ||
| 133 | case dmacHw_SRC_TRANSACTION_WIDTH_64: | ||
| 134 | case dmacHw_DST_TRANSACTION_WIDTH_64: | ||
| 135 | width = 8; | ||
| 136 | break; | ||
| 137 | default: | ||
| 138 | dmacHw_ASSERT(0); | ||
| 139 | } | ||
| 140 | |||
| 141 | /* Default transaction width */ | ||
| 142 | return width; | ||
| 143 | } | ||
| 144 | |||
| 145 | #endif /* _DMACHW_PRIV_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h new file mode 100644 index 000000000000..891cea87e333 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h | |||
| @@ -0,0 +1,406 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file dmacHw_reg.h | ||
| 18 | * | ||
| 19 | * @brief Definitions for low level DMA registers | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | /****************************************************************************/ | ||
| 23 | |||
| 24 | #ifndef _DMACHW_REG_H | ||
| 25 | #define _DMACHW_REG_H | ||
| 26 | |||
| 27 | #include <csp/stdint.h> | ||
| 28 | #include <mach/csp/mm_io.h> | ||
| 29 | |||
| 30 | /* Data type for 64 bit little endian register */ | ||
| 31 | typedef struct { | ||
| 32 | volatile uint32_t lo; /* Lower 32 bit in little endian mode */ | ||
| 33 | volatile uint32_t hi; /* Upper 32 bit in little endian mode */ | ||
| 34 | } dmacHw_REG64_t; | ||
| 35 | |||
| 36 | /* Data type representing DMA channel registers */ | ||
| 37 | typedef struct { | ||
| 38 | dmacHw_REG64_t ChannelSar; /* Source Adress Register. 64 bits (upper 32 bits are reserved) | ||
| 39 | Address must be aligned to CTLx.SRC_TR_WIDTH. | ||
| 40 | */ | ||
| 41 | dmacHw_REG64_t ChannelDar; /* Destination Address Register.64 bits (upper 32 bits are reserved) | ||
| 42 | Address must be aligned to CTLx.DST_TR_WIDTH. | ||
| 43 | */ | ||
| 44 | dmacHw_REG64_t ChannelLlp; /* Link List Pointer.64 bits (upper 32 bits are reserved) | ||
| 45 | LLP contains the pointer to the next LLI for block chaining using linked lists. | ||
| 46 | If LLPis set to 0x0, then transfers using linked lists are not enabled. | ||
| 47 | Address MUST be aligned to a 32-bit boundary. | ||
| 48 | */ | ||
| 49 | dmacHw_REG64_t ChannelCtl; /* Control Register. 64 bits */ | ||
| 50 | dmacHw_REG64_t ChannelSstat; /* Source Status Register */ | ||
| 51 | dmacHw_REG64_t ChannelDstat; /* Destination Status Register */ | ||
| 52 | dmacHw_REG64_t ChannelSstatAddr; /* Source Status Address Register */ | ||
| 53 | dmacHw_REG64_t ChannelDstatAddr; /* Destination Status Address Register */ | ||
| 54 | dmacHw_REG64_t ChannelConfig; /* Channel Configuration Register */ | ||
| 55 | dmacHw_REG64_t SrcGather; /* Source gather register */ | ||
| 56 | dmacHw_REG64_t DstScatter; /* Destination scatter register */ | ||
| 57 | } dmacHw_CH_REG_t; | ||
| 58 | |||
| 59 | /* Data type for RAW interrupt status registers */ | ||
| 60 | typedef struct { | ||
| 61 | dmacHw_REG64_t RawTfr; /* Raw Status for IntTfr Interrupt */ | ||
| 62 | dmacHw_REG64_t RawBlock; /* Raw Status for IntBlock Interrupt */ | ||
| 63 | dmacHw_REG64_t RawSrcTran; /* Raw Status for IntSrcTran Interrupt */ | ||
| 64 | dmacHw_REG64_t RawDstTran; /* Raw Status for IntDstTran Interrupt */ | ||
| 65 | dmacHw_REG64_t RawErr; /* Raw Status for IntErr Interrupt */ | ||
| 66 | } dmacHw_INT_RAW_t; | ||
| 67 | |||
| 68 | /* Data type for interrupt status registers */ | ||
| 69 | typedef struct { | ||
| 70 | dmacHw_REG64_t StatusTfr; /* Status for IntTfr Interrupt */ | ||
| 71 | dmacHw_REG64_t StatusBlock; /* Status for IntBlock Interrupt */ | ||
| 72 | dmacHw_REG64_t StatusSrcTran; /* Status for IntSrcTran Interrupt */ | ||
| 73 | dmacHw_REG64_t StatusDstTran; /* Status for IntDstTran Interrupt */ | ||
| 74 | dmacHw_REG64_t StatusErr; /* Status for IntErr Interrupt */ | ||
| 75 | } dmacHw_INT_STATUS_t; | ||
| 76 | |||
| 77 | /* Data type for interrupt mask registers*/ | ||
| 78 | typedef struct { | ||
| 79 | dmacHw_REG64_t MaskTfr; /* Mask for IntTfr Interrupt */ | ||
| 80 | dmacHw_REG64_t MaskBlock; /* Mask for IntBlock Interrupt */ | ||
| 81 | dmacHw_REG64_t MaskSrcTran; /* Mask for IntSrcTran Interrupt */ | ||
| 82 | dmacHw_REG64_t MaskDstTran; /* Mask for IntDstTran Interrupt */ | ||
| 83 | dmacHw_REG64_t MaskErr; /* Mask for IntErr Interrupt */ | ||
| 84 | } dmacHw_INT_MASK_t; | ||
| 85 | |||
| 86 | /* Data type for interrupt clear registers */ | ||
| 87 | typedef struct { | ||
| 88 | dmacHw_REG64_t ClearTfr; /* Clear for IntTfr Interrupt */ | ||
| 89 | dmacHw_REG64_t ClearBlock; /* Clear for IntBlock Interrupt */ | ||
| 90 | dmacHw_REG64_t ClearSrcTran; /* Clear for IntSrcTran Interrupt */ | ||
| 91 | dmacHw_REG64_t ClearDstTran; /* Clear for IntDstTran Interrupt */ | ||
| 92 | dmacHw_REG64_t ClearErr; /* Clear for IntErr Interrupt */ | ||
| 93 | dmacHw_REG64_t StatusInt; /* Status for each interrupt type */ | ||
| 94 | } dmacHw_INT_CLEAR_t; | ||
| 95 | |||
| 96 | /* Data type for software handshaking registers */ | ||
| 97 | typedef struct { | ||
| 98 | dmacHw_REG64_t ReqSrcReg; /* Source Software Transaction Request Register */ | ||
| 99 | dmacHw_REG64_t ReqDstReg; /* Destination Software Transaction Request Register */ | ||
| 100 | dmacHw_REG64_t SglReqSrcReg; /* Single Source Transaction Request Register */ | ||
| 101 | dmacHw_REG64_t SglReqDstReg; /* Single Destination Transaction Request Register */ | ||
| 102 | dmacHw_REG64_t LstSrcReg; /* Last Source Transaction Request Register */ | ||
| 103 | dmacHw_REG64_t LstDstReg; /* Last Destination Transaction Request Register */ | ||
| 104 | } dmacHw_SW_HANDSHAKE_t; | ||
| 105 | |||
| 106 | /* Data type for misc. registers */ | ||
| 107 | typedef struct { | ||
| 108 | dmacHw_REG64_t DmaCfgReg; /* DMA Configuration Register */ | ||
| 109 | dmacHw_REG64_t ChEnReg; /* DMA Channel Enable Register */ | ||
| 110 | dmacHw_REG64_t DmaIdReg; /* DMA ID Register */ | ||
| 111 | dmacHw_REG64_t DmaTestReg; /* DMA Test Register */ | ||
| 112 | dmacHw_REG64_t Reserved0; /* Reserved */ | ||
| 113 | dmacHw_REG64_t Reserved1; /* Reserved */ | ||
| 114 | dmacHw_REG64_t CompParm6; /* Component Parameter 6 */ | ||
| 115 | dmacHw_REG64_t CompParm5; /* Component Parameter 5 */ | ||
| 116 | dmacHw_REG64_t CompParm4; /* Component Parameter 4 */ | ||
| 117 | dmacHw_REG64_t CompParm3; /* Component Parameter 3 */ | ||
| 118 | dmacHw_REG64_t CompParm2; /* Component Parameter 2 */ | ||
| 119 | dmacHw_REG64_t CompParm1; /* Component Parameter 1 */ | ||
| 120 | dmacHw_REG64_t CompId; /* Compoent ID */ | ||
| 121 | } dmacHw_MISC_t; | ||
| 122 | |||
| 123 | /* Base registers */ | ||
| 124 | #define dmacHw_0_MODULE_BASE_ADDR (char *) MM_IO_BASE_DMA0 /* DMAC 0 module's base address */ | ||
| 125 | #define dmacHw_1_MODULE_BASE_ADDR (char *) MM_IO_BASE_DMA1 /* DMAC 1 module's base address */ | ||
| 126 | |||
| 127 | extern uint32_t dmaChannelCount_0; | ||
| 128 | extern uint32_t dmaChannelCount_1; | ||
| 129 | |||
| 130 | /* Define channel specific registers */ | ||
| 131 | #define dmacHw_CHAN_BASE(module, chan) ((dmacHw_CH_REG_t *) ((char *)((module) ? dmacHw_1_MODULE_BASE_ADDR : dmacHw_0_MODULE_BASE_ADDR) + ((chan) * sizeof(dmacHw_CH_REG_t)))) | ||
| 132 | |||
| 133 | /* Raw interrupt status registers */ | ||
| 134 | #define dmacHw_REG_INT_RAW_BASE(module) ((char *)dmacHw_CHAN_BASE((module), ((module) ? dmaChannelCount_1 : dmaChannelCount_0))) | ||
| 135 | #define dmacHw_REG_INT_RAW_TRAN(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawTfr.lo) | ||
| 136 | #define dmacHw_REG_INT_RAW_BLOCK(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawBlock.lo) | ||
| 137 | #define dmacHw_REG_INT_RAW_STRAN(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawSrcTran.lo) | ||
| 138 | #define dmacHw_REG_INT_RAW_DTRAN(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawDstTran.lo) | ||
| 139 | #define dmacHw_REG_INT_RAW_ERROR(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawErr.lo) | ||
| 140 | |||
| 141 | /* Interrupt status registers */ | ||
| 142 | #define dmacHw_REG_INT_STAT_BASE(module) ((char *)(dmacHw_REG_INT_RAW_BASE((module)) + sizeof(dmacHw_INT_RAW_t))) | ||
| 143 | #define dmacHw_REG_INT_STAT_TRAN(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusTfr.lo) | ||
| 144 | #define dmacHw_REG_INT_STAT_BLOCK(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusBlock.lo) | ||
| 145 | #define dmacHw_REG_INT_STAT_STRAN(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusSrcTran.lo) | ||
| 146 | #define dmacHw_REG_INT_STAT_DTRAN(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusDstTran.lo) | ||
| 147 | #define dmacHw_REG_INT_STAT_ERROR(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusErr.lo) | ||
| 148 | |||
| 149 | /* Interrupt status registers */ | ||
| 150 | #define dmacHw_REG_INT_MASK_BASE(module) ((char *)(dmacHw_REG_INT_STAT_BASE((module)) + sizeof(dmacHw_INT_STATUS_t))) | ||
| 151 | #define dmacHw_REG_INT_MASK_TRAN(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskTfr.lo) | ||
| 152 | #define dmacHw_REG_INT_MASK_BLOCK(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskBlock.lo) | ||
| 153 | #define dmacHw_REG_INT_MASK_STRAN(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskSrcTran.lo) | ||
| 154 | #define dmacHw_REG_INT_MASK_DTRAN(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskDstTran.lo) | ||
| 155 | #define dmacHw_REG_INT_MASK_ERROR(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskErr.lo) | ||
| 156 | |||
| 157 | /* Interrupt clear registers */ | ||
| 158 | #define dmacHw_REG_INT_CLEAR_BASE(module) ((char *)(dmacHw_REG_INT_MASK_BASE((module)) + sizeof(dmacHw_INT_MASK_t))) | ||
| 159 | #define dmacHw_REG_INT_CLEAR_TRAN(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearTfr.lo) | ||
| 160 | #define dmacHw_REG_INT_CLEAR_BLOCK(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearBlock.lo) | ||
| 161 | #define dmacHw_REG_INT_CLEAR_STRAN(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearSrcTran.lo) | ||
| 162 | #define dmacHw_REG_INT_CLEAR_DTRAN(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearDstTran.lo) | ||
| 163 | #define dmacHw_REG_INT_CLEAR_ERROR(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearErr.lo) | ||
| 164 | #define dmacHw_REG_INT_STATUS(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->StatusInt.lo) | ||
| 165 | |||
| 166 | /* Software handshaking registers */ | ||
| 167 | #define dmacHw_REG_SW_HS_BASE(module) ((char *)(dmacHw_REG_INT_CLEAR_BASE((module)) + sizeof(dmacHw_INT_CLEAR_t))) | ||
| 168 | #define dmacHw_REG_SW_HS_SRC_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->ReqSrcReg.lo) | ||
| 169 | #define dmacHw_REG_SW_HS_DST_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->ReqDstReg.lo) | ||
| 170 | #define dmacHw_REG_SW_HS_SRC_SGL_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->SglReqSrcReg.lo) | ||
| 171 | #define dmacHw_REG_SW_HS_DST_SGL_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->SglReqDstReg.lo) | ||
| 172 | #define dmacHw_REG_SW_HS_SRC_LST_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->LstSrcReg.lo) | ||
| 173 | #define dmacHw_REG_SW_HS_DST_LST_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->LstDstReg.lo) | ||
| 174 | |||
| 175 | /* Miscellaneous registers */ | ||
| 176 | #define dmacHw_REG_MISC_BASE(module) ((char *)(dmacHw_REG_SW_HS_BASE((module)) + sizeof(dmacHw_SW_HANDSHAKE_t))) | ||
| 177 | #define dmacHw_REG_MISC_CFG(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->DmaCfgReg.lo) | ||
| 178 | #define dmacHw_REG_MISC_CH_ENABLE(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->ChEnReg.lo) | ||
| 179 | #define dmacHw_REG_MISC_ID(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->DmaIdReg.lo) | ||
| 180 | #define dmacHw_REG_MISC_TEST(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->DmaTestReg.lo) | ||
| 181 | #define dmacHw_REG_MISC_COMP_PARAM1_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm1.lo) | ||
| 182 | #define dmacHw_REG_MISC_COMP_PARAM1_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm1.hi) | ||
| 183 | #define dmacHw_REG_MISC_COMP_PARAM2_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm2.lo) | ||
| 184 | #define dmacHw_REG_MISC_COMP_PARAM2_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm2.hi) | ||
| 185 | #define dmacHw_REG_MISC_COMP_PARAM3_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm3.lo) | ||
| 186 | #define dmacHw_REG_MISC_COMP_PARAM3_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm3.hi) | ||
| 187 | #define dmacHw_REG_MISC_COMP_PARAM4_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm4.lo) | ||
| 188 | #define dmacHw_REG_MISC_COMP_PARAM4_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm4.hi) | ||
| 189 | #define dmacHw_REG_MISC_COMP_PARAM5_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm5.lo) | ||
| 190 | #define dmacHw_REG_MISC_COMP_PARAM5_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm5.hi) | ||
| 191 | #define dmacHw_REG_MISC_COMP_PARAM6_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm6.lo) | ||
| 192 | #define dmacHw_REG_MISC_COMP_PARAM6_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm6.hi) | ||
| 193 | |||
| 194 | /* Channel control registers */ | ||
| 195 | #define dmacHw_REG_SAR(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelSar.lo) | ||
| 196 | #define dmacHw_REG_DAR(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelDar.lo) | ||
| 197 | #define dmacHw_REG_LLP(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelLlp.lo) | ||
| 198 | |||
| 199 | #define dmacHw_REG_CTL_LO(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelCtl.lo) | ||
| 200 | #define dmacHw_REG_CTL_HI(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelCtl.hi) | ||
| 201 | |||
| 202 | #define dmacHw_REG_SSTAT(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelSstat.lo) | ||
| 203 | #define dmacHw_REG_DSTAT(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelDstat.lo) | ||
| 204 | #define dmacHw_REG_SSTATAR(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelSstatAddr.lo) | ||
| 205 | #define dmacHw_REG_DSTATAR(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelDstatAddr.lo) | ||
| 206 | |||
| 207 | #define dmacHw_REG_CFG_LO(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelConfig.lo) | ||
| 208 | #define dmacHw_REG_CFG_HI(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelConfig.hi) | ||
| 209 | |||
| 210 | #define dmacHw_REG_SGR_LO(module, chan) (dmacHw_CHAN_BASE((module), (chan))->SrcGather.lo) | ||
| 211 | #define dmacHw_REG_SGR_HI(module, chan) (dmacHw_CHAN_BASE((module), (chan))->SrcGather.hi) | ||
| 212 | |||
| 213 | #define dmacHw_REG_DSR_LO(module, chan) (dmacHw_CHAN_BASE((module), (chan))->DstScatter.lo) | ||
| 214 | #define dmacHw_REG_DSR_HI(module, chan) (dmacHw_CHAN_BASE((module), (chan))->DstScatter.hi) | ||
| 215 | |||
| 216 | #define INT_STATUS_MASK(channel) (0x00000001 << (channel)) | ||
| 217 | #define CHANNEL_BUSY(mod, channel) (dmacHw_REG_MISC_CH_ENABLE((mod)) & (0x00000001 << (channel))) | ||
| 218 | |||
| 219 | /* Bit mask for REG_DMACx_CTL_LO */ | ||
| 220 | |||
| 221 | #define dmacHw_REG_CTL_INT_EN 0x00000001 /* Channel interrupt enable */ | ||
| 222 | |||
| 223 | #define dmacHw_REG_CTL_DST_TR_WIDTH_MASK 0x0000000E /* Destination transaction width mask */ | ||
| 224 | #define dmacHw_REG_CTL_DST_TR_WIDTH_SHIFT 1 | ||
| 225 | #define dmacHw_REG_CTL_DST_TR_WIDTH_8 0x00000000 /* Destination transaction width 8 bit */ | ||
| 226 | #define dmacHw_REG_CTL_DST_TR_WIDTH_16 0x00000002 /* Destination transaction width 16 bit */ | ||
| 227 | #define dmacHw_REG_CTL_DST_TR_WIDTH_32 0x00000004 /* Destination transaction width 32 bit */ | ||
| 228 | #define dmacHw_REG_CTL_DST_TR_WIDTH_64 0x00000006 /* Destination transaction width 64 bit */ | ||
| 229 | |||
| 230 | #define dmacHw_REG_CTL_SRC_TR_WIDTH_MASK 0x00000070 /* Source transaction width mask */ | ||
| 231 | #define dmacHw_REG_CTL_SRC_TR_WIDTH_SHIFT 4 | ||
| 232 | #define dmacHw_REG_CTL_SRC_TR_WIDTH_8 0x00000000 /* Source transaction width 8 bit */ | ||
| 233 | #define dmacHw_REG_CTL_SRC_TR_WIDTH_16 0x00000010 /* Source transaction width 16 bit */ | ||
| 234 | #define dmacHw_REG_CTL_SRC_TR_WIDTH_32 0x00000020 /* Source transaction width 32 bit */ | ||
| 235 | #define dmacHw_REG_CTL_SRC_TR_WIDTH_64 0x00000030 /* Source transaction width 64 bit */ | ||
| 236 | |||
| 237 | #define dmacHw_REG_CTL_DS_ENABLE 0x00040000 /* Destination scatter enable */ | ||
| 238 | #define dmacHw_REG_CTL_SG_ENABLE 0x00020000 /* Source gather enable */ | ||
| 239 | |||
| 240 | #define dmacHw_REG_CTL_DINC_MASK 0x00000180 /* Destination address inc/dec mask */ | ||
| 241 | #define dmacHw_REG_CTL_DINC_INC 0x00000000 /* Destination address increment */ | ||
| 242 | #define dmacHw_REG_CTL_DINC_DEC 0x00000080 /* Destination address decrement */ | ||
| 243 | #define dmacHw_REG_CTL_DINC_NC 0x00000100 /* Destination address no change */ | ||
| 244 | |||
| 245 | #define dmacHw_REG_CTL_SINC_MASK 0x00000600 /* Source address inc/dec mask */ | ||
| 246 | #define dmacHw_REG_CTL_SINC_INC 0x00000000 /* Source address increment */ | ||
| 247 | #define dmacHw_REG_CTL_SINC_DEC 0x00000200 /* Source address decrement */ | ||
| 248 | #define dmacHw_REG_CTL_SINC_NC 0x00000400 /* Source address no change */ | ||
| 249 | |||
| 250 | #define dmacHw_REG_CTL_DST_MSIZE_MASK 0x00003800 /* Destination burst transaction length */ | ||
| 251 | #define dmacHw_REG_CTL_DST_MSIZE_0 0x00000000 /* No Destination burst */ | ||
| 252 | #define dmacHw_REG_CTL_DST_MSIZE_4 0x00000800 /* Destination burst transaction length 4 */ | ||
| 253 | #define dmacHw_REG_CTL_DST_MSIZE_8 0x00001000 /* Destination burst transaction length 8 */ | ||
| 254 | #define dmacHw_REG_CTL_DST_MSIZE_16 0x00001800 /* Destination burst transaction length 16 */ | ||
| 255 | |||
| 256 | #define dmacHw_REG_CTL_SRC_MSIZE_MASK 0x0001C000 /* Source burst transaction length */ | ||
| 257 | #define dmacHw_REG_CTL_SRC_MSIZE_0 0x00000000 /* No Source burst */ | ||
| 258 | #define dmacHw_REG_CTL_SRC_MSIZE_4 0x00004000 /* Source burst transaction length 4 */ | ||
| 259 | #define dmacHw_REG_CTL_SRC_MSIZE_8 0x00008000 /* Source burst transaction length 8 */ | ||
| 260 | #define dmacHw_REG_CTL_SRC_MSIZE_16 0x0000C000 /* Source burst transaction length 16 */ | ||
| 261 | |||
| 262 | #define dmacHw_REG_CTL_TTFC_MASK 0x00700000 /* Transfer type and flow controller */ | ||
| 263 | #define dmacHw_REG_CTL_TTFC_MM_DMAC 0x00000000 /* Memory to Memory with DMAC as flow controller */ | ||
| 264 | #define dmacHw_REG_CTL_TTFC_MP_DMAC 0x00100000 /* Memory to Peripheral with DMAC as flow controller */ | ||
| 265 | #define dmacHw_REG_CTL_TTFC_PM_DMAC 0x00200000 /* Peripheral to Memory with DMAC as flow controller */ | ||
| 266 | #define dmacHw_REG_CTL_TTFC_PP_DMAC 0x00300000 /* Peripheral to Peripheral with DMAC as flow controller */ | ||
| 267 | #define dmacHw_REG_CTL_TTFC_PM_PERI 0x00400000 /* Peripheral to Memory with Peripheral as flow controller */ | ||
| 268 | #define dmacHw_REG_CTL_TTFC_PP_SPERI 0x00500000 /* Peripheral to Peripheral with Source Peripheral as flow controller */ | ||
| 269 | #define dmacHw_REG_CTL_TTFC_MP_PERI 0x00600000 /* Memory to Peripheral with Peripheral as flow controller */ | ||
| 270 | #define dmacHw_REG_CTL_TTFC_PP_DPERI 0x00700000 /* Peripheral to Peripheral with Destination Peripheral as flow controller */ | ||
| 271 | |||
| 272 | #define dmacHw_REG_CTL_DMS_MASK 0x01800000 /* Destination AHB master interface */ | ||
| 273 | #define dmacHw_REG_CTL_DMS_1 0x00000000 /* Destination AHB master interface 1 */ | ||
| 274 | #define dmacHw_REG_CTL_DMS_2 0x00800000 /* Destination AHB master interface 2 */ | ||
| 275 | |||
| 276 | #define dmacHw_REG_CTL_SMS_MASK 0x06000000 /* Source AHB master interface */ | ||
| 277 | #define dmacHw_REG_CTL_SMS_1 0x00000000 /* Source AHB master interface 1 */ | ||
| 278 | #define dmacHw_REG_CTL_SMS_2 0x02000000 /* Source AHB master interface 2 */ | ||
| 279 | |||
| 280 | #define dmacHw_REG_CTL_LLP_DST_EN 0x08000000 /* Block chaining enable for destination side */ | ||
| 281 | #define dmacHw_REG_CTL_LLP_SRC_EN 0x10000000 /* Block chaining enable for source side */ | ||
| 282 | |||
| 283 | /* Bit mask for REG_DMACx_CTL_HI */ | ||
| 284 | #define dmacHw_REG_CTL_BLOCK_TS_MASK 0x00000FFF /* Block transfer size */ | ||
| 285 | #define dmacHw_REG_CTL_DONE 0x00001000 /* Block trasnfer done */ | ||
| 286 | |||
| 287 | /* Bit mask for REG_DMACx_CFG_LO */ | ||
| 288 | #define dmacHw_REG_CFG_LO_CH_PRIORITY_SHIFT 5 /* Channel priority shift */ | ||
| 289 | #define dmacHw_REG_CFG_LO_CH_PRIORITY_MASK 0x000000E0 /* Channel priority mask */ | ||
| 290 | #define dmacHw_REG_CFG_LO_CH_PRIORITY_0 0x00000000 /* Channel priority 0 */ | ||
| 291 | #define dmacHw_REG_CFG_LO_CH_PRIORITY_1 0x00000020 /* Channel priority 1 */ | ||
| 292 | #define dmacHw_REG_CFG_LO_CH_PRIORITY_2 0x00000040 /* Channel priority 2 */ | ||
| 293 | #define dmacHw_REG_CFG_LO_CH_PRIORITY_3 0x00000060 /* Channel priority 3 */ | ||
| 294 | #define dmacHw_REG_CFG_LO_CH_PRIORITY_4 0x00000080 /* Channel priority 4 */ | ||
| 295 | #define dmacHw_REG_CFG_LO_CH_PRIORITY_5 0x000000A0 /* Channel priority 5 */ | ||
| 296 | #define dmacHw_REG_CFG_LO_CH_PRIORITY_6 0x000000C0 /* Channel priority 6 */ | ||
| 297 | #define dmacHw_REG_CFG_LO_CH_PRIORITY_7 0x000000E0 /* Channel priority 7 */ | ||
| 298 | |||
| 299 | #define dmacHw_REG_CFG_LO_CH_SUSPEND 0x00000100 /* Channel suspend */ | ||
| 300 | #define dmacHw_REG_CFG_LO_CH_FIFO_EMPTY 0x00000200 /* Channel FIFO empty */ | ||
| 301 | #define dmacHw_REG_CFG_LO_DST_CH_SW_HS 0x00000400 /* Destination channel SW handshaking */ | ||
| 302 | #define dmacHw_REG_CFG_LO_SRC_CH_SW_HS 0x00000800 /* Source channel SW handshaking */ | ||
| 303 | |||
| 304 | #define dmacHw_REG_CFG_LO_CH_LOCK_MASK 0x00003000 /* Channel locking mask */ | ||
| 305 | #define dmacHw_REG_CFG_LO_CH_LOCK_DMA 0x00000000 /* Channel lock over the entire DMA transfer operation */ | ||
| 306 | #define dmacHw_REG_CFG_LO_CH_LOCK_BLOCK 0x00001000 /* Channel lock over the block transfer operation */ | ||
| 307 | #define dmacHw_REG_CFG_LO_CH_LOCK_TRANS 0x00002000 /* Channel lock over the transaction */ | ||
| 308 | #define dmacHw_REG_CFG_LO_CH_LOCK_ENABLE 0x00010000 /* Channel lock enable */ | ||
| 309 | |||
| 310 | #define dmacHw_REG_CFG_LO_BUS_LOCK_MASK 0x0000C000 /* Bus locking mask */ | ||
| 311 | #define dmacHw_REG_CFG_LO_BUS_LOCK_DMA 0x00000000 /* Bus lock over the entire DMA transfer operation */ | ||
| 312 | #define dmacHw_REG_CFG_LO_BUS_LOCK_BLOCK 0x00004000 /* Bus lock over the block transfer operation */ | ||
| 313 | #define dmacHw_REG_CFG_LO_BUS_LOCK_TRANS 0x00008000 /* Bus lock over the transaction */ | ||
| 314 | #define dmacHw_REG_CFG_LO_BUS_LOCK_ENABLE 0x00020000 /* Bus lock enable */ | ||
| 315 | |||
| 316 | #define dmacHw_REG_CFG_LO_DST_HS_POLARITY_LOW 0x00040000 /* Destination channel handshaking signal polarity low */ | ||
| 317 | #define dmacHw_REG_CFG_LO_SRC_HS_POLARITY_LOW 0x00080000 /* Source channel handshaking signal polarity low */ | ||
| 318 | |||
| 319 | #define dmacHw_REG_CFG_LO_MAX_AMBA_BURST_LEN_MASK 0x3FF00000 /* Maximum AMBA burst length */ | ||
| 320 | |||
| 321 | #define dmacHw_REG_CFG_LO_AUTO_RELOAD_SRC 0x40000000 /* Source address auto reload */ | ||
| 322 | #define dmacHw_REG_CFG_LO_AUTO_RELOAD_DST 0x80000000 /* Destination address auto reload */ | ||
| 323 | |||
| 324 | /* Bit mask for REG_DMACx_CFG_HI */ | ||
| 325 | #define dmacHw_REG_CFG_HI_FC_DST_READY 0x00000001 /* Source transaction request is serviced when destination is ready */ | ||
| 326 | #define dmacHw_REG_CFG_HI_FIFO_ENOUGH 0x00000002 /* Initiate burst transaction when enough data in available in FIFO */ | ||
| 327 | |||
| 328 | #define dmacHw_REG_CFG_HI_AHB_HPROT_MASK 0x0000001C /* AHB protection mask */ | ||
| 329 | #define dmacHw_REG_CFG_HI_AHB_HPROT_1 0x00000004 /* AHB protection 1 */ | ||
| 330 | #define dmacHw_REG_CFG_HI_AHB_HPROT_2 0x00000008 /* AHB protection 2 */ | ||
| 331 | #define dmacHw_REG_CFG_HI_AHB_HPROT_3 0x00000010 /* AHB protection 3 */ | ||
| 332 | |||
| 333 | #define dmacHw_REG_CFG_HI_UPDATE_DST_STAT 0x00000020 /* Destination status update enable */ | ||
| 334 | #define dmacHw_REG_CFG_HI_UPDATE_SRC_STAT 0x00000040 /* Source status update enable */ | ||
| 335 | |||
| 336 | #define dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK 0x00000780 /* Source peripheral hardware interface mask */ | ||
| 337 | #define dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK 0x00007800 /* Destination peripheral hardware interface mask */ | ||
| 338 | |||
| 339 | /* DMA Configuration Parameters */ | ||
| 340 | #define dmacHw_REG_COMP_PARAM_NUM_CHANNELS 0x00000700 /* Number of channels */ | ||
| 341 | #define dmacHw_REG_COMP_PARAM_NUM_INTERFACE 0x00001800 /* Number of master interface */ | ||
| 342 | #define dmacHw_REG_COMP_PARAM_MAX_BLK_SIZE 0x0000000f /* Maximum brust size */ | ||
| 343 | #define dmacHw_REG_COMP_PARAM_DATA_WIDTH 0x00006000 /* Data transfer width */ | ||
| 344 | |||
| 345 | /* Define GET/SET macros to program the registers */ | ||
| 346 | #define dmacHw_SET_SAR(module, channel, addr) (dmacHw_REG_SAR((module), (channel)) = (uint32_t) (addr)) | ||
| 347 | #define dmacHw_SET_DAR(module, channel, addr) (dmacHw_REG_DAR((module), (channel)) = (uint32_t) (addr)) | ||
| 348 | #define dmacHw_SET_LLP(module, channel, ptr) (dmacHw_REG_LLP((module), (channel)) = (uint32_t) (ptr)) | ||
| 349 | |||
| 350 | #define dmacHw_GET_SSTAT(module, channel) (dmacHw_REG_SSTAT((module), (channel))) | ||
| 351 | #define dmacHw_GET_DSTAT(module, channel) (dmacHw_REG_DSTAT((module), (channel))) | ||
| 352 | |||
| 353 | #define dmacHw_SET_SSTATAR(module, channel, addr) (dmacHw_REG_SSTATAR((module), (channel)) = (uint32_t) (addr)) | ||
| 354 | #define dmacHw_SET_DSTATAR(module, channel, addr) (dmacHw_REG_DSTATAR((module), (channel)) = (uint32_t) (addr)) | ||
| 355 | |||
| 356 | #define dmacHw_SET_CONTROL_LO(module, channel, ctl) (dmacHw_REG_CTL_LO((module), (channel)) |= (ctl)) | ||
| 357 | #define dmacHw_RESET_CONTROL_LO(module, channel) (dmacHw_REG_CTL_LO((module), (channel)) = 0) | ||
| 358 | #define dmacHw_GET_CONTROL_LO(module, channel) (dmacHw_REG_CTL_LO((module), (channel))) | ||
| 359 | |||
| 360 | #define dmacHw_SET_CONTROL_HI(module, channel, ctl) (dmacHw_REG_CTL_HI((module), (channel)) |= (ctl)) | ||
| 361 | #define dmacHw_RESET_CONTROL_HI(module, channel) (dmacHw_REG_CTL_HI((module), (channel)) = 0) | ||
| 362 | #define dmacHw_GET_CONTROL_HI(module, channel) (dmacHw_REG_CTL_HI((module), (channel))) | ||
| 363 | |||
| 364 | #define dmacHw_GET_BLOCK_SIZE(module, channel) (dmacHw_REG_CTL_HI((module), (channel)) & dmacHw_REG_CTL_BLOCK_TS_MASK) | ||
| 365 | #define dmacHw_DMA_COMPLETE(module, channel) (dmacHw_REG_CTL_HI((module), (channel)) & dmacHw_REG_CTL_DONE) | ||
| 366 | |||
| 367 | #define dmacHw_SET_CONFIG_LO(module, channel, cfg) (dmacHw_REG_CFG_LO((module), (channel)) |= (cfg)) | ||
| 368 | #define dmacHw_RESET_CONFIG_LO(module, channel) (dmacHw_REG_CFG_LO((module), (channel)) = 0) | ||
| 369 | #define dmacHw_GET_CONFIG_LO(module, channel) (dmacHw_REG_CFG_LO((module), (channel))) | ||
| 370 | #define dmacHw_SET_AMBA_BUSRT_LEN(module, channel, len) (dmacHw_REG_CFG_LO((module), (channel)) = (dmacHw_REG_CFG_LO((module), (channel)) & ~(dmacHw_REG_CFG_LO_MAX_AMBA_BURST_LEN_MASK)) | (((len) << 20) & dmacHw_REG_CFG_LO_MAX_AMBA_BURST_LEN_MASK)) | ||
| 371 | #define dmacHw_SET_CHANNEL_PRIORITY(module, channel, prio) (dmacHw_REG_CFG_LO((module), (channel)) = (dmacHw_REG_CFG_LO((module), (channel)) & ~(dmacHw_REG_CFG_LO_CH_PRIORITY_MASK)) | (prio)) | ||
| 372 | #define dmacHw_SET_AHB_HPROT(module, channel, protect) (dmacHw_REG_CFG_HI(module, channel) = (dmacHw_REG_CFG_HI((module), (channel)) & ~(dmacHw_REG_CFG_HI_AHB_HPROT_MASK)) | (protect)) | ||
| 373 | |||
| 374 | #define dmacHw_SET_CONFIG_HI(module, channel, cfg) (dmacHw_REG_CFG_HI((module), (channel)) |= (cfg)) | ||
| 375 | #define dmacHw_RESET_CONFIG_HI(module, channel) (dmacHw_REG_CFG_HI((module), (channel)) = 0) | ||
| 376 | #define dmacHw_GET_CONFIG_HI(module, channel) (dmacHw_REG_CFG_HI((module), (channel))) | ||
| 377 | #define dmacHw_SET_SRC_PERI_INTF(module, channel, intf) (dmacHw_REG_CFG_HI((module), (channel)) = (dmacHw_REG_CFG_HI((module), (channel)) & ~(dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK)) | (((intf) << 7) & dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK)) | ||
| 378 | #define dmacHw_SRC_PERI_INTF(intf) (((intf) << 7) & dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK) | ||
| 379 | #define dmacHw_SET_DST_PERI_INTF(module, channel, intf) (dmacHw_REG_CFG_HI((module), (channel)) = (dmacHw_REG_CFG_HI((module), (channel)) & ~(dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK)) | (((intf) << 11) & dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK)) | ||
| 380 | #define dmacHw_DST_PERI_INTF(intf) (((intf) << 11) & dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK) | ||
| 381 | |||
| 382 | #define dmacHw_DMA_START(module, channel) (dmacHw_REG_MISC_CH_ENABLE((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel))) | ||
| 383 | #define dmacHw_DMA_STOP(module, channel) (dmacHw_REG_MISC_CH_ENABLE((module)) = (0x00000001 << ((channel) + 8))) | ||
| 384 | #define dmacHw_DMA_ENABLE(module) (dmacHw_REG_MISC_CFG((module)) = 1) | ||
| 385 | #define dmacHw_DMA_DISABLE(module) (dmacHw_REG_MISC_CFG((module)) = 0) | ||
| 386 | |||
| 387 | #define dmacHw_TRAN_INT_ENABLE(module, channel) (dmacHw_REG_INT_MASK_TRAN((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel))) | ||
| 388 | #define dmacHw_BLOCK_INT_ENABLE(module, channel) (dmacHw_REG_INT_MASK_BLOCK((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel))) | ||
| 389 | #define dmacHw_ERROR_INT_ENABLE(module, channel) (dmacHw_REG_INT_MASK_ERROR((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel))) | ||
| 390 | |||
| 391 | #define dmacHw_TRAN_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_TRAN((module)) = (0x00000001 << ((channel) + 8))) | ||
| 392 | #define dmacHw_BLOCK_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_BLOCK((module)) = (0x00000001 << ((channel) + 8))) | ||
| 393 | #define dmacHw_ERROR_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_ERROR((module)) = (0x00000001 << ((channel) + 8))) | ||
| 394 | #define dmacHw_STRAN_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_STRAN((module)) = (0x00000001 << ((channel) + 8))) | ||
| 395 | #define dmacHw_DTRAN_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_DTRAN((module)) = (0x00000001 << ((channel) + 8))) | ||
| 396 | |||
| 397 | #define dmacHw_TRAN_INT_CLEAR(module, channel) (dmacHw_REG_INT_CLEAR_TRAN((module)) = (0x00000001 << (channel))) | ||
| 398 | #define dmacHw_BLOCK_INT_CLEAR(module, channel) (dmacHw_REG_INT_CLEAR_BLOCK((module)) = (0x00000001 << (channel))) | ||
| 399 | #define dmacHw_ERROR_INT_CLEAR(module, channel) (dmacHw_REG_INT_CLEAR_ERROR((module)) = (0x00000001 << (channel))) | ||
| 400 | |||
| 401 | #define dmacHw_GET_NUM_CHANNEL(module) (((dmacHw_REG_MISC_COMP_PARAM1_HI((module)) & dmacHw_REG_COMP_PARAM_NUM_CHANNELS) >> 8) + 1) | ||
| 402 | #define dmacHw_GET_NUM_INTERFACE(module) (((dmacHw_REG_MISC_COMP_PARAM1_HI((module)) & dmacHw_REG_COMP_PARAM_NUM_INTERFACE) >> 11) + 1) | ||
| 403 | #define dmacHw_GET_MAX_BLOCK_SIZE(module, channel) ((dmacHw_REG_MISC_COMP_PARAM1_LO((module)) >> (4 * (channel))) & dmacHw_REG_COMP_PARAM_MAX_BLK_SIZE) | ||
| 404 | #define dmacHw_GET_CHANNEL_DATA_WIDTH(module, channel) ((dmacHw_REG_MISC_COMP_PARAM1_HI((module)) & dmacHw_REG_COMP_PARAM_DATA_WIDTH) >> 13) | ||
| 405 | |||
| 406 | #endif /* _DMACHW_REG_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h b/arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h new file mode 100644 index 000000000000..cfa91bed9d34 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | |||
| 16 | #ifndef CSP_HW_CFG_H | ||
| 17 | #define CSP_HW_CFG_H | ||
| 18 | |||
| 19 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 20 | |||
| 21 | #include <cfg_global.h> | ||
| 22 | #include <mach/csp/cap_inline.h> | ||
| 23 | |||
| 24 | #if defined(__KERNEL__) | ||
| 25 | #include <mach/memory_settings.h> | ||
| 26 | #else | ||
| 27 | #include <hw_cfg.h> | ||
| 28 | #endif | ||
| 29 | |||
| 30 | /* Some items that can be defined externally, but will be set to default values */ | ||
| 31 | /* if they are not defined. */ | ||
| 32 | /* HW_CFG_PLL_SPREAD_SPECTRUM_DISABLE Default undefined and SS is enabled. */ | ||
| 33 | /* HW_CFG_SDRAM_CAS_LATENCY 5 Default 5, Values [3..6] */ | ||
| 34 | /* HW_CFG_SDRAM_CHIP_SELECT_CNT 1 Default 1, Vaules [1..2] */ | ||
| 35 | /* HW_CFG_SDRAM_SPEED_GRADE 667 Default 667, Values [400,533,667,800] */ | ||
| 36 | /* HW_CFG_SDRAM_WIDTH_BITS 16 Default 16, Vaules [8,16] */ | ||
| 37 | /* HW_CFG_SDRAM_ADDR_BRC Default undefined and Row-Bank-Col (RBC) addressing used. Define to use Bank-Row-Col (BRC). */ | ||
| 38 | /* HW_CFG_SDRAM_CLK_ASYNC Default undefined and DDR clock is synchronous with AXI BUS clock. Define for ASYNC mode. */ | ||
| 39 | |||
| 40 | #if defined(CFG_GLOBAL_CHIP) | ||
| 41 | #if (CFG_GLOBAL_CHIP == FPGA11107) | ||
| 42 | #define HW_CFG_BUS_CLK_HZ 5000000 | ||
| 43 | #define HW_CFG_DDR_CTLR_CLK_HZ 10000000 | ||
| 44 | #define HW_CFG_DDR_PHY_OMIT | ||
| 45 | #define HW_CFG_UART_CLK_HZ 7500000 | ||
| 46 | #else | ||
| 47 | #define HW_CFG_PLL_VCO_HZ 2000000000 | ||
| 48 | #define HW_CFG_PLL2_VCO_HZ 1800000000 | ||
| 49 | #define HW_CFG_ARM_CLK_HZ CAP_HW_CFG_ARM_CLK_HZ | ||
| 50 | #define HW_CFG_BUS_CLK_HZ 166666666 | ||
| 51 | #define HW_CFG_DDR_CTLR_CLK_HZ 333333333 | ||
| 52 | #define HW_CFG_DDR_PHY_CLK_HZ (2 * HW_CFG_DDR_CTLR_CLK_HZ) | ||
| 53 | #define HW_CFG_UART_CLK_HZ 142857142 | ||
| 54 | #define HW_CFG_VPM_CLK_HZ CAP_HW_CFG_VPM_CLK_HZ | ||
| 55 | #endif | ||
| 56 | #else | ||
| 57 | #define HW_CFG_PLL_VCO_HZ 1800000000 | ||
| 58 | #define HW_CFG_PLL2_VCO_HZ 1800000000 | ||
| 59 | #define HW_CFG_ARM_CLK_HZ 450000000 | ||
| 60 | #define HW_CFG_BUS_CLK_HZ 150000000 | ||
| 61 | #define HW_CFG_DDR_CTLR_CLK_HZ 300000000 | ||
| 62 | #define HW_CFG_DDR_PHY_CLK_HZ (2 * HW_CFG_DDR_CTLR_CLK_HZ) | ||
| 63 | #define HW_CFG_UART_CLK_HZ 150000000 | ||
| 64 | #define HW_CFG_VPM_CLK_HZ 300000000 | ||
| 65 | #endif | ||
| 66 | |||
| 67 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 68 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 69 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 70 | |||
| 71 | |||
| 72 | #endif /* CSP_HW_CFG_H */ | ||
| 73 | |||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h new file mode 100644 index 000000000000..e01fc4607c91 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h | |||
| @@ -0,0 +1,246 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file intcHw_reg.h | ||
| 18 | * | ||
| 19 | * @brief platform specific interrupt controller bit assignments | ||
| 20 | * | ||
| 21 | * @note | ||
| 22 | * None | ||
| 23 | */ | ||
| 24 | /****************************************************************************/ | ||
| 25 | |||
| 26 | #ifndef _INTCHW_REG_H | ||
| 27 | #define _INTCHW_REG_H | ||
| 28 | |||
| 29 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 30 | #include <csp/stdint.h> | ||
| 31 | #include <csp/reg.h> | ||
| 32 | #include <mach/csp/mm_io.h> | ||
| 33 | |||
| 34 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 35 | |||
| 36 | #define INTCHW_NUM_IRQ_PER_INTC 32 /* Maximum number of interrupt controllers */ | ||
| 37 | #define INTCHW_NUM_INTC 3 | ||
| 38 | |||
| 39 | /* Defines for interrupt controllers. This simplifies and cleans up the function calls. */ | ||
| 40 | #define INTCHW_INTC0 ((void *)MM_IO_BASE_INTC0) | ||
| 41 | #define INTCHW_INTC1 ((void *)MM_IO_BASE_INTC1) | ||
| 42 | #define INTCHW_SINTC ((void *)MM_IO_BASE_SINTC) | ||
| 43 | |||
| 44 | /* INTC0 - interrupt controller 0 */ | ||
| 45 | #define INTCHW_INTC0_PIF_BITNUM 31 /* Peripheral interface interrupt */ | ||
| 46 | #define INTCHW_INTC0_CLCD_BITNUM 30 /* LCD Controller interrupt */ | ||
| 47 | #define INTCHW_INTC0_GE_BITNUM 29 /* Graphic engine interrupt */ | ||
| 48 | #define INTCHW_INTC0_APM_BITNUM 28 /* Audio process module interrupt */ | ||
| 49 | #define INTCHW_INTC0_ESW_BITNUM 27 /* Ethernet switch interrupt */ | ||
| 50 | #define INTCHW_INTC0_SPIH_BITNUM 26 /* SPI host interrupt */ | ||
| 51 | #define INTCHW_INTC0_TIMER3_BITNUM 25 /* Timer3 interrupt */ | ||
| 52 | #define INTCHW_INTC0_TIMER2_BITNUM 24 /* Timer2 interrupt */ | ||
| 53 | #define INTCHW_INTC0_TIMER1_BITNUM 23 /* Timer1 interrupt */ | ||
| 54 | #define INTCHW_INTC0_TIMER0_BITNUM 22 /* Timer0 interrupt */ | ||
| 55 | #define INTCHW_INTC0_SDIOH1_BITNUM 21 /* SDIO1 host interrupt */ | ||
| 56 | #define INTCHW_INTC0_SDIOH0_BITNUM 20 /* SDIO0 host interrupt */ | ||
| 57 | #define INTCHW_INTC0_USBD_BITNUM 19 /* USB device interrupt */ | ||
| 58 | #define INTCHW_INTC0_USBH1_BITNUM 18 /* USB1 host interrupt */ | ||
| 59 | #define INTCHW_INTC0_USBHD2_BITNUM 17 /* USB host2/device2 interrupt */ | ||
| 60 | #define INTCHW_INTC0_VPM_BITNUM 16 /* Voice process module interrupt */ | ||
| 61 | #define INTCHW_INTC0_DMA1C7_BITNUM 15 /* DMA1 channel 7 interrupt */ | ||
| 62 | #define INTCHW_INTC0_DMA1C6_BITNUM 14 /* DMA1 channel 6 interrupt */ | ||
| 63 | #define INTCHW_INTC0_DMA1C5_BITNUM 13 /* DMA1 channel 5 interrupt */ | ||
| 64 | #define INTCHW_INTC0_DMA1C4_BITNUM 12 /* DMA1 channel 4 interrupt */ | ||
| 65 | #define INTCHW_INTC0_DMA1C3_BITNUM 11 /* DMA1 channel 3 interrupt */ | ||
| 66 | #define INTCHW_INTC0_DMA1C2_BITNUM 10 /* DMA1 channel 2 interrupt */ | ||
| 67 | #define INTCHW_INTC0_DMA1C1_BITNUM 9 /* DMA1 channel 1 interrupt */ | ||
| 68 | #define INTCHW_INTC0_DMA1C0_BITNUM 8 /* DMA1 channel 0 interrupt */ | ||
| 69 | #define INTCHW_INTC0_DMA0C7_BITNUM 7 /* DMA0 channel 7 interrupt */ | ||
| 70 | #define INTCHW_INTC0_DMA0C6_BITNUM 6 /* DMA0 channel 6 interrupt */ | ||
| 71 | #define INTCHW_INTC0_DMA0C5_BITNUM 5 /* DMA0 channel 5 interrupt */ | ||
| 72 | #define INTCHW_INTC0_DMA0C4_BITNUM 4 /* DMA0 channel 4 interrupt */ | ||
| 73 | #define INTCHW_INTC0_DMA0C3_BITNUM 3 /* DMA0 channel 3 interrupt */ | ||
| 74 | #define INTCHW_INTC0_DMA0C2_BITNUM 2 /* DMA0 channel 2 interrupt */ | ||
| 75 | #define INTCHW_INTC0_DMA0C1_BITNUM 1 /* DMA0 channel 1 interrupt */ | ||
| 76 | #define INTCHW_INTC0_DMA0C0_BITNUM 0 /* DMA0 channel 0 interrupt */ | ||
| 77 | |||
| 78 | #define INTCHW_INTC0_PIF (1<<INTCHW_INTC0_PIF_BITNUM) | ||
| 79 | #define INTCHW_INTC0_CLCD (1<<INTCHW_INTC0_CLCD_BITNUM) | ||
| 80 | #define INTCHW_INTC0_GE (1<<INTCHW_INTC0_GE_BITNUM) | ||
| 81 | #define INTCHW_INTC0_APM (1<<INTCHW_INTC0_APM_BITNUM) | ||
| 82 | #define INTCHW_INTC0_ESW (1<<INTCHW_INTC0_ESW_BITNUM) | ||
| 83 | #define INTCHW_INTC0_SPIH (1<<INTCHW_INTC0_SPIH_BITNUM) | ||
| 84 | #define INTCHW_INTC0_TIMER3 (1<<INTCHW_INTC0_TIMER3_BITNUM) | ||
| 85 | #define INTCHW_INTC0_TIMER2 (1<<INTCHW_INTC0_TIMER2_BITNUM) | ||
| 86 | #define INTCHW_INTC0_TIMER1 (1<<INTCHW_INTC0_TIMER1_BITNUM) | ||
| 87 | #define INTCHW_INTC0_TIMER0 (1<<INTCHW_INTC0_TIMER0_BITNUM) | ||
| 88 | #define INTCHW_INTC0_SDIOH1 (1<<INTCHW_INTC0_SDIOH1_BITNUM) | ||
| 89 | #define INTCHW_INTC0_SDIOH0 (1<<INTCHW_INTC0_SDIOH0_BITNUM) | ||
| 90 | #define INTCHW_INTC0_USBD (1<<INTCHW_INTC0_USBD_BITNUM) | ||
| 91 | #define INTCHW_INTC0_USBH1 (1<<INTCHW_INTC0_USBH1_BITNUM) | ||
| 92 | #define INTCHW_INTC0_USBHD2 (1<<INTCHW_INTC0_USBHD2_BITNUM) | ||
| 93 | #define INTCHW_INTC0_VPM (1<<INTCHW_INTC0_VPM_BITNUM) | ||
| 94 | #define INTCHW_INTC0_DMA1C7 (1<<INTCHW_INTC0_DMA1C7_BITNUM) | ||
| 95 | #define INTCHW_INTC0_DMA1C6 (1<<INTCHW_INTC0_DMA1C6_BITNUM) | ||
| 96 | #define INTCHW_INTC0_DMA1C5 (1<<INTCHW_INTC0_DMA1C5_BITNUM) | ||
| 97 | #define INTCHW_INTC0_DMA1C4 (1<<INTCHW_INTC0_DMA1C4_BITNUM) | ||
| 98 | #define INTCHW_INTC0_DMA1C3 (1<<INTCHW_INTC0_DMA1C3_BITNUM) | ||
| 99 | #define INTCHW_INTC0_DMA1C2 (1<<INTCHW_INTC0_DMA1C2_BITNUM) | ||
| 100 | #define INTCHW_INTC0_DMA1C1 (1<<INTCHW_INTC0_DMA1C1_BITNUM) | ||
| 101 | #define INTCHW_INTC0_DMA1C0 (1<<INTCHW_INTC0_DMA1C0_BITNUM) | ||
| 102 | #define INTCHW_INTC0_DMA0C7 (1<<INTCHW_INTC0_DMA0C7_BITNUM) | ||
| 103 | #define INTCHW_INTC0_DMA0C6 (1<<INTCHW_INTC0_DMA0C6_BITNUM) | ||
| 104 | #define INTCHW_INTC0_DMA0C5 (1<<INTCHW_INTC0_DMA0C5_BITNUM) | ||
| 105 | #define INTCHW_INTC0_DMA0C4 (1<<INTCHW_INTC0_DMA0C4_BITNUM) | ||
| 106 | #define INTCHW_INTC0_DMA0C3 (1<<INTCHW_INTC0_DMA0C3_BITNUM) | ||
| 107 | #define INTCHW_INTC0_DMA0C2 (1<<INTCHW_INTC0_DMA0C2_BITNUM) | ||
| 108 | #define INTCHW_INTC0_DMA0C1 (1<<INTCHW_INTC0_DMA0C1_BITNUM) | ||
| 109 | #define INTCHW_INTC0_DMA0C0 (1<<INTCHW_INTC0_DMA0C0_BITNUM) | ||
| 110 | |||
| 111 | /* INTC1 - interrupt controller 1 */ | ||
| 112 | #define INTCHW_INTC1_DDRVPMP_BITNUM 27 /* DDR and VPM PLL clock phase relationship interupt (Not for A0) */ | ||
| 113 | #define INTCHW_INTC1_DDRVPMT_BITNUM 26 /* DDR and VPM HW phase align timeout interrupt (Not for A0) */ | ||
| 114 | #define INTCHW_INTC1_DDRP_BITNUM 26 /* DDR and PLL clock phase relationship interupt (For A0 only)) */ | ||
| 115 | #define INTCHW_INTC1_RTC2_BITNUM 25 /* Real time clock tamper interrupt */ | ||
| 116 | #define INTCHW_INTC1_VDEC_BITNUM 24 /* Hantro Video Decoder interrupt */ | ||
| 117 | /* Bits 13-23 are non-secure versions of the corresponding secure bits in SINTC bits 0-10. */ | ||
| 118 | #define INTCHW_INTC1_SPUM_BITNUM 23 /* Secure process module interrupt */ | ||
| 119 | #define INTCHW_INTC1_RTC1_BITNUM 22 /* Real time clock one-shot interrupt */ | ||
| 120 | #define INTCHW_INTC1_RTC0_BITNUM 21 /* Real time clock periodic interrupt */ | ||
| 121 | #define INTCHW_INTC1_RNG_BITNUM 20 /* Random number generator interrupt */ | ||
| 122 | #define INTCHW_INTC1_FMPU_BITNUM 19 /* Flash memory parition unit interrupt */ | ||
| 123 | #define INTCHW_INTC1_VMPU_BITNUM 18 /* VRAM memory partition interrupt */ | ||
| 124 | #define INTCHW_INTC1_DMPU_BITNUM 17 /* DDR2 memory partition interrupt */ | ||
| 125 | #define INTCHW_INTC1_KEYC_BITNUM 16 /* Key pad controller interrupt */ | ||
| 126 | #define INTCHW_INTC1_TSC_BITNUM 15 /* Touch screen controller interrupt */ | ||
| 127 | #define INTCHW_INTC1_UART0_BITNUM 14 /* UART 0 */ | ||
| 128 | #define INTCHW_INTC1_WDOG_BITNUM 13 /* Watchdog timer interrupt */ | ||
| 129 | |||
| 130 | #define INTCHW_INTC1_UART1_BITNUM 12 /* UART 1 */ | ||
| 131 | #define INTCHW_INTC1_PMUIRQ_BITNUM 11 /* ARM performance monitor interrupt */ | ||
| 132 | #define INTCHW_INTC1_COMMRX_BITNUM 10 /* ARM DDC receive interrupt */ | ||
| 133 | #define INTCHW_INTC1_COMMTX_BITNUM 9 /* ARM DDC transmit interrupt */ | ||
| 134 | #define INTCHW_INTC1_FLASHC_BITNUM 8 /* Flash controller interrupt */ | ||
| 135 | #define INTCHW_INTC1_GPHY_BITNUM 7 /* Gigabit Phy interrupt */ | ||
| 136 | #define INTCHW_INTC1_SPIS_BITNUM 6 /* SPI slave interrupt */ | ||
| 137 | #define INTCHW_INTC1_I2CS_BITNUM 5 /* I2C slave interrupt */ | ||
| 138 | #define INTCHW_INTC1_I2CH_BITNUM 4 /* I2C host interrupt */ | ||
| 139 | #define INTCHW_INTC1_I2S1_BITNUM 3 /* I2S1 interrupt */ | ||
| 140 | #define INTCHW_INTC1_I2S0_BITNUM 2 /* I2S0 interrupt */ | ||
| 141 | #define INTCHW_INTC1_GPIO1_BITNUM 1 /* GPIO bit 64//32 combined interrupt */ | ||
| 142 | #define INTCHW_INTC1_GPIO0_BITNUM 0 /* GPIO bit 31//0 combined interrupt */ | ||
| 143 | |||
| 144 | #define INTCHW_INTC1_DDRVPMT (1<<INTCHW_INTC1_DDRVPMT_BITNUM) | ||
| 145 | #define INTCHW_INTC1_DDRVPMP (1<<INTCHW_INTC1_DDRVPMP_BITNUM) | ||
| 146 | #define INTCHW_INTC1_DDRP (1<<INTCHW_INTC1_DDRP_BITNUM) | ||
| 147 | #define INTCHW_INTC1_VDEC (1<<INTCHW_INTC1_VDEC_BITNUM) | ||
| 148 | #define INTCHW_INTC1_SPUM (1<<INTCHW_INTC1_SPUM_BITNUM) | ||
| 149 | #define INTCHW_INTC1_RTC2 (1<<INTCHW_INTC1_RTC2_BITNUM) | ||
| 150 | #define INTCHW_INTC1_RTC1 (1<<INTCHW_INTC1_RTC1_BITNUM) | ||
| 151 | #define INTCHW_INTC1_RTC0 (1<<INTCHW_INTC1_RTC0_BITNUM) | ||
| 152 | #define INTCHW_INTC1_RNG (1<<INTCHW_INTC1_RNG_BITNUM) | ||
| 153 | #define INTCHW_INTC1_FMPU (1<<INTCHW_INTC1_FMPU_BITNUM) | ||
| 154 | #define INTCHW_INTC1_IMPU (1<<INTCHW_INTC1_IMPU_BITNUM) | ||
| 155 | #define INTCHW_INTC1_DMPU (1<<INTCHW_INTC1_DMPU_BITNUM) | ||
| 156 | #define INTCHW_INTC1_KEYC (1<<INTCHW_INTC1_KEYC_BITNUM) | ||
| 157 | #define INTCHW_INTC1_TSC (1<<INTCHW_INTC1_TSC_BITNUM) | ||
| 158 | #define INTCHW_INTC1_UART0 (1<<INTCHW_INTC1_UART0_BITNUM) | ||
| 159 | #define INTCHW_INTC1_WDOG (1<<INTCHW_INTC1_WDOG_BITNUM) | ||
| 160 | #define INTCHW_INTC1_UART1 (1<<INTCHW_INTC1_UART1_BITNUM) | ||
| 161 | #define INTCHW_INTC1_PMUIRQ (1<<INTCHW_INTC1_PMUIRQ_BITNUM) | ||
| 162 | #define INTCHW_INTC1_COMMRX (1<<INTCHW_INTC1_COMMRX_BITNUM) | ||
| 163 | #define INTCHW_INTC1_COMMTX (1<<INTCHW_INTC1_COMMTX_BITNUM) | ||
| 164 | #define INTCHW_INTC1_FLASHC (1<<INTCHW_INTC1_FLASHC_BITNUM) | ||
| 165 | #define INTCHW_INTC1_GPHY (1<<INTCHW_INTC1_GPHY_BITNUM) | ||
| 166 | #define INTCHW_INTC1_SPIS (1<<INTCHW_INTC1_SPIS_BITNUM) | ||
| 167 | #define INTCHW_INTC1_I2CS (1<<INTCHW_INTC1_I2CS_BITNUM) | ||
| 168 | #define INTCHW_INTC1_I2CH (1<<INTCHW_INTC1_I2CH_BITNUM) | ||
| 169 | #define INTCHW_INTC1_I2S1 (1<<INTCHW_INTC1_I2S1_BITNUM) | ||
| 170 | #define INTCHW_INTC1_I2S0 (1<<INTCHW_INTC1_I2S0_BITNUM) | ||
| 171 | #define INTCHW_INTC1_GPIO1 (1<<INTCHW_INTC1_GPIO1_BITNUM) | ||
| 172 | #define INTCHW_INTC1_GPIO0 (1<<INTCHW_INTC1_GPIO0_BITNUM) | ||
| 173 | |||
| 174 | /* SINTC secure int controller */ | ||
| 175 | #define INTCHW_SINTC_RTC2_BITNUM 15 /* Real time clock tamper interrupt */ | ||
| 176 | #define INTCHW_SINTC_TIMER3_BITNUM 14 /* Secure timer3 interrupt */ | ||
| 177 | #define INTCHW_SINTC_TIMER2_BITNUM 13 /* Secure timer2 interrupt */ | ||
| 178 | #define INTCHW_SINTC_TIMER1_BITNUM 12 /* Secure timer1 interrupt */ | ||
| 179 | #define INTCHW_SINTC_TIMER0_BITNUM 11 /* Secure timer0 interrupt */ | ||
| 180 | #define INTCHW_SINTC_SPUM_BITNUM 10 /* Secure process module interrupt */ | ||
| 181 | #define INTCHW_SINTC_RTC1_BITNUM 9 /* Real time clock one-shot interrupt */ | ||
| 182 | #define INTCHW_SINTC_RTC0_BITNUM 8 /* Real time clock periodic interrupt */ | ||
| 183 | #define INTCHW_SINTC_RNG_BITNUM 7 /* Random number generator interrupt */ | ||
| 184 | #define INTCHW_SINTC_FMPU_BITNUM 6 /* Flash memory parition unit interrupt */ | ||
| 185 | #define INTCHW_SINTC_VMPU_BITNUM 5 /* VRAM memory partition interrupt */ | ||
| 186 | #define INTCHW_SINTC_DMPU_BITNUM 4 /* DDR2 memory partition interrupt */ | ||
| 187 | #define INTCHW_SINTC_KEYC_BITNUM 3 /* Key pad controller interrupt */ | ||
| 188 | #define INTCHW_SINTC_TSC_BITNUM 2 /* Touch screen controller interrupt */ | ||
| 189 | #define INTCHW_SINTC_UART0_BITNUM 1 /* UART0 interrupt */ | ||
| 190 | #define INTCHW_SINTC_WDOG_BITNUM 0 /* Watchdog timer interrupt */ | ||
| 191 | |||
| 192 | #define INTCHW_SINTC_TIMER3 (1<<INTCHW_SINTC_TIMER3_BITNUM) | ||
| 193 | #define INTCHW_SINTC_TIMER2 (1<<INTCHW_SINTC_TIMER2_BITNUM) | ||
| 194 | #define INTCHW_SINTC_TIMER1 (1<<INTCHW_SINTC_TIMER1_BITNUM) | ||
| 195 | #define INTCHW_SINTC_TIMER0 (1<<INTCHW_SINTC_TIMER0_BITNUM) | ||
| 196 | #define INTCHW_SINTC_SPUM (1<<INTCHW_SINTC_SPUM_BITNUM) | ||
| 197 | #define INTCHW_SINTC_RTC2 (1<<INTCHW_SINTC_RTC2_BITNUM) | ||
| 198 | #define INTCHW_SINTC_RTC1 (1<<INTCHW_SINTC_RTC1_BITNUM) | ||
| 199 | #define INTCHW_SINTC_RTC0 (1<<INTCHW_SINTC_RTC0_BITNUM) | ||
| 200 | #define INTCHW_SINTC_RNG (1<<INTCHW_SINTC_RNG_BITNUM) | ||
| 201 | #define INTCHW_SINTC_FMPU (1<<INTCHW_SINTC_FMPU_BITNUM) | ||
| 202 | #define INTCHW_SINTC_IMPU (1<<INTCHW_SINTC_IMPU_BITNUM) | ||
| 203 | #define INTCHW_SINTC_DMPU (1<<INTCHW_SINTC_DMPU_BITNUM) | ||
| 204 | #define INTCHW_SINTC_KEYC (1<<INTCHW_SINTC_KEYC_BITNUM) | ||
| 205 | #define INTCHW_SINTC_TSC (1<<INTCHW_SINTC_TSC_BITNUM) | ||
| 206 | #define INTCHW_SINTC_UART0 (1<<INTCHW_SINTC_UART0_BITNUM) | ||
| 207 | #define INTCHW_SINTC_WDOG (1<<INTCHW_SINTC_WDOG_BITNUM) | ||
| 208 | |||
| 209 | /* PL192 Vectored Interrupt Controller (VIC) layout */ | ||
| 210 | #define INTCHW_IRQSTATUS 0x00 /* IRQ status register */ | ||
| 211 | #define INTCHW_FIQSTATUS 0x04 /* FIQ status register */ | ||
| 212 | #define INTCHW_RAWINTR 0x08 /* Raw Interrupt Status register */ | ||
| 213 | #define INTCHW_INTSELECT 0x0c /* Interrupt Select Register */ | ||
| 214 | #define INTCHW_INTENABLE 0x10 /* Interrupt Enable Register */ | ||
| 215 | #define INTCHW_INTENCLEAR 0x14 /* Interrupt Enable Clear Register */ | ||
| 216 | #define INTCHW_SOFTINT 0x18 /* Soft Interrupt Register */ | ||
| 217 | #define INTCHW_SOFTINTCLEAR 0x1c /* Soft Interrupt Clear Register */ | ||
| 218 | #define INTCHW_PROTECTION 0x20 /* Protection Enable Register */ | ||
| 219 | #define INTCHW_SWPRIOMASK 0x24 /* Software Priority Mask Register */ | ||
| 220 | #define INTCHW_PRIODAISY 0x28 /* Priority Daisy Chain Register */ | ||
| 221 | #define INTCHW_VECTADDR0 0x100 /* Vector Address Registers */ | ||
| 222 | #define INTCHW_VECTPRIO0 0x200 /* Vector Priority Registers 0-31 */ | ||
| 223 | #define INTCHW_ADDRESS 0xf00 /* Vector Address Register 0-31 */ | ||
| 224 | #define INTCHW_PID 0xfe0 /* Peripheral ID Register 0-3 */ | ||
| 225 | #define INTCHW_PCELLID 0xff0 /* PrimeCell ID Register 0-3 */ | ||
| 226 | |||
| 227 | /* Example Usage: intcHw_irq_enable(INTCHW_INTC0, INTCHW_INTC0_TIMER0); */ | ||
| 228 | /* intcHw_irq_clear(INTCHW_INTC0, INTCHW_INTC0_TIMER0); */ | ||
| 229 | /* uint32_t bits = intcHw_irq_status(INTCHW_INTC0); */ | ||
| 230 | /* uint32_t bits = intcHw_irq_raw_status(INTCHW_INTC0); */ | ||
| 231 | |||
| 232 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 233 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 234 | /* Clear one or more IRQ interrupts. */ | ||
| 235 | static inline void intcHw_irq_disable(void *basep, uint32_t mask) | ||
| 236 | { | ||
| 237 | __REG32(basep + INTCHW_INTENCLEAR) = mask; | ||
| 238 | } | ||
| 239 | |||
| 240 | /* Enables one or more IRQ interrupts. */ | ||
| 241 | static inline void intcHw_irq_enable(void *basep, uint32_t mask) | ||
| 242 | { | ||
| 243 | __REG32(basep + INTCHW_INTENABLE) = mask; | ||
| 244 | } | ||
| 245 | |||
| 246 | #endif /* _INTCHW_REG_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h new file mode 100644 index 000000000000..86bb58d4f58c --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file mm_addr.h | ||
| 18 | * | ||
| 19 | * @brief Memory Map address defintions | ||
| 20 | * | ||
| 21 | * @note | ||
| 22 | * None | ||
| 23 | */ | ||
| 24 | /****************************************************************************/ | ||
| 25 | |||
| 26 | #ifndef _MM_ADDR_H | ||
| 27 | #define _MM_ADDR_H | ||
| 28 | |||
| 29 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 30 | |||
| 31 | #if !defined(CSP_SIMULATION) | ||
| 32 | #include <cfg_global.h> | ||
| 33 | #endif | ||
| 34 | |||
| 35 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 36 | |||
| 37 | /* Memory Map address definitions */ | ||
| 38 | |||
| 39 | #define MM_ADDR_DDR 0x00000000 | ||
| 40 | |||
| 41 | #define MM_ADDR_IO_VPM_EXTMEM_RSVD 0x0F000000 /* 16 MB - Reserved external memory for VPM use */ | ||
| 42 | |||
| 43 | #define MM_ADDR_IO_FLASHC 0x20000000 | ||
| 44 | #define MM_ADDR_IO_BROM 0x30000000 | ||
| 45 | #define MM_ADDR_IO_ARAM 0x30100000 /* 64 KB - extra cycle latency - WS switch */ | ||
| 46 | #define MM_ADDR_IO_DMA0 0x30200000 | ||
| 47 | #define MM_ADDR_IO_DMA1 0x30300000 | ||
| 48 | #define MM_ADDR_IO_ESW 0x30400000 | ||
| 49 | #define MM_ADDR_IO_CLCD 0x30500000 | ||
| 50 | #define MM_ADDR_IO_PIF 0x30580000 | ||
| 51 | #define MM_ADDR_IO_APM 0x30600000 | ||
| 52 | #define MM_ADDR_IO_SPUM 0x30700000 | ||
| 53 | #define MM_ADDR_IO_VPM_PROG 0x30800000 | ||
| 54 | #define MM_ADDR_IO_VPM_DATA 0x30A00000 | ||
| 55 | #define MM_ADDR_IO_VRAM 0x40000000 /* 64 KB - security block in front of it */ | ||
| 56 | #define MM_ADDR_IO_CHIPC 0x80000000 | ||
| 57 | #define MM_ADDR_IO_UMI 0x80001000 | ||
| 58 | #define MM_ADDR_IO_NAND 0x80001800 | ||
| 59 | #define MM_ADDR_IO_LEDM 0x80002000 | ||
| 60 | #define MM_ADDR_IO_PWM 0x80002040 | ||
| 61 | #define MM_ADDR_IO_VINTC 0x80003000 | ||
| 62 | #define MM_ADDR_IO_GPIO0 0x80004000 | ||
| 63 | #define MM_ADDR_IO_GPIO1 0x80004800 | ||
| 64 | #define MM_ADDR_IO_I2CS 0x80005000 | ||
| 65 | #define MM_ADDR_IO_SPIS 0x80006000 | ||
| 66 | #define MM_ADDR_IO_HPM 0x80007400 | ||
| 67 | #define MM_ADDR_IO_HPM_REMAP 0x80007800 | ||
| 68 | #define MM_ADDR_IO_TZPC 0x80008000 | ||
| 69 | #define MM_ADDR_IO_MPU 0x80009000 | ||
| 70 | #define MM_ADDR_IO_SPUMP 0x8000a000 | ||
| 71 | #define MM_ADDR_IO_PKA 0x8000b000 | ||
| 72 | #define MM_ADDR_IO_RNG 0x8000c000 | ||
| 73 | #define MM_ADDR_IO_KEYC 0x8000d000 | ||
| 74 | #define MM_ADDR_IO_BBL 0x8000e000 | ||
| 75 | #define MM_ADDR_IO_OTP 0x8000f000 | ||
| 76 | #define MM_ADDR_IO_I2S0 0x80010000 | ||
| 77 | #define MM_ADDR_IO_I2S1 0x80011000 | ||
| 78 | #define MM_ADDR_IO_UARTA 0x80012000 | ||
| 79 | #define MM_ADDR_IO_UARTB 0x80013000 | ||
| 80 | #define MM_ADDR_IO_I2CH 0x80014020 | ||
| 81 | #define MM_ADDR_IO_SPIH 0x80015000 | ||
| 82 | #define MM_ADDR_IO_TSC 0x80016000 | ||
| 83 | #define MM_ADDR_IO_TMR 0x80017000 | ||
| 84 | #define MM_ADDR_IO_WATCHDOG 0x80017800 | ||
| 85 | #define MM_ADDR_IO_ETM 0x80018000 | ||
| 86 | #define MM_ADDR_IO_DDRC 0x80019000 | ||
| 87 | #define MM_ADDR_IO_SINTC 0x80100000 | ||
| 88 | #define MM_ADDR_IO_INTC0 0x80200000 | ||
| 89 | #define MM_ADDR_IO_INTC1 0x80201000 | ||
| 90 | #define MM_ADDR_IO_GE 0x80300000 | ||
| 91 | #define MM_ADDR_IO_USB_CTLR0 0x80400000 | ||
| 92 | #define MM_ADDR_IO_USB_CTLR1 0x80410000 | ||
| 93 | #define MM_ADDR_IO_USB_PHY 0x80420000 | ||
| 94 | #define MM_ADDR_IO_SDIOH0 0x80500000 | ||
| 95 | #define MM_ADDR_IO_SDIOH1 0x80600000 | ||
| 96 | #define MM_ADDR_IO_VDEC 0x80700000 | ||
| 97 | |||
| 98 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 99 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 100 | |||
| 101 | #endif /* _MM_ADDR_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/mm_io.h b/arch/arm/mach-bcmring/include/mach/csp/mm_io.h new file mode 100644 index 000000000000..de92ec6a01aa --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/mm_io.h | |||
| @@ -0,0 +1,147 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file mm_io.h | ||
| 18 | * | ||
| 19 | * @brief Memory Map I/O definitions | ||
| 20 | * | ||
| 21 | * @note | ||
| 22 | * None | ||
| 23 | */ | ||
| 24 | /****************************************************************************/ | ||
| 25 | |||
| 26 | #ifndef _MM_IO_H | ||
| 27 | #define _MM_IO_H | ||
| 28 | |||
| 29 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 30 | #include <mach/csp/mm_addr.h> | ||
| 31 | |||
| 32 | #if !defined(CSP_SIMULATION) | ||
| 33 | #include <cfg_global.h> | ||
| 34 | #endif | ||
| 35 | |||
| 36 | /* ---- Public Constants and Types --------------------------------------- */ | ||
| 37 | |||
| 38 | #if defined(CONFIG_MMU) | ||
| 39 | |||
| 40 | /* This macro is referenced in <mach/io.h> | ||
| 41 | * Phys to Virtual 0xNyxxxxxx => 0xFNxxxxxx | ||
| 42 | * This macro is referenced in <asm/arch/io.h> | ||
| 43 | * | ||
| 44 | * Assume VPM address is the last x MB of memory. For VPM, map to | ||
| 45 | * 0xf0000000 and up. | ||
| 46 | */ | ||
| 47 | |||
| 48 | #ifndef MM_IO_PHYS_TO_VIRT | ||
| 49 | #ifdef __ASSEMBLY__ | ||
| 50 | #define MM_IO_PHYS_TO_VIRT(phys) (0xF0000000 | (((phys) >> 4) & 0x0F000000) | ((phys) & 0xFFFFFF)) | ||
| 51 | #else | ||
| 52 | #define MM_IO_PHYS_TO_VIRT(phys) (((phys) == MM_ADDR_IO_VPM_EXTMEM_RSVD) ? 0xF0000000 : \ | ||
| 53 | (0xF0000000 | (((phys) >> 4) & 0x0F000000) | ((phys) & 0xFFFFFF))) | ||
| 54 | #endif | ||
| 55 | #endif | ||
| 56 | |||
| 57 | /* Virtual to Physical 0xFNxxxxxx => 0xN0xxxxxx */ | ||
| 58 | |||
| 59 | #ifndef MM_IO_VIRT_TO_PHYS | ||
| 60 | #ifdef __ASSEMBLY__ | ||
| 61 | #define MM_IO_VIRT_TO_PHYS(virt) ((((virt) & 0x0F000000) << 4) | ((virt) & 0xFFFFFF)) | ||
| 62 | #else | ||
| 63 | #define MM_IO_VIRT_TO_PHYS(virt) (((virt) == 0xF0000000) ? MM_ADDR_IO_VPM_EXTMEM_RSVD : \ | ||
| 64 | ((((virt) & 0x0F000000) << 4) | ((virt) & 0xFFFFFF))) | ||
| 65 | #endif | ||
| 66 | #endif | ||
| 67 | |||
| 68 | #else | ||
| 69 | |||
| 70 | #ifndef MM_IO_PHYS_TO_VIRT | ||
| 71 | #define MM_IO_PHYS_TO_VIRT(phys) (phys) | ||
| 72 | #endif | ||
| 73 | |||
| 74 | #ifndef MM_IO_VIRT_TO_PHYS | ||
| 75 | #define MM_IO_VIRT_TO_PHYS(virt) (virt) | ||
| 76 | #endif | ||
| 77 | |||
| 78 | #endif | ||
| 79 | |||
| 80 | /* Registers in 0xExxxxxxx that should be moved to 0xFxxxxxxx */ | ||
| 81 | #define MM_IO_BASE_FLASHC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_FLASHC) | ||
| 82 | #define MM_IO_BASE_NAND MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_NAND) | ||
| 83 | #define MM_IO_BASE_UMI MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_UMI) | ||
| 84 | |||
| 85 | #define MM_IO_START MM_ADDR_IO_FLASHC /* Physical beginning of IO mapped memory */ | ||
| 86 | #define MM_IO_BASE MM_IO_BASE_FLASHC /* Virtual beginning of IO mapped memory */ | ||
| 87 | |||
| 88 | #define MM_IO_BASE_BROM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_BROM) | ||
| 89 | #define MM_IO_BASE_ARAM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_ARAM) | ||
| 90 | #define MM_IO_BASE_DMA0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_DMA0) | ||
| 91 | #define MM_IO_BASE_DMA1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_DMA1) | ||
| 92 | #define MM_IO_BASE_ESW MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_ESW) | ||
| 93 | #define MM_IO_BASE_CLCD MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_CLCD) | ||
| 94 | #define MM_IO_BASE_PIF MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_PIF) | ||
| 95 | #define MM_IO_BASE_APM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_APM) | ||
| 96 | #define MM_IO_BASE_SPUM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPUM) | ||
| 97 | #define MM_IO_BASE_VPM_PROG MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VPM_PROG) | ||
| 98 | #define MM_IO_BASE_VPM_DATA MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VPM_DATA) | ||
| 99 | |||
| 100 | #define MM_IO_BASE_VRAM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VRAM) | ||
| 101 | |||
| 102 | #define MM_IO_BASE_CHIPC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_CHIPC) | ||
| 103 | #define MM_IO_BASE_DDRC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_DDRC) | ||
| 104 | #define MM_IO_BASE_LEDM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_LEDM) | ||
| 105 | #define MM_IO_BASE_PWM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_PWM) | ||
| 106 | #define MM_IO_BASE_VINTC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VINTC) | ||
| 107 | #define MM_IO_BASE_GPIO0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_GPIO0) | ||
| 108 | #define MM_IO_BASE_GPIO1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_GPIO1) | ||
| 109 | #define MM_IO_BASE_TMR MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_TMR) | ||
| 110 | #define MM_IO_BASE_WATCHDOG MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_WATCHDOG) | ||
| 111 | #define MM_IO_BASE_ETM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_ETM) | ||
| 112 | #define MM_IO_BASE_HPM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_HPM) | ||
| 113 | #define MM_IO_BASE_HPM_REMAP MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_HPM_REMAP) | ||
| 114 | #define MM_IO_BASE_TZPC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_TZPC) | ||
| 115 | #define MM_IO_BASE_MPU MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_MPU) | ||
| 116 | #define MM_IO_BASE_SPUMP MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPUMP) | ||
| 117 | #define MM_IO_BASE_PKA MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_PKA) | ||
| 118 | #define MM_IO_BASE_RNG MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_RNG) | ||
| 119 | #define MM_IO_BASE_KEYC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_KEYC) | ||
| 120 | #define MM_IO_BASE_BBL MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_BBL) | ||
| 121 | #define MM_IO_BASE_OTP MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_OTP) | ||
| 122 | #define MM_IO_BASE_I2S0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2S0) | ||
| 123 | #define MM_IO_BASE_I2S1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2S1) | ||
| 124 | #define MM_IO_BASE_UARTA MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_UARTA) | ||
| 125 | #define MM_IO_BASE_UARTB MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_UARTB) | ||
| 126 | #define MM_IO_BASE_I2CH MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2CH) | ||
| 127 | #define MM_IO_BASE_SPIH MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPIH) | ||
| 128 | #define MM_IO_BASE_TSC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_TSC) | ||
| 129 | #define MM_IO_BASE_I2CS MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2CS) | ||
| 130 | #define MM_IO_BASE_SPIS MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPIS) | ||
| 131 | #define MM_IO_BASE_SINTC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SINTC) | ||
| 132 | #define MM_IO_BASE_INTC0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_INTC0) | ||
| 133 | #define MM_IO_BASE_INTC1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_INTC1) | ||
| 134 | #define MM_IO_BASE_GE MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_GE) | ||
| 135 | #define MM_IO_BASE_USB_CTLR0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_USB_CTLR0) | ||
| 136 | #define MM_IO_BASE_USB_CTLR1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_USB_CTLR1) | ||
| 137 | #define MM_IO_BASE_USB_PHY MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_USB_PHY) | ||
| 138 | #define MM_IO_BASE_SDIOH0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SDIOH0) | ||
| 139 | #define MM_IO_BASE_SDIOH1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SDIOH1) | ||
| 140 | #define MM_IO_BASE_VDEC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VDEC) | ||
| 141 | |||
| 142 | #define MM_IO_BASE_VPM_EXTMEM_RSVD MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VPM_EXTMEM_RSVD) | ||
| 143 | |||
| 144 | /* ---- Public Variable Externs ------------------------------------------ */ | ||
| 145 | /* ---- Public Function Prototypes --------------------------------------- */ | ||
| 146 | |||
| 147 | #endif /* _MM_IO_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/secHw_def.h b/arch/arm/mach-bcmring/include/mach/csp/secHw_def.h new file mode 100644 index 000000000000..d15f5f3ec2d8 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/secHw_def.h | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file secHw_def.h | ||
| 18 | * | ||
| 19 | * @brief Definitions for configuring/testing secure blocks | ||
| 20 | * | ||
| 21 | * @note | ||
| 22 | * None | ||
| 23 | */ | ||
| 24 | /****************************************************************************/ | ||
| 25 | |||
| 26 | #ifndef SECHW_DEF_H | ||
| 27 | #define SECHW_DEF_H | ||
| 28 | |||
| 29 | #include <mach/csp/mm_io.h> | ||
| 30 | |||
| 31 | /* Bit mask for various secure device */ | ||
| 32 | #define secHw_BLK_MASK_CHIP_CONTROL 0x00000001 | ||
| 33 | #define secHw_BLK_MASK_KEY_SCAN 0x00000002 | ||
| 34 | #define secHw_BLK_MASK_TOUCH_SCREEN 0x00000004 | ||
| 35 | #define secHw_BLK_MASK_UART0 0x00000008 | ||
| 36 | #define secHw_BLK_MASK_UART1 0x00000010 | ||
| 37 | #define secHw_BLK_MASK_WATCHDOG 0x00000020 | ||
| 38 | #define secHw_BLK_MASK_SPUM 0x00000040 | ||
| 39 | #define secHw_BLK_MASK_DDR2 0x00000080 | ||
| 40 | #define secHw_BLK_MASK_EXT_MEM 0x00000100 | ||
| 41 | #define secHw_BLK_MASK_ESW 0x00000200 | ||
| 42 | #define secHw_BLK_MASK_SPU 0x00010000 | ||
| 43 | #define secHw_BLK_MASK_PKA 0x00020000 | ||
| 44 | #define secHw_BLK_MASK_RNG 0x00040000 | ||
| 45 | #define secHw_BLK_MASK_RTC 0x00080000 | ||
| 46 | #define secHw_BLK_MASK_OTP 0x00100000 | ||
| 47 | #define secHw_BLK_MASK_BOOT 0x00200000 | ||
| 48 | #define secHw_BLK_MASK_MPU 0x00400000 | ||
| 49 | #define secHw_BLK_MASK_TZCTRL 0x00800000 | ||
| 50 | #define secHw_BLK_MASK_INTR 0x01000000 | ||
| 51 | |||
| 52 | /* Trustzone register set */ | ||
| 53 | typedef struct { | ||
| 54 | volatile uint32_t status; /* read only - reflects status of writes of 2 write registers */ | ||
| 55 | volatile uint32_t setUnsecure; /* write only. reads back as 0 */ | ||
| 56 | volatile uint32_t setSecure; /* write only. reads back as 0 */ | ||
| 57 | } secHw_TZREG_t; | ||
| 58 | |||
| 59 | /* There are 2 register sets. The first is for the lower 16 bits, the 2nd */ | ||
| 60 | /* is for the higher 16 bits. */ | ||
| 61 | |||
| 62 | typedef enum { | ||
| 63 | secHw_IDX_LS = 0, | ||
| 64 | secHw_IDX_MS = 1, | ||
| 65 | secHw_IDX_NUM | ||
| 66 | } secHw_IDX_e; | ||
| 67 | |||
| 68 | typedef struct { | ||
| 69 | volatile secHw_TZREG_t reg[secHw_IDX_NUM]; | ||
| 70 | } secHw_REGS_t; | ||
| 71 | |||
| 72 | /****************************************************************************/ | ||
| 73 | /** | ||
| 74 | * @brief Configures a device as a secure device | ||
| 75 | * | ||
| 76 | */ | ||
| 77 | /****************************************************************************/ | ||
| 78 | static inline void secHw_setSecure(uint32_t mask /* mask of type secHw_BLK_MASK_XXXXXX */ | ||
| 79 | ); | ||
| 80 | |||
| 81 | /****************************************************************************/ | ||
| 82 | /** | ||
| 83 | * @brief Configures a device as a non-secure device | ||
| 84 | * | ||
| 85 | */ | ||
| 86 | /****************************************************************************/ | ||
| 87 | static inline void secHw_setUnsecure(uint32_t mask /* mask of type secHw_BLK_MASK_XXXXXX */ | ||
| 88 | ); | ||
| 89 | |||
| 90 | /****************************************************************************/ | ||
| 91 | /** | ||
| 92 | * @brief Get the trustzone status for all components. 1 = non-secure, 0 = secure | ||
| 93 | * | ||
| 94 | */ | ||
| 95 | /****************************************************************************/ | ||
| 96 | static inline uint32_t secHw_getStatus(void); | ||
| 97 | |||
| 98 | #include <mach/csp/secHw_inline.h> | ||
| 99 | |||
| 100 | #endif /* SECHW_DEF_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h b/arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h new file mode 100644 index 000000000000..9cd6a032ab71 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file secHw_inline.h | ||
| 18 | * | ||
| 19 | * @brief Definitions for configuring/testing secure blocks | ||
| 20 | * | ||
| 21 | * @note | ||
| 22 | * None | ||
| 23 | */ | ||
| 24 | /****************************************************************************/ | ||
| 25 | |||
| 26 | #ifndef SECHW_INLINE_H | ||
| 27 | #define SECHW_INLINE_H | ||
| 28 | |||
| 29 | /****************************************************************************/ | ||
| 30 | /** | ||
| 31 | * @brief Configures a device as a secure device | ||
| 32 | * | ||
| 33 | */ | ||
| 34 | /****************************************************************************/ | ||
| 35 | static inline void secHw_setSecure(uint32_t mask /* mask of type secHw_BLK_MASK_XXXXXX */ | ||
| 36 | ) { | ||
| 37 | secHw_REGS_t *regp = (secHw_REGS_t *) MM_IO_BASE_TZPC; | ||
| 38 | |||
| 39 | if (mask & 0x0000FFFF) { | ||
| 40 | regp->reg[secHw_IDX_LS].setSecure = mask & 0x0000FFFF; | ||
| 41 | } | ||
| 42 | |||
| 43 | if (mask & 0xFFFF0000) { | ||
| 44 | regp->reg[secHw_IDX_MS].setSecure = mask >> 16; | ||
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 48 | /****************************************************************************/ | ||
| 49 | /** | ||
| 50 | * @brief Configures a device as a non-secure device | ||
| 51 | * | ||
| 52 | */ | ||
| 53 | /****************************************************************************/ | ||
| 54 | static inline void secHw_setUnsecure(uint32_t mask /* mask of type secHw_BLK_MASK_XXXXXX */ | ||
| 55 | ) { | ||
| 56 | secHw_REGS_t *regp = (secHw_REGS_t *) MM_IO_BASE_TZPC; | ||
| 57 | |||
| 58 | if (mask & 0x0000FFFF) { | ||
| 59 | regp->reg[secHw_IDX_LS].setUnsecure = mask & 0x0000FFFF; | ||
| 60 | } | ||
| 61 | if (mask & 0xFFFF0000) { | ||
| 62 | regp->reg[secHw_IDX_MS].setUnsecure = mask >> 16; | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | /****************************************************************************/ | ||
| 67 | /** | ||
| 68 | * @brief Get the trustzone status for all components. 1 = non-secure, 0 = secure | ||
| 69 | * | ||
| 70 | */ | ||
| 71 | /****************************************************************************/ | ||
| 72 | static inline uint32_t secHw_getStatus(void) | ||
| 73 | { | ||
| 74 | secHw_REGS_t *regp = (secHw_REGS_t *) MM_IO_BASE_TZPC; | ||
| 75 | |||
| 76 | return (regp->reg[1].status << 16) + regp->reg[0].status; | ||
| 77 | } | ||
| 78 | |||
| 79 | #endif /* SECHW_INLINE_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h new file mode 100644 index 000000000000..3080ac7239a1 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file tmrHw_reg.h | ||
| 18 | * | ||
| 19 | * @brief Definitions for low level Timer registers | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | /****************************************************************************/ | ||
| 23 | #ifndef _TMRHW_REG_H | ||
| 24 | #define _TMRHW_REG_H | ||
| 25 | |||
| 26 | #include <mach/csp/mm_io.h> | ||
| 27 | #include <mach/csp/hw_cfg.h> | ||
| 28 | /* Base address */ | ||
| 29 | #define tmrHw_MODULE_BASE_ADDR MM_IO_BASE_TMR | ||
| 30 | |||
| 31 | /* | ||
| 32 | This platform has four different timers running at different clock speed | ||
| 33 | |||
| 34 | Timer one (Timer ID 0) runs at 25 MHz | ||
| 35 | Timer two (Timer ID 1) runs at 25 MHz | ||
| 36 | Timer three (Timer ID 2) runs at 150 MHz | ||
| 37 | Timer four (Timer ID 3) runs at 150 MHz | ||
| 38 | */ | ||
| 39 | #define tmrHw_LOW_FREQUENCY_MHZ 25 /* Always 25MHz from XTAL */ | ||
| 40 | #define tmrHw_LOW_FREQUENCY_HZ 25000000 | ||
| 41 | |||
| 42 | #if defined(CFG_GLOBAL_CHIP) && (CFG_GLOBAL_CHIP == FPGA11107) | ||
| 43 | #define tmrHw_HIGH_FREQUENCY_MHZ 150 /* Always 150MHz for FPGA */ | ||
| 44 | #define tmrHw_HIGH_FREQUENCY_HZ 150000000 | ||
| 45 | #else | ||
| 46 | #define tmrHw_HIGH_FREQUENCY_HZ HW_CFG_BUS_CLK_HZ | ||
| 47 | #define tmrHw_HIGH_FREQUENCY_MHZ (HW_CFG_BUS_CLK_HZ / 1000000) | ||
| 48 | #endif | ||
| 49 | |||
| 50 | #define tmrHw_LOW_RESOLUTION_CLOCK tmrHw_LOW_FREQUENCY_HZ | ||
| 51 | #define tmrHw_HIGH_RESOLUTION_CLOCK tmrHw_HIGH_FREQUENCY_HZ | ||
| 52 | #define tmrHw_MAX_COUNT (0xFFFFFFFF) /* maximum number of count a timer can count */ | ||
| 53 | #define tmrHw_TIMER_NUM_COUNT (4) /* Number of timer module supported */ | ||
| 54 | |||
| 55 | typedef struct { | ||
| 56 | uint32_t LoadValue; /* Load value for timer */ | ||
| 57 | uint32_t CurrentValue; /* Current value for timer */ | ||
| 58 | uint32_t Control; /* Control register */ | ||
| 59 | uint32_t InterruptClear; /* Interrupt clear register */ | ||
| 60 | uint32_t RawInterruptStatus; /* Raw interrupt status */ | ||
| 61 | uint32_t InterruptStatus; /* Masked interrupt status */ | ||
| 62 | uint32_t BackgroundLoad; /* Background load value */ | ||
| 63 | uint32_t padding; /* Padding register */ | ||
| 64 | } tmrHw_REG_t; | ||
| 65 | |||
| 66 | /* Control bot masks */ | ||
| 67 | #define tmrHw_CONTROL_TIMER_ENABLE 0x00000080 | ||
| 68 | #define tmrHw_CONTROL_PERIODIC 0x00000040 | ||
| 69 | #define tmrHw_CONTROL_INTERRUPT_ENABLE 0x00000020 | ||
| 70 | #define tmrHw_CONTROL_PRESCALE_MASK 0x0000000C | ||
| 71 | #define tmrHw_CONTROL_PRESCALE_1 0x00000000 | ||
| 72 | #define tmrHw_CONTROL_PRESCALE_16 0x00000004 | ||
| 73 | #define tmrHw_CONTROL_PRESCALE_256 0x00000008 | ||
| 74 | #define tmrHw_CONTROL_32BIT 0x00000002 | ||
| 75 | #define tmrHw_CONTROL_ONESHOT 0x00000001 | ||
| 76 | #define tmrHw_CONTROL_FREE_RUNNING 0x00000000 | ||
| 77 | |||
| 78 | #define tmrHw_CONTROL_MODE_MASK (tmrHw_CONTROL_PERIODIC | tmrHw_CONTROL_ONESHOT) | ||
| 79 | |||
| 80 | #define pTmrHw ((volatile tmrHw_REG_t *)tmrHw_MODULE_BASE_ADDR) | ||
| 81 | |||
| 82 | #endif /* _TMRHW_REG_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/dma.h b/arch/arm/mach-bcmring/include/mach/dma.h new file mode 100644 index 000000000000..847980c85c88 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/dma.h | |||
| @@ -0,0 +1,826 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /****************************************************************************/ | ||
| 16 | /** | ||
| 17 | * @file dma.h | ||
| 18 | * | ||
| 19 | * @brief API definitions for the linux DMA interface. | ||
| 20 | */ | ||
| 21 | /****************************************************************************/ | ||
| 22 | |||
| 23 | #if !defined(ASM_ARM_ARCH_BCMRING_DMA_H) | ||
| 24 | #define ASM_ARM_ARCH_BCMRING_DMA_H | ||
| 25 | |||
| 26 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 27 | |||
| 28 | #include <linux/kernel.h> | ||
| 29 | #include <linux/wait.h> | ||
| 30 | #include <linux/semaphore.h> | ||
| 31 | #include <csp/dmacHw.h> | ||
| 32 | #include <mach/timer.h> | ||
| 33 | #include <linux/scatterlist.h> | ||
| 34 | #include <linux/dma-mapping.h> | ||
| 35 | #include <linux/mm.h> | ||
| 36 | #include <linux/vmalloc.h> | ||
| 37 | #include <linux/pagemap.h> | ||
| 38 | |||
| 39 | /* ---- Constants and Types ---------------------------------------------- */ | ||
| 40 | |||
| 41 | /* If DMA_DEBUG_TRACK_RESERVATION is set to a non-zero value, then the filename */ | ||
| 42 | /* and line number of the reservation request will be recorded in the channel table */ | ||
| 43 | |||
| 44 | #define DMA_DEBUG_TRACK_RESERVATION 1 | ||
| 45 | |||
| 46 | #define DMA_NUM_CONTROLLERS 2 | ||
| 47 | #define DMA_NUM_CHANNELS 8 /* per controller */ | ||
| 48 | |||
| 49 | typedef enum { | ||
| 50 | DMA_DEVICE_MEM_TO_MEM, /* For memory to memory transfers */ | ||
| 51 | DMA_DEVICE_I2S0_DEV_TO_MEM, | ||
| 52 | DMA_DEVICE_I2S0_MEM_TO_DEV, | ||
| 53 | DMA_DEVICE_I2S1_DEV_TO_MEM, | ||
| 54 | DMA_DEVICE_I2S1_MEM_TO_DEV, | ||
| 55 | DMA_DEVICE_APM_CODEC_A_DEV_TO_MEM, | ||
| 56 | DMA_DEVICE_APM_CODEC_A_MEM_TO_DEV, | ||
| 57 | DMA_DEVICE_APM_CODEC_B_DEV_TO_MEM, | ||
| 58 | DMA_DEVICE_APM_CODEC_B_MEM_TO_DEV, | ||
| 59 | DMA_DEVICE_APM_CODEC_C_DEV_TO_MEM, /* Additional mic input for beam-forming */ | ||
| 60 | DMA_DEVICE_APM_PCM0_DEV_TO_MEM, | ||
| 61 | DMA_DEVICE_APM_PCM0_MEM_TO_DEV, | ||
| 62 | DMA_DEVICE_APM_PCM1_DEV_TO_MEM, | ||
| 63 | DMA_DEVICE_APM_PCM1_MEM_TO_DEV, | ||
| 64 | DMA_DEVICE_SPUM_DEV_TO_MEM, | ||
| 65 | DMA_DEVICE_SPUM_MEM_TO_DEV, | ||
| 66 | DMA_DEVICE_SPIH_DEV_TO_MEM, | ||
| 67 | DMA_DEVICE_SPIH_MEM_TO_DEV, | ||
| 68 | DMA_DEVICE_UART_A_DEV_TO_MEM, | ||
| 69 | DMA_DEVICE_UART_A_MEM_TO_DEV, | ||
| 70 | DMA_DEVICE_UART_B_DEV_TO_MEM, | ||
| 71 | DMA_DEVICE_UART_B_MEM_TO_DEV, | ||
| 72 | DMA_DEVICE_PIF_MEM_TO_DEV, | ||
| 73 | DMA_DEVICE_PIF_DEV_TO_MEM, | ||
| 74 | DMA_DEVICE_ESW_DEV_TO_MEM, | ||
| 75 | DMA_DEVICE_ESW_MEM_TO_DEV, | ||
| 76 | DMA_DEVICE_VPM_MEM_TO_MEM, | ||
| 77 | DMA_DEVICE_CLCD_MEM_TO_MEM, | ||
| 78 | DMA_DEVICE_NAND_MEM_TO_MEM, | ||
| 79 | DMA_DEVICE_MEM_TO_VRAM, | ||
| 80 | DMA_DEVICE_VRAM_TO_MEM, | ||
| 81 | |||
| 82 | /* Add new entries before this line. */ | ||
| 83 | |||
| 84 | DMA_NUM_DEVICE_ENTRIES, | ||
| 85 | DMA_DEVICE_NONE = 0xff, /* Special value to indicate that no device is currently assigned. */ | ||
| 86 | |||
| 87 | } DMA_Device_t; | ||
| 88 | |||
| 89 | /**************************************************************************** | ||
| 90 | * | ||
| 91 | * The DMA_Handle_t is the primary object used by callers of the API. | ||
| 92 | * | ||
| 93 | *****************************************************************************/ | ||
| 94 | |||
| 95 | #define DMA_INVALID_HANDLE ((DMA_Handle_t) -1) | ||
| 96 | |||
| 97 | typedef int DMA_Handle_t; | ||
| 98 | |||
| 99 | /**************************************************************************** | ||
| 100 | * | ||
| 101 | * The DMA_DescriptorRing_t contains a ring of descriptors which is used | ||
| 102 | * to point to regions of memory. | ||
| 103 | * | ||
| 104 | *****************************************************************************/ | ||
| 105 | |||
| 106 | typedef struct { | ||
| 107 | void *virtAddr; /* Virtual Address of the descriptor ring */ | ||
| 108 | dma_addr_t physAddr; /* Physical address of the descriptor ring */ | ||
| 109 | int descriptorsAllocated; /* Number of descriptors allocated in the descriptor ring */ | ||
| 110 | size_t bytesAllocated; /* Number of bytes allocated in the descriptor ring */ | ||
| 111 | |||
| 112 | } DMA_DescriptorRing_t; | ||
| 113 | |||
| 114 | /**************************************************************************** | ||
| 115 | * | ||
| 116 | * The DMA_MemType_t and DMA_MemMap_t are helper structures used to setup | ||
| 117 | * DMA chains from a variety of memory sources. | ||
| 118 | * | ||
| 119 | *****************************************************************************/ | ||
| 120 | |||
| 121 | #define DMA_MEM_MAP_MIN_SIZE 4096 /* Pages less than this size are better */ | ||
| 122 | /* off not being DMA'd. */ | ||
| 123 | |||
| 124 | typedef enum { | ||
| 125 | DMA_MEM_TYPE_NONE, /* Not a valid setting */ | ||
| 126 | DMA_MEM_TYPE_VMALLOC, /* Memory came from vmalloc call */ | ||
| 127 | DMA_MEM_TYPE_KMALLOC, /* Memory came from kmalloc call */ | ||
| 128 | DMA_MEM_TYPE_DMA, /* Memory came from dma_alloc_xxx call */ | ||
| 129 | DMA_MEM_TYPE_USER, /* Memory came from user space. */ | ||
| 130 | |||
| 131 | } DMA_MemType_t; | ||
| 132 | |||
| 133 | /* A segment represents a physically and virtually contiguous chunk of memory. */ | ||
| 134 | /* i.e. each segment can be DMA'd */ | ||
| 135 | /* A user of the DMA code will add memory regions. Each region may need to be */ | ||
| 136 | /* represented by one or more segments. */ | ||
| 137 | |||
| 138 | typedef struct { | ||
| 139 | void *virtAddr; /* Virtual address used for this segment */ | ||
| 140 | dma_addr_t physAddr; /* Physical address this segment maps to */ | ||
| 141 | size_t numBytes; /* Size of the segment, in bytes */ | ||
| 142 | |||
| 143 | } DMA_Segment_t; | ||
| 144 | |||
| 145 | /* A region represents a virtually contiguous chunk of memory, which may be */ | ||
| 146 | /* made up of multiple segments. */ | ||
| 147 | |||
| 148 | typedef struct { | ||
| 149 | DMA_MemType_t memType; | ||
| 150 | void *virtAddr; | ||
| 151 | size_t numBytes; | ||
| 152 | |||
| 153 | /* Each region (virtually contiguous) consists of one or more segments. Each */ | ||
| 154 | /* segment is virtually and physically contiguous. */ | ||
| 155 | |||
| 156 | int numSegmentsUsed; | ||
| 157 | int numSegmentsAllocated; | ||
| 158 | DMA_Segment_t *segment; | ||
| 159 | |||
| 160 | /* When a region corresponds to user memory, we need to lock all of the pages */ | ||
| 161 | /* down before we can figure out the physical addresses. The lockedPage array contains */ | ||
| 162 | /* the pages that were locked, and which subsequently need to be unlocked once the */ | ||
| 163 | /* memory is unmapped. */ | ||
| 164 | |||
| 165 | unsigned numLockedPages; | ||
| 166 | struct page **lockedPages; | ||
| 167 | |||
| 168 | } DMA_Region_t; | ||
| 169 | |||
| 170 | typedef struct { | ||
| 171 | int inUse; /* Is this mapping currently being used? */ | ||
| 172 | struct semaphore lock; /* Acquired when using this structure */ | ||
| 173 | enum dma_data_direction dir; /* Direction this transfer is intended for */ | ||
| 174 | |||
| 175 | /* In the event that we're mapping user memory, we need to know which task */ | ||
| 176 | /* the memory is for, so that we can obtain the correct mm locks. */ | ||
| 177 | |||
| 178 | struct task_struct *userTask; | ||
| 179 | |||
| 180 | int numRegionsUsed; | ||
| 181 | int numRegionsAllocated; | ||
| 182 | DMA_Region_t *region; | ||
| 183 | |||
| 184 | } DMA_MemMap_t; | ||
| 185 | |||
| 186 | /**************************************************************************** | ||
| 187 | * | ||
| 188 | * The DMA_DeviceAttribute_t contains information which describes a | ||
| 189 | * particular DMA device (or peripheral). | ||
| 190 | * | ||
| 191 | * It is anticipated that the arrary of DMA_DeviceAttribute_t's will be | ||
| 192 | * statically initialized. | ||
| 193 | * | ||
| 194 | *****************************************************************************/ | ||
| 195 | |||
| 196 | /* The device handler is called whenever a DMA operation completes. The reaon */ | ||
| 197 | /* for it to be called will be a bitmask with one or more of the following bits */ | ||
| 198 | /* set. */ | ||
| 199 | |||
| 200 | #define DMA_HANDLER_REASON_BLOCK_COMPLETE dmacHw_INTERRUPT_STATUS_BLOCK | ||
| 201 | #define DMA_HANDLER_REASON_TRANSFER_COMPLETE dmacHw_INTERRUPT_STATUS_TRANS | ||
| 202 | #define DMA_HANDLER_REASON_ERROR dmacHw_INTERRUPT_STATUS_ERROR | ||
| 203 | |||
| 204 | typedef void (*DMA_DeviceHandler_t) (DMA_Device_t dev, int reason, | ||
| 205 | void *userData); | ||
| 206 | |||
| 207 | #define DMA_DEVICE_FLAG_ON_DMA0 0x00000001 | ||
| 208 | #define DMA_DEVICE_FLAG_ON_DMA1 0x00000002 | ||
| 209 | #define DMA_DEVICE_FLAG_PORT_PER_DMAC 0x00000004 /* If set, it means that the port used on DMAC0 is different from the port used on DMAC1 */ | ||
| 210 | #define DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST 0x00000008 /* If set, allocate from DMA1 before allocating from DMA0 */ | ||
| 211 | #define DMA_DEVICE_FLAG_IS_DEDICATED 0x00000100 | ||
| 212 | #define DMA_DEVICE_FLAG_NO_ISR 0x00000200 | ||
| 213 | #define DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO 0x00000400 | ||
| 214 | #define DMA_DEVICE_FLAG_IN_USE 0x00000800 /* If set, device is in use on a channel */ | ||
| 215 | |||
| 216 | /* Note: Some DMA devices can be used from multiple DMA Controllers. The bitmask is used to */ | ||
| 217 | /* determine which DMA controllers a given device can be used from, and the interface */ | ||
| 218 | /* array determeines the actual interface number to use for a given controller. */ | ||
| 219 | |||
| 220 | typedef struct { | ||
| 221 | uint32_t flags; /* Bitmask of DMA_DEVICE_FLAG_xxx constants */ | ||
| 222 | uint8_t dedicatedController; /* Controller number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */ | ||
| 223 | uint8_t dedicatedChannel; /* Channel number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */ | ||
| 224 | const char *name; /* Will show up in the /proc entry */ | ||
| 225 | |||
| 226 | uint32_t dmacPort[DMA_NUM_CONTROLLERS]; /* Specifies the port number when DMA_DEVICE_FLAG_PORT_PER_DMAC flag is set */ | ||
| 227 | |||
| 228 | dmacHw_CONFIG_t config; /* Configuration to use when DMA'ing using this device */ | ||
| 229 | |||
| 230 | void *userData; /* Passed to the devHandler */ | ||
| 231 | DMA_DeviceHandler_t devHandler; /* Called when DMA operations finish. */ | ||
| 232 | |||
| 233 | timer_tick_count_t transferStartTime; /* Time the current transfer was started */ | ||
| 234 | |||
| 235 | /* The following statistical information will be collected and presented in a proc entry. */ | ||
| 236 | /* Note: With a contiuous bandwidth of 1 Gb/sec, it would take 584 years to overflow */ | ||
| 237 | /* a 64 bit counter. */ | ||
| 238 | |||
| 239 | uint64_t numTransfers; /* Number of DMA transfers performed */ | ||
| 240 | uint64_t transferTicks; /* Total time spent doing DMA transfers (measured in timer_tick_count_t's) */ | ||
| 241 | uint64_t transferBytes; /* Total bytes transferred */ | ||
| 242 | uint32_t timesBlocked; /* Number of times a channel was unavailable */ | ||
| 243 | uint32_t numBytes; /* Last transfer size */ | ||
| 244 | |||
| 245 | /* It's not possible to free memory which is allocated for the descriptors from within */ | ||
| 246 | /* the ISR. So make the presumption that a given device will tend to use the */ | ||
| 247 | /* same sized buffers over and over again, and we keep them around. */ | ||
| 248 | |||
| 249 | DMA_DescriptorRing_t ring; /* Ring of descriptors allocated for this device */ | ||
| 250 | |||
| 251 | /* We stash away some of the information from the previous transfer. If back-to-back */ | ||
| 252 | /* transfers are performed from the same buffer, then we don't have to keep re-initializing */ | ||
| 253 | /* the descriptor buffers. */ | ||
| 254 | |||
| 255 | uint32_t prevNumBytes; | ||
| 256 | dma_addr_t prevSrcData; | ||
| 257 | dma_addr_t prevDstData; | ||
| 258 | |||
| 259 | } DMA_DeviceAttribute_t; | ||
| 260 | |||
| 261 | /**************************************************************************** | ||
| 262 | * | ||
| 263 | * DMA_Channel_t, DMA_Controller_t, and DMA_State_t are really internal | ||
| 264 | * data structures and don't belong in this header file, but are included | ||
| 265 | * merely for discussion. | ||
| 266 | * | ||
| 267 | * By the time this is implemented, these structures will be moved out into | ||
| 268 | * the appropriate C source file instead. | ||
| 269 | * | ||
| 270 | *****************************************************************************/ | ||
| 271 | |||
| 272 | /**************************************************************************** | ||
| 273 | * | ||
| 274 | * The DMA_Channel_t contains state information about each DMA channel. Some | ||
| 275 | * of the channels are dedicated. Non-dedicated channels are shared | ||
| 276 | * amongst the other devices. | ||
| 277 | * | ||
| 278 | *****************************************************************************/ | ||
| 279 | |||
| 280 | #define DMA_CHANNEL_FLAG_IN_USE 0x00000001 | ||
| 281 | #define DMA_CHANNEL_FLAG_IS_DEDICATED 0x00000002 | ||
| 282 | #define DMA_CHANNEL_FLAG_NO_ISR 0x00000004 | ||
| 283 | #define DMA_CHANNEL_FLAG_LARGE_FIFO 0x00000008 | ||
| 284 | |||
| 285 | typedef struct { | ||
| 286 | uint32_t flags; /* bitmask of DMA_CHANNEL_FLAG_xxx constants */ | ||
| 287 | DMA_Device_t devType; /* Device this channel is currently reserved for */ | ||
| 288 | DMA_Device_t lastDevType; /* Device type that used this previously */ | ||
| 289 | char name[20]; /* Name passed onto request_irq */ | ||
| 290 | |||
| 291 | #if (DMA_DEBUG_TRACK_RESERVATION) | ||
| 292 | const char *fileName; /* Place where channel reservation took place */ | ||
| 293 | int lineNum; /* Place where channel reservation took place */ | ||
| 294 | #endif | ||
| 295 | dmacHw_HANDLE_t dmacHwHandle; /* low level channel handle. */ | ||
| 296 | |||
| 297 | } DMA_Channel_t; | ||
| 298 | |||
| 299 | /**************************************************************************** | ||
| 300 | * | ||
| 301 | * The DMA_Controller_t contains state information about each DMA controller. | ||
| 302 | * | ||
| 303 | * The freeChannelQ is stored in the controller data structure rather than | ||
| 304 | * the channel data structure since several of the devices are accessible | ||
| 305 | * from multiple controllers, and there is no way to know which controller | ||
| 306 | * will become available first. | ||
| 307 | * | ||
| 308 | *****************************************************************************/ | ||
| 309 | |||
| 310 | typedef struct { | ||
| 311 | DMA_Channel_t channel[DMA_NUM_CHANNELS]; | ||
| 312 | |||
| 313 | } DMA_Controller_t; | ||
| 314 | |||
| 315 | /**************************************************************************** | ||
| 316 | * | ||
| 317 | * The DMA_Global_t contains all of the global state information used by | ||
| 318 | * the DMA code. | ||
| 319 | * | ||
| 320 | * Callers which need to allocate a shared channel will be queued up | ||
| 321 | * on the freeChannelQ until a channel becomes available. | ||
| 322 | * | ||
| 323 | *****************************************************************************/ | ||
| 324 | |||
| 325 | typedef struct { | ||
| 326 | struct semaphore lock; /* acquired when manipulating table entries */ | ||
| 327 | wait_queue_head_t freeChannelQ; | ||
| 328 | |||
| 329 | DMA_Controller_t controller[DMA_NUM_CONTROLLERS]; | ||
| 330 | |||
| 331 | } DMA_Global_t; | ||
| 332 | |||
| 333 | /* ---- Variable Externs ------------------------------------------------- */ | ||
| 334 | |||
| 335 | extern DMA_DeviceAttribute_t DMA_gDeviceAttribute[DMA_NUM_DEVICE_ENTRIES]; | ||
| 336 | |||
| 337 | /* ---- Function Prototypes ---------------------------------------------- */ | ||
| 338 | |||
| 339 | #if defined(__KERNEL__) | ||
| 340 | |||
| 341 | /****************************************************************************/ | ||
| 342 | /** | ||
| 343 | * Initializes the DMA module. | ||
| 344 | * | ||
| 345 | * @return | ||
| 346 | * 0 - Success | ||
| 347 | * < 0 - Error | ||
| 348 | */ | ||
| 349 | /****************************************************************************/ | ||
| 350 | |||
| 351 | int dma_init(void); | ||
| 352 | |||
| 353 | #if (DMA_DEBUG_TRACK_RESERVATION) | ||
| 354 | DMA_Handle_t dma_request_channel_dbg(DMA_Device_t dev, const char *fileName, | ||
| 355 | int lineNum); | ||
| 356 | #define dma_request_channel(dev) dma_request_channel_dbg(dev, __FILE__, __LINE__) | ||
| 357 | #else | ||
| 358 | |||
| 359 | /****************************************************************************/ | ||
| 360 | /** | ||
| 361 | * Reserves a channel for use with @a dev. If the device is setup to use | ||
| 362 | * a shared channel, then this function will block until a free channel | ||
| 363 | * becomes available. | ||
| 364 | * | ||
| 365 | * @return | ||
| 366 | * >= 0 - A valid DMA Handle. | ||
| 367 | * -EBUSY - Device is currently being used. | ||
| 368 | * -ENODEV - Device handed in is invalid. | ||
| 369 | */ | ||
| 370 | /****************************************************************************/ | ||
| 371 | |||
| 372 | DMA_Handle_t dma_request_channel(DMA_Device_t dev /* Device to use with the allocated channel. */ | ||
| 373 | ); | ||
| 374 | #endif | ||
| 375 | |||
| 376 | /****************************************************************************/ | ||
| 377 | /** | ||
| 378 | * Frees a previously allocated DMA Handle. | ||
| 379 | * | ||
| 380 | * @return | ||
| 381 | * 0 - DMA Handle was released successfully. | ||
| 382 | * -EINVAL - Invalid DMA handle | ||
| 383 | */ | ||
| 384 | /****************************************************************************/ | ||
| 385 | |||
| 386 | int dma_free_channel(DMA_Handle_t channel /* DMA handle. */ | ||
| 387 | ); | ||
| 388 | |||
| 389 | /****************************************************************************/ | ||
| 390 | /** | ||
| 391 | * Determines if a given device has been configured as using a shared | ||
| 392 | * channel. | ||
| 393 | * | ||
| 394 | * @return boolean | ||
| 395 | * 0 Device uses a dedicated channel | ||
| 396 | * non-zero Device uses a shared channel | ||
| 397 | */ | ||
| 398 | /****************************************************************************/ | ||
| 399 | |||
| 400 | int dma_device_is_channel_shared(DMA_Device_t dev /* Device to check. */ | ||
| 401 | ); | ||
| 402 | |||
| 403 | /****************************************************************************/ | ||
| 404 | /** | ||
| 405 | * Allocates memory to hold a descriptor ring. The descriptor ring then | ||
| 406 | * needs to be populated by making one or more calls to | ||
| 407 | * dna_add_descriptors. | ||
| 408 | * | ||
| 409 | * The returned descriptor ring will be automatically initialized. | ||
| 410 | * | ||
| 411 | * @return | ||
| 412 | * 0 Descriptor ring was allocated successfully | ||
| 413 | * -ENOMEM Unable to allocate memory for the desired number of descriptors. | ||
| 414 | */ | ||
| 415 | /****************************************************************************/ | ||
| 416 | |||
| 417 | int dma_alloc_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to populate */ | ||
| 418 | int numDescriptors /* Number of descriptors that need to be allocated. */ | ||
| 419 | ); | ||
| 420 | |||
| 421 | /****************************************************************************/ | ||
| 422 | /** | ||
| 423 | * Releases the memory which was previously allocated for a descriptor ring. | ||
| 424 | */ | ||
| 425 | /****************************************************************************/ | ||
| 426 | |||
| 427 | void dma_free_descriptor_ring(DMA_DescriptorRing_t *ring /* Descriptor to release */ | ||
| 428 | ); | ||
| 429 | |||
| 430 | /****************************************************************************/ | ||
| 431 | /** | ||
| 432 | * Initializes a descriptor ring, so that descriptors can be added to it. | ||
| 433 | * Once a descriptor ring has been allocated, it may be reinitialized for | ||
| 434 | * use with additional/different regions of memory. | ||
| 435 | * | ||
| 436 | * Note that if 7 descriptors are allocated, it's perfectly acceptable to | ||
| 437 | * initialize the ring with a smaller number of descriptors. The amount | ||
| 438 | * of memory allocated for the descriptor ring will not be reduced, and | ||
| 439 | * the descriptor ring may be reinitialized later | ||
| 440 | * | ||
| 441 | * @return | ||
| 442 | * 0 Descriptor ring was initialized successfully | ||
| 443 | * -ENOMEM The descriptor which was passed in has insufficient space | ||
| 444 | * to hold the desired number of descriptors. | ||
| 445 | */ | ||
| 446 | /****************************************************************************/ | ||
| 447 | |||
| 448 | int dma_init_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to initialize */ | ||
| 449 | int numDescriptors /* Number of descriptors to initialize. */ | ||
| 450 | ); | ||
| 451 | |||
| 452 | /****************************************************************************/ | ||
| 453 | /** | ||
| 454 | * Determines the number of descriptors which would be required for a | ||
| 455 | * transfer of the indicated memory region. | ||
| 456 | * | ||
| 457 | * This function also needs to know which DMA device this transfer will | ||
| 458 | * be destined for, so that the appropriate DMA configuration can be retrieved. | ||
| 459 | * DMA parameters such as transfer width, and whether this is a memory-to-memory | ||
| 460 | * or memory-to-peripheral, etc can all affect the actual number of descriptors | ||
| 461 | * required. | ||
| 462 | * | ||
| 463 | * @return | ||
| 464 | * > 0 Returns the number of descriptors required for the indicated transfer | ||
| 465 | * -EINVAL Invalid device type for this kind of transfer | ||
| 466 | * (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) | ||
| 467 | * -ENOMEM Memory exhausted | ||
| 468 | */ | ||
| 469 | /****************************************************************************/ | ||
| 470 | |||
| 471 | int dma_calculate_descriptor_count(DMA_Device_t device, /* DMA Device that this will be associated with */ | ||
| 472 | dma_addr_t srcData, /* Place to get data to write to device */ | ||
| 473 | dma_addr_t dstData, /* Pointer to device data address */ | ||
| 474 | size_t numBytes /* Number of bytes to transfer to the device */ | ||
| 475 | ); | ||
| 476 | |||
| 477 | /****************************************************************************/ | ||
| 478 | /** | ||
| 479 | * Adds a region of memory to the descriptor ring. Note that it may take | ||
| 480 | * multiple descriptors for each region of memory. It is the callers | ||
| 481 | * responsibility to allocate a sufficiently large descriptor ring. | ||
| 482 | * | ||
| 483 | * @return | ||
| 484 | * 0 Descriptors were added successfully | ||
| 485 | * -EINVAL Invalid device type for this kind of transfer | ||
| 486 | * (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) | ||
| 487 | * -ENOMEM Memory exhausted | ||
| 488 | */ | ||
| 489 | /****************************************************************************/ | ||
| 490 | |||
| 491 | int dma_add_descriptors(DMA_DescriptorRing_t *ring, /* Descriptor ring to add descriptors to */ | ||
| 492 | DMA_Device_t device, /* DMA Device that descriptors are for */ | ||
| 493 | dma_addr_t srcData, /* Place to get data (memory or device) */ | ||
| 494 | dma_addr_t dstData, /* Place to put data (memory or device) */ | ||
| 495 | size_t numBytes /* Number of bytes to transfer to the device */ | ||
| 496 | ); | ||
| 497 | |||
| 498 | /****************************************************************************/ | ||
| 499 | /** | ||
| 500 | * Sets the descriptor ring associated with a device. | ||
| 501 | * | ||
| 502 | * Once set, the descriptor ring will be associated with the device, even | ||
| 503 | * across channel request/free calls. Passing in a NULL descriptor ring | ||
| 504 | * will release any descriptor ring currently associated with the device. | ||
| 505 | * | ||
| 506 | * Note: If you call dma_transfer, or one of the other dma_alloc_ functions | ||
| 507 | * the descriptor ring may be released and reallocated. | ||
| 508 | * | ||
| 509 | * Note: This function will release the descriptor memory for any current | ||
| 510 | * descriptor ring associated with this device. | ||
| 511 | */ | ||
| 512 | /****************************************************************************/ | ||
| 513 | |||
| 514 | int dma_set_device_descriptor_ring(DMA_Device_t device, /* Device to update the descriptor ring for. */ | ||
| 515 | DMA_DescriptorRing_t *ring /* Descriptor ring to add descriptors to */ | ||
| 516 | ); | ||
| 517 | |||
| 518 | /****************************************************************************/ | ||
| 519 | /** | ||
| 520 | * Retrieves the descriptor ring associated with a device. | ||
| 521 | */ | ||
| 522 | /****************************************************************************/ | ||
| 523 | |||
| 524 | int dma_get_device_descriptor_ring(DMA_Device_t device, /* Device to retrieve the descriptor ring for. */ | ||
| 525 | DMA_DescriptorRing_t *ring /* Place to store retrieved ring */ | ||
| 526 | ); | ||
| 527 | |||
| 528 | /****************************************************************************/ | ||
| 529 | /** | ||
| 530 | * Allocates buffers for the descriptors. This is normally done automatically | ||
| 531 | * but needs to be done explicitly when initiating a dma from interrupt | ||
| 532 | * context. | ||
| 533 | * | ||
| 534 | * @return | ||
| 535 | * 0 Descriptors were allocated successfully | ||
| 536 | * -EINVAL Invalid device type for this kind of transfer | ||
| 537 | * (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) | ||
| 538 | * -ENOMEM Memory exhausted | ||
| 539 | */ | ||
| 540 | /****************************************************************************/ | ||
| 541 | |||
| 542 | int dma_alloc_descriptors(DMA_Handle_t handle, /* DMA Handle */ | ||
| 543 | dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */ | ||
| 544 | dma_addr_t srcData, /* Place to get data to write to device */ | ||
| 545 | dma_addr_t dstData, /* Pointer to device data address */ | ||
| 546 | size_t numBytes /* Number of bytes to transfer to the device */ | ||
| 547 | ); | ||
| 548 | |||
| 549 | /****************************************************************************/ | ||
| 550 | /** | ||
| 551 | * Allocates and sets up descriptors for a double buffered circular buffer. | ||
| 552 | * | ||
| 553 | * This is primarily intended to be used for things like the ingress samples | ||
| 554 | * from a microphone. | ||
| 555 | * | ||
| 556 | * @return | ||
| 557 | * > 0 Number of descriptors actually allocated. | ||
| 558 | * -EINVAL Invalid device type for this kind of transfer | ||
| 559 | * (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) | ||
| 560 | * -ENOMEM Memory exhausted | ||
| 561 | */ | ||
| 562 | /****************************************************************************/ | ||
| 563 | |||
| 564 | int dma_alloc_double_dst_descriptors(DMA_Handle_t handle, /* DMA Handle */ | ||
| 565 | dma_addr_t srcData, /* Physical address of source data */ | ||
| 566 | dma_addr_t dstData1, /* Physical address of first destination buffer */ | ||
| 567 | dma_addr_t dstData2, /* Physical address of second destination buffer */ | ||
| 568 | size_t numBytes /* Number of bytes in each destination buffer */ | ||
| 569 | ); | ||
| 570 | |||
| 571 | /****************************************************************************/ | ||
| 572 | /** | ||
| 573 | * Initializes a DMA_MemMap_t data structure | ||
| 574 | */ | ||
| 575 | /****************************************************************************/ | ||
| 576 | |||
| 577 | int dma_init_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */ | ||
| 578 | ); | ||
| 579 | |||
| 580 | /****************************************************************************/ | ||
| 581 | /** | ||
| 582 | * Releases any memory currently being held by a memory mapping structure. | ||
| 583 | */ | ||
| 584 | /****************************************************************************/ | ||
| 585 | |||
| 586 | int dma_term_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */ | ||
| 587 | ); | ||
| 588 | |||
| 589 | /****************************************************************************/ | ||
| 590 | /** | ||
| 591 | * Looks at a memory address and categorizes it. | ||
| 592 | * | ||
| 593 | * @return One of the values from the DMA_MemType_t enumeration. | ||
| 594 | */ | ||
| 595 | /****************************************************************************/ | ||
| 596 | |||
| 597 | DMA_MemType_t dma_mem_type(void *addr); | ||
| 598 | |||
| 599 | /****************************************************************************/ | ||
| 600 | /** | ||
| 601 | * Sets the process (aka userTask) associated with a mem map. This is | ||
| 602 | * required if user-mode segments will be added to the mapping. | ||
| 603 | */ | ||
| 604 | /****************************************************************************/ | ||
| 605 | |||
| 606 | static inline void dma_mem_map_set_user_task(DMA_MemMap_t *memMap, | ||
| 607 | struct task_struct *task) | ||
| 608 | { | ||
| 609 | memMap->userTask = task; | ||
| 610 | } | ||
| 611 | |||
| 612 | /****************************************************************************/ | ||
| 613 | /** | ||
| 614 | * Looks at a memory address and determines if we support DMA'ing to/from | ||
| 615 | * that type of memory. | ||
| 616 | * | ||
| 617 | * @return boolean - | ||
| 618 | * return value != 0 means dma supported | ||
| 619 | * return value == 0 means dma not supported | ||
| 620 | */ | ||
| 621 | /****************************************************************************/ | ||
| 622 | |||
| 623 | int dma_mem_supports_dma(void *addr); | ||
| 624 | |||
| 625 | /****************************************************************************/ | ||
| 626 | /** | ||
| 627 | * Initializes a memory map for use. Since this function acquires a | ||
| 628 | * sempaphore within the memory map, it is VERY important that dma_unmap | ||
| 629 | * be called when you're finished using the map. | ||
| 630 | */ | ||
| 631 | /****************************************************************************/ | ||
| 632 | |||
| 633 | int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */ | ||
| 634 | enum dma_data_direction dir /* Direction that the mapping will be going */ | ||
| 635 | ); | ||
| 636 | |||
| 637 | /****************************************************************************/ | ||
| 638 | /** | ||
| 639 | * Adds a segment of memory to a memory map. | ||
| 640 | * | ||
| 641 | * @return 0 on success, error code otherwise. | ||
| 642 | */ | ||
| 643 | /****************************************************************************/ | ||
| 644 | |||
| 645 | int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */ | ||
| 646 | void *mem, /* Virtual address that we want to get a map of */ | ||
| 647 | size_t numBytes /* Number of bytes being mapped */ | ||
| 648 | ); | ||
| 649 | |||
| 650 | /****************************************************************************/ | ||
| 651 | /** | ||
| 652 | * Creates a descriptor ring from a memory mapping. | ||
| 653 | * | ||
| 654 | * @return 0 on sucess, error code otherwise. | ||
| 655 | */ | ||
| 656 | /****************************************************************************/ | ||
| 657 | |||
| 658 | int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */ | ||
| 659 | DMA_MemMap_t *memMap, /* Memory map that will be used */ | ||
| 660 | dma_addr_t devPhysAddr /* Physical address of device */ | ||
| 661 | ); | ||
| 662 | |||
| 663 | /****************************************************************************/ | ||
| 664 | /** | ||
| 665 | * Maps in a memory region such that it can be used for performing a DMA. | ||
| 666 | * | ||
| 667 | * @return | ||
| 668 | */ | ||
| 669 | /****************************************************************************/ | ||
| 670 | |||
| 671 | int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */ | ||
| 672 | void *addr, /* Virtual address that we want to get a map of */ | ||
| 673 | size_t count, /* Number of bytes being mapped */ | ||
| 674 | enum dma_data_direction dir /* Direction that the mapping will be going */ | ||
| 675 | ); | ||
| 676 | |||
| 677 | /****************************************************************************/ | ||
| 678 | /** | ||
| 679 | * Maps in a memory region such that it can be used for performing a DMA. | ||
| 680 | * | ||
| 681 | * @return | ||
| 682 | */ | ||
| 683 | /****************************************************************************/ | ||
| 684 | |||
| 685 | int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */ | ||
| 686 | int dirtied /* non-zero if any of the pages were modified */ | ||
| 687 | ); | ||
| 688 | |||
| 689 | /****************************************************************************/ | ||
| 690 | /** | ||
| 691 | * Initiates a transfer when the descriptors have already been setup. | ||
| 692 | * | ||
| 693 | * This is a special case, and normally, the dma_transfer_xxx functions should | ||
| 694 | * be used. | ||
| 695 | * | ||
| 696 | * @return | ||
| 697 | * 0 Transfer was started successfully | ||
| 698 | * -ENODEV Invalid handle | ||
| 699 | */ | ||
| 700 | /****************************************************************************/ | ||
| 701 | |||
| 702 | int dma_start_transfer(DMA_Handle_t handle); | ||
| 703 | |||
| 704 | /****************************************************************************/ | ||
| 705 | /** | ||
| 706 | * Stops a previously started DMA transfer. | ||
| 707 | * | ||
| 708 | * @return | ||
| 709 | * 0 Transfer was stopped successfully | ||
| 710 | * -ENODEV Invalid handle | ||
| 711 | */ | ||
| 712 | /****************************************************************************/ | ||
| 713 | |||
| 714 | int dma_stop_transfer(DMA_Handle_t handle); | ||
| 715 | |||
| 716 | /****************************************************************************/ | ||
| 717 | /** | ||
| 718 | * Waits for a DMA to complete by polling. This function is only intended | ||
| 719 | * to be used for testing. Interrupts should be used for most DMA operations. | ||
| 720 | */ | ||
| 721 | /****************************************************************************/ | ||
| 722 | |||
| 723 | int dma_wait_transfer_done(DMA_Handle_t handle); | ||
| 724 | |||
| 725 | /****************************************************************************/ | ||
| 726 | /** | ||
| 727 | * Initiates a DMA transfer | ||
| 728 | * | ||
| 729 | * @return | ||
| 730 | * 0 Transfer was started successfully | ||
| 731 | * -EINVAL Invalid device type for this kind of transfer | ||
| 732 | * (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) | ||
| 733 | */ | ||
| 734 | /****************************************************************************/ | ||
| 735 | |||
| 736 | int dma_transfer(DMA_Handle_t handle, /* DMA Handle */ | ||
| 737 | dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */ | ||
| 738 | dma_addr_t srcData, /* Place to get data to write to device */ | ||
| 739 | dma_addr_t dstData, /* Pointer to device data address */ | ||
| 740 | size_t numBytes /* Number of bytes to transfer to the device */ | ||
| 741 | ); | ||
| 742 | |||
| 743 | /****************************************************************************/ | ||
| 744 | /** | ||
| 745 | * Initiates a transfer from memory to a device. | ||
| 746 | * | ||
| 747 | * @return | ||
| 748 | * 0 Transfer was started successfully | ||
| 749 | * -EINVAL Invalid device type for this kind of transfer | ||
| 750 | * (i.e. the device is _DEV_TO_MEM and not _MEM_TO_DEV) | ||
| 751 | */ | ||
| 752 | /****************************************************************************/ | ||
| 753 | |||
| 754 | static inline int dma_transfer_to_device(DMA_Handle_t handle, /* DMA Handle */ | ||
| 755 | dma_addr_t srcData, /* Place to get data to write to device (physical address) */ | ||
| 756 | dma_addr_t dstData, /* Pointer to device data address (physical address) */ | ||
| 757 | size_t numBytes /* Number of bytes to transfer to the device */ | ||
| 758 | ) { | ||
| 759 | return dma_transfer(handle, | ||
| 760 | dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, | ||
| 761 | srcData, dstData, numBytes); | ||
| 762 | } | ||
| 763 | |||
| 764 | /****************************************************************************/ | ||
| 765 | /** | ||
| 766 | * Initiates a transfer from a device to memory. | ||
| 767 | * | ||
| 768 | * @return | ||
| 769 | * 0 Transfer was started successfully | ||
| 770 | * -EINVAL Invalid device type for this kind of transfer | ||
| 771 | * (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM) | ||
| 772 | */ | ||
| 773 | /****************************************************************************/ | ||
| 774 | |||
| 775 | static inline int dma_transfer_from_device(DMA_Handle_t handle, /* DMA Handle */ | ||
| 776 | dma_addr_t srcData, /* Pointer to the device data address (physical address) */ | ||
| 777 | dma_addr_t dstData, /* Place to store data retrieved from the device (physical address) */ | ||
| 778 | size_t numBytes /* Number of bytes to retrieve from the device */ | ||
| 779 | ) { | ||
| 780 | return dma_transfer(handle, | ||
| 781 | dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, | ||
| 782 | srcData, dstData, numBytes); | ||
| 783 | } | ||
| 784 | |||
| 785 | /****************************************************************************/ | ||
| 786 | /** | ||
| 787 | * Initiates a memory to memory transfer. | ||
| 788 | * | ||
| 789 | * @return | ||
| 790 | * 0 Transfer was started successfully | ||
| 791 | * -EINVAL Invalid device type for this kind of transfer | ||
| 792 | * (i.e. the device wasn't DMA_DEVICE_MEM_TO_MEM) | ||
| 793 | */ | ||
| 794 | /****************************************************************************/ | ||
| 795 | |||
| 796 | static inline int dma_transfer_mem_to_mem(DMA_Handle_t handle, /* DMA Handle */ | ||
| 797 | dma_addr_t srcData, /* Place to transfer data from (physical address) */ | ||
| 798 | dma_addr_t dstData, /* Place to transfer data to (physical address) */ | ||
| 799 | size_t numBytes /* Number of bytes to transfer */ | ||
| 800 | ) { | ||
| 801 | return dma_transfer(handle, | ||
| 802 | dmacHw_TRANSFER_TYPE_MEM_TO_MEM, | ||
| 803 | srcData, dstData, numBytes); | ||
| 804 | } | ||
| 805 | |||
| 806 | /****************************************************************************/ | ||
| 807 | /** | ||
| 808 | * Set the callback function which will be called when a transfer completes. | ||
| 809 | * If a NULL callback function is set, then no callback will occur. | ||
| 810 | * | ||
| 811 | * @note @a devHandler will be called from IRQ context. | ||
| 812 | * | ||
| 813 | * @return | ||
| 814 | * 0 - Success | ||
| 815 | * -ENODEV - Device handed in is invalid. | ||
| 816 | */ | ||
| 817 | /****************************************************************************/ | ||
| 818 | |||
| 819 | int dma_set_device_handler(DMA_Device_t dev, /* Device to set the callback for. */ | ||
| 820 | DMA_DeviceHandler_t devHandler, /* Function to call when the DMA completes */ | ||
| 821 | void *userData /* Pointer which will be passed to devHandler. */ | ||
| 822 | ); | ||
| 823 | |||
| 824 | #endif | ||
| 825 | |||
| 826 | #endif /* ASM_ARM_ARCH_BCMRING_DMA_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/entry-macro.S b/arch/arm/mach-bcmring/include/mach/entry-macro.S new file mode 100644 index 000000000000..7d393ca010ac --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/entry-macro.S | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2006 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /* | ||
| 16 | * | ||
| 17 | * Low-level IRQ helper macros for BCMRing-based platforms | ||
| 18 | * | ||
| 19 | */ | ||
| 20 | #include <mach/irqs.h> | ||
| 21 | #include <mach/hardware.h> | ||
| 22 | #include <mach/csp/mm_io.h> | ||
| 23 | |||
| 24 | .macro disable_fiq | ||
| 25 | .endm | ||
| 26 | |||
| 27 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
| 28 | ldr \base, =(MM_IO_BASE_INTC0) | ||
| 29 | ldr \irqstat, [\base, #0] @ get status | ||
| 30 | ldr \irqnr, [\base, #0x10] @ mask with enable register | ||
| 31 | ands \irqstat, \irqstat, \irqnr | ||
| 32 | mov \irqnr, #IRQ_INTC0_START | ||
| 33 | cmp \irqstat, #0 | ||
| 34 | bne 1001f | ||
| 35 | |||
| 36 | ldr \base, =(MM_IO_BASE_INTC1) | ||
| 37 | ldr \irqstat, [\base, #0] @ get status | ||
| 38 | ldr \irqnr, [\base, #0x10] @ mask with enable register | ||
| 39 | ands \irqstat, \irqstat, \irqnr | ||
| 40 | mov \irqnr, #IRQ_INTC1_START | ||
| 41 | cmp \irqstat, #0 | ||
| 42 | bne 1001f | ||
| 43 | |||
| 44 | ldr \base, =(MM_IO_BASE_SINTC) | ||
| 45 | ldr \irqstat, [\base, #0] @ get status | ||
| 46 | ldr \irqnr, [\base, #0x10] @ mask with enable register | ||
| 47 | ands \irqstat, \irqstat, \irqnr | ||
| 48 | mov \irqnr, #0xffffffff @ code meaning no interrupt bits set | ||
| 49 | cmp \irqstat, #0 | ||
| 50 | beq 1002f | ||
| 51 | |||
| 52 | mov \irqnr, #IRQ_SINTC_START @ something is set, so fixup return value | ||
| 53 | |||
| 54 | 1001: | ||
| 55 | movs \tmp, \irqstat, lsl #16 | ||
| 56 | movne \irqstat, \tmp | ||
| 57 | addeq \irqnr, \irqnr, #16 | ||
| 58 | |||
| 59 | movs \tmp, \irqstat, lsl #8 | ||
| 60 | movne \irqstat, \tmp | ||
| 61 | addeq \irqnr, \irqnr, #8 | ||
| 62 | |||
| 63 | movs \tmp, \irqstat, lsl #4 | ||
| 64 | movne \irqstat, \tmp | ||
| 65 | addeq \irqnr, \irqnr, #4 | ||
| 66 | |||
| 67 | movs \tmp, \irqstat, lsl #2 | ||
| 68 | movne \irqstat, \tmp | ||
| 69 | addeq \irqnr, \irqnr, #2 | ||
| 70 | |||
| 71 | movs \tmp, \irqstat, lsl #1 | ||
| 72 | addeq \irqnr, \irqnr, #1 | ||
| 73 | orrs \base, \base, #1 | ||
| 74 | |||
| 75 | 1002: @ irqnr will be set to 0xffffffff if no irq bits are set | ||
| 76 | .endm | ||
| 77 | |||
| 78 | .macro get_irqnr_preamble, base, tmp | ||
| 79 | .endm | ||
| 80 | |||
| 81 | .macro arch_ret_to_user, tmp1, tmp2 | ||
| 82 | .endm | ||
| 83 | |||
| 84 | .macro irq_prio_table | ||
| 85 | .endm | ||
| 86 | |||
diff --git a/arch/arm/mach-bcmring/include/mach/hardware.h b/arch/arm/mach-bcmring/include/mach/hardware.h new file mode 100644 index 000000000000..447eb340c611 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/hardware.h | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * This file contains the hardware definitions of the BCMRing. | ||
| 4 | * | ||
| 5 | * Copyright (C) 1999 ARM Limited. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | ||
| 21 | #ifndef __ASM_ARCH_HARDWARE_H | ||
| 22 | #define __ASM_ARCH_HARDWARE_H | ||
| 23 | |||
| 24 | #include <asm/sizes.h> | ||
| 25 | #include <mach/memory.h> | ||
| 26 | #include <cfg_global.h> | ||
| 27 | #include <mach/csp/mm_io.h> | ||
| 28 | |||
| 29 | /* Hardware addresses of major areas. | ||
| 30 | * *_START is the physical address | ||
| 31 | * *_SIZE is the size of the region | ||
| 32 | * *_BASE is the virtual address | ||
| 33 | */ | ||
| 34 | #define RAM_START PHYS_OFFSET | ||
| 35 | |||
| 36 | #define RAM_SIZE (CFG_GLOBAL_RAM_SIZE-CFG_GLOBAL_RAM_SIZE_RESERVED) | ||
| 37 | #define RAM_BASE PAGE_OFFSET | ||
| 38 | |||
| 39 | #define pcibios_assign_all_busses() 1 | ||
| 40 | |||
| 41 | /* Macros to make managing spinlocks a bit more controlled in terms of naming. */ | ||
| 42 | /* See reg_gpio.h, reg_irq.h, arch.c, gpio.c for example usage. */ | ||
| 43 | #if defined(__KERNEL__) | ||
| 44 | #define HW_DECLARE_SPINLOCK(name) DEFINE_SPINLOCK(bcmring_##name##_reg_lock); | ||
| 45 | #define HW_EXTERN_SPINLOCK(name) extern spinlock_t bcmring_##name##_reg_lock; | ||
| 46 | #define HW_IRQ_SAVE(name, val) spin_lock_irqsave(&bcmring_##name##_reg_lock, (val)) | ||
| 47 | #define HW_IRQ_RESTORE(name, val) spin_unlock_irqrestore(&bcmring_##name##_reg_lock, (val)) | ||
| 48 | #else | ||
| 49 | #define HW_DECLARE_SPINLOCK(name) | ||
| 50 | #define HW_EXTERN_SPINLOCK(name) | ||
| 51 | #define HW_IRQ_SAVE(name, val) {(void)(name); (void)(val); } | ||
| 52 | #define HW_IRQ_RESTORE(name, val) {(void)(name); (void)(val); } | ||
| 53 | #endif | ||
| 54 | |||
| 55 | #ifndef HW_IO_PHYS_TO_VIRT | ||
| 56 | #define HW_IO_PHYS_TO_VIRT MM_IO_PHYS_TO_VIRT | ||
| 57 | #endif | ||
| 58 | #define HW_IO_VIRT_TO_PHYS MM_IO_VIRT_TO_PHYS | ||
| 59 | |||
| 60 | #endif | ||
diff --git a/arch/arm/mach-bcmring/include/mach/io.h b/arch/arm/mach-bcmring/include/mach/io.h new file mode 100644 index 000000000000..4db0eff90357 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/io.h | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright (C) 1999 ARM Limited | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | */ | ||
| 19 | #ifndef __ASM_ARM_ARCH_IO_H | ||
| 20 | #define __ASM_ARM_ARCH_IO_H | ||
| 21 | |||
| 22 | #include <mach/hardware.h> | ||
| 23 | |||
| 24 | #define IO_SPACE_LIMIT 0xffffffff | ||
| 25 | |||
| 26 | #define __io(a) ((void __iomem *)HW_IO_PHYS_TO_VIRT(a)) | ||
| 27 | |||
| 28 | /* Do not enable mem_pci for a big endian arm architecture or unexpected byteswaps will */ | ||
| 29 | /* happen in readw/writew etc. */ | ||
| 30 | |||
| 31 | #define readb(c) __raw_readb(c) | ||
| 32 | #define readw(c) __raw_readw(c) | ||
| 33 | #define readl(c) __raw_readl(c) | ||
| 34 | #define readb_relaxed(addr) readb(addr) | ||
| 35 | #define readw_relaxed(addr) readw(addr) | ||
| 36 | #define readl_relaxed(addr) readl(addr) | ||
| 37 | |||
| 38 | #define readsb(p, d, l) __raw_readsb(p, d, l) | ||
| 39 | #define readsw(p, d, l) __raw_readsw(p, d, l) | ||
| 40 | #define readsl(p, d, l) __raw_readsl(p, d, l) | ||
| 41 | |||
| 42 | #define writeb(v, c) __raw_writeb(v, c) | ||
| 43 | #define writew(v, c) __raw_writew(v, c) | ||
| 44 | #define writel(v, c) __raw_writel(v, c) | ||
| 45 | |||
| 46 | #define writesb(p, d, l) __raw_writesb(p, d, l) | ||
| 47 | #define writesw(p, d, l) __raw_writesw(p, d, l) | ||
| 48 | #define writesl(p, d, l) __raw_writesl(p, d, l) | ||
| 49 | |||
| 50 | #define memset_io(c, v, l) _memset_io((c), (v), (l)) | ||
| 51 | #define memcpy_fromio(a, c, l) _memcpy_fromio((a), (c), (l)) | ||
| 52 | #define memcpy_toio(c, a, l) _memcpy_toio((c), (a), (l)) | ||
| 53 | |||
| 54 | #define eth_io_copy_and_sum(s, c, l, b) eth_copy_and_sum((s), (c), (l), (b)) | ||
| 55 | |||
| 56 | #endif | ||
diff --git a/arch/arm/mach-bcmring/include/mach/irqs.h b/arch/arm/mach-bcmring/include/mach/irqs.h new file mode 100644 index 000000000000..b279b825d4a7 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/irqs.h | |||
| @@ -0,0 +1,132 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2007 Broadcom | ||
| 3 | * Copyright (C) 1999 ARM Limited | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #if !defined(ARCH_BCMRING_IRQS_H) | ||
| 21 | #define ARCH_BCMRING_IRQS_H | ||
| 22 | |||
| 23 | /* INTC0 - interrupt controller 0 */ | ||
| 24 | #define IRQ_INTC0_START 0 | ||
| 25 | #define IRQ_DMA0C0 0 /* DMA0 channel 0 interrupt */ | ||
| 26 | #define IRQ_DMA0C1 1 /* DMA0 channel 1 interrupt */ | ||
| 27 | #define IRQ_DMA0C2 2 /* DMA0 channel 2 interrupt */ | ||
| 28 | #define IRQ_DMA0C3 3 /* DMA0 channel 3 interrupt */ | ||
| 29 | #define IRQ_DMA0C4 4 /* DMA0 channel 4 interrupt */ | ||
| 30 | #define IRQ_DMA0C5 5 /* DMA0 channel 5 interrupt */ | ||
| 31 | #define IRQ_DMA0C6 6 /* DMA0 channel 6 interrupt */ | ||
| 32 | #define IRQ_DMA0C7 7 /* DMA0 channel 7 interrupt */ | ||
| 33 | #define IRQ_DMA1C0 8 /* DMA1 channel 0 interrupt */ | ||
| 34 | #define IRQ_DMA1C1 9 /* DMA1 channel 1 interrupt */ | ||
| 35 | #define IRQ_DMA1C2 10 /* DMA1 channel 2 interrupt */ | ||
| 36 | #define IRQ_DMA1C3 11 /* DMA1 channel 3 interrupt */ | ||
| 37 | #define IRQ_DMA1C4 12 /* DMA1 channel 4 interrupt */ | ||
| 38 | #define IRQ_DMA1C5 13 /* DMA1 channel 5 interrupt */ | ||
| 39 | #define IRQ_DMA1C6 14 /* DMA1 channel 6 interrupt */ | ||
| 40 | #define IRQ_DMA1C7 15 /* DMA1 channel 7 interrupt */ | ||
| 41 | #define IRQ_VPM 16 /* Voice process module interrupt */ | ||
| 42 | #define IRQ_USBHD2 17 /* USB host2/device2 interrupt */ | ||
| 43 | #define IRQ_USBH1 18 /* USB1 host interrupt */ | ||
| 44 | #define IRQ_USBD 19 /* USB device interrupt */ | ||
| 45 | #define IRQ_SDIOH0 20 /* SDIO0 host interrupt */ | ||
| 46 | #define IRQ_SDIOH1 21 /* SDIO1 host interrupt */ | ||
| 47 | #define IRQ_TIMER0 22 /* Timer0 interrupt */ | ||
| 48 | #define IRQ_TIMER1 23 /* Timer1 interrupt */ | ||
| 49 | #define IRQ_TIMER2 24 /* Timer2 interrupt */ | ||
| 50 | #define IRQ_TIMER3 25 /* Timer3 interrupt */ | ||
| 51 | #define IRQ_SPIH 26 /* SPI host interrupt */ | ||
| 52 | #define IRQ_ESW 27 /* Ethernet switch interrupt */ | ||
| 53 | #define IRQ_APM 28 /* Audio process module interrupt */ | ||
| 54 | #define IRQ_GE 29 /* Graphic engine interrupt */ | ||
| 55 | #define IRQ_CLCD 30 /* LCD Controller interrupt */ | ||
| 56 | #define IRQ_PIF 31 /* Peripheral interface interrupt */ | ||
| 57 | #define IRQ_INTC0_END 31 | ||
| 58 | |||
| 59 | /* INTC1 - interrupt controller 1 */ | ||
| 60 | #define IRQ_INTC1_START 32 | ||
| 61 | #define IRQ_GPIO0 32 /* 0 GPIO bit 31//0 combined interrupt */ | ||
| 62 | #define IRQ_GPIO1 33 /* 1 GPIO bit 64//32 combined interrupt */ | ||
| 63 | #define IRQ_I2S0 34 /* 2 I2S0 interrupt */ | ||
| 64 | #define IRQ_I2S1 35 /* 3 I2S1 interrupt */ | ||
| 65 | #define IRQ_I2CH 36 /* 4 I2C host interrupt */ | ||
| 66 | #define IRQ_I2CS 37 /* 5 I2C slave interrupt */ | ||
| 67 | #define IRQ_SPIS 38 /* 6 SPI slave interrupt */ | ||
| 68 | #define IRQ_GPHY 39 /* 7 Gigabit Phy interrupt */ | ||
| 69 | #define IRQ_FLASHC 40 /* 8 Flash controller interrupt */ | ||
| 70 | #define IRQ_COMMTX 41 /* 9 ARM DDC transmit interrupt */ | ||
| 71 | #define IRQ_COMMRX 42 /* 10 ARM DDC receive interrupt */ | ||
| 72 | #define IRQ_PMUIRQ 43 /* 11 ARM performance monitor interrupt */ | ||
| 73 | #define IRQ_UARTB 44 /* 12 UARTB */ | ||
| 74 | #define IRQ_WATCHDOG 45 /* 13 Watchdog timer interrupt */ | ||
| 75 | #define IRQ_UARTA 46 /* 14 UARTA */ | ||
| 76 | #define IRQ_TSC 47 /* 15 Touch screen controller interrupt */ | ||
| 77 | #define IRQ_KEYC 48 /* 16 Key pad controller interrupt */ | ||
| 78 | #define IRQ_DMPU 49 /* 17 DDR2 memory partition interrupt */ | ||
| 79 | #define IRQ_VMPU 50 /* 18 VRAM memory partition interrupt */ | ||
| 80 | #define IRQ_FMPU 51 /* 19 Flash memory parition unit interrupt */ | ||
| 81 | #define IRQ_RNG 52 /* 20 Random number generator interrupt */ | ||
| 82 | #define IRQ_RTC0 53 /* 21 Real time clock periodic interrupt */ | ||
| 83 | #define IRQ_RTC1 54 /* 22 Real time clock one-shot interrupt */ | ||
| 84 | #define IRQ_SPUM 55 /* 23 Secure process module interrupt */ | ||
| 85 | #define IRQ_VDEC 56 /* 24 Hantro video decoder interrupt */ | ||
| 86 | #define IRQ_RTC2 57 /* 25 Real time clock tamper interrupt */ | ||
| 87 | #define IRQ_DDRP 58 /* 26 DDR Panic interrupt */ | ||
| 88 | #define IRQ_INTC1_END 58 | ||
| 89 | |||
| 90 | /* SINTC secure int controller */ | ||
| 91 | #define IRQ_SINTC_START 59 | ||
| 92 | #define IRQ_SEC_WATCHDOG 59 /* 0 Watchdog timer interrupt */ | ||
| 93 | #define IRQ_SEC_UARTA 60 /* 1 UARTA interrupt */ | ||
| 94 | #define IRQ_SEC_TSC 61 /* 2 Touch screen controller interrupt */ | ||
| 95 | #define IRQ_SEC_KEYC 62 /* 3 Key pad controller interrupt */ | ||
| 96 | #define IRQ_SEC_DMPU 63 /* 4 DDR2 memory partition interrupt */ | ||
| 97 | #define IRQ_SEC_VMPU 64 /* 5 VRAM memory partition interrupt */ | ||
| 98 | #define IRQ_SEC_FMPU 65 /* 6 Flash memory parition unit interrupt */ | ||
| 99 | #define IRQ_SEC_RNG 66 /* 7 Random number generator interrupt */ | ||
| 100 | #define IRQ_SEC_RTC0 67 /* 8 Real time clock periodic interrupt */ | ||
| 101 | #define IRQ_SEC_RTC1 68 /* 9 Real time clock one-shot interrupt */ | ||
| 102 | #define IRQ_SEC_SPUM 69 /* 10 Secure process module interrupt */ | ||
| 103 | #define IRQ_SEC_TIMER0 70 /* 11 Secure timer0 interrupt */ | ||
| 104 | #define IRQ_SEC_TIMER1 71 /* 12 Secure timer1 interrupt */ | ||
| 105 | #define IRQ_SEC_TIMER2 72 /* 13 Secure timer2 interrupt */ | ||
| 106 | #define IRQ_SEC_TIMER3 73 /* 14 Secure timer3 interrupt */ | ||
| 107 | #define IRQ_SEC_RTC2 74 /* 15 Real time clock tamper interrupt */ | ||
| 108 | |||
| 109 | #define IRQ_SINTC_END 74 | ||
| 110 | |||
| 111 | /* Note: there are 3 INTC registers of 32 bits each. So internal IRQs could go from 0-95 */ | ||
| 112 | /* Since IRQs are typically viewed in decimal, we start the gpio based IRQs off at 100 */ | ||
| 113 | /* to make the mapping easy for humans to decipher. */ | ||
| 114 | |||
| 115 | #define IRQ_GPIO_0 100 | ||
| 116 | |||
| 117 | #define NUM_INTERNAL_IRQS (IRQ_SINTC_END+1) | ||
| 118 | |||
| 119 | /* I couldn't get the gpioHw_reg.h file to be included cleanly, so I hardcoded it */ | ||
| 120 | /* define NUM_GPIO_IRQS GPIOHW_TOTAL_NUM_PINS */ | ||
| 121 | #define NUM_GPIO_IRQS 62 | ||
| 122 | |||
| 123 | #define NR_IRQS (IRQ_GPIO_0 + NUM_GPIO_IRQS) | ||
| 124 | |||
| 125 | #define IRQ_UNKNOWN -1 | ||
| 126 | |||
| 127 | /* Tune these bits to preclude noisy or unsupported interrupt sources as required. */ | ||
| 128 | #define IRQ_INTC0_VALID_MASK 0xffffffff | ||
| 129 | #define IRQ_INTC1_VALID_MASK 0x07ffffff | ||
| 130 | #define IRQ_SINTC_VALID_MASK 0x0000ffff | ||
| 131 | |||
| 132 | #endif /* ARCH_BCMRING_IRQS_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/memory.h b/arch/arm/mach-bcmring/include/mach/memory.h new file mode 100644 index 000000000000..114f942bb4f3 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/memory.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2005 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #ifndef __ASM_ARCH_MEMORY_H | ||
| 16 | #define __ASM_ARCH_MEMORY_H | ||
| 17 | |||
| 18 | #include <cfg_global.h> | ||
| 19 | |||
| 20 | /* | ||
| 21 | * Physical vs virtual RAM address space conversion. These are | ||
| 22 | * private definitions which should NOT be used outside memory.h | ||
| 23 | * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #define PHYS_OFFSET CFG_GLOBAL_RAM_BASE | ||
| 27 | |||
| 28 | /* | ||
| 29 | * Maximum DMA memory allowed is 14M | ||
| 30 | */ | ||
| 31 | #define CONSISTENT_DMA_SIZE (SZ_16M - SZ_2M) | ||
| 32 | |||
| 33 | #endif | ||
diff --git a/arch/arm/mach-bcmring/include/mach/memory_settings.h b/arch/arm/mach-bcmring/include/mach/memory_settings.h new file mode 100644 index 000000000000..ce5cd16f2ac4 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/memory_settings.h | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #ifndef MEMORY_SETTINGS_H | ||
| 16 | #define MEMORY_SETTINGS_H | ||
| 17 | |||
| 18 | /* ---- Include Files ---------------------------------------- */ | ||
| 19 | /* ---- Constants and Types ---------------------------------- */ | ||
| 20 | |||
| 21 | /* Memory devices */ | ||
| 22 | /* NAND Flash timing for 166 MHz setting */ | ||
| 23 | #define HW_CFG_NAND_tBTA (5 << 16) /* Bus turnaround cycle (n) 0-7 (30 ns) */ | ||
| 24 | #define HW_CFG_NAND_tWP (4 << 11) /* Write pulse width cycle (n+1) 0-31 (25 ns) */ | ||
| 25 | #define HW_CFG_NAND_tWR (1 << 9) /* Write recovery cycle (n+1) 0-3 (10 ns) */ | ||
| 26 | #define HW_CFG_NAND_tAS (0 << 7) /* Write address setup cycle (n+1) 0-3 ( 0 ns) */ | ||
| 27 | #define HW_CFG_NAND_tOE (3 << 5) /* Output enable delay cycle (n) 0-3 (15 ns) */ | ||
| 28 | #define HW_CFG_NAND_tRC (7 << 0) /* Read access cycle (n+2) 0-31 (50 ns) */ | ||
| 29 | |||
| 30 | #define HW_CFG_NAND_TCR (HW_CFG_NAND_tBTA \ | ||
| 31 | | HW_CFG_NAND_tWP \ | ||
| 32 | | HW_CFG_NAND_tWR \ | ||
| 33 | | HW_CFG_NAND_tAS \ | ||
| 34 | | HW_CFG_NAND_tOE \ | ||
| 35 | | HW_CFG_NAND_tRC) | ||
| 36 | |||
| 37 | /* NOR Flash timing for 166 MHz setting */ | ||
| 38 | #define HW_CFG_NOR_TPRC_TWLC (0 << 19) /* Page read access cycle / Burst write latency (n+2 / n+1) (max 25ns) */ | ||
| 39 | #define HW_CFG_NOR_TBTA (0 << 16) /* Bus turnaround cycle (n) (DNA) */ | ||
| 40 | #define HW_CFG_NOR_TWP (6 << 11) /* Write pulse width cycle (n+1) (35ns) */ | ||
| 41 | #define HW_CFG_NOR_TWR (0 << 9) /* Write recovery cycle (n+1) (0ns) */ | ||
| 42 | #define HW_CFG_NOR_TAS (0 << 7) /* Write address setup cycle (n+1) (0ns) */ | ||
| 43 | #define HW_CFG_NOR_TOE (0 << 5) /* Output enable delay cycle (n) (max 25ns) */ | ||
| 44 | #define HW_CFG_NOR_TRC_TLC (0x10 << 0) /* Read access cycle / Burst read latency (n+2 / n+1) (100ns) */ | ||
| 45 | |||
| 46 | #define HW_CFG_FLASH0_TCR (HW_CFG_NOR_TPRC_TWLC \ | ||
| 47 | | HW_CFG_NOR_TBTA \ | ||
| 48 | | HW_CFG_NOR_TWP \ | ||
| 49 | | HW_CFG_NOR_TWR \ | ||
| 50 | | HW_CFG_NOR_TAS \ | ||
| 51 | | HW_CFG_NOR_TOE \ | ||
| 52 | | HW_CFG_NOR_TRC_TLC) | ||
| 53 | |||
| 54 | #define HW_CFG_FLASH1_TCR HW_CFG_FLASH0_TCR | ||
| 55 | #define HW_CFG_FLASH2_TCR HW_CFG_FLASH0_TCR | ||
| 56 | |||
| 57 | /* SDRAM Settings */ | ||
| 58 | /* #define HW_CFG_SDRAM_CAS_LATENCY 5 Default 5, Values [3..6] */ | ||
| 59 | /* #define HW_CFG_SDRAM_CHIP_SELECT_CNT 1 Default 1, Vaules [1..2] */ | ||
| 60 | /* #define HW_CFG_SDRAM_SPEED_GRADE 667 Default 667, Values [400,533,667,800] */ | ||
| 61 | /* #define HW_CFG_SDRAM_WIDTH_BITS 16 Default 16, Vaules [8,16] */ | ||
| 62 | #define HW_CFG_SDRAM_SIZE_BYTES 0x10000000 /* Total memory, not per device size */ | ||
| 63 | |||
| 64 | /* ---- Variable Externs ------------------------------------- */ | ||
| 65 | /* ---- Function Prototypes ---------------------------------- */ | ||
| 66 | |||
| 67 | #endif /* MEMORY_SETTINGS_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/system.h b/arch/arm/mach-bcmring/include/mach/system.h new file mode 100644 index 000000000000..cdbf93c694a6 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/system.h | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright (C) 1999 ARM Limited | ||
| 4 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | */ | ||
| 20 | #ifndef __ASM_ARCH_SYSTEM_H | ||
| 21 | #define __ASM_ARCH_SYSTEM_H | ||
| 22 | |||
| 23 | #include <mach/csp/chipcHw_inline.h> | ||
| 24 | |||
| 25 | extern int bcmring_arch_warm_reboot; | ||
| 26 | |||
| 27 | static inline void arch_idle(void) | ||
| 28 | { | ||
| 29 | cpu_do_idle(); | ||
| 30 | } | ||
| 31 | |||
| 32 | static inline void arch_reset(char mode, char *cmd) | ||
| 33 | { | ||
| 34 | printk("arch_reset:%c %x\n", mode, bcmring_arch_warm_reboot); | ||
| 35 | |||
| 36 | if (mode == 'h') { | ||
| 37 | /* Reboot configured in proc entry */ | ||
| 38 | if (bcmring_arch_warm_reboot) { | ||
| 39 | printk("warm reset\n"); | ||
| 40 | /* Issue Warm reset (do not reset ethernet switch, keep alive) */ | ||
| 41 | chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_WARM); | ||
| 42 | } else { | ||
| 43 | /* Force reset of everything */ | ||
| 44 | printk("force reset\n"); | ||
| 45 | chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_SOFT); | ||
| 46 | } | ||
| 47 | } else { | ||
| 48 | /* Force reset of everything */ | ||
| 49 | printk("force reset\n"); | ||
| 50 | chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_SOFT); | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | #endif | ||
diff --git a/arch/arm/mach-bcmring/include/mach/timer.h b/arch/arm/mach-bcmring/include/mach/timer.h new file mode 100644 index 000000000000..5a94bbb032b6 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/timer.h | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | /* | ||
| 16 | * | ||
| 17 | ***************************************************************************** | ||
| 18 | * | ||
| 19 | * timer.h | ||
| 20 | * | ||
| 21 | * PURPOSE: | ||
| 22 | * | ||
| 23 | * | ||
| 24 | * | ||
| 25 | * NOTES: | ||
| 26 | * | ||
| 27 | *****************************************************************************/ | ||
| 28 | |||
| 29 | #if !defined(BCM_LINUX_TIMER_H) | ||
| 30 | #define BCM_LINUX_TIMER_H | ||
| 31 | |||
| 32 | #if defined(__KERNEL__) | ||
| 33 | |||
| 34 | /* ---- Include Files ---------------------------------------------------- */ | ||
| 35 | /* ---- Constants and Types ---------------------------------------------- */ | ||
| 36 | |||
| 37 | typedef unsigned int timer_tick_count_t; | ||
| 38 | typedef unsigned int timer_tick_rate_t; | ||
| 39 | typedef unsigned int timer_msec_t; | ||
| 40 | |||
| 41 | /* ---- Variable Externs ------------------------------------------------- */ | ||
| 42 | /* ---- Function Prototypes ---------------------------------------------- */ | ||
| 43 | |||
| 44 | /**************************************************************************** | ||
| 45 | * | ||
| 46 | * timer_get_tick_count | ||
| 47 | * | ||
| 48 | * | ||
| 49 | ***************************************************************************/ | ||
| 50 | timer_tick_count_t timer_get_tick_count(void); | ||
| 51 | |||
| 52 | /**************************************************************************** | ||
| 53 | * | ||
| 54 | * timer_get_tick_rate | ||
| 55 | * | ||
| 56 | * | ||
| 57 | ***************************************************************************/ | ||
| 58 | timer_tick_rate_t timer_get_tick_rate(void); | ||
| 59 | |||
| 60 | /**************************************************************************** | ||
| 61 | * | ||
| 62 | * timer_get_msec | ||
| 63 | * | ||
| 64 | * | ||
| 65 | ***************************************************************************/ | ||
| 66 | timer_msec_t timer_get_msec(void); | ||
| 67 | |||
| 68 | /**************************************************************************** | ||
| 69 | * | ||
| 70 | * timer_ticks_to_msec | ||
| 71 | * | ||
| 72 | * | ||
| 73 | ***************************************************************************/ | ||
| 74 | timer_msec_t timer_ticks_to_msec(timer_tick_count_t ticks); | ||
| 75 | |||
| 76 | #endif /* __KERNEL__ */ | ||
| 77 | #endif /* BCM_LINUX_TIMER_H */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/timex.h b/arch/arm/mach-bcmring/include/mach/timex.h new file mode 100644 index 000000000000..40d033ec5892 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/timex.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Integrator architecture timex specifications | ||
| 4 | * | ||
| 5 | * Copyright (C) 1999 ARM Limited | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | /* | ||
| 23 | * Specifies the number of ticks per second | ||
| 24 | */ | ||
| 25 | #define CLOCK_TICK_RATE 100000 /* REG_SMT_TICKS_PER_SEC */ | ||
diff --git a/arch/arm/mach-bcmring/include/mach/uncompress.h b/arch/arm/mach-bcmring/include/mach/uncompress.h new file mode 100644 index 000000000000..9c9821b77977 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/uncompress.h | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2005 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | #include <mach/csp/mm_addr.h> | ||
| 15 | |||
| 16 | #define BCMRING_UART_0_DR (*(volatile unsigned int *)MM_ADDR_IO_UARTA) | ||
| 17 | #define BCMRING_UART_0_FR (*(volatile unsigned int *)(MM_ADDR_IO_UARTA + 0x18)) | ||
| 18 | /* | ||
| 19 | * This does not append a newline | ||
| 20 | */ | ||
| 21 | static inline void putc(int c) | ||
| 22 | { | ||
| 23 | /* Send out UARTA */ | ||
| 24 | while (BCMRING_UART_0_FR & (1 << 5)) | ||
| 25 | ; | ||
| 26 | |||
| 27 | BCMRING_UART_0_DR = c; | ||
| 28 | } | ||
| 29 | |||
| 30 | |||
| 31 | static inline void flush(void) | ||
| 32 | { | ||
| 33 | /* Wait for the tx fifo to be empty */ | ||
| 34 | while ((BCMRING_UART_0_FR & (1 << 7)) == 0) | ||
| 35 | ; | ||
| 36 | |||
| 37 | /* Wait for the final character to be sent on the txd line */ | ||
| 38 | while (BCMRING_UART_0_FR & (1 << 3)) | ||
| 39 | ; | ||
| 40 | } | ||
| 41 | |||
| 42 | #define arch_decomp_setup() | ||
| 43 | #define arch_decomp_wdog() | ||
diff --git a/arch/arm/mach-bcmring/include/mach/vmalloc.h b/arch/arm/mach-bcmring/include/mach/vmalloc.h new file mode 100644 index 000000000000..35e2ead8395c --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/vmalloc.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright (C) 2000 Russell King. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | /* | ||
| 21 | * Move VMALLOC_END to 0xf0000000 so that the vm space can range from | ||
| 22 | * 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles | ||
| 23 | * larger physical memory designs better. | ||
| 24 | */ | ||
| 25 | #define VMALLOC_END (PAGE_OFFSET + 0x30000000) | ||
diff --git a/arch/arm/mach-bcmring/irq.c b/arch/arm/mach-bcmring/irq.c new file mode 100644 index 000000000000..dc1c4939b0ce --- /dev/null +++ b/arch/arm/mach-bcmring/irq.c | |||
| @@ -0,0 +1,127 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * Copyright (C) 1999 ARM Limited | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | */ | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/stddef.h> | ||
| 21 | #include <linux/list.h> | ||
| 22 | #include <linux/timer.h> | ||
| 23 | #include <linux/version.h> | ||
| 24 | #include <linux/io.h> | ||
| 25 | |||
| 26 | #include <mach/hardware.h> | ||
| 27 | #include <asm/irq.h> | ||
| 28 | |||
| 29 | #include <asm/mach/irq.h> | ||
| 30 | #include <mach/csp/intcHw_reg.h> | ||
| 31 | #include <mach/csp/mm_io.h> | ||
| 32 | |||
| 33 | static void bcmring_mask_irq0(unsigned int irq) | ||
| 34 | { | ||
| 35 | writel(1 << (irq - IRQ_INTC0_START), | ||
| 36 | MM_IO_BASE_INTC0 + INTCHW_INTENCLEAR); | ||
| 37 | } | ||
| 38 | |||
| 39 | static void bcmring_unmask_irq0(unsigned int irq) | ||
| 40 | { | ||
| 41 | writel(1 << (irq - IRQ_INTC0_START), | ||
| 42 | MM_IO_BASE_INTC0 + INTCHW_INTENABLE); | ||
| 43 | } | ||
| 44 | |||
| 45 | static void bcmring_mask_irq1(unsigned int irq) | ||
| 46 | { | ||
| 47 | writel(1 << (irq - IRQ_INTC1_START), | ||
| 48 | MM_IO_BASE_INTC1 + INTCHW_INTENCLEAR); | ||
| 49 | } | ||
| 50 | |||
| 51 | static void bcmring_unmask_irq1(unsigned int irq) | ||
| 52 | { | ||
| 53 | writel(1 << (irq - IRQ_INTC1_START), | ||
| 54 | MM_IO_BASE_INTC1 + INTCHW_INTENABLE); | ||
| 55 | } | ||
| 56 | |||
| 57 | static void bcmring_mask_irq2(unsigned int irq) | ||
| 58 | { | ||
| 59 | writel(1 << (irq - IRQ_SINTC_START), | ||
| 60 | MM_IO_BASE_SINTC + INTCHW_INTENCLEAR); | ||
| 61 | } | ||
| 62 | |||
| 63 | static void bcmring_unmask_irq2(unsigned int irq) | ||
| 64 | { | ||
| 65 | writel(1 << (irq - IRQ_SINTC_START), | ||
| 66 | MM_IO_BASE_SINTC + INTCHW_INTENABLE); | ||
| 67 | } | ||
| 68 | |||
| 69 | static struct irq_chip bcmring_irq0_chip = { | ||
| 70 | .typename = "ARM-INTC0", | ||
| 71 | .ack = bcmring_mask_irq0, | ||
| 72 | .mask = bcmring_mask_irq0, /* mask a specific interrupt, blocking its delivery. */ | ||
| 73 | .unmask = bcmring_unmask_irq0, /* unmaks an interrupt */ | ||
| 74 | }; | ||
| 75 | |||
| 76 | static struct irq_chip bcmring_irq1_chip = { | ||
| 77 | .typename = "ARM-INTC1", | ||
| 78 | .ack = bcmring_mask_irq1, | ||
| 79 | .mask = bcmring_mask_irq1, | ||
| 80 | .unmask = bcmring_unmask_irq1, | ||
| 81 | }; | ||
| 82 | |||
| 83 | static struct irq_chip bcmring_irq2_chip = { | ||
| 84 | .typename = "ARM-SINTC", | ||
| 85 | .ack = bcmring_mask_irq2, | ||
| 86 | .mask = bcmring_mask_irq2, | ||
| 87 | .unmask = bcmring_unmask_irq2, | ||
| 88 | }; | ||
| 89 | |||
| 90 | static void vic_init(void __iomem *base, struct irq_chip *chip, | ||
| 91 | unsigned int irq_start, unsigned int vic_sources) | ||
| 92 | { | ||
| 93 | unsigned int i; | ||
| 94 | for (i = 0; i < 32; i++) { | ||
| 95 | unsigned int irq = irq_start + i; | ||
| 96 | set_irq_chip(irq, chip); | ||
| 97 | set_irq_chip_data(irq, base); | ||
| 98 | |||
| 99 | if (vic_sources & (1 << i)) { | ||
| 100 | set_irq_handler(irq, handle_level_irq); | ||
| 101 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
| 102 | } | ||
| 103 | } | ||
| 104 | writel(0, base + INTCHW_INTSELECT); | ||
| 105 | writel(0, base + INTCHW_INTENABLE); | ||
| 106 | writel(~0, base + INTCHW_INTENCLEAR); | ||
| 107 | writel(0, base + INTCHW_IRQSTATUS); | ||
| 108 | writel(~0, base + INTCHW_SOFTINTCLEAR); | ||
| 109 | } | ||
| 110 | |||
| 111 | void __init bcmring_init_irq(void) | ||
| 112 | { | ||
| 113 | vic_init((void __iomem *)MM_IO_BASE_INTC0, &bcmring_irq0_chip, | ||
| 114 | IRQ_INTC0_START, IRQ_INTC0_VALID_MASK); | ||
| 115 | vic_init((void __iomem *)MM_IO_BASE_INTC1, &bcmring_irq1_chip, | ||
| 116 | IRQ_INTC1_START, IRQ_INTC1_VALID_MASK); | ||
| 117 | vic_init((void __iomem *)MM_IO_BASE_SINTC, &bcmring_irq2_chip, | ||
| 118 | IRQ_SINTC_START, IRQ_SINTC_VALID_MASK); | ||
| 119 | |||
| 120 | /* special cases */ | ||
| 121 | if (INTCHW_INTC1_GPIO0 & IRQ_INTC1_VALID_MASK) { | ||
| 122 | set_irq_handler(IRQ_GPIO0, handle_simple_irq); | ||
| 123 | } | ||
| 124 | if (INTCHW_INTC1_GPIO1 & IRQ_INTC1_VALID_MASK) { | ||
| 125 | set_irq_handler(IRQ_GPIO1, handle_simple_irq); | ||
| 126 | } | ||
| 127 | } | ||
diff --git a/arch/arm/mach-bcmring/mm.c b/arch/arm/mach-bcmring/mm.c new file mode 100644 index 000000000000..0f1c37e4523a --- /dev/null +++ b/arch/arm/mach-bcmring/mm.c | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <asm/mach/map.h> | ||
| 17 | |||
| 18 | #include <mach/hardware.h> | ||
| 19 | #include <mach/csp/mm_io.h> | ||
| 20 | |||
| 21 | #define IO_DESC(va, sz) { .virtual = va, \ | ||
| 22 | .pfn = __phys_to_pfn(HW_IO_VIRT_TO_PHYS(va)), \ | ||
| 23 | .length = sz, \ | ||
| 24 | .type = MT_DEVICE } | ||
| 25 | |||
| 26 | #define MEM_DESC(va, sz) { .virtual = va, \ | ||
| 27 | .pfn = __phys_to_pfn(HW_IO_VIRT_TO_PHYS(va)), \ | ||
| 28 | .length = sz, \ | ||
| 29 | .type = MT_MEMORY } | ||
| 30 | |||
| 31 | static struct map_desc bcmring_io_desc[] __initdata = { | ||
| 32 | IO_DESC(MM_IO_BASE_NAND, SZ_64K), /* phys:0x28000000-0x28000FFF virt:0xE8000000-0xE8000FFF size:0x00010000 */ | ||
| 33 | IO_DESC(MM_IO_BASE_UMI, SZ_64K), /* phys:0x2C000000-0x2C000FFF virt:0xEC000000-0xEC000FFF size:0x00010000 */ | ||
| 34 | |||
| 35 | IO_DESC(MM_IO_BASE_BROM, SZ_64K), /* phys:0x30000000-0x3000FFFF virt:0xF3000000-0xF300FFFF size:0x00010000 */ | ||
| 36 | MEM_DESC(MM_IO_BASE_ARAM, SZ_1M), /* phys:0x31000000-0x31FFFFFF virt:0xF3100000-0xF31FFFFF size:0x01000000 */ | ||
| 37 | IO_DESC(MM_IO_BASE_DMA0, SZ_1M), /* phys:0x32000000-0x32FFFFFF virt:0xF3200000-0xF32FFFFF size:0x01000000 */ | ||
| 38 | IO_DESC(MM_IO_BASE_DMA1, SZ_1M), /* phys:0x33000000-0x33FFFFFF virt:0xF3300000-0xF33FFFFF size:0x01000000 */ | ||
| 39 | IO_DESC(MM_IO_BASE_ESW, SZ_1M), /* phys:0x34000000-0x34FFFFFF virt:0xF3400000-0xF34FFFFF size:0x01000000 */ | ||
| 40 | IO_DESC(MM_IO_BASE_CLCD, SZ_1M), /* phys:0x35000000-0x35FFFFFF virt:0xF3500000-0xF35FFFFF size:0x01000000 */ | ||
| 41 | IO_DESC(MM_IO_BASE_APM, SZ_1M), /* phys:0x36000000-0x36FFFFFF virt:0xF3600000-0xF36FFFFF size:0x01000000 */ | ||
| 42 | IO_DESC(MM_IO_BASE_SPUM, SZ_1M), /* phys:0x37000000-0x37FFFFFF virt:0xF3700000-0xF37FFFFF size:0x01000000 */ | ||
| 43 | IO_DESC(MM_IO_BASE_VPM_PROG, SZ_1M), /* phys:0x38000000-0x38FFFFFF virt:0xF3800000-0xF38FFFFF size:0x01000000 */ | ||
| 44 | IO_DESC(MM_IO_BASE_VPM_DATA, SZ_1M), /* phys:0x3A000000-0x3AFFFFFF virt:0xF3A00000-0xF3AFFFFF size:0x01000000 */ | ||
| 45 | |||
| 46 | IO_DESC(MM_IO_BASE_VRAM, SZ_64K), /* phys:0x40000000-0x4000FFFF virt:0xF4000000-0xF400FFFF size:0x00010000 */ | ||
| 47 | IO_DESC(MM_IO_BASE_CHIPC, SZ_16M), /* phys:0x80000000-0x80FFFFFF virt:0xF8000000-0xF8FFFFFF size:0x01000000 */ | ||
| 48 | IO_DESC(MM_IO_BASE_VPM_EXTMEM_RSVD, | ||
| 49 | SZ_16M), /* phys:0x0F000000-0x0FFFFFFF virt:0xF0000000-0xF0FFFFFF size:0x01000000 */ | ||
| 50 | }; | ||
| 51 | |||
| 52 | void __init bcmring_map_io(void) | ||
| 53 | { | ||
| 54 | |||
| 55 | iotable_init(bcmring_io_desc, ARRAY_SIZE(bcmring_io_desc)); | ||
| 56 | } | ||
diff --git a/arch/arm/mach-bcmring/timer.c b/arch/arm/mach-bcmring/timer.c new file mode 100644 index 000000000000..2d415d2a8e68 --- /dev/null +++ b/arch/arm/mach-bcmring/timer.c | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | /***************************************************************************** | ||
| 2 | * Copyright 2003 - 2008 Broadcom Corporation. All rights reserved. | ||
| 3 | * | ||
| 4 | * Unless you and Broadcom execute a separate written software license | ||
| 5 | * agreement governing use of this software, this software is licensed to you | ||
| 6 | * under the terms of the GNU General Public License version 2, available at | ||
| 7 | * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). | ||
| 8 | * | ||
| 9 | * Notwithstanding the above, under no circumstances may you combine this | ||
| 10 | * software in any way with any other Broadcom software provided under a | ||
| 11 | * license other than the GPL, without Broadcom's express prior written | ||
| 12 | * consent. | ||
| 13 | *****************************************************************************/ | ||
| 14 | |||
| 15 | #include <linux/version.h> | ||
| 16 | #include <linux/types.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <csp/tmrHw.h> | ||
| 19 | |||
| 20 | #include <mach/timer.h> | ||
| 21 | /* The core.c file initializes timers 1 and 3 as a linux clocksource. */ | ||
| 22 | /* The real time clock should probably be the real linux clocksource. */ | ||
| 23 | /* In the meantime, this file should agree with core.c as to the */ | ||
| 24 | /* profiling timer. If the clocksource is moved to rtc later, then */ | ||
| 25 | /* we can init the profiling timer here instead. */ | ||
| 26 | |||
| 27 | /* Timer 1 provides 25MHz resolution syncrhonized to scheduling and APM timing */ | ||
| 28 | /* Timer 3 provides bus freqeuncy sychronized to ACLK, but spread spectrum will */ | ||
| 29 | /* affect synchronization with scheduling and APM timing. */ | ||
| 30 | |||
| 31 | #define PROF_TIMER 1 | ||
| 32 | |||
| 33 | timer_tick_rate_t timer_get_tick_rate(void) | ||
| 34 | { | ||
| 35 | return tmrHw_getCountRate(PROF_TIMER); | ||
| 36 | } | ||
| 37 | |||
| 38 | timer_tick_count_t timer_get_tick_count(void) | ||
| 39 | { | ||
| 40 | return tmrHw_GetCurrentCount(PROF_TIMER); /* change downcounter to upcounter */ | ||
| 41 | } | ||
| 42 | |||
| 43 | timer_msec_t timer_ticks_to_msec(timer_tick_count_t ticks) | ||
| 44 | { | ||
| 45 | static int tickRateMsec; | ||
| 46 | |||
| 47 | if (tickRateMsec == 0) { | ||
| 48 | tickRateMsec = timer_get_tick_rate() / 1000; | ||
| 49 | } | ||
| 50 | |||
| 51 | return ticks / tickRateMsec; | ||
| 52 | } | ||
| 53 | |||
| 54 | timer_msec_t timer_get_msec(void) | ||
| 55 | { | ||
| 56 | return timer_ticks_to_msec(timer_get_tick_count()); | ||
| 57 | } | ||
| 58 | |||
| 59 | EXPORT_SYMBOL(timer_get_tick_count); | ||
| 60 | EXPORT_SYMBOL(timer_ticks_to_msec); | ||
| 61 | EXPORT_SYMBOL(timer_get_tick_rate); | ||
| 62 | EXPORT_SYMBOL(timer_get_msec); | ||
diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c index 3fbd9b0fbe24..caf6d5154aec 100644 --- a/arch/arm/mach-ep93xx/adssphere.c +++ b/arch/arm/mach-ep93xx/adssphere.c | |||
| @@ -12,18 +12,15 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <linux/mm.h> | ||
| 16 | #include <linux/sched.h> | ||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/ioport.h> | ||
| 19 | #include <linux/mtd/physmap.h> | ||
| 20 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| 21 | #include <linux/io.h> | 16 | #include <linux/mtd/physmap.h> |
| 22 | #include <linux/i2c.h> | 17 | |
| 23 | #include <mach/hardware.h> | 18 | #include <mach/hardware.h> |
| 19 | |||
| 24 | #include <asm/mach-types.h> | 20 | #include <asm/mach-types.h> |
| 25 | #include <asm/mach/arch.h> | 21 | #include <asm/mach/arch.h> |
| 26 | 22 | ||
| 23 | |||
| 27 | static struct physmap_flash_data adssphere_flash_data = { | 24 | static struct physmap_flash_data adssphere_flash_data = { |
| 28 | .width = 4, | 25 | .width = 4, |
| 29 | }; | 26 | }; |
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index 6c4c1633ed12..3dd0e2a23095 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c | |||
| @@ -22,48 +22,39 @@ | |||
| 22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | /* | ||
| 26 | * The EP93xx has two external crystal oscillators. To generate the | ||
| 27 | * required high-frequency clocks, the processor uses two phase-locked- | ||
| 28 | * loops (PLLs) to multiply the incoming external clock signal to much | ||
| 29 | * higher frequencies that are then divided down by programmable dividers | ||
| 30 | * to produce the needed clocks. The PLLs operate independently of one | ||
| 31 | * another. | ||
| 32 | */ | ||
| 33 | #define EP93XX_EXT_CLK_RATE 14745600 | ||
| 34 | #define EP93XX_EXT_RTC_RATE 32768 | ||
| 35 | |||
| 36 | |||
| 37 | struct clk { | 25 | struct clk { |
| 38 | unsigned long rate; | 26 | unsigned long rate; |
| 39 | int users; | 27 | int users; |
| 40 | int sw_locked; | 28 | int sw_locked; |
| 41 | u32 enable_reg; | 29 | void __iomem *enable_reg; |
| 42 | u32 enable_mask; | 30 | u32 enable_mask; |
| 43 | 31 | ||
| 44 | unsigned long (*get_rate)(struct clk *clk); | 32 | unsigned long (*get_rate)(struct clk *clk); |
| 33 | int (*set_rate)(struct clk *clk, unsigned long rate); | ||
| 45 | }; | 34 | }; |
| 46 | 35 | ||
| 47 | 36 | ||
| 48 | static unsigned long get_uart_rate(struct clk *clk); | 37 | static unsigned long get_uart_rate(struct clk *clk); |
| 49 | 38 | ||
| 39 | static int set_keytchclk_rate(struct clk *clk, unsigned long rate); | ||
| 40 | |||
| 50 | 41 | ||
| 51 | static struct clk clk_uart1 = { | 42 | static struct clk clk_uart1 = { |
| 52 | .sw_locked = 1, | 43 | .sw_locked = 1, |
| 53 | .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, | 44 | .enable_reg = EP93XX_SYSCON_DEVCFG, |
| 54 | .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U1EN, | 45 | .enable_mask = EP93XX_SYSCON_DEVCFG_U1EN, |
| 55 | .get_rate = get_uart_rate, | 46 | .get_rate = get_uart_rate, |
| 56 | }; | 47 | }; |
| 57 | static struct clk clk_uart2 = { | 48 | static struct clk clk_uart2 = { |
| 58 | .sw_locked = 1, | 49 | .sw_locked = 1, |
| 59 | .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, | 50 | .enable_reg = EP93XX_SYSCON_DEVCFG, |
| 60 | .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U2EN, | 51 | .enable_mask = EP93XX_SYSCON_DEVCFG_U2EN, |
| 61 | .get_rate = get_uart_rate, | 52 | .get_rate = get_uart_rate, |
| 62 | }; | 53 | }; |
| 63 | static struct clk clk_uart3 = { | 54 | static struct clk clk_uart3 = { |
| 64 | .sw_locked = 1, | 55 | .sw_locked = 1, |
| 65 | .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, | 56 | .enable_reg = EP93XX_SYSCON_DEVCFG, |
| 66 | .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U3EN, | 57 | .enable_mask = EP93XX_SYSCON_DEVCFG_U3EN, |
| 67 | .get_rate = get_uart_rate, | 58 | .get_rate = get_uart_rate, |
| 68 | }; | 59 | }; |
| 69 | static struct clk clk_pll1; | 60 | static struct clk clk_pll1; |
| @@ -75,6 +66,15 @@ static struct clk clk_usb_host = { | |||
| 75 | .enable_reg = EP93XX_SYSCON_PWRCNT, | 66 | .enable_reg = EP93XX_SYSCON_PWRCNT, |
| 76 | .enable_mask = EP93XX_SYSCON_PWRCNT_USH_EN, | 67 | .enable_mask = EP93XX_SYSCON_PWRCNT_USH_EN, |
| 77 | }; | 68 | }; |
| 69 | static struct clk clk_keypad = { | ||
| 70 | .sw_locked = 1, | ||
| 71 | .enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV, | ||
| 72 | .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN, | ||
| 73 | .set_rate = set_keytchclk_rate, | ||
| 74 | }; | ||
| 75 | static struct clk clk_pwm = { | ||
| 76 | .rate = EP93XX_EXT_CLK_RATE, | ||
| 77 | }; | ||
| 78 | 78 | ||
| 79 | /* DMA Clocks */ | 79 | /* DMA Clocks */ |
| 80 | static struct clk clk_m2p0 = { | 80 | static struct clk clk_m2p0 = { |
| @@ -130,27 +130,29 @@ static struct clk clk_m2m1 = { | |||
| 130 | { .dev_id = dev, .con_id = con, .clk = ck } | 130 | { .dev_id = dev, .con_id = con, .clk = ck } |
| 131 | 131 | ||
| 132 | static struct clk_lookup clocks[] = { | 132 | static struct clk_lookup clocks[] = { |
| 133 | INIT_CK("apb:uart1", NULL, &clk_uart1), | 133 | INIT_CK("apb:uart1", NULL, &clk_uart1), |
| 134 | INIT_CK("apb:uart2", NULL, &clk_uart2), | 134 | INIT_CK("apb:uart2", NULL, &clk_uart2), |
| 135 | INIT_CK("apb:uart3", NULL, &clk_uart3), | 135 | INIT_CK("apb:uart3", NULL, &clk_uart3), |
| 136 | INIT_CK(NULL, "pll1", &clk_pll1), | 136 | INIT_CK(NULL, "pll1", &clk_pll1), |
| 137 | INIT_CK(NULL, "fclk", &clk_f), | 137 | INIT_CK(NULL, "fclk", &clk_f), |
| 138 | INIT_CK(NULL, "hclk", &clk_h), | 138 | INIT_CK(NULL, "hclk", &clk_h), |
| 139 | INIT_CK(NULL, "pclk", &clk_p), | 139 | INIT_CK(NULL, "pclk", &clk_p), |
| 140 | INIT_CK(NULL, "pll2", &clk_pll2), | 140 | INIT_CK(NULL, "pll2", &clk_pll2), |
| 141 | INIT_CK("ep93xx-ohci", NULL, &clk_usb_host), | 141 | INIT_CK("ep93xx-ohci", NULL, &clk_usb_host), |
| 142 | INIT_CK(NULL, "m2p0", &clk_m2p0), | 142 | INIT_CK("ep93xx-keypad", NULL, &clk_keypad), |
| 143 | INIT_CK(NULL, "m2p1", &clk_m2p1), | 143 | INIT_CK(NULL, "pwm_clk", &clk_pwm), |
| 144 | INIT_CK(NULL, "m2p2", &clk_m2p2), | 144 | INIT_CK(NULL, "m2p0", &clk_m2p0), |
| 145 | INIT_CK(NULL, "m2p3", &clk_m2p3), | 145 | INIT_CK(NULL, "m2p1", &clk_m2p1), |
| 146 | INIT_CK(NULL, "m2p4", &clk_m2p4), | 146 | INIT_CK(NULL, "m2p2", &clk_m2p2), |
| 147 | INIT_CK(NULL, "m2p5", &clk_m2p5), | 147 | INIT_CK(NULL, "m2p3", &clk_m2p3), |
| 148 | INIT_CK(NULL, "m2p6", &clk_m2p6), | 148 | INIT_CK(NULL, "m2p4", &clk_m2p4), |
| 149 | INIT_CK(NULL, "m2p7", &clk_m2p7), | 149 | INIT_CK(NULL, "m2p5", &clk_m2p5), |
| 150 | INIT_CK(NULL, "m2p8", &clk_m2p8), | 150 | INIT_CK(NULL, "m2p6", &clk_m2p6), |
| 151 | INIT_CK(NULL, "m2p9", &clk_m2p9), | 151 | INIT_CK(NULL, "m2p7", &clk_m2p7), |
| 152 | INIT_CK(NULL, "m2m0", &clk_m2m0), | 152 | INIT_CK(NULL, "m2p8", &clk_m2p8), |
| 153 | INIT_CK(NULL, "m2m1", &clk_m2m1), | 153 | INIT_CK(NULL, "m2p9", &clk_m2p9), |
| 154 | INIT_CK(NULL, "m2m0", &clk_m2m0), | ||
| 155 | INIT_CK(NULL, "m2m1", &clk_m2m1), | ||
| 154 | }; | 156 | }; |
| 155 | 157 | ||
| 156 | 158 | ||
| @@ -160,9 +162,11 @@ int clk_enable(struct clk *clk) | |||
| 160 | u32 value; | 162 | u32 value; |
| 161 | 163 | ||
| 162 | value = __raw_readl(clk->enable_reg); | 164 | value = __raw_readl(clk->enable_reg); |
| 165 | value |= clk->enable_mask; | ||
| 163 | if (clk->sw_locked) | 166 | if (clk->sw_locked) |
| 164 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | 167 | ep93xx_syscon_swlocked_write(value, clk->enable_reg); |
| 165 | __raw_writel(value | clk->enable_mask, clk->enable_reg); | 168 | else |
| 169 | __raw_writel(value, clk->enable_reg); | ||
| 166 | } | 170 | } |
| 167 | 171 | ||
| 168 | return 0; | 172 | return 0; |
| @@ -175,9 +179,11 @@ void clk_disable(struct clk *clk) | |||
| 175 | u32 value; | 179 | u32 value; |
| 176 | 180 | ||
| 177 | value = __raw_readl(clk->enable_reg); | 181 | value = __raw_readl(clk->enable_reg); |
| 182 | value &= ~clk->enable_mask; | ||
| 178 | if (clk->sw_locked) | 183 | if (clk->sw_locked) |
| 179 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | 184 | ep93xx_syscon_swlocked_write(value, clk->enable_reg); |
| 180 | __raw_writel(value & ~clk->enable_mask, clk->enable_reg); | 185 | else |
| 186 | __raw_writel(value, clk->enable_reg); | ||
| 181 | } | 187 | } |
| 182 | } | 188 | } |
| 183 | EXPORT_SYMBOL(clk_disable); | 189 | EXPORT_SYMBOL(clk_disable); |
| @@ -202,6 +208,43 @@ unsigned long clk_get_rate(struct clk *clk) | |||
| 202 | } | 208 | } |
| 203 | EXPORT_SYMBOL(clk_get_rate); | 209 | EXPORT_SYMBOL(clk_get_rate); |
| 204 | 210 | ||
| 211 | static int set_keytchclk_rate(struct clk *clk, unsigned long rate) | ||
| 212 | { | ||
| 213 | u32 val; | ||
| 214 | u32 div_bit; | ||
| 215 | |||
| 216 | val = __raw_readl(clk->enable_reg); | ||
| 217 | |||
| 218 | /* | ||
| 219 | * The Key Matrix and ADC clocks are configured using the same | ||
| 220 | * System Controller register. The clock used will be either | ||
| 221 | * 1/4 or 1/16 the external clock rate depending on the | ||
| 222 | * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV | ||
| 223 | * bit being set or cleared. | ||
| 224 | */ | ||
| 225 | div_bit = clk->enable_mask >> 15; | ||
| 226 | |||
| 227 | if (rate == EP93XX_KEYTCHCLK_DIV4) | ||
| 228 | val |= div_bit; | ||
| 229 | else if (rate == EP93XX_KEYTCHCLK_DIV16) | ||
| 230 | val &= ~div_bit; | ||
| 231 | else | ||
| 232 | return -EINVAL; | ||
| 233 | |||
| 234 | ep93xx_syscon_swlocked_write(val, clk->enable_reg); | ||
| 235 | clk->rate = rate; | ||
| 236 | return 0; | ||
| 237 | } | ||
| 238 | |||
| 239 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
| 240 | { | ||
| 241 | if (clk->set_rate) | ||
| 242 | return clk->set_rate(clk, rate); | ||
| 243 | |||
| 244 | return -EINVAL; | ||
| 245 | } | ||
| 246 | EXPORT_SYMBOL(clk_set_rate); | ||
| 247 | |||
| 205 | 248 | ||
| 206 | static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 }; | 249 | static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 }; |
| 207 | static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 }; | 250 | static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 }; |
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 204dc5cbd0b8..16b92c37ec99 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c | |||
| @@ -16,40 +16,24 @@ | |||
| 16 | 16 | ||
| 17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
| 18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | #include <linux/spinlock.h> | 19 | #include <linux/platform_device.h> |
| 20 | #include <linux/sched.h> | ||
| 21 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
| 22 | #include <linux/serial.h> | ||
| 23 | #include <linux/tty.h> | ||
| 24 | #include <linux/bitops.h> | ||
| 25 | #include <linux/serial_8250.h> | ||
| 26 | #include <linux/serial_core.h> | ||
| 27 | #include <linux/device.h> | ||
| 28 | #include <linux/mm.h> | ||
| 29 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
| 30 | #include <linux/time.h> | ||
| 31 | #include <linux/timex.h> | 22 | #include <linux/timex.h> |
| 32 | #include <linux/delay.h> | 23 | #include <linux/io.h> |
| 24 | #include <linux/gpio.h> | ||
| 25 | #include <linux/leds.h> | ||
| 33 | #include <linux/termios.h> | 26 | #include <linux/termios.h> |
| 34 | #include <linux/amba/bus.h> | 27 | #include <linux/amba/bus.h> |
| 35 | #include <linux/amba/serial.h> | 28 | #include <linux/amba/serial.h> |
| 36 | #include <linux/io.h> | ||
| 37 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
| 38 | #include <linux/i2c-gpio.h> | 30 | #include <linux/i2c-gpio.h> |
| 39 | 31 | ||
| 40 | #include <asm/types.h> | ||
| 41 | #include <asm/setup.h> | ||
| 42 | #include <asm/memory.h> | ||
| 43 | #include <mach/hardware.h> | 32 | #include <mach/hardware.h> |
| 44 | #include <asm/irq.h> | ||
| 45 | #include <asm/system.h> | ||
| 46 | #include <asm/tlbflush.h> | ||
| 47 | #include <asm/pgtable.h> | ||
| 48 | 33 | ||
| 49 | #include <asm/mach/map.h> | 34 | #include <asm/mach/map.h> |
| 50 | #include <asm/mach/time.h> | 35 | #include <asm/mach/time.h> |
| 51 | #include <asm/mach/irq.h> | 36 | #include <asm/mach/irq.h> |
| 52 | #include <mach/gpio.h> | ||
| 53 | 37 | ||
| 54 | #include <asm/hardware/vic.h> | 38 | #include <asm/hardware/vic.h> |
| 55 | 39 | ||
| @@ -98,7 +82,7 @@ void __init ep93xx_map_io(void) | |||
| 98 | */ | 82 | */ |
| 99 | static unsigned int last_jiffy_time; | 83 | static unsigned int last_jiffy_time; |
| 100 | 84 | ||
| 101 | #define TIMER4_TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ) | 85 | #define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(CLOCK_TICK_RATE, HZ) |
| 102 | 86 | ||
| 103 | static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id) | 87 | static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id) |
| 104 | { | 88 | { |
| @@ -362,8 +346,8 @@ void __init ep93xx_init_irq(void) | |||
| 362 | { | 346 | { |
| 363 | int gpio_irq; | 347 | int gpio_irq; |
| 364 | 348 | ||
| 365 | vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0); | 349 | vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0); |
| 366 | vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0); | 350 | vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0); |
| 367 | 351 | ||
| 368 | for (gpio_irq = gpio_to_irq(0); | 352 | for (gpio_irq = gpio_to_irq(0); |
| 369 | gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) { | 353 | gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) { |
| @@ -385,6 +369,47 @@ void __init ep93xx_init_irq(void) | |||
| 385 | 369 | ||
| 386 | 370 | ||
| 387 | /************************************************************************* | 371 | /************************************************************************* |
| 372 | * EP93xx System Controller Software Locked register handling | ||
| 373 | *************************************************************************/ | ||
| 374 | |||
| 375 | /* | ||
| 376 | * syscon_swlock prevents anything else from writing to the syscon | ||
| 377 | * block while a software locked register is being written. | ||
| 378 | */ | ||
| 379 | static DEFINE_SPINLOCK(syscon_swlock); | ||
| 380 | |||
| 381 | void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg) | ||
| 382 | { | ||
| 383 | unsigned long flags; | ||
| 384 | |||
| 385 | spin_lock_irqsave(&syscon_swlock, flags); | ||
| 386 | |||
| 387 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | ||
| 388 | __raw_writel(val, reg); | ||
| 389 | |||
| 390 | spin_unlock_irqrestore(&syscon_swlock, flags); | ||
| 391 | } | ||
| 392 | EXPORT_SYMBOL(ep93xx_syscon_swlocked_write); | ||
| 393 | |||
| 394 | void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits) | ||
| 395 | { | ||
| 396 | unsigned long flags; | ||
| 397 | unsigned int val; | ||
| 398 | |||
| 399 | spin_lock_irqsave(&syscon_swlock, flags); | ||
| 400 | |||
| 401 | val = __raw_readl(EP93XX_SYSCON_DEVCFG); | ||
| 402 | val |= set_bits; | ||
| 403 | val &= ~clear_bits; | ||
| 404 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | ||
| 405 | __raw_writel(val, EP93XX_SYSCON_DEVCFG); | ||
| 406 | |||
| 407 | spin_unlock_irqrestore(&syscon_swlock, flags); | ||
| 408 | } | ||
| 409 | EXPORT_SYMBOL(ep93xx_devcfg_set_clear); | ||
| 410 | |||
| 411 | |||
| 412 | /************************************************************************* | ||
| 388 | * EP93xx peripheral handling | 413 | * EP93xx peripheral handling |
| 389 | *************************************************************************/ | 414 | *************************************************************************/ |
| 390 | #define EP93XX_UART_MCR_OFFSET (0x0100) | 415 | #define EP93XX_UART_MCR_OFFSET (0x0100) |
| @@ -517,10 +542,8 @@ static struct platform_device ep93xx_eth_device = { | |||
| 517 | 542 | ||
| 518 | void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr) | 543 | void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr) |
| 519 | { | 544 | { |
| 520 | if (copy_addr) { | 545 | if (copy_addr) |
| 521 | memcpy(data->dev_addr, | 546 | memcpy_fromio(data->dev_addr, EP93XX_ETHERNET_BASE + 0x50, 6); |
| 522 | (void *)(EP93XX_ETHERNET_BASE + 0x50), 6); | ||
| 523 | } | ||
| 524 | 547 | ||
| 525 | ep93xx_eth_data = *data; | 548 | ep93xx_eth_data = *data; |
| 526 | platform_device_register(&ep93xx_eth_device); | 549 | platform_device_register(&ep93xx_eth_device); |
| @@ -546,19 +569,125 @@ void __init ep93xx_register_i2c(struct i2c_board_info *devices, int num) | |||
| 546 | platform_device_register(&ep93xx_i2c_device); | 569 | platform_device_register(&ep93xx_i2c_device); |
| 547 | } | 570 | } |
| 548 | 571 | ||
| 572 | |||
| 573 | /************************************************************************* | ||
| 574 | * EP93xx LEDs | ||
| 575 | *************************************************************************/ | ||
| 576 | static struct gpio_led ep93xx_led_pins[] = { | ||
| 577 | { | ||
| 578 | .name = "platform:grled", | ||
| 579 | .gpio = EP93XX_GPIO_LINE_GRLED, | ||
| 580 | }, { | ||
| 581 | .name = "platform:rdled", | ||
| 582 | .gpio = EP93XX_GPIO_LINE_RDLED, | ||
| 583 | }, | ||
| 584 | }; | ||
| 585 | |||
| 586 | static struct gpio_led_platform_data ep93xx_led_data = { | ||
| 587 | .num_leds = ARRAY_SIZE(ep93xx_led_pins), | ||
| 588 | .leds = ep93xx_led_pins, | ||
| 589 | }; | ||
| 590 | |||
| 591 | static struct platform_device ep93xx_leds = { | ||
| 592 | .name = "leds-gpio", | ||
| 593 | .id = -1, | ||
| 594 | .dev = { | ||
| 595 | .platform_data = &ep93xx_led_data, | ||
| 596 | }, | ||
| 597 | }; | ||
| 598 | |||
| 599 | |||
| 600 | /************************************************************************* | ||
| 601 | * EP93xx pwm peripheral handling | ||
| 602 | *************************************************************************/ | ||
| 603 | static struct resource ep93xx_pwm0_resource[] = { | ||
| 604 | { | ||
| 605 | .start = EP93XX_PWM_PHYS_BASE, | ||
| 606 | .end = EP93XX_PWM_PHYS_BASE + 0x10 - 1, | ||
| 607 | .flags = IORESOURCE_MEM, | ||
| 608 | }, | ||
| 609 | }; | ||
| 610 | |||
| 611 | static struct platform_device ep93xx_pwm0_device = { | ||
| 612 | .name = "ep93xx-pwm", | ||
| 613 | .id = 0, | ||
| 614 | .num_resources = ARRAY_SIZE(ep93xx_pwm0_resource), | ||
| 615 | .resource = ep93xx_pwm0_resource, | ||
| 616 | }; | ||
| 617 | |||
| 618 | static struct resource ep93xx_pwm1_resource[] = { | ||
| 619 | { | ||
| 620 | .start = EP93XX_PWM_PHYS_BASE + 0x20, | ||
| 621 | .end = EP93XX_PWM_PHYS_BASE + 0x30 - 1, | ||
| 622 | .flags = IORESOURCE_MEM, | ||
| 623 | }, | ||
| 624 | }; | ||
| 625 | |||
| 626 | static struct platform_device ep93xx_pwm1_device = { | ||
| 627 | .name = "ep93xx-pwm", | ||
| 628 | .id = 1, | ||
| 629 | .num_resources = ARRAY_SIZE(ep93xx_pwm1_resource), | ||
| 630 | .resource = ep93xx_pwm1_resource, | ||
| 631 | }; | ||
| 632 | |||
| 633 | void __init ep93xx_register_pwm(int pwm0, int pwm1) | ||
| 634 | { | ||
| 635 | if (pwm0) | ||
| 636 | platform_device_register(&ep93xx_pwm0_device); | ||
| 637 | |||
| 638 | /* NOTE: EP9307 does not have PWMOUT1 (pin EGPIO14) */ | ||
| 639 | if (pwm1) | ||
| 640 | platform_device_register(&ep93xx_pwm1_device); | ||
| 641 | } | ||
| 642 | |||
| 643 | int ep93xx_pwm_acquire_gpio(struct platform_device *pdev) | ||
| 644 | { | ||
| 645 | int err; | ||
| 646 | |||
| 647 | if (pdev->id == 0) { | ||
| 648 | err = 0; | ||
| 649 | } else if (pdev->id == 1) { | ||
| 650 | err = gpio_request(EP93XX_GPIO_LINE_EGPIO14, | ||
| 651 | dev_name(&pdev->dev)); | ||
| 652 | if (err) | ||
| 653 | return err; | ||
| 654 | err = gpio_direction_output(EP93XX_GPIO_LINE_EGPIO14, 0); | ||
| 655 | if (err) | ||
| 656 | goto fail; | ||
| 657 | |||
| 658 | /* PWM 1 output on EGPIO[14] */ | ||
| 659 | ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_PONG); | ||
| 660 | } else { | ||
| 661 | err = -ENODEV; | ||
| 662 | } | ||
| 663 | |||
| 664 | return err; | ||
| 665 | |||
| 666 | fail: | ||
| 667 | gpio_free(EP93XX_GPIO_LINE_EGPIO14); | ||
| 668 | return err; | ||
| 669 | } | ||
| 670 | EXPORT_SYMBOL(ep93xx_pwm_acquire_gpio); | ||
| 671 | |||
| 672 | void ep93xx_pwm_release_gpio(struct platform_device *pdev) | ||
| 673 | { | ||
| 674 | if (pdev->id == 1) { | ||
| 675 | gpio_direction_input(EP93XX_GPIO_LINE_EGPIO14); | ||
| 676 | gpio_free(EP93XX_GPIO_LINE_EGPIO14); | ||
| 677 | |||
| 678 | /* EGPIO[14] used for GPIO */ | ||
| 679 | ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_PONG); | ||
| 680 | } | ||
| 681 | } | ||
| 682 | EXPORT_SYMBOL(ep93xx_pwm_release_gpio); | ||
| 683 | |||
| 684 | |||
| 549 | extern void ep93xx_gpio_init(void); | 685 | extern void ep93xx_gpio_init(void); |
| 550 | 686 | ||
| 551 | void __init ep93xx_init_devices(void) | 687 | void __init ep93xx_init_devices(void) |
| 552 | { | 688 | { |
| 553 | unsigned int v; | 689 | /* Disallow access to MaverickCrunch initially */ |
| 554 | 690 | ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA); | |
| 555 | /* | ||
| 556 | * Disallow access to MaverickCrunch initially. | ||
| 557 | */ | ||
| 558 | v = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); | ||
| 559 | v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; | ||
| 560 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | ||
| 561 | __raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG); | ||
| 562 | 691 | ||
| 563 | ep93xx_gpio_init(); | 692 | ep93xx_gpio_init(); |
| 564 | 693 | ||
| @@ -568,4 +697,5 @@ void __init ep93xx_init_devices(void) | |||
| 568 | 697 | ||
| 569 | platform_device_register(&ep93xx_rtc_device); | 698 | platform_device_register(&ep93xx_rtc_device); |
| 570 | platform_device_register(&ep93xx_ohci_device); | 699 | platform_device_register(&ep93xx_ohci_device); |
| 700 | platform_device_register(&ep93xx_leds); | ||
| 571 | } | 701 | } |
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index e9e45b92457e..73145ae5d3fa 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c | |||
| @@ -26,18 +26,16 @@ | |||
| 26 | 26 | ||
| 27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
| 28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
| 29 | #include <linux/mm.h> | ||
| 30 | #include <linux/sched.h> | ||
| 31 | #include <linux/interrupt.h> | ||
| 32 | #include <linux/ioport.h> | ||
| 33 | #include <linux/mtd/physmap.h> | ||
| 34 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
| 35 | #include <linux/io.h> | ||
| 36 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
| 31 | #include <linux/mtd/physmap.h> | ||
| 32 | |||
| 37 | #include <mach/hardware.h> | 33 | #include <mach/hardware.h> |
| 34 | |||
| 38 | #include <asm/mach-types.h> | 35 | #include <asm/mach-types.h> |
| 39 | #include <asm/mach/arch.h> | 36 | #include <asm/mach/arch.h> |
| 40 | 37 | ||
| 38 | |||
| 41 | static struct physmap_flash_data edb93xx_flash_data; | 39 | static struct physmap_flash_data edb93xx_flash_data; |
| 42 | 40 | ||
| 43 | static struct resource edb93xx_flash_resource = { | 41 | static struct resource edb93xx_flash_resource = { |
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c index 3bad500b71b6..3da7ca816d19 100644 --- a/arch/arm/mach-ep93xx/gesbc9312.c +++ b/arch/arm/mach-ep93xx/gesbc9312.c | |||
| @@ -12,18 +12,15 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <linux/mm.h> | ||
| 16 | #include <linux/sched.h> | ||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/ioport.h> | ||
| 19 | #include <linux/mtd/physmap.h> | ||
| 20 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| 21 | #include <linux/io.h> | 16 | #include <linux/mtd/physmap.h> |
| 22 | #include <linux/i2c.h> | 17 | |
| 23 | #include <mach/hardware.h> | 18 | #include <mach/hardware.h> |
| 19 | |||
| 24 | #include <asm/mach-types.h> | 20 | #include <asm/mach-types.h> |
| 25 | #include <asm/mach/arch.h> | 21 | #include <asm/mach/arch.h> |
| 26 | 22 | ||
| 23 | |||
| 27 | static struct physmap_flash_data gesbc9312_flash_data = { | 24 | static struct physmap_flash_data gesbc9312_flash_data = { |
| 28 | .width = 4, | 25 | .width = 4, |
| 29 | }; | 26 | }; |
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c index 482cf3d2fbcd..1ea8871e03a9 100644 --- a/arch/arm/mach-ep93xx/gpio.c +++ b/arch/arm/mach-ep93xx/gpio.c | |||
| @@ -17,15 +17,16 @@ | |||
| 17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 18 | #include <linux/seq_file.h> | 18 | #include <linux/seq_file.h> |
| 19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
| 20 | #include <linux/gpio.h> | ||
| 21 | #include <linux/irq.h> | ||
| 20 | 22 | ||
| 21 | #include <mach/ep93xx-regs.h> | 23 | #include <mach/hardware.h> |
| 22 | #include <asm/gpio.h> | ||
| 23 | 24 | ||
| 24 | struct ep93xx_gpio_chip { | 25 | struct ep93xx_gpio_chip { |
| 25 | struct gpio_chip chip; | 26 | struct gpio_chip chip; |
| 26 | 27 | ||
| 27 | unsigned int data_reg; | 28 | void __iomem *data_reg; |
| 28 | unsigned int data_dir_reg; | 29 | void __iomem *data_dir_reg; |
| 29 | }; | 30 | }; |
| 30 | 31 | ||
| 31 | #define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip) | 32 | #define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip) |
| @@ -111,15 +112,61 @@ static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
| 111 | { | 112 | { |
| 112 | struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); | 113 | struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); |
| 113 | u8 data_reg, data_dir_reg; | 114 | u8 data_reg, data_dir_reg; |
| 114 | int i; | 115 | int gpio, i; |
| 115 | 116 | ||
| 116 | data_reg = __raw_readb(ep93xx_chip->data_reg); | 117 | data_reg = __raw_readb(ep93xx_chip->data_reg); |
| 117 | data_dir_reg = __raw_readb(ep93xx_chip->data_dir_reg); | 118 | data_dir_reg = __raw_readb(ep93xx_chip->data_dir_reg); |
| 118 | 119 | ||
| 119 | for (i = 0; i < chip->ngpio; i++) | 120 | gpio = ep93xx_chip->chip.base; |
| 120 | seq_printf(s, "GPIO %s%d: %s %s\n", chip->label, i, | 121 | for (i = 0; i < chip->ngpio; i++, gpio++) { |
| 121 | (data_reg & (1 << i)) ? "set" : "clear", | 122 | int is_out = data_dir_reg & (1 << i); |
| 122 | (data_dir_reg & (1 << i)) ? "out" : "in"); | 123 | |
| 124 | seq_printf(s, " %s%d gpio-%-3d (%-12s) %s %s", | ||
| 125 | chip->label, i, gpio, | ||
| 126 | gpiochip_is_requested(chip, i) ? : "", | ||
| 127 | is_out ? "out" : "in ", | ||
| 128 | (data_reg & (1 << i)) ? "hi" : "lo"); | ||
| 129 | |||
| 130 | if (!is_out) { | ||
| 131 | int irq = gpio_to_irq(gpio); | ||
| 132 | struct irq_desc *desc = irq_desc + irq; | ||
| 133 | |||
| 134 | if (irq >= 0 && desc->action) { | ||
| 135 | char *trigger; | ||
| 136 | |||
| 137 | switch (desc->status & IRQ_TYPE_SENSE_MASK) { | ||
| 138 | case IRQ_TYPE_NONE: | ||
| 139 | trigger = "(default)"; | ||
| 140 | break; | ||
| 141 | case IRQ_TYPE_EDGE_FALLING: | ||
| 142 | trigger = "edge-falling"; | ||
| 143 | break; | ||
| 144 | case IRQ_TYPE_EDGE_RISING: | ||
| 145 | trigger = "edge-rising"; | ||
| 146 | break; | ||
| 147 | case IRQ_TYPE_EDGE_BOTH: | ||
| 148 | trigger = "edge-both"; | ||
| 149 | break; | ||
| 150 | case IRQ_TYPE_LEVEL_HIGH: | ||
| 151 | trigger = "level-high"; | ||
| 152 | break; | ||
| 153 | case IRQ_TYPE_LEVEL_LOW: | ||
| 154 | trigger = "level-low"; | ||
| 155 | break; | ||
| 156 | default: | ||
| 157 | trigger = "?trigger?"; | ||
| 158 | break; | ||
| 159 | } | ||
| 160 | |||
| 161 | seq_printf(s, " irq-%d %s%s", | ||
| 162 | irq, trigger, | ||
| 163 | (desc->status & IRQ_WAKEUP) | ||
| 164 | ? " wakeup" : ""); | ||
| 165 | } | ||
| 166 | } | ||
| 167 | |||
| 168 | seq_printf(s, "\n"); | ||
| 169 | } | ||
| 123 | } | 170 | } |
| 124 | 171 | ||
| 125 | #define EP93XX_GPIO_BANK(name, dr, ddr, base_gpio) \ | 172 | #define EP93XX_GPIO_BANK(name, dr, ddr, base_gpio) \ |
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index 967c079180db..ea78e908fc82 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | |||
| @@ -52,40 +52,43 @@ | |||
| 52 | #define EP93XX_AHB_VIRT_BASE 0xfef00000 | 52 | #define EP93XX_AHB_VIRT_BASE 0xfef00000 |
| 53 | #define EP93XX_AHB_SIZE 0x00100000 | 53 | #define EP93XX_AHB_SIZE 0x00100000 |
| 54 | 54 | ||
| 55 | #define EP93XX_AHB_IOMEM(x) IOMEM(EP93XX_AHB_VIRT_BASE + (x)) | ||
| 56 | |||
| 55 | #define EP93XX_APB_PHYS_BASE 0x80800000 | 57 | #define EP93XX_APB_PHYS_BASE 0x80800000 |
| 56 | #define EP93XX_APB_VIRT_BASE 0xfed00000 | 58 | #define EP93XX_APB_VIRT_BASE 0xfed00000 |
| 57 | #define EP93XX_APB_SIZE 0x00200000 | 59 | #define EP93XX_APB_SIZE 0x00200000 |
| 58 | 60 | ||
| 61 | #define EP93XX_APB_IOMEM(x) IOMEM(EP93XX_APB_VIRT_BASE + (x)) | ||
| 62 | |||
| 59 | 63 | ||
| 60 | /* AHB peripherals */ | 64 | /* AHB peripherals */ |
| 61 | #define EP93XX_DMA_BASE ((void __iomem *) \ | 65 | #define EP93XX_DMA_BASE EP93XX_AHB_IOMEM(0x00000000) |
| 62 | (EP93XX_AHB_VIRT_BASE + 0x00000000)) | ||
| 63 | 66 | ||
| 64 | #define EP93XX_ETHERNET_BASE (EP93XX_AHB_VIRT_BASE + 0x00010000) | ||
| 65 | #define EP93XX_ETHERNET_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00010000) | 67 | #define EP93XX_ETHERNET_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00010000) |
| 68 | #define EP93XX_ETHERNET_BASE EP93XX_AHB_IOMEM(0x00010000) | ||
| 66 | 69 | ||
| 67 | #define EP93XX_USB_BASE (EP93XX_AHB_VIRT_BASE + 0x00020000) | ||
| 68 | #define EP93XX_USB_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00020000) | 70 | #define EP93XX_USB_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00020000) |
| 71 | #define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000) | ||
| 69 | 72 | ||
| 70 | #define EP93XX_RASTER_BASE (EP93XX_AHB_VIRT_BASE + 0x00030000) | 73 | #define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000) |
| 71 | 74 | ||
| 72 | #define EP93XX_GRAPHICS_ACCEL_BASE (EP93XX_AHB_VIRT_BASE + 0x00040000) | 75 | #define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000) |
| 73 | 76 | ||
| 74 | #define EP93XX_SDRAM_CONTROLLER_BASE (EP93XX_AHB_VIRT_BASE + 0x00060000) | 77 | #define EP93XX_SDRAM_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00060000) |
| 75 | 78 | ||
| 76 | #define EP93XX_PCMCIA_CONTROLLER_BASE (EP93XX_AHB_VIRT_BASE + 0x00080000) | 79 | #define EP93XX_PCMCIA_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00080000) |
| 77 | 80 | ||
| 78 | #define EP93XX_BOOT_ROM_BASE (EP93XX_AHB_VIRT_BASE + 0x00090000) | 81 | #define EP93XX_BOOT_ROM_BASE EP93XX_AHB_IOMEM(0x00090000) |
| 79 | 82 | ||
| 80 | #define EP93XX_IDE_BASE (EP93XX_AHB_VIRT_BASE + 0x000a0000) | 83 | #define EP93XX_IDE_BASE EP93XX_AHB_IOMEM(0x000a0000) |
| 81 | 84 | ||
| 82 | #define EP93XX_VIC1_BASE (EP93XX_AHB_VIRT_BASE + 0x000b0000) | 85 | #define EP93XX_VIC1_BASE EP93XX_AHB_IOMEM(0x000b0000) |
| 83 | 86 | ||
| 84 | #define EP93XX_VIC2_BASE (EP93XX_AHB_VIRT_BASE + 0x000c0000) | 87 | #define EP93XX_VIC2_BASE EP93XX_AHB_IOMEM(0x000c0000) |
| 85 | 88 | ||
| 86 | 89 | ||
| 87 | /* APB peripherals */ | 90 | /* APB peripherals */ |
| 88 | #define EP93XX_TIMER_BASE (EP93XX_APB_VIRT_BASE + 0x00010000) | 91 | #define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000) |
| 89 | #define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x)) | 92 | #define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x)) |
| 90 | #define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00) | 93 | #define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00) |
| 91 | #define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04) | 94 | #define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04) |
| @@ -102,11 +105,11 @@ | |||
| 102 | #define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88) | 105 | #define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88) |
| 103 | #define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c) | 106 | #define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c) |
| 104 | 107 | ||
| 105 | #define EP93XX_I2S_BASE (EP93XX_APB_VIRT_BASE + 0x00020000) | 108 | #define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000) |
| 106 | 109 | ||
| 107 | #define EP93XX_SECURITY_BASE (EP93XX_APB_VIRT_BASE + 0x00030000) | 110 | #define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000) |
| 108 | 111 | ||
| 109 | #define EP93XX_GPIO_BASE (EP93XX_APB_VIRT_BASE + 0x00040000) | 112 | #define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000) |
| 110 | #define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x)) | 113 | #define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x)) |
| 111 | #define EP93XX_GPIO_F_INT_TYPE1 EP93XX_GPIO_REG(0x4c) | 114 | #define EP93XX_GPIO_F_INT_TYPE1 EP93XX_GPIO_REG(0x4c) |
| 112 | #define EP93XX_GPIO_F_INT_TYPE2 EP93XX_GPIO_REG(0x50) | 115 | #define EP93XX_GPIO_F_INT_TYPE2 EP93XX_GPIO_REG(0x50) |
| @@ -124,32 +127,33 @@ | |||
| 124 | #define EP93XX_GPIO_B_INT_ENABLE EP93XX_GPIO_REG(0xb8) | 127 | #define EP93XX_GPIO_B_INT_ENABLE EP93XX_GPIO_REG(0xb8) |
| 125 | #define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc) | 128 | #define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc) |
| 126 | 129 | ||
| 127 | #define EP93XX_AAC_BASE (EP93XX_APB_VIRT_BASE + 0x00080000) | 130 | #define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000) |
| 128 | 131 | ||
| 129 | #define EP93XX_SPI_BASE (EP93XX_APB_VIRT_BASE + 0x000a0000) | 132 | #define EP93XX_SPI_BASE EP93XX_APB_IOMEM(0x000a0000) |
| 130 | 133 | ||
| 131 | #define EP93XX_IRDA_BASE (EP93XX_APB_VIRT_BASE + 0x000b0000) | 134 | #define EP93XX_IRDA_BASE EP93XX_APB_IOMEM(0x000b0000) |
| 132 | 135 | ||
| 133 | #define EP93XX_UART1_BASE (EP93XX_APB_VIRT_BASE + 0x000c0000) | ||
| 134 | #define EP93XX_UART1_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000c0000) | 136 | #define EP93XX_UART1_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000c0000) |
| 137 | #define EP93XX_UART1_BASE EP93XX_APB_IOMEM(0x000c0000) | ||
| 135 | 138 | ||
| 136 | #define EP93XX_UART2_BASE (EP93XX_APB_VIRT_BASE + 0x000d0000) | ||
| 137 | #define EP93XX_UART2_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000d0000) | 139 | #define EP93XX_UART2_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000d0000) |
| 140 | #define EP93XX_UART2_BASE EP93XX_APB_IOMEM(0x000d0000) | ||
| 138 | 141 | ||
| 139 | #define EP93XX_UART3_BASE (EP93XX_APB_VIRT_BASE + 0x000e0000) | ||
| 140 | #define EP93XX_UART3_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000e0000) | 142 | #define EP93XX_UART3_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000e0000) |
| 143 | #define EP93XX_UART3_BASE EP93XX_APB_IOMEM(0x000e0000) | ||
| 141 | 144 | ||
| 142 | #define EP93XX_KEY_MATRIX_BASE (EP93XX_APB_VIRT_BASE + 0x000f0000) | 145 | #define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000) |
| 143 | 146 | ||
| 144 | #define EP93XX_ADC_BASE (EP93XX_APB_VIRT_BASE + 0x00100000) | 147 | #define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000) |
| 145 | #define EP93XX_TOUCHSCREEN_BASE (EP93XX_APB_VIRT_BASE + 0x00100000) | 148 | #define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000) |
| 146 | 149 | ||
| 147 | #define EP93XX_PWM_BASE (EP93XX_APB_VIRT_BASE + 0x00110000) | 150 | #define EP93XX_PWM_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00110000) |
| 151 | #define EP93XX_PWM_BASE EP93XX_APB_IOMEM(0x00110000) | ||
| 148 | 152 | ||
| 149 | #define EP93XX_RTC_BASE (EP93XX_APB_VIRT_BASE + 0x00120000) | ||
| 150 | #define EP93XX_RTC_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00120000) | 153 | #define EP93XX_RTC_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00120000) |
| 154 | #define EP93XX_RTC_BASE EP93XX_APB_IOMEM(0x00120000) | ||
| 151 | 155 | ||
| 152 | #define EP93XX_SYSCON_BASE (EP93XX_APB_VIRT_BASE + 0x00130000) | 156 | #define EP93XX_SYSCON_BASE EP93XX_APB_IOMEM(0x00130000) |
| 153 | #define EP93XX_SYSCON_REG(x) (EP93XX_SYSCON_BASE + (x)) | 157 | #define EP93XX_SYSCON_REG(x) (EP93XX_SYSCON_BASE + (x)) |
| 154 | #define EP93XX_SYSCON_POWER_STATE EP93XX_SYSCON_REG(0x00) | 158 | #define EP93XX_SYSCON_POWER_STATE EP93XX_SYSCON_REG(0x00) |
| 155 | #define EP93XX_SYSCON_PWRCNT EP93XX_SYSCON_REG(0x04) | 159 | #define EP93XX_SYSCON_PWRCNT EP93XX_SYSCON_REG(0x04) |
| @@ -172,14 +176,45 @@ | |||
| 172 | #define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c) | 176 | #define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c) |
| 173 | #define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20) | 177 | #define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20) |
| 174 | #define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24) | 178 | #define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24) |
| 175 | #define EP93XX_SYSCON_DEVICE_CONFIG EP93XX_SYSCON_REG(0x80) | 179 | #define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80) |
| 176 | #define EP93XX_SYSCON_DEVICE_CONFIG_U3EN (1<<24) | 180 | #define EP93XX_SYSCON_DEVCFG_SWRST (1<<31) |
| 177 | #define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE (1<<23) | 181 | #define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30) |
| 178 | #define EP93XX_SYSCON_DEVICE_CONFIG_U2EN (1<<20) | 182 | #define EP93XX_SYSCON_DEVCFG_D0ONG (1<<29) |
| 179 | #define EP93XX_SYSCON_DEVICE_CONFIG_U1EN (1<<18) | 183 | #define EP93XX_SYSCON_DEVCFG_IONU2 (1<<28) |
| 184 | #define EP93XX_SYSCON_DEVCFG_GONK (1<<27) | ||
| 185 | #define EP93XX_SYSCON_DEVCFG_TONG (1<<26) | ||
| 186 | #define EP93XX_SYSCON_DEVCFG_MONG (1<<25) | ||
| 187 | #define EP93XX_SYSCON_DEVCFG_U3EN (1<<24) | ||
| 188 | #define EP93XX_SYSCON_DEVCFG_CPENA (1<<23) | ||
| 189 | #define EP93XX_SYSCON_DEVCFG_A2ONG (1<<22) | ||
| 190 | #define EP93XX_SYSCON_DEVCFG_A1ONG (1<<21) | ||
| 191 | #define EP93XX_SYSCON_DEVCFG_U2EN (1<<20) | ||
| 192 | #define EP93XX_SYSCON_DEVCFG_EXVC (1<<19) | ||
| 193 | #define EP93XX_SYSCON_DEVCFG_U1EN (1<<18) | ||
| 194 | #define EP93XX_SYSCON_DEVCFG_TIN (1<<17) | ||
| 195 | #define EP93XX_SYSCON_DEVCFG_HC3IN (1<<15) | ||
| 196 | #define EP93XX_SYSCON_DEVCFG_HC3EN (1<<14) | ||
| 197 | #define EP93XX_SYSCON_DEVCFG_HC1IN (1<<13) | ||
| 198 | #define EP93XX_SYSCON_DEVCFG_HC1EN (1<<12) | ||
| 199 | #define EP93XX_SYSCON_DEVCFG_HONIDE (1<<11) | ||
| 200 | #define EP93XX_SYSCON_DEVCFG_GONIDE (1<<10) | ||
| 201 | #define EP93XX_SYSCON_DEVCFG_PONG (1<<9) | ||
| 202 | #define EP93XX_SYSCON_DEVCFG_EONIDE (1<<8) | ||
| 203 | #define EP93XX_SYSCON_DEVCFG_I2SONSSP (1<<7) | ||
| 204 | #define EP93XX_SYSCON_DEVCFG_I2SONAC97 (1<<6) | ||
| 205 | #define EP93XX_SYSCON_DEVCFG_RASONP3 (1<<4) | ||
| 206 | #define EP93XX_SYSCON_DEVCFG_RAS (1<<3) | ||
| 207 | #define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2) | ||
| 208 | #define EP93XX_SYSCON_DEVCFG_KEYS (1<<1) | ||
| 209 | #define EP93XX_SYSCON_DEVCFG_SHENA (1<<0) | ||
| 210 | #define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90) | ||
| 211 | #define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31) | ||
| 212 | #define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16) | ||
| 213 | #define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15) | ||
| 214 | #define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0) | ||
| 180 | #define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) | 215 | #define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) |
| 181 | 216 | ||
| 182 | #define EP93XX_WATCHDOG_BASE (EP93XX_APB_VIRT_BASE + 0x00140000) | 217 | #define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000) |
| 183 | 218 | ||
| 184 | 219 | ||
| 185 | #endif | 220 | #endif |
diff --git a/arch/arm/mach-ep93xx/include/mach/hardware.h b/arch/arm/mach-ep93xx/include/mach/hardware.h index 2866297310b7..349fa7cb72d5 100644 --- a/arch/arm/mach-ep93xx/include/mach/hardware.h +++ b/arch/arm/mach-ep93xx/include/mach/hardware.h | |||
| @@ -4,12 +4,23 @@ | |||
| 4 | #ifndef __ASM_ARCH_HARDWARE_H | 4 | #ifndef __ASM_ARCH_HARDWARE_H |
| 5 | #define __ASM_ARCH_HARDWARE_H | 5 | #define __ASM_ARCH_HARDWARE_H |
| 6 | 6 | ||
| 7 | #include "ep93xx-regs.h" | 7 | #include <mach/ep93xx-regs.h> |
| 8 | #include <mach/platform.h> | ||
| 8 | 9 | ||
| 9 | #define pcibios_assign_all_busses() 0 | 10 | #define pcibios_assign_all_busses() 0 |
| 10 | 11 | ||
| 11 | #include "platform.h" | 12 | /* |
| 13 | * The EP93xx has two external crystal oscillators. To generate the | ||
| 14 | * required high-frequency clocks, the processor uses two phase-locked- | ||
| 15 | * loops (PLLs) to multiply the incoming external clock signal to much | ||
| 16 | * higher frequencies that are then divided down by programmable dividers | ||
| 17 | * to produce the needed clocks. The PLLs operate independently of one | ||
| 18 | * another. | ||
| 19 | */ | ||
| 20 | #define EP93XX_EXT_CLK_RATE 14745600 | ||
| 21 | #define EP93XX_EXT_RTC_RATE 32768 | ||
| 12 | 22 | ||
| 13 | #include "ts72xx.h" | 23 | #define EP93XX_KEYTCHCLK_DIV4 (EP93XX_EXT_CLK_RATE / 4) |
| 24 | #define EP93XX_KEYTCHCLK_DIV16 (EP93XX_EXT_CLK_RATE / 16) | ||
| 14 | 25 | ||
| 15 | #endif | 26 | #endif |
diff --git a/arch/arm/mach-ep93xx/include/mach/io.h b/arch/arm/mach-ep93xx/include/mach/io.h index fd5f081cc8b7..cebcc1c53d63 100644 --- a/arch/arm/mach-ep93xx/include/mach/io.h +++ b/arch/arm/mach-ep93xx/include/mach/io.h | |||
| @@ -1,8 +1,21 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * arch/arm/mach-ep93xx/include/mach/io.h | 2 | * arch/arm/mach-ep93xx/include/mach/io.h |
| 3 | */ | 3 | */ |
| 4 | #ifndef __ASM_MACH_IO_H | ||
| 5 | #define __ASM_MACH_IO_H | ||
| 4 | 6 | ||
| 5 | #define IO_SPACE_LIMIT 0xffffffff | 7 | #define IO_SPACE_LIMIT 0xffffffff |
| 6 | 8 | ||
| 7 | #define __io(p) __typesafe_io(p) | 9 | #define __io(p) __typesafe_io(p) |
| 8 | #define __mem_pci(p) (p) | 10 | #define __mem_pci(p) (p) |
| 11 | |||
| 12 | /* | ||
| 13 | * A typesafe __io() variation for variable initialisers | ||
| 14 | */ | ||
| 15 | #ifdef __ASSEMBLER__ | ||
| 16 | #define IOMEM(p) p | ||
| 17 | #else | ||
| 18 | #define IOMEM(p) ((void __iomem __force *)(p)) | ||
| 19 | #endif | ||
| 20 | |||
| 21 | #endif /* __ASM_MACH_IO_H */ | ||
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index 05f0f4f2f3ce..5f5fa6574d34 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #ifndef __ASSEMBLY__ | 5 | #ifndef __ASSEMBLY__ |
| 6 | 6 | ||
| 7 | struct i2c_board_info; | 7 | struct i2c_board_info; |
| 8 | struct platform_device; | ||
| 8 | 9 | ||
| 9 | struct ep93xx_eth_data | 10 | struct ep93xx_eth_data |
| 10 | { | 11 | { |
| @@ -15,8 +16,27 @@ struct ep93xx_eth_data | |||
| 15 | void ep93xx_map_io(void); | 16 | void ep93xx_map_io(void); |
| 16 | void ep93xx_init_irq(void); | 17 | void ep93xx_init_irq(void); |
| 17 | void ep93xx_init_time(unsigned long); | 18 | void ep93xx_init_time(unsigned long); |
| 19 | |||
| 20 | /* EP93xx System Controller software locked register write */ | ||
| 21 | void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg); | ||
| 22 | void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits); | ||
| 23 | |||
| 24 | static inline void ep93xx_devcfg_set_bits(unsigned int bits) | ||
| 25 | { | ||
| 26 | ep93xx_devcfg_set_clear(bits, 0x00); | ||
| 27 | } | ||
| 28 | |||
| 29 | static inline void ep93xx_devcfg_clear_bits(unsigned int bits) | ||
| 30 | { | ||
| 31 | ep93xx_devcfg_set_clear(0x00, bits); | ||
| 32 | } | ||
| 33 | |||
| 18 | void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); | 34 | void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); |
| 19 | void ep93xx_register_i2c(struct i2c_board_info *devices, int num); | 35 | void ep93xx_register_i2c(struct i2c_board_info *devices, int num); |
| 36 | void ep93xx_register_pwm(int pwm0, int pwm1); | ||
| 37 | int ep93xx_pwm_acquire_gpio(struct platform_device *pdev); | ||
| 38 | void ep93xx_pwm_release_gpio(struct platform_device *pdev); | ||
| 39 | |||
| 20 | void ep93xx_init_devices(void); | 40 | void ep93xx_init_devices(void); |
| 21 | extern struct sys_timer ep93xx_timer; | 41 | extern struct sys_timer ep93xx_timer; |
| 22 | 42 | ||
diff --git a/arch/arm/mach-ep93xx/include/mach/system.h b/arch/arm/mach-ep93xx/include/mach/system.h index ed8f35e4f068..6d661fe9d66c 100644 --- a/arch/arm/mach-ep93xx/include/mach/system.h +++ b/arch/arm/mach-ep93xx/include/mach/system.h | |||
| @@ -11,15 +11,13 @@ static inline void arch_idle(void) | |||
| 11 | 11 | ||
| 12 | static inline void arch_reset(char mode, const char *cmd) | 12 | static inline void arch_reset(char mode, const char *cmd) |
| 13 | { | 13 | { |
| 14 | u32 devicecfg; | ||
| 15 | |||
| 16 | local_irq_disable(); | 14 | local_irq_disable(); |
| 17 | 15 | ||
| 18 | devicecfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); | 16 | /* |
| 19 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | 17 | * Set then clear the SWRST bit to initiate a software reset |
| 20 | __raw_writel(devicecfg | 0x80000000, EP93XX_SYSCON_DEVICE_CONFIG); | 18 | */ |
| 21 | __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); | 19 | ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_SWRST); |
| 22 | __raw_writel(devicecfg & ~0x80000000, EP93XX_SYSCON_DEVICE_CONFIG); | 20 | ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_SWRST); |
| 23 | 21 | ||
| 24 | while (1) | 22 | while (1) |
| 25 | ; | 23 | ; |
diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h index 411734422c1d..3bd934e9a7f1 100644 --- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h +++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h | |||
| @@ -67,7 +67,6 @@ | |||
| 67 | 67 | ||
| 68 | 68 | ||
| 69 | #ifndef __ASSEMBLY__ | 69 | #ifndef __ASSEMBLY__ |
| 70 | #include <linux/io.h> | ||
| 71 | 70 | ||
| 72 | static inline int board_is_ts7200(void) | 71 | static inline int board_is_ts7200(void) |
| 73 | { | 72 | { |
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c index 15d6815d78c4..0a313e82fb74 100644 --- a/arch/arm/mach-ep93xx/micro9.c +++ b/arch/arm/mach-ep93xx/micro9.c | |||
| @@ -9,21 +9,16 @@ | |||
| 9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/interrupt.h> | ||
| 14 | #include <linux/ioport.h> | ||
| 15 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
| 16 | #include <linux/mm.h> | 13 | #include <linux/init.h> |
| 17 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 18 | #include <linux/sched.h> | ||
| 19 | #include <linux/io.h> | ||
| 20 | #include <linux/i2c.h> | ||
| 21 | #include <linux/mtd/physmap.h> | 15 | #include <linux/mtd/physmap.h> |
| 22 | 16 | ||
| 23 | #include <mach/hardware.h> | 17 | #include <mach/hardware.h> |
| 24 | 18 | ||
| 25 | #include <asm/mach/arch.h> | ||
| 26 | #include <asm/mach-types.h> | 19 | #include <asm/mach-types.h> |
| 20 | #include <asm/mach/arch.h> | ||
| 21 | |||
| 27 | 22 | ||
| 28 | static struct ep93xx_eth_data micro9_eth_data = { | 23 | static struct ep93xx_eth_data micro9_eth_data = { |
| 29 | .phy_id = 0x1f, | 24 | .phy_id = 0x1f, |
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index aaf1371412af..259f7822ba52 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c | |||
| @@ -12,19 +12,18 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <linux/mm.h> | ||
| 16 | #include <linux/sched.h> | ||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/ioport.h> | ||
| 19 | #include <linux/mtd/physmap.h> | ||
| 20 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| 21 | #include <linux/m48t86.h> | ||
| 22 | #include <linux/io.h> | 16 | #include <linux/io.h> |
| 23 | #include <linux/i2c.h> | 17 | #include <linux/m48t86.h> |
| 18 | #include <linux/mtd/physmap.h> | ||
| 19 | |||
| 24 | #include <mach/hardware.h> | 20 | #include <mach/hardware.h> |
| 21 | #include <mach/ts72xx.h> | ||
| 22 | |||
| 25 | #include <asm/mach-types.h> | 23 | #include <asm/mach-types.h> |
| 26 | #include <asm/mach/arch.h> | ||
| 27 | #include <asm/mach/map.h> | 24 | #include <asm/mach/map.h> |
| 25 | #include <asm/mach/arch.h> | ||
| 26 | |||
| 28 | 27 | ||
| 29 | static struct map_desc ts72xx_io_desc[] __initdata = { | 28 | static struct map_desc ts72xx_io_desc[] __initdata = { |
| 30 | { | 29 | { |
diff --git a/arch/arm/mach-integrator/include/mach/hardware.h b/arch/arm/mach-integrator/include/mach/hardware.h index 1251319ef9ae..d795642fad22 100644 --- a/arch/arm/mach-integrator/include/mach/hardware.h +++ b/arch/arm/mach-integrator/include/mach/hardware.h | |||
| @@ -36,8 +36,12 @@ | |||
| 36 | #define PCIO_BASE PCI_IO_VADDR | 36 | #define PCIO_BASE PCI_IO_VADDR |
| 37 | #define PCIMEM_BASE PCI_MEMORY_VADDR | 37 | #define PCIMEM_BASE PCI_MEMORY_VADDR |
| 38 | 38 | ||
| 39 | #ifdef CONFIG_MMU | ||
| 39 | /* macro to get at IO space when running virtually */ | 40 | /* macro to get at IO space when running virtually */ |
| 40 | #define IO_ADDRESS(x) (((x) >> 4) + IO_BASE) | 41 | #define IO_ADDRESS(x) (((x) >> 4) + IO_BASE) |
| 42 | #else | ||
| 43 | #define IO_ADDRESS(x) (x) | ||
| 44 | #endif | ||
| 41 | 45 | ||
| 42 | #define pcibios_assign_all_busses() 1 | 46 | #define pcibios_assign_all_busses() 1 |
| 43 | 47 | ||
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 4ac04055c2ea..2a318eba1b07 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c | |||
| @@ -49,14 +49,14 @@ | |||
| 49 | 49 | ||
| 50 | #define INTCP_PA_CLCD_BASE 0xc0000000 | 50 | #define INTCP_PA_CLCD_BASE 0xc0000000 |
| 51 | 51 | ||
| 52 | #define INTCP_VA_CIC_BASE 0xf1000040 | 52 | #define INTCP_VA_CIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + 0x40 |
| 53 | #define INTCP_VA_PIC_BASE 0xf1400000 | 53 | #define INTCP_VA_PIC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) |
| 54 | #define INTCP_VA_SIC_BASE 0xfca00000 | 54 | #define INTCP_VA_SIC_BASE IO_ADDRESS(0xca000000) |
| 55 | 55 | ||
| 56 | #define INTCP_PA_ETH_BASE 0xc8000000 | 56 | #define INTCP_PA_ETH_BASE 0xc8000000 |
| 57 | #define INTCP_ETH_SIZE 0x10 | 57 | #define INTCP_ETH_SIZE 0x10 |
| 58 | 58 | ||
| 59 | #define INTCP_VA_CTRL_BASE 0xfcb00000 | 59 | #define INTCP_VA_CTRL_BASE IO_ADDRESS(0xcb000000) |
| 60 | #define INTCP_FLASHPROG 0x04 | 60 | #define INTCP_FLASHPROG 0x04 |
| 61 | #define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0) | 61 | #define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0) |
| 62 | #define CINTEGRATOR_FLASHPROG_FLWREN (1 << 1) | 62 | #define CINTEGRATOR_FLASHPROG_FLWREN (1 << 1) |
| @@ -121,12 +121,12 @@ static struct map_desc intcp_io_desc[] __initdata = { | |||
| 121 | .length = SZ_4K, | 121 | .length = SZ_4K, |
| 122 | .type = MT_DEVICE | 122 | .type = MT_DEVICE |
| 123 | }, { | 123 | }, { |
| 124 | .virtual = 0xfca00000, | 124 | .virtual = IO_ADDRESS(0xca000000), |
| 125 | .pfn = __phys_to_pfn(0xca000000), | 125 | .pfn = __phys_to_pfn(0xca000000), |
| 126 | .length = SZ_4K, | 126 | .length = SZ_4K, |
| 127 | .type = MT_DEVICE | 127 | .type = MT_DEVICE |
| 128 | }, { | 128 | }, { |
| 129 | .virtual = 0xfcb00000, | 129 | .virtual = IO_ADDRESS(0xcb000000), |
| 130 | .pfn = __phys_to_pfn(0xcb000000), | 130 | .pfn = __phys_to_pfn(0xcb000000), |
| 131 | .length = SZ_4K, | 131 | .length = SZ_4K, |
| 132 | .type = MT_DEVICE | 132 | .type = MT_DEVICE |
| @@ -394,8 +394,8 @@ static struct platform_device *intcp_devs[] __initdata = { | |||
| 394 | */ | 394 | */ |
| 395 | static unsigned int mmc_status(struct device *dev) | 395 | static unsigned int mmc_status(struct device *dev) |
| 396 | { | 396 | { |
| 397 | unsigned int status = readl(0xfca00004); | 397 | unsigned int status = readl(IO_ADDRESS(0xca000000) + 4); |
| 398 | writel(8, 0xfcb00008); | 398 | writel(8, IO_ADDRESS(0xcb000000) + 8); |
| 399 | 399 | ||
| 400 | return status & 8; | 400 | return status & 8; |
| 401 | } | 401 | } |
| @@ -403,6 +403,8 @@ static unsigned int mmc_status(struct device *dev) | |||
| 403 | static struct mmc_platform_data mmc_data = { | 403 | static struct mmc_platform_data mmc_data = { |
| 404 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | 404 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, |
| 405 | .status = mmc_status, | 405 | .status = mmc_status, |
| 406 | .gpio_wp = -1, | ||
| 407 | .gpio_cd = -1, | ||
| 406 | }; | 408 | }; |
| 407 | 409 | ||
| 408 | static struct amba_device mmc_device = { | 410 | static struct amba_device mmc_device = { |
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 1e93dfee7543..5083f03e9b5e 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c | |||
| @@ -416,6 +416,7 @@ static struct clocksource clocksource_ixp4xx = { | |||
| 416 | }; | 416 | }; |
| 417 | 417 | ||
| 418 | unsigned long ixp4xx_timer_freq = FREQ; | 418 | unsigned long ixp4xx_timer_freq = FREQ; |
| 419 | EXPORT_SYMBOL(ixp4xx_timer_freq); | ||
| 419 | static int __init ixp4xx_clocksource_init(void) | 420 | static int __init ixp4xx_clocksource_init(void) |
| 420 | { | 421 | { |
| 421 | clocksource_ixp4xx.mult = | 422 | clocksource_ixp4xx.mult = |
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 25100f7acf4c..0aca451b216d 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig | |||
| @@ -38,6 +38,12 @@ config MACH_TS219 | |||
| 38 | Say 'Y' here if you want your kernel to support the | 38 | Say 'Y' here if you want your kernel to support the |
| 39 | QNAP TS-119 and TS-219 Turbo NAS devices. | 39 | QNAP TS-119 and TS-219 Turbo NAS devices. |
| 40 | 40 | ||
| 41 | config MACH_OPENRD_BASE | ||
| 42 | bool "Marvell OpenRD Base Board" | ||
| 43 | help | ||
| 44 | Say 'Y' here if you want your kernel to support the | ||
| 45 | Marvell OpenRD Base Board. | ||
| 46 | |||
| 41 | endmenu | 47 | endmenu |
| 42 | 48 | ||
| 43 | endif | 49 | endif |
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index 9dd680e964d6..80ab0ec90ee1 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile | |||
| @@ -6,5 +6,6 @@ obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o | |||
| 6 | obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o | 6 | obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o |
| 7 | obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o | 7 | obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o |
| 8 | obj-$(CONFIG_MACH_TS219) += ts219-setup.o | 8 | obj-$(CONFIG_MACH_TS219) += ts219-setup.o |
| 9 | obj-$(CONFIG_MACH_OPENRD_BASE) += openrd_base-setup.o | ||
| 9 | 10 | ||
| 10 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | 11 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o |
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 0f6919838011..0acb61f3c10b 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c | |||
| @@ -838,7 +838,8 @@ int __init kirkwood_find_tclk(void) | |||
| 838 | u32 dev, rev; | 838 | u32 dev, rev; |
| 839 | 839 | ||
| 840 | kirkwood_pcie_id(&dev, &rev); | 840 | kirkwood_pcie_id(&dev, &rev); |
| 841 | if (dev == MV88F6281_DEV_ID && rev == MV88F6281_REV_A0) | 841 | if (dev == MV88F6281_DEV_ID && (rev == MV88F6281_REV_A0 || |
| 842 | rev == MV88F6281_REV_A1)) | ||
| 842 | return 200000000; | 843 | return 200000000; |
| 843 | 844 | ||
| 844 | return 166666667; | 845 | return 166666667; |
| @@ -872,6 +873,8 @@ static char * __init kirkwood_id(void) | |||
| 872 | return "MV88F6281-Z0"; | 873 | return "MV88F6281-Z0"; |
| 873 | else if (rev == MV88F6281_REV_A0) | 874 | else if (rev == MV88F6281_REV_A0) |
| 874 | return "MV88F6281-A0"; | 875 | return "MV88F6281-A0"; |
| 876 | else if (rev == MV88F6281_REV_A1) | ||
| 877 | return "MV88F6281-A1"; | ||
| 875 | else | 878 | else |
| 876 | return "MV88F6281-Rev-Unsupported"; | 879 | return "MV88F6281-Rev-Unsupported"; |
| 877 | } else if (dev == MV88F6192_DEV_ID) { | 880 | } else if (dev == MV88F6192_DEV_ID) { |
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h index 07af858814a0..54c132731d2d 100644 --- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h | |||
| @@ -101,6 +101,7 @@ | |||
| 101 | #define MV88F6281_DEV_ID 0x6281 | 101 | #define MV88F6281_DEV_ID 0x6281 |
| 102 | #define MV88F6281_REV_Z0 0 | 102 | #define MV88F6281_REV_Z0 0 |
| 103 | #define MV88F6281_REV_A0 2 | 103 | #define MV88F6281_REV_A0 2 |
| 104 | #define MV88F6281_REV_A1 3 | ||
| 104 | 105 | ||
| 105 | #define MV88F6192_DEV_ID 0x6192 | 106 | #define MV88F6192_DEV_ID 0x6192 |
| 106 | #define MV88F6192_REV_Z0 0 | 107 | #define MV88F6192_REV_Z0 0 |
diff --git a/arch/arm/mach-kirkwood/openrd_base-setup.c b/arch/arm/mach-kirkwood/openrd_base-setup.c new file mode 100644 index 000000000000..947dfb8cd5b2 --- /dev/null +++ b/arch/arm/mach-kirkwood/openrd_base-setup.c | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/mach-kirkwood/openrd_base-setup.c | ||
| 3 | * | ||
| 4 | * Marvell OpenRD Base Board Setup | ||
| 5 | * | ||
| 6 | * This file is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2. This program is licensed "as is" without any | ||
| 8 | * warranty of any kind, whether express or implied. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/mtd/partitions.h> | ||
| 15 | #include <linux/ata_platform.h> | ||
| 16 | #include <linux/mv643xx_eth.h> | ||
| 17 | #include <asm/mach-types.h> | ||
| 18 | #include <asm/mach/arch.h> | ||
| 19 | #include <mach/kirkwood.h> | ||
| 20 | #include <plat/mvsdio.h> | ||
| 21 | #include "common.h" | ||
| 22 | #include "mpp.h" | ||
| 23 | |||
| 24 | static struct mtd_partition openrd_base_nand_parts[] = { | ||
| 25 | { | ||
| 26 | .name = "u-boot", | ||
| 27 | .offset = 0, | ||
| 28 | .size = SZ_1M | ||
| 29 | }, { | ||
| 30 | .name = "uImage", | ||
| 31 | .offset = MTDPART_OFS_NXTBLK, | ||
| 32 | .size = SZ_4M | ||
| 33 | }, { | ||
| 34 | .name = "root", | ||
| 35 | .offset = MTDPART_OFS_NXTBLK, | ||
| 36 | .size = MTDPART_SIZ_FULL | ||
| 37 | }, | ||
| 38 | }; | ||
| 39 | |||
| 40 | static struct mv643xx_eth_platform_data openrd_base_ge00_data = { | ||
| 41 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), | ||
| 42 | }; | ||
| 43 | |||
| 44 | static struct mv_sata_platform_data openrd_base_sata_data = { | ||
| 45 | .n_ports = 2, | ||
| 46 | }; | ||
| 47 | |||
| 48 | static struct mvsdio_platform_data openrd_base_mvsdio_data = { | ||
| 49 | .gpio_card_detect = 29, /* MPP29 used as SD card detect */ | ||
| 50 | }; | ||
| 51 | |||
| 52 | static unsigned int openrd_base_mpp_config[] __initdata = { | ||
| 53 | MPP29_GPIO, | ||
| 54 | 0 | ||
| 55 | }; | ||
| 56 | |||
| 57 | static void __init openrd_base_init(void) | ||
| 58 | { | ||
| 59 | /* | ||
| 60 | * Basic setup. Needs to be called early. | ||
| 61 | */ | ||
| 62 | kirkwood_init(); | ||
| 63 | kirkwood_mpp_conf(openrd_base_mpp_config); | ||
| 64 | |||
| 65 | kirkwood_uart0_init(); | ||
| 66 | kirkwood_nand_init(ARRAY_AND_SIZE(openrd_base_nand_parts), 25); | ||
| 67 | |||
| 68 | kirkwood_ehci_init(); | ||
| 69 | |||
| 70 | kirkwood_ge00_init(&openrd_base_ge00_data); | ||
| 71 | kirkwood_sata_init(&openrd_base_sata_data); | ||
| 72 | kirkwood_sdio_init(&openrd_base_mvsdio_data); | ||
| 73 | } | ||
| 74 | |||
| 75 | MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board") | ||
| 76 | /* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */ | ||
| 77 | .phys_io = KIRKWOOD_REGS_PHYS_BASE, | ||
| 78 | .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, | ||
| 79 | .boot_params = 0x00000100, | ||
| 80 | .init_machine = openrd_base_init, | ||
| 81 | .map_io = kirkwood_map_io, | ||
| 82 | .init_irq = kirkwood_init_irq, | ||
| 83 | .timer = &kirkwood_timer, | ||
| 84 | MACHINE_END | ||
diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c index 01aa213c0a6f..ec1a64f263d2 100644 --- a/arch/arm/mach-kirkwood/ts219-setup.c +++ b/arch/arm/mach-kirkwood/ts219-setup.c | |||
| @@ -206,6 +206,15 @@ static void __init qnap_ts219_init(void) | |||
| 206 | 206 | ||
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | static int __init ts219_pci_init(void) | ||
| 210 | { | ||
| 211 | if (machine_is_ts219()) | ||
| 212 | kirkwood_pcie_init(); | ||
| 213 | |||
| 214 | return 0; | ||
| 215 | } | ||
| 216 | subsys_initcall(ts219_pci_init); | ||
| 217 | |||
| 209 | MACHINE_START(TS219, "QNAP TS-119/TS-219") | 218 | MACHINE_START(TS219, "QNAP TS-119/TS-219") |
| 210 | /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */ | 219 | /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */ |
| 211 | .phys_io = KIRKWOOD_REGS_PHYS_BASE, | 220 | .phys_io = KIRKWOOD_REGS_PHYS_BASE, |
diff --git a/arch/arm/mach-mx1/clock.c b/arch/arm/mach-mx1/clock.c index 0d0f306851d0..d1b588519ad2 100644 --- a/arch/arm/mach-mx1/clock.c +++ b/arch/arm/mach-mx1/clock.c | |||
| @@ -18,11 +18,14 @@ | |||
| 18 | 18 | ||
| 19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
| 20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
| 21 | #include <linux/list.h> | ||
| 21 | #include <linux/math64.h> | 22 | #include <linux/math64.h> |
| 22 | #include <linux/err.h> | 23 | #include <linux/err.h> |
| 23 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
| 24 | #include <linux/io.h> | 25 | #include <linux/io.h> |
| 25 | 26 | ||
| 27 | #include <asm/clkdev.h> | ||
| 28 | |||
| 26 | #include <mach/clock.h> | 29 | #include <mach/clock.h> |
| 27 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
| 28 | #include <mach/common.h> | 31 | #include <mach/common.h> |
| @@ -94,7 +97,6 @@ static unsigned long clk16m_get_rate(struct clk *clk) | |||
| 94 | } | 97 | } |
| 95 | 98 | ||
| 96 | static struct clk clk16m = { | 99 | static struct clk clk16m = { |
| 97 | .name = "CLK16M", | ||
| 98 | .get_rate = clk16m_get_rate, | 100 | .get_rate = clk16m_get_rate, |
| 99 | .enable = _clk_enable, | 101 | .enable = _clk_enable, |
| 100 | .enable_reg = CCM_CSCR, | 102 | .enable_reg = CCM_CSCR, |
| @@ -111,7 +113,6 @@ static unsigned long clk32_get_rate(struct clk *clk) | |||
| 111 | } | 113 | } |
| 112 | 114 | ||
| 113 | static struct clk clk32 = { | 115 | static struct clk clk32 = { |
| 114 | .name = "CLK32", | ||
| 115 | .get_rate = clk32_get_rate, | 116 | .get_rate = clk32_get_rate, |
| 116 | }; | 117 | }; |
| 117 | 118 | ||
| @@ -121,7 +122,6 @@ static unsigned long clk32_premult_get_rate(struct clk *clk) | |||
| 121 | } | 122 | } |
| 122 | 123 | ||
| 123 | static struct clk clk32_premult = { | 124 | static struct clk clk32_premult = { |
| 124 | .name = "CLK32_premultiplier", | ||
| 125 | .parent = &clk32, | 125 | .parent = &clk32, |
| 126 | .get_rate = clk32_premult_get_rate, | 126 | .get_rate = clk32_premult_get_rate, |
| 127 | }; | 127 | }; |
| @@ -156,7 +156,6 @@ static int prem_clk_set_parent(struct clk *clk, struct clk *parent) | |||
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | static struct clk prem_clk = { | 158 | static struct clk prem_clk = { |
| 159 | .name = "prem_clk", | ||
| 160 | .set_parent = prem_clk_set_parent, | 159 | .set_parent = prem_clk_set_parent, |
| 161 | }; | 160 | }; |
| 162 | 161 | ||
| @@ -167,7 +166,6 @@ static unsigned long system_clk_get_rate(struct clk *clk) | |||
| 167 | } | 166 | } |
| 168 | 167 | ||
| 169 | static struct clk system_clk = { | 168 | static struct clk system_clk = { |
| 170 | .name = "system_clk", | ||
| 171 | .parent = &prem_clk, | 169 | .parent = &prem_clk, |
| 172 | .get_rate = system_clk_get_rate, | 170 | .get_rate = system_clk_get_rate, |
| 173 | }; | 171 | }; |
| @@ -179,7 +177,6 @@ static unsigned long mcu_clk_get_rate(struct clk *clk) | |||
| 179 | } | 177 | } |
| 180 | 178 | ||
| 181 | static struct clk mcu_clk = { | 179 | static struct clk mcu_clk = { |
| 182 | .name = "mcu_clk", | ||
| 183 | .parent = &clk32_premult, | 180 | .parent = &clk32_premult, |
| 184 | .get_rate = mcu_clk_get_rate, | 181 | .get_rate = mcu_clk_get_rate, |
| 185 | }; | 182 | }; |
| @@ -195,7 +192,6 @@ static unsigned long fclk_get_rate(struct clk *clk) | |||
| 195 | } | 192 | } |
| 196 | 193 | ||
| 197 | static struct clk fclk = { | 194 | static struct clk fclk = { |
| 198 | .name = "fclk", | ||
| 199 | .parent = &mcu_clk, | 195 | .parent = &mcu_clk, |
| 200 | .get_rate = fclk_get_rate, | 196 | .get_rate = fclk_get_rate, |
| 201 | }; | 197 | }; |
| @@ -238,7 +234,6 @@ static int hclk_set_rate(struct clk *clk, unsigned long rate) | |||
| 238 | } | 234 | } |
| 239 | 235 | ||
| 240 | static struct clk hclk = { | 236 | static struct clk hclk = { |
| 241 | .name = "hclk", | ||
| 242 | .parent = &system_clk, | 237 | .parent = &system_clk, |
| 243 | .get_rate = hclk_get_rate, | 238 | .get_rate = hclk_get_rate, |
| 244 | .round_rate = hclk_round_rate, | 239 | .round_rate = hclk_round_rate, |
| @@ -280,7 +275,6 @@ static int clk48m_set_rate(struct clk *clk, unsigned long rate) | |||
| 280 | } | 275 | } |
| 281 | 276 | ||
| 282 | static struct clk clk48m = { | 277 | static struct clk clk48m = { |
| 283 | .name = "CLK48M", | ||
| 284 | .parent = &system_clk, | 278 | .parent = &system_clk, |
| 285 | .get_rate = clk48m_get_rate, | 279 | .get_rate = clk48m_get_rate, |
| 286 | .round_rate = clk48m_round_rate, | 280 | .round_rate = clk48m_round_rate, |
| @@ -400,21 +394,18 @@ static int perclk3_set_rate(struct clk *clk, unsigned long rate) | |||
| 400 | 394 | ||
| 401 | static struct clk perclk[] = { | 395 | static struct clk perclk[] = { |
| 402 | { | 396 | { |
| 403 | .name = "perclk", | ||
| 404 | .id = 0, | 397 | .id = 0, |
| 405 | .parent = &system_clk, | 398 | .parent = &system_clk, |
| 406 | .get_rate = perclk1_get_rate, | 399 | .get_rate = perclk1_get_rate, |
| 407 | .round_rate = perclk1_round_rate, | 400 | .round_rate = perclk1_round_rate, |
| 408 | .set_rate = perclk1_set_rate, | 401 | .set_rate = perclk1_set_rate, |
| 409 | }, { | 402 | }, { |
| 410 | .name = "perclk", | ||
| 411 | .id = 1, | 403 | .id = 1, |
| 412 | .parent = &system_clk, | 404 | .parent = &system_clk, |
| 413 | .get_rate = perclk2_get_rate, | 405 | .get_rate = perclk2_get_rate, |
| 414 | .round_rate = perclk2_round_rate, | 406 | .round_rate = perclk2_round_rate, |
| 415 | .set_rate = perclk2_set_rate, | 407 | .set_rate = perclk2_set_rate, |
| 416 | }, { | 408 | }, { |
| 417 | .name = "perclk", | ||
| 418 | .id = 2, | 409 | .id = 2, |
| 419 | .parent = &system_clk, | 410 | .parent = &system_clk, |
| 420 | .get_rate = perclk3_get_rate, | 411 | .get_rate = perclk3_get_rate, |
| @@ -457,12 +448,10 @@ static int clko_set_parent(struct clk *clk, struct clk *parent) | |||
| 457 | } | 448 | } |
| 458 | 449 | ||
| 459 | static struct clk clko_clk = { | 450 | static struct clk clko_clk = { |
| 460 | .name = "clko_clk", | ||
| 461 | .set_parent = clko_set_parent, | 451 | .set_parent = clko_set_parent, |
| 462 | }; | 452 | }; |
| 463 | 453 | ||
| 464 | static struct clk dma_clk = { | 454 | static struct clk dma_clk = { |
| 465 | .name = "dma", | ||
| 466 | .parent = &hclk, | 455 | .parent = &hclk, |
| 467 | .round_rate = _clk_parent_round_rate, | 456 | .round_rate = _clk_parent_round_rate, |
| 468 | .set_rate = _clk_parent_set_rate, | 457 | .set_rate = _clk_parent_set_rate, |
| @@ -473,7 +462,6 @@ static struct clk dma_clk = { | |||
| 473 | }; | 462 | }; |
| 474 | 463 | ||
| 475 | static struct clk csi_clk = { | 464 | static struct clk csi_clk = { |
| 476 | .name = "csi_clk", | ||
| 477 | .parent = &hclk, | 465 | .parent = &hclk, |
| 478 | .round_rate = _clk_parent_round_rate, | 466 | .round_rate = _clk_parent_round_rate, |
| 479 | .set_rate = _clk_parent_set_rate, | 467 | .set_rate = _clk_parent_set_rate, |
| @@ -484,7 +472,6 @@ static struct clk csi_clk = { | |||
| 484 | }; | 472 | }; |
| 485 | 473 | ||
| 486 | static struct clk mma_clk = { | 474 | static struct clk mma_clk = { |
| 487 | .name = "mma_clk", | ||
| 488 | .parent = &hclk, | 475 | .parent = &hclk, |
| 489 | .round_rate = _clk_parent_round_rate, | 476 | .round_rate = _clk_parent_round_rate, |
| 490 | .set_rate = _clk_parent_set_rate, | 477 | .set_rate = _clk_parent_set_rate, |
| @@ -495,7 +482,6 @@ static struct clk mma_clk = { | |||
| 495 | }; | 482 | }; |
| 496 | 483 | ||
| 497 | static struct clk usbd_clk = { | 484 | static struct clk usbd_clk = { |
| 498 | .name = "usbd_clk", | ||
| 499 | .parent = &clk48m, | 485 | .parent = &clk48m, |
| 500 | .round_rate = _clk_parent_round_rate, | 486 | .round_rate = _clk_parent_round_rate, |
| 501 | .set_rate = _clk_parent_set_rate, | 487 | .set_rate = _clk_parent_set_rate, |
| @@ -506,99 +492,85 @@ static struct clk usbd_clk = { | |||
| 506 | }; | 492 | }; |
| 507 | 493 | ||
| 508 | static struct clk gpt_clk = { | 494 | static struct clk gpt_clk = { |
| 509 | .name = "gpt_clk", | ||
| 510 | .parent = &perclk[0], | 495 | .parent = &perclk[0], |
| 511 | .round_rate = _clk_parent_round_rate, | 496 | .round_rate = _clk_parent_round_rate, |
| 512 | .set_rate = _clk_parent_set_rate, | 497 | .set_rate = _clk_parent_set_rate, |
| 513 | }; | 498 | }; |
| 514 | 499 | ||
| 515 | static struct clk uart_clk = { | 500 | static struct clk uart_clk = { |
| 516 | .name = "uart", | ||
| 517 | .parent = &perclk[0], | 501 | .parent = &perclk[0], |
| 518 | .round_rate = _clk_parent_round_rate, | 502 | .round_rate = _clk_parent_round_rate, |
| 519 | .set_rate = _clk_parent_set_rate, | 503 | .set_rate = _clk_parent_set_rate, |
| 520 | }; | 504 | }; |
| 521 | 505 | ||
| 522 | static struct clk i2c_clk = { | 506 | static struct clk i2c_clk = { |
| 523 | .name = "i2c_clk", | ||
| 524 | .parent = &hclk, | 507 | .parent = &hclk, |
| 525 | .round_rate = _clk_parent_round_rate, | 508 | .round_rate = _clk_parent_round_rate, |
| 526 | .set_rate = _clk_parent_set_rate, | 509 | .set_rate = _clk_parent_set_rate, |
| 527 | }; | 510 | }; |
| 528 | 511 | ||
| 529 | static struct clk spi_clk = { | 512 | static struct clk spi_clk = { |
| 530 | .name = "spi_clk", | ||
| 531 | .parent = &perclk[1], | 513 | .parent = &perclk[1], |
| 532 | .round_rate = _clk_parent_round_rate, | 514 | .round_rate = _clk_parent_round_rate, |
| 533 | .set_rate = _clk_parent_set_rate, | 515 | .set_rate = _clk_parent_set_rate, |
| 534 | }; | 516 | }; |
| 535 | 517 | ||
| 536 | static struct clk sdhc_clk = { | 518 | static struct clk sdhc_clk = { |
| 537 | .name = "sdhc_clk", | ||
| 538 | .parent = &perclk[1], | 519 | .parent = &perclk[1], |
| 539 | .round_rate = _clk_parent_round_rate, | 520 | .round_rate = _clk_parent_round_rate, |
| 540 | .set_rate = _clk_parent_set_rate, | 521 | .set_rate = _clk_parent_set_rate, |
| 541 | }; | 522 | }; |
| 542 | 523 | ||
| 543 | static struct clk lcdc_clk = { | 524 | static struct clk lcdc_clk = { |
| 544 | .name = "lcdc_clk", | ||
| 545 | .parent = &perclk[1], | 525 | .parent = &perclk[1], |
| 546 | .round_rate = _clk_parent_round_rate, | 526 | .round_rate = _clk_parent_round_rate, |
| 547 | .set_rate = _clk_parent_set_rate, | 527 | .set_rate = _clk_parent_set_rate, |
| 548 | }; | 528 | }; |
| 549 | 529 | ||
| 550 | static struct clk mshc_clk = { | 530 | static struct clk mshc_clk = { |
| 551 | .name = "mshc_clk", | ||
| 552 | .parent = &hclk, | 531 | .parent = &hclk, |
| 553 | .round_rate = _clk_parent_round_rate, | 532 | .round_rate = _clk_parent_round_rate, |
| 554 | .set_rate = _clk_parent_set_rate, | 533 | .set_rate = _clk_parent_set_rate, |
| 555 | }; | 534 | }; |
| 556 | 535 | ||
| 557 | static struct clk ssi_clk = { | 536 | static struct clk ssi_clk = { |
| 558 | .name = "ssi_clk", | ||
| 559 | .parent = &perclk[2], | 537 | .parent = &perclk[2], |
| 560 | .round_rate = _clk_parent_round_rate, | 538 | .round_rate = _clk_parent_round_rate, |
| 561 | .set_rate = _clk_parent_set_rate, | 539 | .set_rate = _clk_parent_set_rate, |
| 562 | }; | 540 | }; |
| 563 | 541 | ||
| 564 | static struct clk rtc_clk = { | 542 | static struct clk rtc_clk = { |
| 565 | .name = "rtc_clk", | ||
| 566 | .parent = &clk32, | 543 | .parent = &clk32, |
| 567 | }; | 544 | }; |
| 568 | 545 | ||
| 569 | static struct clk *mxc_clks[] = { | 546 | #define _REGISTER_CLOCK(d, n, c) \ |
| 570 | &clk16m, | 547 | { \ |
| 571 | &clk32, | 548 | .dev_id = d, \ |
| 572 | &clk32_premult, | 549 | .con_id = n, \ |
| 573 | &prem_clk, | 550 | .clk = &c, \ |
| 574 | &system_clk, | 551 | }, |
| 575 | &mcu_clk, | 552 | static struct clk_lookup lookups[] __initdata = { |
| 576 | &fclk, | 553 | _REGISTER_CLOCK(NULL, "dma", dma_clk) |
| 577 | &hclk, | 554 | _REGISTER_CLOCK("mx1-camera.0", NULL, csi_clk) |
| 578 | &clk48m, | 555 | _REGISTER_CLOCK(NULL, "mma", mma_clk) |
| 579 | &perclk[0], | 556 | _REGISTER_CLOCK("imx_udc.0", NULL, usbd_clk) |
| 580 | &perclk[1], | 557 | _REGISTER_CLOCK(NULL, "gpt", gpt_clk) |
| 581 | &perclk[2], | 558 | _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk) |
| 582 | &clko_clk, | 559 | _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk) |
| 583 | &dma_clk, | 560 | _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk) |
| 584 | &csi_clk, | 561 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) |
| 585 | &mma_clk, | 562 | _REGISTER_CLOCK("spi_imx.0", NULL, spi_clk) |
| 586 | &usbd_clk, | 563 | _REGISTER_CLOCK("imx-mmc.0", NULL, sdhc_clk) |
| 587 | &gpt_clk, | 564 | _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) |
| 588 | &uart_clk, | 565 | _REGISTER_CLOCK(NULL, "mshc", mshc_clk) |
| 589 | &i2c_clk, | 566 | _REGISTER_CLOCK(NULL, "ssi", ssi_clk) |
| 590 | &spi_clk, | 567 | _REGISTER_CLOCK("mxc_rtc.0", NULL, rtc_clk) |
| 591 | &sdhc_clk, | ||
| 592 | &lcdc_clk, | ||
| 593 | &mshc_clk, | ||
| 594 | &ssi_clk, | ||
| 595 | &rtc_clk, | ||
| 596 | }; | 568 | }; |
| 597 | 569 | ||
| 598 | int __init mx1_clocks_init(unsigned long fref) | 570 | int __init mx1_clocks_init(unsigned long fref) |
| 599 | { | 571 | { |
| 600 | struct clk **clkp; | ||
| 601 | unsigned int reg; | 572 | unsigned int reg; |
| 573 | int i; | ||
| 602 | 574 | ||
| 603 | /* disable clocks we are able to */ | 575 | /* disable clocks we are able to */ |
| 604 | __raw_writel(0, SCM_GCCR); | 576 | __raw_writel(0, SCM_GCCR); |
| @@ -620,13 +592,13 @@ int __init mx1_clocks_init(unsigned long fref) | |||
| 620 | reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET; | 592 | reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET; |
| 621 | clko_clk.parent = (struct clk *)clko_clocks[reg]; | 593 | clko_clk.parent = (struct clk *)clko_clocks[reg]; |
| 622 | 594 | ||
| 623 | for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) | 595 | for (i = 0; i < ARRAY_SIZE(lookups); i++) |
| 624 | clk_register(*clkp); | 596 | clkdev_add(&lookups[i]); |
| 625 | 597 | ||
| 626 | clk_enable(&hclk); | 598 | clk_enable(&hclk); |
| 627 | clk_enable(&fclk); | 599 | clk_enable(&fclk); |
| 628 | 600 | ||
| 629 | mxc_timer_init(&gpt_clk); | 601 | mxc_timer_init(&gpt_clk, IO_ADDRESS(TIM1_BASE_ADDR), TIM1_INT); |
| 630 | 602 | ||
| 631 | return 0; | 603 | return 0; |
| 632 | } | 604 | } |
diff --git a/arch/arm/mach-mx1/devices.c b/arch/arm/mach-mx1/devices.c index 76d1ffb48079..b6be29d1cb08 100644 --- a/arch/arm/mach-mx1/devices.c +++ b/arch/arm/mach-mx1/devices.c | |||
| @@ -29,12 +29,11 @@ | |||
| 29 | #include "devices.h" | 29 | #include "devices.h" |
| 30 | 30 | ||
| 31 | static struct resource imx_csi_resources[] = { | 31 | static struct resource imx_csi_resources[] = { |
| 32 | [0] = { | 32 | { |
| 33 | .start = 0x00224000, | 33 | .start = 0x00224000, |
| 34 | .end = 0x00224010, | 34 | .end = 0x00224010, |
| 35 | .flags = IORESOURCE_MEM, | 35 | .flags = IORESOURCE_MEM, |
| 36 | }, | 36 | }, { |
| 37 | [1] = { | ||
| 38 | .start = CSI_INT, | 37 | .start = CSI_INT, |
| 39 | .end = CSI_INT, | 38 | .end = CSI_INT, |
| 40 | .flags = IORESOURCE_IRQ, | 39 | .flags = IORESOURCE_IRQ, |
| @@ -55,12 +54,11 @@ struct platform_device imx_csi_device = { | |||
| 55 | }; | 54 | }; |
| 56 | 55 | ||
| 57 | static struct resource imx_i2c_resources[] = { | 56 | static struct resource imx_i2c_resources[] = { |
| 58 | [0] = { | 57 | { |
| 59 | .start = 0x00217000, | 58 | .start = 0x00217000, |
| 60 | .end = 0x00217010, | 59 | .end = 0x00217010, |
| 61 | .flags = IORESOURCE_MEM, | 60 | .flags = IORESOURCE_MEM, |
| 62 | }, | 61 | }, { |
| 63 | [1] = { | ||
| 64 | .start = I2C_INT, | 62 | .start = I2C_INT, |
| 65 | .end = I2C_INT, | 63 | .end = I2C_INT, |
| 66 | .flags = IORESOURCE_IRQ, | 64 | .flags = IORESOURCE_IRQ, |
| @@ -75,22 +73,19 @@ struct platform_device imx_i2c_device = { | |||
| 75 | }; | 73 | }; |
| 76 | 74 | ||
| 77 | static struct resource imx_uart1_resources[] = { | 75 | static struct resource imx_uart1_resources[] = { |
| 78 | [0] = { | 76 | { |
| 79 | .start = UART1_BASE_ADDR, | 77 | .start = UART1_BASE_ADDR, |
| 80 | .end = UART1_BASE_ADDR + 0xD0, | 78 | .end = UART1_BASE_ADDR + 0xD0, |
| 81 | .flags = IORESOURCE_MEM, | 79 | .flags = IORESOURCE_MEM, |
| 82 | }, | 80 | }, { |
| 83 | [1] = { | ||
| 84 | .start = UART1_MINT_RX, | 81 | .start = UART1_MINT_RX, |
| 85 | .end = UART1_MINT_RX, | 82 | .end = UART1_MINT_RX, |
| 86 | .flags = IORESOURCE_IRQ, | 83 | .flags = IORESOURCE_IRQ, |
| 87 | }, | 84 | }, { |
| 88 | [2] = { | ||
| 89 | .start = UART1_MINT_TX, | 85 | .start = UART1_MINT_TX, |
| 90 | .end = UART1_MINT_TX, | 86 | .end = UART1_MINT_TX, |
| 91 | .flags = IORESOURCE_IRQ, | 87 | .flags = IORESOURCE_IRQ, |
| 92 | }, | 88 | }, { |
| 93 | [3] = { | ||
| 94 | .start = UART1_MINT_RTS, | 89 | .start = UART1_MINT_RTS, |
| 95 | .end = UART1_MINT_RTS, | 90 | .end = UART1_MINT_RTS, |
| 96 | .flags = IORESOURCE_IRQ, | 91 | .flags = IORESOURCE_IRQ, |
| @@ -105,22 +100,19 @@ struct platform_device imx_uart1_device = { | |||
| 105 | }; | 100 | }; |
| 106 | 101 | ||
| 107 | static struct resource imx_uart2_resources[] = { | 102 | static struct resource imx_uart2_resources[] = { |
| 108 | [0] = { | 103 | { |
| 109 | .start = UART2_BASE_ADDR, | 104 | .start = UART2_BASE_ADDR, |
| 110 | .end = UART2_BASE_ADDR + 0xD0, | 105 | .end = UART2_BASE_ADDR + 0xD0, |
| 111 | .flags = IORESOURCE_MEM, | 106 | .flags = IORESOURCE_MEM, |
| 112 | }, | 107 | }, { |
| 113 | [1] = { | ||
| 114 | .start = UART2_MINT_RX, | 108 | .start = UART2_MINT_RX, |
| 115 | .end = UART2_MINT_RX, | 109 | .end = UART2_MINT_RX, |
| 116 | .flags = IORESOURCE_IRQ, | 110 | .flags = IORESOURCE_IRQ, |
| 117 | }, | 111 | }, { |
| 118 | [2] = { | ||
| 119 | .start = UART2_MINT_TX, | 112 | .start = UART2_MINT_TX, |
| 120 | .end = UART2_MINT_TX, | 113 | .end = UART2_MINT_TX, |
| 121 | .flags = IORESOURCE_IRQ, | 114 | .flags = IORESOURCE_IRQ, |
| 122 | }, | 115 | }, { |
| 123 | [3] = { | ||
| 124 | .start = UART2_MINT_RTS, | 116 | .start = UART2_MINT_RTS, |
| 125 | .end = UART2_MINT_RTS, | 117 | .end = UART2_MINT_RTS, |
| 126 | .flags = IORESOURCE_IRQ, | 118 | .flags = IORESOURCE_IRQ, |
| @@ -135,17 +127,15 @@ struct platform_device imx_uart2_device = { | |||
| 135 | }; | 127 | }; |
| 136 | 128 | ||
| 137 | static struct resource imx_rtc_resources[] = { | 129 | static struct resource imx_rtc_resources[] = { |
| 138 | [0] = { | 130 | { |
| 139 | .start = 0x00204000, | 131 | .start = 0x00204000, |
| 140 | .end = 0x00204024, | 132 | .end = 0x00204024, |
| 141 | .flags = IORESOURCE_MEM, | 133 | .flags = IORESOURCE_MEM, |
| 142 | }, | 134 | }, { |
| 143 | [1] = { | ||
| 144 | .start = RTC_INT, | 135 | .start = RTC_INT, |
| 145 | .end = RTC_INT, | 136 | .end = RTC_INT, |
| 146 | .flags = IORESOURCE_IRQ, | 137 | .flags = IORESOURCE_IRQ, |
| 147 | }, | 138 | }, { |
| 148 | [2] = { | ||
| 149 | .start = RTC_SAMINT, | 139 | .start = RTC_SAMINT, |
| 150 | .end = RTC_SAMINT, | 140 | .end = RTC_SAMINT, |
| 151 | .flags = IORESOURCE_IRQ, | 141 | .flags = IORESOURCE_IRQ, |
| @@ -160,12 +150,11 @@ struct platform_device imx_rtc_device = { | |||
| 160 | }; | 150 | }; |
| 161 | 151 | ||
| 162 | static struct resource imx_wdt_resources[] = { | 152 | static struct resource imx_wdt_resources[] = { |
| 163 | [0] = { | 153 | { |
| 164 | .start = 0x00201000, | 154 | .start = 0x00201000, |
| 165 | .end = 0x00201008, | 155 | .end = 0x00201008, |
| 166 | .flags = IORESOURCE_MEM, | 156 | .flags = IORESOURCE_MEM, |
| 167 | }, | 157 | }, { |
| 168 | [1] = { | ||
| 169 | .start = WDT_INT, | 158 | .start = WDT_INT, |
| 170 | .end = WDT_INT, | 159 | .end = WDT_INT, |
| 171 | .flags = IORESOURCE_IRQ, | 160 | .flags = IORESOURCE_IRQ, |
| @@ -180,42 +169,35 @@ struct platform_device imx_wdt_device = { | |||
| 180 | }; | 169 | }; |
| 181 | 170 | ||
| 182 | static struct resource imx_usb_resources[] = { | 171 | static struct resource imx_usb_resources[] = { |
| 183 | [0] = { | 172 | { |
| 184 | .start = 0x00212000, | 173 | .start = 0x00212000, |
| 185 | .end = 0x00212148, | 174 | .end = 0x00212148, |
| 186 | .flags = IORESOURCE_MEM, | 175 | .flags = IORESOURCE_MEM, |
| 187 | }, | 176 | }, { |
| 188 | [1] = { | ||
| 189 | .start = USBD_INT0, | 177 | .start = USBD_INT0, |
| 190 | .end = USBD_INT0, | 178 | .end = USBD_INT0, |
| 191 | .flags = IORESOURCE_IRQ, | 179 | .flags = IORESOURCE_IRQ, |
| 192 | }, | 180 | }, { |
| 193 | [2] = { | ||
| 194 | .start = USBD_INT1, | 181 | .start = USBD_INT1, |
| 195 | .end = USBD_INT1, | 182 | .end = USBD_INT1, |
| 196 | .flags = IORESOURCE_IRQ, | 183 | .flags = IORESOURCE_IRQ, |
| 197 | }, | 184 | }, { |
| 198 | [3] = { | ||
| 199 | .start = USBD_INT2, | 185 | .start = USBD_INT2, |
| 200 | .end = USBD_INT2, | 186 | .end = USBD_INT2, |
| 201 | .flags = IORESOURCE_IRQ, | 187 | .flags = IORESOURCE_IRQ, |
| 202 | }, | 188 | }, { |
| 203 | [4] = { | ||
| 204 | .start = USBD_INT3, | 189 | .start = USBD_INT3, |
| 205 | .end = USBD_INT3, | 190 | .end = USBD_INT3, |
| 206 | .flags = IORESOURCE_IRQ, | 191 | .flags = IORESOURCE_IRQ, |
| 207 | }, | 192 | }, { |
| 208 | [5] = { | ||
| 209 | .start = USBD_INT4, | 193 | .start = USBD_INT4, |
| 210 | .end = USBD_INT4, | 194 | .end = USBD_INT4, |
| 211 | .flags = IORESOURCE_IRQ, | 195 | .flags = IORESOURCE_IRQ, |
| 212 | }, | 196 | }, { |
| 213 | [6] = { | ||
| 214 | .start = USBD_INT5, | 197 | .start = USBD_INT5, |
| 215 | .end = USBD_INT5, | 198 | .end = USBD_INT5, |
| 216 | .flags = IORESOURCE_IRQ, | 199 | .flags = IORESOURCE_IRQ, |
| 217 | }, | 200 | }, { |
| 218 | [7] = { | ||
| 219 | .start = USBD_INT6, | 201 | .start = USBD_INT6, |
| 220 | .end = USBD_INT6, | 202 | .end = USBD_INT6, |
| 221 | .flags = IORESOURCE_IRQ, | 203 | .flags = IORESOURCE_IRQ, |
| @@ -231,29 +213,26 @@ struct platform_device imx_usb_device = { | |||
| 231 | 213 | ||
| 232 | /* GPIO port description */ | 214 | /* GPIO port description */ |
| 233 | static struct mxc_gpio_port imx_gpio_ports[] = { | 215 | static struct mxc_gpio_port imx_gpio_ports[] = { |
| 234 | [0] = { | 216 | { |
| 235 | .chip.label = "gpio-0", | 217 | .chip.label = "gpio-0", |
| 236 | .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR), | 218 | .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR), |
| 237 | .irq = GPIO_INT_PORTA, | 219 | .irq = GPIO_INT_PORTA, |
| 238 | .virtual_irq_start = MXC_GPIO_IRQ_START | 220 | .virtual_irq_start = MXC_GPIO_IRQ_START, |
| 239 | }, | 221 | }, { |
| 240 | [1] = { | ||
| 241 | .chip.label = "gpio-1", | 222 | .chip.label = "gpio-1", |
| 242 | .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x100), | 223 | .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x100), |
| 243 | .irq = GPIO_INT_PORTB, | 224 | .irq = GPIO_INT_PORTB, |
| 244 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32 | 225 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32, |
| 245 | }, | 226 | }, { |
| 246 | [2] = { | ||
| 247 | .chip.label = "gpio-2", | 227 | .chip.label = "gpio-2", |
| 248 | .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x200), | 228 | .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x200), |
| 249 | .irq = GPIO_INT_PORTC, | 229 | .irq = GPIO_INT_PORTC, |
| 250 | .virtual_irq_start = MXC_GPIO_IRQ_START + 64 | 230 | .virtual_irq_start = MXC_GPIO_IRQ_START + 64, |
| 251 | }, | 231 | }, { |
| 252 | [3] = { | ||
| 253 | .chip.label = "gpio-3", | 232 | .chip.label = "gpio-3", |
| 254 | .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x300), | 233 | .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x300), |
| 255 | .irq = GPIO_INT_PORTD, | 234 | .irq = GPIO_INT_PORTD, |
| 256 | .virtual_irq_start = MXC_GPIO_IRQ_START + 96 | 235 | .virtual_irq_start = MXC_GPIO_IRQ_START + 96, |
| 257 | } | 236 | } |
| 258 | }; | 237 | }; |
| 259 | 238 | ||
diff --git a/arch/arm/mach-mx1/generic.c b/arch/arm/mach-mx1/generic.c index 7622c9b38c97..7f9fc1034c08 100644 --- a/arch/arm/mach-mx1/generic.c +++ b/arch/arm/mach-mx1/generic.c | |||
| @@ -41,6 +41,13 @@ static struct map_desc imx_io_desc[] __initdata = { | |||
| 41 | void __init mx1_map_io(void) | 41 | void __init mx1_map_io(void) |
| 42 | { | 42 | { |
| 43 | mxc_set_cpu_type(MXC_CPU_MX1); | 43 | mxc_set_cpu_type(MXC_CPU_MX1); |
| 44 | mxc_arch_reset_init(IO_ADDRESS(WDT_BASE_ADDR)); | ||
| 44 | 45 | ||
| 45 | iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc)); | 46 | iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc)); |
| 46 | } | 47 | } |
| 48 | |||
| 49 | void __init mx1_init_irq(void) | ||
| 50 | { | ||
| 51 | mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR)); | ||
| 52 | } | ||
| 53 | |||
diff --git a/arch/arm/mach-mx1/mx1ads.c b/arch/arm/mach-mx1/mx1ads.c index e5b0c0a83c3b..30f04e56fafe 100644 --- a/arch/arm/mach-mx1/mx1ads.c +++ b/arch/arm/mach-mx1/mx1ads.c | |||
| @@ -104,12 +104,10 @@ static struct imxi2c_platform_data mx1ads_i2c_data = { | |||
| 104 | 104 | ||
| 105 | static struct i2c_board_info mx1ads_i2c_devices[] = { | 105 | static struct i2c_board_info mx1ads_i2c_devices[] = { |
| 106 | { | 106 | { |
| 107 | I2C_BOARD_INFO("pcf857x", 0x22), | 107 | I2C_BOARD_INFO("pcf8575", 0x22), |
| 108 | .type = "pcf8575", | ||
| 109 | .platform_data = &pcf857x_data[0], | 108 | .platform_data = &pcf857x_data[0], |
| 110 | }, { | 109 | }, { |
| 111 | I2C_BOARD_INFO("pcf857x", 0x24), | 110 | I2C_BOARD_INFO("pcf8575", 0x24), |
| 112 | .type = "pcf8575", | ||
| 113 | .platform_data = &pcf857x_data[1], | 111 | .platform_data = &pcf857x_data[1], |
| 114 | }, | 112 | }, |
| 115 | }; | 113 | }; |
| @@ -151,7 +149,7 @@ MACHINE_START(MX1ADS, "Freescale MX1ADS") | |||
| 151 | .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc, | 149 | .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc, |
| 152 | .boot_params = PHYS_OFFSET + 0x100, | 150 | .boot_params = PHYS_OFFSET + 0x100, |
| 153 | .map_io = mx1_map_io, | 151 | .map_io = mx1_map_io, |
| 154 | .init_irq = mxc_init_irq, | 152 | .init_irq = mx1_init_irq, |
| 155 | .timer = &mx1ads_timer, | 153 | .timer = &mx1ads_timer, |
| 156 | .init_machine = mx1ads_init, | 154 | .init_machine = mx1ads_init, |
| 157 | MACHINE_END | 155 | MACHINE_END |
| @@ -161,7 +159,7 @@ MACHINE_START(MXLADS, "Freescale MXLADS") | |||
| 161 | .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc, | 159 | .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc, |
| 162 | .boot_params = PHYS_OFFSET + 0x100, | 160 | .boot_params = PHYS_OFFSET + 0x100, |
| 163 | .map_io = mx1_map_io, | 161 | .map_io = mx1_map_io, |
| 164 | .init_irq = mxc_init_irq, | 162 | .init_irq = mx1_init_irq, |
| 165 | .timer = &mx1ads_timer, | 163 | .timer = &mx1ads_timer, |
| 166 | .init_machine = mx1ads_init, | 164 | .init_machine = mx1ads_init, |
| 167 | MACHINE_END | 165 | MACHINE_END |
diff --git a/arch/arm/mach-mx1/scb9328.c b/arch/arm/mach-mx1/scb9328.c index 20e0b5bcdffc..325d98df6053 100644 --- a/arch/arm/mach-mx1/scb9328.c +++ b/arch/arm/mach-mx1/scb9328.c | |||
| @@ -68,22 +68,20 @@ static struct dm9000_plat_data dm9000_platdata = { | |||
| 68 | * to gain access to address latch registers and the data path. | 68 | * to gain access to address latch registers and the data path. |
| 69 | */ | 69 | */ |
| 70 | static struct resource dm9000x_resources[] = { | 70 | static struct resource dm9000x_resources[] = { |
| 71 | [0] = { | 71 | { |
| 72 | .name = "address area", | 72 | .name = "address area", |
| 73 | .start = IMX_CS5_PHYS, | 73 | .start = IMX_CS5_PHYS, |
| 74 | .end = IMX_CS5_PHYS + 1, | 74 | .end = IMX_CS5_PHYS + 1, |
| 75 | .flags = IORESOURCE_MEM /* address access */ | 75 | .flags = IORESOURCE_MEM, /* address access */ |
| 76 | }, | 76 | }, { |
| 77 | [1] = { | ||
| 78 | .name = "data area", | 77 | .name = "data area", |
| 79 | .start = IMX_CS5_PHYS + 4, | 78 | .start = IMX_CS5_PHYS + 4, |
| 80 | .end = IMX_CS5_PHYS + 5, | 79 | .end = IMX_CS5_PHYS + 5, |
| 81 | .flags = IORESOURCE_MEM /* data access */ | 80 | .flags = IORESOURCE_MEM, /* data access */ |
| 82 | }, | 81 | }, { |
| 83 | [2] = { | ||
| 84 | .start = IRQ_GPIOC(3), | 82 | .start = IRQ_GPIOC(3), |
| 85 | .end = IRQ_GPIOC(3), | 83 | .end = IRQ_GPIOC(3), |
| 86 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL | 84 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, |
| 87 | }, | 85 | }, |
| 88 | }; | 86 | }; |
| 89 | 87 | ||
| @@ -154,7 +152,7 @@ MACHINE_START(SCB9328, "Synertronixx scb9328") | |||
| 154 | .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc, | 152 | .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc, |
| 155 | .boot_params = 0x08000100, | 153 | .boot_params = 0x08000100, |
| 156 | .map_io = mx1_map_io, | 154 | .map_io = mx1_map_io, |
| 157 | .init_irq = mxc_init_irq, | 155 | .init_irq = mx1_init_irq, |
| 158 | .timer = &scb9328_timer, | 156 | .timer = &scb9328_timer, |
| 159 | .init_machine = scb9328_init, | 157 | .init_machine = scb9328_init, |
| 160 | MACHINE_END | 158 | MACHINE_END |
diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index c77da586b71d..c8a2eac4d13c 100644 --- a/arch/arm/mach-mx2/Kconfig +++ b/arch/arm/mach-mx2/Kconfig | |||
| @@ -53,6 +53,34 @@ config MACH_PCM970_BASEBOARD | |||
| 53 | 53 | ||
| 54 | endchoice | 54 | endchoice |
| 55 | 55 | ||
| 56 | config MACH_EUKREA_CPUIMX27 | ||
| 57 | bool "Eukrea CPUIMX27 module" | ||
| 58 | depends on MACH_MX27 | ||
| 59 | help | ||
| 60 | Include support for Eukrea CPUIMX27 platform. This includes | ||
| 61 | specific configurations for the module and its peripherals. | ||
| 62 | |||
| 63 | config MACH_EUKREA_CPUIMX27_USESDHC2 | ||
| 64 | bool "CPUIMX27 integrates SDHC2 module" | ||
| 65 | depends on MACH_EUKREA_CPUIMX27 | ||
| 66 | help | ||
| 67 | This adds support for the internal SDHC2 used on CPUIMX27 used | ||
| 68 | for wifi or eMMC. | ||
| 69 | |||
| 70 | choice | ||
| 71 | prompt "Baseboard" | ||
| 72 | depends on MACH_EUKREA_CPUIMX27 | ||
| 73 | default MACH_EUKREA_MBIMX27_BASEBOARD | ||
| 74 | |||
| 75 | config MACH_EUKREA_MBIMX27_BASEBOARD | ||
| 76 | prompt "Eukrea MBIMX27 development board" | ||
| 77 | bool | ||
| 78 | help | ||
| 79 | This adds board specific devices that can be found on Eukrea's | ||
| 80 | MBIMX27 evaluation board. | ||
| 81 | |||
| 82 | endchoice | ||
| 83 | |||
| 56 | config MACH_MX27_3DS | 84 | config MACH_MX27_3DS |
| 57 | bool "MX27PDK platform" | 85 | bool "MX27PDK platform" |
| 58 | depends on MACH_MX27 | 86 | depends on MACH_MX27 |
| @@ -67,4 +95,11 @@ config MACH_MX27LITE | |||
| 67 | Include support for MX27 LITEKIT platform. This includes specific | 95 | Include support for MX27 LITEKIT platform. This includes specific |
| 68 | configurations for the board and its peripherals. | 96 | configurations for the board and its peripherals. |
| 69 | 97 | ||
| 98 | config MACH_PCA100 | ||
| 99 | bool "Phytec phyCARD-s (pca100)" | ||
| 100 | depends on MACH_MX27 | ||
| 101 | help | ||
| 102 | Include support for phyCARD-s (aka pca100) platform. This | ||
| 103 | includes specific configurations for the module and its peripherals. | ||
| 104 | |||
| 70 | endif | 105 | endif |
diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index b9b1cca4e9bc..19560f045632 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile | |||
| @@ -17,4 +17,7 @@ obj-$(CONFIG_MACH_PCM038) += pcm038.o | |||
| 17 | obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o | 17 | obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o |
| 18 | obj-$(CONFIG_MACH_MX27_3DS) += mx27pdk.o | 18 | obj-$(CONFIG_MACH_MX27_3DS) += mx27pdk.o |
| 19 | obj-$(CONFIG_MACH_MX27LITE) += mx27lite.o | 19 | obj-$(CONFIG_MACH_MX27LITE) += mx27lite.o |
| 20 | obj-$(CONFIG_MACH_EUKREA_CPUIMX27) += eukrea_cpuimx27.o | ||
| 21 | obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o | ||
| 22 | obj-$(CONFIG_MACH_PCA100) += pca100.o | ||
| 20 | 23 | ||
diff --git a/arch/arm/mach-mx2/clock_imx21.c b/arch/arm/mach-mx2/clock_imx21.c index 0850fb88ec15..eede79855f4a 100644 --- a/arch/arm/mach-mx2/clock_imx21.c +++ b/arch/arm/mach-mx2/clock_imx21.c | |||
| @@ -1004,6 +1004,6 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href) | |||
| 1004 | clk_enable(&uart_clk[0]); | 1004 | clk_enable(&uart_clk[0]); |
| 1005 | #endif | 1005 | #endif |
| 1006 | 1006 | ||
| 1007 | mxc_timer_init(&gpt_clk[0]); | 1007 | mxc_timer_init(&gpt_clk[0], IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT1); |
| 1008 | return 0; | 1008 | return 0; |
| 1009 | } | 1009 | } |
diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c index 2c971442f3f2..4089951acb47 100644 --- a/arch/arm/mach-mx2/clock_imx27.c +++ b/arch/arm/mach-mx2/clock_imx27.c | |||
| @@ -643,7 +643,14 @@ static struct clk_lookup lookups[] = { | |||
| 643 | _REGISTER_CLOCK(NULL, "cspi3", cspi3_clk) | 643 | _REGISTER_CLOCK(NULL, "cspi3", cspi3_clk) |
| 644 | _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) | 644 | _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) |
| 645 | _REGISTER_CLOCK(NULL, "csi", csi_clk) | 645 | _REGISTER_CLOCK(NULL, "csi", csi_clk) |
| 646 | _REGISTER_CLOCK(NULL, "usb", usb_clk) | 646 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk) |
| 647 | _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk1) | ||
| 648 | _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk) | ||
| 649 | _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk1) | ||
| 650 | _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk) | ||
| 651 | _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1) | ||
| 652 | _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk) | ||
| 653 | _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1) | ||
| 647 | _REGISTER_CLOCK(NULL, "ssi1", ssi1_clk) | 654 | _REGISTER_CLOCK(NULL, "ssi1", ssi1_clk) |
| 648 | _REGISTER_CLOCK(NULL, "ssi2", ssi2_clk) | 655 | _REGISTER_CLOCK(NULL, "ssi2", ssi2_clk) |
| 649 | _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) | 656 | _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) |
| @@ -748,7 +755,7 @@ int __init mx27_clocks_init(unsigned long fref) | |||
| 748 | clk_enable(&uart1_clk); | 755 | clk_enable(&uart1_clk); |
| 749 | #endif | 756 | #endif |
| 750 | 757 | ||
| 751 | mxc_timer_init(&gpt1_clk); | 758 | mxc_timer_init(&gpt1_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT1); |
| 752 | 759 | ||
| 753 | return 0; | 760 | return 0; |
| 754 | } | 761 | } |
diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c index a0f1b3674327..50199aff0143 100644 --- a/arch/arm/mach-mx2/devices.c +++ b/arch/arm/mach-mx2/devices.c | |||
| @@ -40,45 +40,87 @@ | |||
| 40 | #include "devices.h" | 40 | #include "devices.h" |
| 41 | 41 | ||
| 42 | /* | 42 | /* |
| 43 | * Resource definition for the MXC IrDA | 43 | * SPI master controller |
| 44 | * | ||
| 45 | * - i.MX1: 2 channel (slighly different register setting) | ||
| 46 | * - i.MX21: 2 channel | ||
| 47 | * - i.MX27: 3 channel | ||
| 44 | */ | 48 | */ |
| 45 | static struct resource mxc_irda_resources[] = { | 49 | static struct resource mxc_spi_resources0[] = { |
| 46 | [0] = { | 50 | { |
| 47 | .start = UART3_BASE_ADDR, | 51 | .start = CSPI1_BASE_ADDR, |
| 48 | .end = UART3_BASE_ADDR + SZ_4K - 1, | 52 | .end = CSPI1_BASE_ADDR + SZ_4K - 1, |
| 49 | .flags = IORESOURCE_MEM, | 53 | .flags = IORESOURCE_MEM, |
| 54 | }, { | ||
| 55 | .start = MXC_INT_CSPI1, | ||
| 56 | .end = MXC_INT_CSPI1, | ||
| 57 | .flags = IORESOURCE_IRQ, | ||
| 50 | }, | 58 | }, |
| 51 | [1] = { | 59 | }; |
| 52 | .start = MXC_INT_UART3, | 60 | |
| 53 | .end = MXC_INT_UART3, | 61 | static struct resource mxc_spi_resources1[] = { |
| 54 | .flags = IORESOURCE_IRQ, | 62 | { |
| 63 | .start = CSPI2_BASE_ADDR, | ||
| 64 | .end = CSPI2_BASE_ADDR + SZ_4K - 1, | ||
| 65 | .flags = IORESOURCE_MEM, | ||
| 66 | }, { | ||
| 67 | .start = MXC_INT_CSPI2, | ||
| 68 | .end = MXC_INT_CSPI2, | ||
| 69 | .flags = IORESOURCE_IRQ, | ||
| 55 | }, | 70 | }, |
| 56 | }; | 71 | }; |
| 57 | 72 | ||
| 58 | /* Platform Data for MXC IrDA */ | 73 | #ifdef CONFIG_MACH_MX27 |
| 59 | struct platform_device mxc_irda_device = { | 74 | static struct resource mxc_spi_resources2[] = { |
| 60 | .name = "mxc_irda", | 75 | { |
| 76 | .start = CSPI3_BASE_ADDR, | ||
| 77 | .end = CSPI3_BASE_ADDR + SZ_4K - 1, | ||
| 78 | .flags = IORESOURCE_MEM, | ||
| 79 | }, { | ||
| 80 | .start = MXC_INT_CSPI3, | ||
| 81 | .end = MXC_INT_CSPI3, | ||
| 82 | .flags = IORESOURCE_IRQ, | ||
| 83 | }, | ||
| 84 | }; | ||
| 85 | #endif | ||
| 86 | |||
| 87 | struct platform_device mxc_spi_device0 = { | ||
| 88 | .name = "spi_imx", | ||
| 61 | .id = 0, | 89 | .id = 0, |
| 62 | .num_resources = ARRAY_SIZE(mxc_irda_resources), | 90 | .num_resources = ARRAY_SIZE(mxc_spi_resources0), |
| 63 | .resource = mxc_irda_resources, | 91 | .resource = mxc_spi_resources0, |
| 92 | }; | ||
| 93 | |||
| 94 | struct platform_device mxc_spi_device1 = { | ||
| 95 | .name = "spi_imx", | ||
| 96 | .id = 1, | ||
| 97 | .num_resources = ARRAY_SIZE(mxc_spi_resources1), | ||
| 98 | .resource = mxc_spi_resources1, | ||
| 99 | }; | ||
| 100 | |||
| 101 | #ifdef CONFIG_MACH_MX27 | ||
| 102 | struct platform_device mxc_spi_device2 = { | ||
| 103 | .name = "spi_imx", | ||
| 104 | .id = 2, | ||
| 105 | .num_resources = ARRAY_SIZE(mxc_spi_resources2), | ||
| 106 | .resource = mxc_spi_resources2, | ||
| 64 | }; | 107 | }; |
| 108 | #endif | ||
| 65 | 109 | ||
| 66 | /* | 110 | /* |
| 67 | * General Purpose Timer | 111 | * General Purpose Timer |
| 68 | * - i.MX1: 2 timer (slighly different register handling) | 112 | * - i.MX21: 3 timers |
| 69 | * - i.MX21: 3 timer | 113 | * - i.MX27: 6 timers |
| 70 | * - i.MX27: 6 timer | ||
| 71 | */ | 114 | */ |
| 72 | 115 | ||
| 73 | /* We use gpt0 as system timer, so do not add a device for this one */ | 116 | /* We use gpt0 as system timer, so do not add a device for this one */ |
| 74 | 117 | ||
| 75 | static struct resource timer1_resources[] = { | 118 | static struct resource timer1_resources[] = { |
| 76 | [0] = { | 119 | { |
| 77 | .start = GPT2_BASE_ADDR, | 120 | .start = GPT2_BASE_ADDR, |
| 78 | .end = GPT2_BASE_ADDR + 0x17, | 121 | .end = GPT2_BASE_ADDR + 0x17, |
| 79 | .flags = IORESOURCE_MEM | 122 | .flags = IORESOURCE_MEM, |
| 80 | }, | 123 | }, { |
| 81 | [1] = { | ||
| 82 | .start = MXC_INT_GPT2, | 124 | .start = MXC_INT_GPT2, |
| 83 | .end = MXC_INT_GPT2, | 125 | .end = MXC_INT_GPT2, |
| 84 | .flags = IORESOURCE_IRQ, | 126 | .flags = IORESOURCE_IRQ, |
| @@ -89,16 +131,15 @@ struct platform_device mxc_gpt1 = { | |||
| 89 | .name = "imx_gpt", | 131 | .name = "imx_gpt", |
| 90 | .id = 1, | 132 | .id = 1, |
| 91 | .num_resources = ARRAY_SIZE(timer1_resources), | 133 | .num_resources = ARRAY_SIZE(timer1_resources), |
| 92 | .resource = timer1_resources | 134 | .resource = timer1_resources, |
| 93 | }; | 135 | }; |
| 94 | 136 | ||
| 95 | static struct resource timer2_resources[] = { | 137 | static struct resource timer2_resources[] = { |
| 96 | [0] = { | 138 | { |
| 97 | .start = GPT3_BASE_ADDR, | 139 | .start = GPT3_BASE_ADDR, |
| 98 | .end = GPT3_BASE_ADDR + 0x17, | 140 | .end = GPT3_BASE_ADDR + 0x17, |
| 99 | .flags = IORESOURCE_MEM | 141 | .flags = IORESOURCE_MEM, |
| 100 | }, | 142 | }, { |
| 101 | [1] = { | ||
| 102 | .start = MXC_INT_GPT3, | 143 | .start = MXC_INT_GPT3, |
| 103 | .end = MXC_INT_GPT3, | 144 | .end = MXC_INT_GPT3, |
| 104 | .flags = IORESOURCE_IRQ, | 145 | .flags = IORESOURCE_IRQ, |
| @@ -109,17 +150,16 @@ struct platform_device mxc_gpt2 = { | |||
| 109 | .name = "imx_gpt", | 150 | .name = "imx_gpt", |
| 110 | .id = 2, | 151 | .id = 2, |
| 111 | .num_resources = ARRAY_SIZE(timer2_resources), | 152 | .num_resources = ARRAY_SIZE(timer2_resources), |
| 112 | .resource = timer2_resources | 153 | .resource = timer2_resources, |
| 113 | }; | 154 | }; |
| 114 | 155 | ||
| 115 | #ifdef CONFIG_MACH_MX27 | 156 | #ifdef CONFIG_MACH_MX27 |
| 116 | static struct resource timer3_resources[] = { | 157 | static struct resource timer3_resources[] = { |
| 117 | [0] = { | 158 | { |
| 118 | .start = GPT4_BASE_ADDR, | 159 | .start = GPT4_BASE_ADDR, |
| 119 | .end = GPT4_BASE_ADDR + 0x17, | 160 | .end = GPT4_BASE_ADDR + 0x17, |
| 120 | .flags = IORESOURCE_MEM | 161 | .flags = IORESOURCE_MEM, |
| 121 | }, | 162 | }, { |
| 122 | [1] = { | ||
| 123 | .start = MXC_INT_GPT4, | 163 | .start = MXC_INT_GPT4, |
| 124 | .end = MXC_INT_GPT4, | 164 | .end = MXC_INT_GPT4, |
| 125 | .flags = IORESOURCE_IRQ, | 165 | .flags = IORESOURCE_IRQ, |
| @@ -130,16 +170,15 @@ struct platform_device mxc_gpt3 = { | |||
| 130 | .name = "imx_gpt", | 170 | .name = "imx_gpt", |
| 131 | .id = 3, | 171 | .id = 3, |
| 132 | .num_resources = ARRAY_SIZE(timer3_resources), | 172 | .num_resources = ARRAY_SIZE(timer3_resources), |
| 133 | .resource = timer3_resources | 173 | .resource = timer3_resources, |
| 134 | }; | 174 | }; |
| 135 | 175 | ||
| 136 | static struct resource timer4_resources[] = { | 176 | static struct resource timer4_resources[] = { |
| 137 | [0] = { | 177 | { |
| 138 | .start = GPT5_BASE_ADDR, | 178 | .start = GPT5_BASE_ADDR, |
| 139 | .end = GPT5_BASE_ADDR + 0x17, | 179 | .end = GPT5_BASE_ADDR + 0x17, |
| 140 | .flags = IORESOURCE_MEM | 180 | .flags = IORESOURCE_MEM, |
| 141 | }, | 181 | }, { |
| 142 | [1] = { | ||
| 143 | .start = MXC_INT_GPT5, | 182 | .start = MXC_INT_GPT5, |
| 144 | .end = MXC_INT_GPT5, | 183 | .end = MXC_INT_GPT5, |
| 145 | .flags = IORESOURCE_IRQ, | 184 | .flags = IORESOURCE_IRQ, |
| @@ -150,16 +189,15 @@ struct platform_device mxc_gpt4 = { | |||
| 150 | .name = "imx_gpt", | 189 | .name = "imx_gpt", |
| 151 | .id = 4, | 190 | .id = 4, |
| 152 | .num_resources = ARRAY_SIZE(timer4_resources), | 191 | .num_resources = ARRAY_SIZE(timer4_resources), |
| 153 | .resource = timer4_resources | 192 | .resource = timer4_resources, |
| 154 | }; | 193 | }; |
| 155 | 194 | ||
| 156 | static struct resource timer5_resources[] = { | 195 | static struct resource timer5_resources[] = { |
| 157 | [0] = { | 196 | { |
| 158 | .start = GPT6_BASE_ADDR, | 197 | .start = GPT6_BASE_ADDR, |
| 159 | .end = GPT6_BASE_ADDR + 0x17, | 198 | .end = GPT6_BASE_ADDR + 0x17, |
| 160 | .flags = IORESOURCE_MEM | 199 | .flags = IORESOURCE_MEM, |
| 161 | }, | 200 | }, { |
| 162 | [1] = { | ||
| 163 | .start = MXC_INT_GPT6, | 201 | .start = MXC_INT_GPT6, |
| 164 | .end = MXC_INT_GPT6, | 202 | .end = MXC_INT_GPT6, |
| 165 | .flags = IORESOURCE_IRQ, | 203 | .flags = IORESOURCE_IRQ, |
| @@ -170,7 +208,7 @@ struct platform_device mxc_gpt5 = { | |||
| 170 | .name = "imx_gpt", | 208 | .name = "imx_gpt", |
| 171 | .id = 5, | 209 | .id = 5, |
| 172 | .num_resources = ARRAY_SIZE(timer5_resources), | 210 | .num_resources = ARRAY_SIZE(timer5_resources), |
| 173 | .resource = timer5_resources | 211 | .resource = timer5_resources, |
| 174 | }; | 212 | }; |
| 175 | #endif | 213 | #endif |
| 176 | 214 | ||
| @@ -214,11 +252,11 @@ static struct resource mxc_nand_resources[] = { | |||
| 214 | { | 252 | { |
| 215 | .start = NFC_BASE_ADDR, | 253 | .start = NFC_BASE_ADDR, |
| 216 | .end = NFC_BASE_ADDR + 0xfff, | 254 | .end = NFC_BASE_ADDR + 0xfff, |
| 217 | .flags = IORESOURCE_MEM | 255 | .flags = IORESOURCE_MEM, |
| 218 | }, { | 256 | }, { |
| 219 | .start = MXC_INT_NANDFC, | 257 | .start = MXC_INT_NANDFC, |
| 220 | .end = MXC_INT_NANDFC, | 258 | .end = MXC_INT_NANDFC, |
| 221 | .flags = IORESOURCE_IRQ | 259 | .flags = IORESOURCE_IRQ, |
| 222 | }, | 260 | }, |
| 223 | }; | 261 | }; |
| 224 | 262 | ||
| @@ -240,8 +278,7 @@ static struct resource mxc_fb[] = { | |||
| 240 | .start = LCDC_BASE_ADDR, | 278 | .start = LCDC_BASE_ADDR, |
| 241 | .end = LCDC_BASE_ADDR + 0xFFF, | 279 | .end = LCDC_BASE_ADDR + 0xFFF, |
| 242 | .flags = IORESOURCE_MEM, | 280 | .flags = IORESOURCE_MEM, |
| 243 | }, | 281 | }, { |
| 244 | { | ||
| 245 | .start = MXC_INT_LCDC, | 282 | .start = MXC_INT_LCDC, |
| 246 | .end = MXC_INT_LCDC, | 283 | .end = MXC_INT_LCDC, |
| 247 | .flags = IORESOURCE_IRQ, | 284 | .flags = IORESOURCE_IRQ, |
| @@ -264,11 +301,11 @@ static struct resource mxc_fec_resources[] = { | |||
| 264 | { | 301 | { |
| 265 | .start = FEC_BASE_ADDR, | 302 | .start = FEC_BASE_ADDR, |
| 266 | .end = FEC_BASE_ADDR + 0xfff, | 303 | .end = FEC_BASE_ADDR + 0xfff, |
| 267 | .flags = IORESOURCE_MEM | 304 | .flags = IORESOURCE_MEM, |
| 268 | }, { | 305 | }, { |
| 269 | .start = MXC_INT_FEC, | 306 | .start = MXC_INT_FEC, |
| 270 | .end = MXC_INT_FEC, | 307 | .end = MXC_INT_FEC, |
| 271 | .flags = IORESOURCE_IRQ | 308 | .flags = IORESOURCE_IRQ, |
| 272 | }, | 309 | }, |
| 273 | }; | 310 | }; |
| 274 | 311 | ||
| @@ -281,15 +318,14 @@ struct platform_device mxc_fec_device = { | |||
| 281 | #endif | 318 | #endif |
| 282 | 319 | ||
| 283 | static struct resource mxc_i2c_1_resources[] = { | 320 | static struct resource mxc_i2c_1_resources[] = { |
| 284 | [0] = { | 321 | { |
| 285 | .start = I2C_BASE_ADDR, | 322 | .start = I2C_BASE_ADDR, |
| 286 | .end = I2C_BASE_ADDR + 0x0fff, | 323 | .end = I2C_BASE_ADDR + 0x0fff, |
| 287 | .flags = IORESOURCE_MEM | 324 | .flags = IORESOURCE_MEM, |
| 288 | }, | 325 | }, { |
| 289 | [1] = { | ||
| 290 | .start = MXC_INT_I2C, | 326 | .start = MXC_INT_I2C, |
| 291 | .end = MXC_INT_I2C, | 327 | .end = MXC_INT_I2C, |
| 292 | .flags = IORESOURCE_IRQ | 328 | .flags = IORESOURCE_IRQ, |
| 293 | } | 329 | } |
| 294 | }; | 330 | }; |
| 295 | 331 | ||
| @@ -297,20 +333,19 @@ struct platform_device mxc_i2c_device0 = { | |||
| 297 | .name = "imx-i2c", | 333 | .name = "imx-i2c", |
| 298 | .id = 0, | 334 | .id = 0, |
| 299 | .num_resources = ARRAY_SIZE(mxc_i2c_1_resources), | 335 | .num_resources = ARRAY_SIZE(mxc_i2c_1_resources), |
| 300 | .resource = mxc_i2c_1_resources | 336 | .resource = mxc_i2c_1_resources, |
| 301 | }; | 337 | }; |
| 302 | 338 | ||
| 303 | #ifdef CONFIG_MACH_MX27 | 339 | #ifdef CONFIG_MACH_MX27 |
| 304 | static struct resource mxc_i2c_2_resources[] = { | 340 | static struct resource mxc_i2c_2_resources[] = { |
| 305 | [0] = { | 341 | { |
| 306 | .start = I2C2_BASE_ADDR, | 342 | .start = I2C2_BASE_ADDR, |
| 307 | .end = I2C2_BASE_ADDR + 0x0fff, | 343 | .end = I2C2_BASE_ADDR + 0x0fff, |
| 308 | .flags = IORESOURCE_MEM | 344 | .flags = IORESOURCE_MEM, |
| 309 | }, | 345 | }, { |
| 310 | [1] = { | ||
| 311 | .start = MXC_INT_I2C2, | 346 | .start = MXC_INT_I2C2, |
| 312 | .end = MXC_INT_I2C2, | 347 | .end = MXC_INT_I2C2, |
| 313 | .flags = IORESOURCE_IRQ | 348 | .flags = IORESOURCE_IRQ, |
| 314 | } | 349 | } |
| 315 | }; | 350 | }; |
| 316 | 351 | ||
| @@ -318,17 +353,16 @@ struct platform_device mxc_i2c_device1 = { | |||
| 318 | .name = "imx-i2c", | 353 | .name = "imx-i2c", |
| 319 | .id = 1, | 354 | .id = 1, |
| 320 | .num_resources = ARRAY_SIZE(mxc_i2c_2_resources), | 355 | .num_resources = ARRAY_SIZE(mxc_i2c_2_resources), |
| 321 | .resource = mxc_i2c_2_resources | 356 | .resource = mxc_i2c_2_resources, |
| 322 | }; | 357 | }; |
| 323 | #endif | 358 | #endif |
| 324 | 359 | ||
| 325 | static struct resource mxc_pwm_resources[] = { | 360 | static struct resource mxc_pwm_resources[] = { |
| 326 | [0] = { | 361 | { |
| 327 | .start = PWM_BASE_ADDR, | 362 | .start = PWM_BASE_ADDR, |
| 328 | .end = PWM_BASE_ADDR + 0x0fff, | 363 | .end = PWM_BASE_ADDR + 0x0fff, |
| 329 | .flags = IORESOURCE_MEM | 364 | .flags = IORESOURCE_MEM, |
| 330 | }, | 365 | }, { |
| 331 | [1] = { | ||
| 332 | .start = MXC_INT_PWM, | 366 | .start = MXC_INT_PWM, |
| 333 | .end = MXC_INT_PWM, | 367 | .end = MXC_INT_PWM, |
| 334 | .flags = IORESOURCE_IRQ, | 368 | .flags = IORESOURCE_IRQ, |
| @@ -339,28 +373,26 @@ struct platform_device mxc_pwm_device = { | |||
| 339 | .name = "mxc_pwm", | 373 | .name = "mxc_pwm", |
| 340 | .id = 0, | 374 | .id = 0, |
| 341 | .num_resources = ARRAY_SIZE(mxc_pwm_resources), | 375 | .num_resources = ARRAY_SIZE(mxc_pwm_resources), |
| 342 | .resource = mxc_pwm_resources | 376 | .resource = mxc_pwm_resources, |
| 343 | }; | 377 | }; |
| 344 | 378 | ||
| 345 | /* | 379 | /* |
| 346 | * Resource definition for the MXC SDHC | 380 | * Resource definition for the MXC SDHC |
| 347 | */ | 381 | */ |
| 348 | static struct resource mxc_sdhc1_resources[] = { | 382 | static struct resource mxc_sdhc1_resources[] = { |
| 349 | [0] = { | 383 | { |
| 350 | .start = SDHC1_BASE_ADDR, | 384 | .start = SDHC1_BASE_ADDR, |
| 351 | .end = SDHC1_BASE_ADDR + SZ_4K - 1, | 385 | .end = SDHC1_BASE_ADDR + SZ_4K - 1, |
| 352 | .flags = IORESOURCE_MEM, | 386 | .flags = IORESOURCE_MEM, |
| 353 | }, | 387 | }, { |
| 354 | [1] = { | 388 | .start = MXC_INT_SDHC1, |
| 355 | .start = MXC_INT_SDHC1, | 389 | .end = MXC_INT_SDHC1, |
| 356 | .end = MXC_INT_SDHC1, | 390 | .flags = IORESOURCE_IRQ, |
| 357 | .flags = IORESOURCE_IRQ, | 391 | }, { |
| 358 | }, | 392 | .start = DMA_REQ_SDHC1, |
| 359 | [2] = { | 393 | .end = DMA_REQ_SDHC1, |
| 360 | .start = DMA_REQ_SDHC1, | 394 | .flags = IORESOURCE_DMA, |
| 361 | .end = DMA_REQ_SDHC1, | 395 | }, |
| 362 | .flags = IORESOURCE_DMA | ||
| 363 | }, | ||
| 364 | }; | 396 | }; |
| 365 | 397 | ||
| 366 | static u64 mxc_sdhc1_dmamask = 0xffffffffUL; | 398 | static u64 mxc_sdhc1_dmamask = 0xffffffffUL; |
| @@ -377,21 +409,19 @@ struct platform_device mxc_sdhc_device0 = { | |||
| 377 | }; | 409 | }; |
| 378 | 410 | ||
| 379 | static struct resource mxc_sdhc2_resources[] = { | 411 | static struct resource mxc_sdhc2_resources[] = { |
| 380 | [0] = { | 412 | { |
| 381 | .start = SDHC2_BASE_ADDR, | 413 | .start = SDHC2_BASE_ADDR, |
| 382 | .end = SDHC2_BASE_ADDR + SZ_4K - 1, | 414 | .end = SDHC2_BASE_ADDR + SZ_4K - 1, |
| 383 | .flags = IORESOURCE_MEM, | 415 | .flags = IORESOURCE_MEM, |
| 384 | }, | 416 | }, { |
| 385 | [1] = { | 417 | .start = MXC_INT_SDHC2, |
| 386 | .start = MXC_INT_SDHC2, | 418 | .end = MXC_INT_SDHC2, |
| 387 | .end = MXC_INT_SDHC2, | 419 | .flags = IORESOURCE_IRQ, |
| 388 | .flags = IORESOURCE_IRQ, | 420 | }, { |
| 389 | }, | 421 | .start = DMA_REQ_SDHC2, |
| 390 | [2] = { | 422 | .end = DMA_REQ_SDHC2, |
| 391 | .start = DMA_REQ_SDHC2, | 423 | .flags = IORESOURCE_DMA, |
| 392 | .end = DMA_REQ_SDHC2, | 424 | }, |
| 393 | .flags = IORESOURCE_DMA | ||
| 394 | }, | ||
| 395 | }; | 425 | }; |
| 396 | 426 | ||
| 397 | static u64 mxc_sdhc2_dmamask = 0xffffffffUL; | 427 | static u64 mxc_sdhc2_dmamask = 0xffffffffUL; |
| @@ -407,35 +437,123 @@ struct platform_device mxc_sdhc_device1 = { | |||
| 407 | .resource = mxc_sdhc2_resources, | 437 | .resource = mxc_sdhc2_resources, |
| 408 | }; | 438 | }; |
| 409 | 439 | ||
| 440 | #ifdef CONFIG_MACH_MX27 | ||
| 441 | static struct resource otg_resources[] = { | ||
| 442 | { | ||
| 443 | .start = OTG_BASE_ADDR, | ||
| 444 | .end = OTG_BASE_ADDR + 0x1ff, | ||
| 445 | .flags = IORESOURCE_MEM, | ||
| 446 | }, { | ||
| 447 | .start = MXC_INT_USB3, | ||
| 448 | .end = MXC_INT_USB3, | ||
| 449 | .flags = IORESOURCE_IRQ, | ||
| 450 | }, | ||
| 451 | }; | ||
| 452 | |||
| 453 | static u64 otg_dmamask = 0xffffffffUL; | ||
| 454 | |||
| 455 | /* OTG gadget device */ | ||
| 456 | struct platform_device mxc_otg_udc_device = { | ||
| 457 | .name = "fsl-usb2-udc", | ||
| 458 | .id = -1, | ||
| 459 | .dev = { | ||
| 460 | .dma_mask = &otg_dmamask, | ||
| 461 | .coherent_dma_mask = 0xffffffffUL, | ||
| 462 | }, | ||
| 463 | .resource = otg_resources, | ||
| 464 | .num_resources = ARRAY_SIZE(otg_resources), | ||
| 465 | }; | ||
| 466 | |||
| 467 | /* OTG host */ | ||
| 468 | struct platform_device mxc_otg_host = { | ||
| 469 | .name = "mxc-ehci", | ||
| 470 | .id = 0, | ||
| 471 | .dev = { | ||
| 472 | .coherent_dma_mask = 0xffffffff, | ||
| 473 | .dma_mask = &otg_dmamask, | ||
| 474 | }, | ||
| 475 | .resource = otg_resources, | ||
| 476 | .num_resources = ARRAY_SIZE(otg_resources), | ||
| 477 | }; | ||
| 478 | |||
| 479 | /* USB host 1 */ | ||
| 480 | |||
| 481 | static u64 usbh1_dmamask = 0xffffffffUL; | ||
| 482 | |||
| 483 | static struct resource mxc_usbh1_resources[] = { | ||
| 484 | { | ||
| 485 | .start = OTG_BASE_ADDR + 0x200, | ||
| 486 | .end = OTG_BASE_ADDR + 0x3ff, | ||
| 487 | .flags = IORESOURCE_MEM, | ||
| 488 | }, { | ||
| 489 | .start = MXC_INT_USB1, | ||
| 490 | .end = MXC_INT_USB1, | ||
| 491 | .flags = IORESOURCE_IRQ, | ||
| 492 | }, | ||
| 493 | }; | ||
| 494 | |||
| 495 | struct platform_device mxc_usbh1 = { | ||
| 496 | .name = "mxc-ehci", | ||
| 497 | .id = 1, | ||
| 498 | .dev = { | ||
| 499 | .coherent_dma_mask = 0xffffffff, | ||
| 500 | .dma_mask = &usbh1_dmamask, | ||
| 501 | }, | ||
| 502 | .resource = mxc_usbh1_resources, | ||
| 503 | .num_resources = ARRAY_SIZE(mxc_usbh1_resources), | ||
| 504 | }; | ||
| 505 | |||
| 506 | /* USB host 2 */ | ||
| 507 | static u64 usbh2_dmamask = 0xffffffffUL; | ||
| 508 | |||
| 509 | static struct resource mxc_usbh2_resources[] = { | ||
| 510 | { | ||
| 511 | .start = OTG_BASE_ADDR + 0x400, | ||
| 512 | .end = OTG_BASE_ADDR + 0x5ff, | ||
| 513 | .flags = IORESOURCE_MEM, | ||
| 514 | }, { | ||
| 515 | .start = MXC_INT_USB2, | ||
| 516 | .end = MXC_INT_USB2, | ||
| 517 | .flags = IORESOURCE_IRQ, | ||
| 518 | }, | ||
| 519 | }; | ||
| 520 | |||
| 521 | struct platform_device mxc_usbh2 = { | ||
| 522 | .name = "mxc-ehci", | ||
| 523 | .id = 2, | ||
| 524 | .dev = { | ||
| 525 | .coherent_dma_mask = 0xffffffff, | ||
| 526 | .dma_mask = &usbh2_dmamask, | ||
| 527 | }, | ||
| 528 | .resource = mxc_usbh2_resources, | ||
| 529 | .num_resources = ARRAY_SIZE(mxc_usbh2_resources), | ||
| 530 | }; | ||
| 531 | #endif | ||
| 532 | |||
| 410 | /* GPIO port description */ | 533 | /* GPIO port description */ |
| 411 | static struct mxc_gpio_port imx_gpio_ports[] = { | 534 | static struct mxc_gpio_port imx_gpio_ports[] = { |
| 412 | [0] = { | 535 | { |
| 413 | .chip.label = "gpio-0", | 536 | .chip.label = "gpio-0", |
| 414 | .irq = MXC_INT_GPIO, | 537 | .irq = MXC_INT_GPIO, |
| 415 | .base = IO_ADDRESS(GPIO_BASE_ADDR), | 538 | .base = IO_ADDRESS(GPIO_BASE_ADDR), |
| 416 | .virtual_irq_start = MXC_GPIO_IRQ_START, | 539 | .virtual_irq_start = MXC_GPIO_IRQ_START, |
| 417 | }, | 540 | }, { |
| 418 | [1] = { | ||
| 419 | .chip.label = "gpio-1", | 541 | .chip.label = "gpio-1", |
| 420 | .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100), | 542 | .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100), |
| 421 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32, | 543 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32, |
| 422 | }, | 544 | }, { |
| 423 | [2] = { | ||
| 424 | .chip.label = "gpio-2", | 545 | .chip.label = "gpio-2", |
| 425 | .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200), | 546 | .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200), |
| 426 | .virtual_irq_start = MXC_GPIO_IRQ_START + 64, | 547 | .virtual_irq_start = MXC_GPIO_IRQ_START + 64, |
| 427 | }, | 548 | }, { |
| 428 | [3] = { | ||
| 429 | .chip.label = "gpio-3", | 549 | .chip.label = "gpio-3", |
| 430 | .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300), | 550 | .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300), |
| 431 | .virtual_irq_start = MXC_GPIO_IRQ_START + 96, | 551 | .virtual_irq_start = MXC_GPIO_IRQ_START + 96, |
| 432 | }, | 552 | }, { |
| 433 | [4] = { | ||
| 434 | .chip.label = "gpio-4", | 553 | .chip.label = "gpio-4", |
| 435 | .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400), | 554 | .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400), |
| 436 | .virtual_irq_start = MXC_GPIO_IRQ_START + 128, | 555 | .virtual_irq_start = MXC_GPIO_IRQ_START + 128, |
| 437 | }, | 556 | }, { |
| 438 | [5] = { | ||
| 439 | .chip.label = "gpio-5", | 557 | .chip.label = "gpio-5", |
| 440 | .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500), | 558 | .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500), |
| 441 | .virtual_irq_start = MXC_GPIO_IRQ_START + 160, | 559 | .virtual_irq_start = MXC_GPIO_IRQ_START + 160, |
diff --git a/arch/arm/mach-mx2/devices.h b/arch/arm/mach-mx2/devices.h index 049005bb6aa9..d315406d6725 100644 --- a/arch/arm/mach-mx2/devices.h +++ b/arch/arm/mach-mx2/devices.h | |||
| @@ -4,7 +4,6 @@ extern struct platform_device mxc_gpt3; | |||
| 4 | extern struct platform_device mxc_gpt4; | 4 | extern struct platform_device mxc_gpt4; |
| 5 | extern struct platform_device mxc_gpt5; | 5 | extern struct platform_device mxc_gpt5; |
| 6 | extern struct platform_device mxc_wdt; | 6 | extern struct platform_device mxc_wdt; |
| 7 | extern struct platform_device mxc_irda_device; | ||
| 8 | extern struct platform_device mxc_uart_device0; | 7 | extern struct platform_device mxc_uart_device0; |
| 9 | extern struct platform_device mxc_uart_device1; | 8 | extern struct platform_device mxc_uart_device1; |
| 10 | extern struct platform_device mxc_uart_device2; | 9 | extern struct platform_device mxc_uart_device2; |
| @@ -20,3 +19,11 @@ extern struct platform_device mxc_i2c_device0; | |||
| 20 | extern struct platform_device mxc_i2c_device1; | 19 | extern struct platform_device mxc_i2c_device1; |
| 21 | extern struct platform_device mxc_sdhc_device0; | 20 | extern struct platform_device mxc_sdhc_device0; |
| 22 | extern struct platform_device mxc_sdhc_device1; | 21 | extern struct platform_device mxc_sdhc_device1; |
| 22 | extern struct platform_device mxc_otg_udc_device; | ||
| 23 | extern struct platform_device mxc_otg_host; | ||
| 24 | extern struct platform_device mxc_usbh1; | ||
| 25 | extern struct platform_device mxc_usbh2; | ||
| 26 | extern struct platform_device mxc_spi_device0; | ||
| 27 | extern struct platform_device mxc_spi_device1; | ||
| 28 | extern struct platform_device mxc_spi_device2; | ||
| 29 | |||
diff --git a/arch/arm/mach-mx2/eukrea_cpuimx27.c b/arch/arm/mach-mx2/eukrea_cpuimx27.c new file mode 100644 index 000000000000..7b187606682c --- /dev/null +++ b/arch/arm/mach-mx2/eukrea_cpuimx27.c | |||
| @@ -0,0 +1,234 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 Eric Benard - eric@eukrea.com | ||
| 3 | * | ||
| 4 | * Based on pcm038.c which is : | ||
| 5 | * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix | ||
| 6 | * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU General Public License | ||
| 10 | * as published by the Free Software Foundation; either version 2 | ||
| 11 | * of the License, or (at your option) any later version. | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
| 20 | * MA 02110-1301, USA. | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/i2c.h> | ||
| 24 | #include <linux/io.h> | ||
| 25 | #include <linux/mtd/plat-ram.h> | ||
| 26 | #include <linux/mtd/physmap.h> | ||
| 27 | #include <linux/platform_device.h> | ||
| 28 | #include <linux/serial_8250.h> | ||
| 29 | |||
| 30 | #include <asm/mach-types.h> | ||
| 31 | #include <asm/mach/arch.h> | ||
| 32 | #include <asm/mach/time.h> | ||
| 33 | #include <asm/mach/map.h> | ||
| 34 | |||
| 35 | #include <mach/board-eukrea_cpuimx27.h> | ||
| 36 | #include <mach/common.h> | ||
| 37 | #include <mach/hardware.h> | ||
| 38 | #include <mach/i2c.h> | ||
| 39 | #include <mach/iomux.h> | ||
| 40 | #include <mach/imx-uart.h> | ||
| 41 | #include <mach/mxc_nand.h> | ||
| 42 | |||
| 43 | #include "devices.h" | ||
| 44 | |||
| 45 | static int eukrea_cpuimx27_pins[] = { | ||
| 46 | /* UART1 */ | ||
| 47 | PE12_PF_UART1_TXD, | ||
| 48 | PE13_PF_UART1_RXD, | ||
| 49 | PE14_PF_UART1_CTS, | ||
| 50 | PE15_PF_UART1_RTS, | ||
| 51 | /* UART4 */ | ||
| 52 | PB26_AF_UART4_RTS, | ||
| 53 | PB28_AF_UART4_TXD, | ||
| 54 | PB29_AF_UART4_CTS, | ||
| 55 | PB31_AF_UART4_RXD, | ||
| 56 | /* FEC */ | ||
| 57 | PD0_AIN_FEC_TXD0, | ||
| 58 | PD1_AIN_FEC_TXD1, | ||
| 59 | PD2_AIN_FEC_TXD2, | ||
| 60 | PD3_AIN_FEC_TXD3, | ||
| 61 | PD4_AOUT_FEC_RX_ER, | ||
| 62 | PD5_AOUT_FEC_RXD1, | ||
| 63 | PD6_AOUT_FEC_RXD2, | ||
| 64 | PD7_AOUT_FEC_RXD3, | ||
| 65 | PD8_AF_FEC_MDIO, | ||
| 66 | PD9_AIN_FEC_MDC, | ||
| 67 | PD10_AOUT_FEC_CRS, | ||
| 68 | PD11_AOUT_FEC_TX_CLK, | ||
| 69 | PD12_AOUT_FEC_RXD0, | ||
| 70 | PD13_AOUT_FEC_RX_DV, | ||
| 71 | PD14_AOUT_FEC_RX_CLK, | ||
| 72 | PD15_AOUT_FEC_COL, | ||
| 73 | PD16_AIN_FEC_TX_ER, | ||
| 74 | PF23_AIN_FEC_TX_EN, | ||
| 75 | /* I2C1 */ | ||
| 76 | PD17_PF_I2C_DATA, | ||
| 77 | PD18_PF_I2C_CLK, | ||
| 78 | /* SDHC2 */ | ||
| 79 | PB4_PF_SD2_D0, | ||
| 80 | PB5_PF_SD2_D1, | ||
| 81 | PB6_PF_SD2_D2, | ||
| 82 | PB7_PF_SD2_D3, | ||
| 83 | PB8_PF_SD2_CMD, | ||
| 84 | PB9_PF_SD2_CLK, | ||
| 85 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) | ||
| 86 | /* Quad UART's IRQ */ | ||
| 87 | GPIO_PORTD | 22 | GPIO_GPIO | GPIO_IN, | ||
| 88 | GPIO_PORTD | 23 | GPIO_GPIO | GPIO_IN, | ||
| 89 | GPIO_PORTD | 27 | GPIO_GPIO | GPIO_IN, | ||
| 90 | GPIO_PORTD | 30 | GPIO_GPIO | GPIO_IN, | ||
| 91 | #endif | ||
| 92 | }; | ||
| 93 | |||
| 94 | static struct physmap_flash_data eukrea_cpuimx27_flash_data = { | ||
| 95 | .width = 2, | ||
| 96 | }; | ||
| 97 | |||
| 98 | static struct resource eukrea_cpuimx27_flash_resource = { | ||
| 99 | .start = 0xc0000000, | ||
| 100 | .end = 0xc3ffffff, | ||
| 101 | .flags = IORESOURCE_MEM, | ||
| 102 | }; | ||
| 103 | |||
| 104 | static struct platform_device eukrea_cpuimx27_nor_mtd_device = { | ||
| 105 | .name = "physmap-flash", | ||
| 106 | .id = 0, | ||
| 107 | .dev = { | ||
| 108 | .platform_data = &eukrea_cpuimx27_flash_data, | ||
| 109 | }, | ||
| 110 | .num_resources = 1, | ||
| 111 | .resource = &eukrea_cpuimx27_flash_resource, | ||
| 112 | }; | ||
| 113 | |||
| 114 | static struct imxuart_platform_data uart_pdata[] = { | ||
| 115 | { | ||
| 116 | .flags = IMXUART_HAVE_RTSCTS, | ||
| 117 | }, { | ||
| 118 | .flags = IMXUART_HAVE_RTSCTS, | ||
| 119 | }, | ||
| 120 | }; | ||
| 121 | |||
| 122 | static struct mxc_nand_platform_data eukrea_cpuimx27_nand_board_info = { | ||
| 123 | .width = 1, | ||
| 124 | .hw_ecc = 1, | ||
| 125 | }; | ||
| 126 | |||
| 127 | static struct platform_device *platform_devices[] __initdata = { | ||
| 128 | &eukrea_cpuimx27_nor_mtd_device, | ||
| 129 | &mxc_fec_device, | ||
| 130 | }; | ||
| 131 | |||
| 132 | static struct imxi2c_platform_data eukrea_cpuimx27_i2c_1_data = { | ||
| 133 | .bitrate = 100000, | ||
| 134 | }; | ||
| 135 | |||
| 136 | static struct i2c_board_info eukrea_cpuimx27_i2c_devices[] = { | ||
| 137 | { | ||
| 138 | I2C_BOARD_INFO("pcf8563", 0x51), | ||
| 139 | }, | ||
| 140 | }; | ||
| 141 | |||
| 142 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) | ||
| 143 | static struct plat_serial8250_port serial_platform_data[] = { | ||
| 144 | { | ||
| 145 | .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x200000), | ||
| 146 | .irq = IRQ_GPIOB(23), | ||
| 147 | .uartclk = 14745600, | ||
| 148 | .regshift = 1, | ||
| 149 | .iotype = UPIO_MEM, | ||
| 150 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, | ||
| 151 | }, { | ||
| 152 | .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x400000), | ||
| 153 | .irq = IRQ_GPIOB(22), | ||
| 154 | .uartclk = 14745600, | ||
| 155 | .regshift = 1, | ||
| 156 | .iotype = UPIO_MEM, | ||
| 157 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, | ||
| 158 | }, { | ||
| 159 | .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x800000), | ||
| 160 | .irq = IRQ_GPIOB(27), | ||
| 161 | .uartclk = 14745600, | ||
| 162 | .regshift = 1, | ||
| 163 | .iotype = UPIO_MEM, | ||
| 164 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, | ||
| 165 | }, { | ||
| 166 | .mapbase = (unsigned long)(CS3_BASE_ADDR + 0x1000000), | ||
| 167 | .irq = IRQ_GPIOB(30), | ||
| 168 | .uartclk = 14745600, | ||
| 169 | .regshift = 1, | ||
| 170 | .iotype = UPIO_MEM, | ||
| 171 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, | ||
| 172 | }, { | ||
| 173 | } | ||
| 174 | }; | ||
| 175 | |||
| 176 | static struct platform_device serial_device = { | ||
| 177 | .name = "serial8250", | ||
| 178 | .id = 0, | ||
| 179 | .dev = { | ||
| 180 | .platform_data = serial_platform_data, | ||
| 181 | }, | ||
| 182 | }; | ||
| 183 | #endif | ||
| 184 | |||
| 185 | static void __init eukrea_cpuimx27_init(void) | ||
| 186 | { | ||
| 187 | mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins, | ||
| 188 | ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27"); | ||
| 189 | |||
| 190 | mxc_register_device(&mxc_uart_device0, &uart_pdata[0]); | ||
| 191 | |||
| 192 | mxc_register_device(&mxc_nand_device, &eukrea_cpuimx27_nand_board_info); | ||
| 193 | |||
| 194 | i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices, | ||
| 195 | ARRAY_SIZE(eukrea_cpuimx27_i2c_devices)); | ||
| 196 | |||
| 197 | mxc_register_device(&mxc_i2c_device0, &eukrea_cpuimx27_i2c_1_data); | ||
| 198 | |||
| 199 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | ||
| 200 | |||
| 201 | #if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2) | ||
| 202 | /* SDHC2 can be used for Wifi */ | ||
| 203 | mxc_register_device(&mxc_sdhc_device1, NULL); | ||
| 204 | /* in which case UART4 is also used for Bluetooth */ | ||
| 205 | mxc_register_device(&mxc_uart_device3, &uart_pdata[1]); | ||
| 206 | #endif | ||
| 207 | |||
| 208 | #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) | ||
| 209 | platform_device_register(&serial_device); | ||
| 210 | #endif | ||
| 211 | |||
| 212 | #ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD | ||
| 213 | eukrea_mbimx27_baseboard_init(); | ||
| 214 | #endif | ||
| 215 | } | ||
| 216 | |||
| 217 | static void __init eukrea_cpuimx27_timer_init(void) | ||
| 218 | { | ||
| 219 | mx27_clocks_init(26000000); | ||
| 220 | } | ||
| 221 | |||
| 222 | static struct sys_timer eukrea_cpuimx27_timer = { | ||
| 223 | .init = eukrea_cpuimx27_timer_init, | ||
| 224 | }; | ||
| 225 | |||
| 226 | MACHINE_START(CPUIMX27, "EUKREA CPUIMX27") | ||
| 227 | .phys_io = AIPI_BASE_ADDR, | ||
| 228 | .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, | ||
| 229 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 230 | .map_io = mx27_map_io, | ||
| 231 | .init_irq = mx27_init_irq, | ||
| 232 | .init_machine = eukrea_cpuimx27_init, | ||
| 233 | .timer = &eukrea_cpuimx27_timer, | ||
| 234 | MACHINE_END | ||
diff --git a/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c b/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c new file mode 100644 index 000000000000..7382b6d27ee1 --- /dev/null +++ b/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c | |||
| @@ -0,0 +1,249 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 Eric Benard - eric@eukrea.com | ||
| 3 | * | ||
| 4 | * Based on pcm970-baseboard.c which is : | ||
| 5 | * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version 2 | ||
| 10 | * of the License, or (at your option) any later version. | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
| 19 | * MA 02110-1301, USA. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/gpio.h> | ||
| 23 | #include <linux/irq.h> | ||
| 24 | #include <linux/platform_device.h> | ||
| 25 | #include <linux/spi/spi.h> | ||
| 26 | #include <linux/spi/ads7846.h> | ||
| 27 | |||
| 28 | #include <asm/mach/arch.h> | ||
| 29 | |||
| 30 | #include <mach/common.h> | ||
| 31 | #include <mach/iomux.h> | ||
| 32 | #include <mach/imxfb.h> | ||
| 33 | #include <mach/hardware.h> | ||
| 34 | #include <mach/mmc.h> | ||
| 35 | #include <mach/imx-uart.h> | ||
| 36 | |||
| 37 | #include "devices.h" | ||
| 38 | |||
| 39 | static int eukrea_mbimx27_pins[] = { | ||
| 40 | /* UART2 */ | ||
| 41 | PE3_PF_UART2_CTS, | ||
| 42 | PE4_PF_UART2_RTS, | ||
| 43 | PE6_PF_UART2_TXD, | ||
| 44 | PE7_PF_UART2_RXD, | ||
| 45 | /* UART3 */ | ||
| 46 | PE8_PF_UART3_TXD, | ||
| 47 | PE9_PF_UART3_RXD, | ||
| 48 | PE10_PF_UART3_CTS, | ||
| 49 | PE11_PF_UART3_RTS, | ||
| 50 | /* UART4 */ | ||
| 51 | PB26_AF_UART4_RTS, | ||
| 52 | PB28_AF_UART4_TXD, | ||
| 53 | PB29_AF_UART4_CTS, | ||
| 54 | PB31_AF_UART4_RXD, | ||
| 55 | /* SDHC1*/ | ||
| 56 | PE18_PF_SD1_D0, | ||
| 57 | PE19_PF_SD1_D1, | ||
| 58 | PE20_PF_SD1_D2, | ||
| 59 | PE21_PF_SD1_D3, | ||
| 60 | PE22_PF_SD1_CMD, | ||
| 61 | PE23_PF_SD1_CLK, | ||
| 62 | /* display */ | ||
| 63 | PA5_PF_LSCLK, | ||
| 64 | PA6_PF_LD0, | ||
| 65 | PA7_PF_LD1, | ||
| 66 | PA8_PF_LD2, | ||
| 67 | PA9_PF_LD3, | ||
| 68 | PA10_PF_LD4, | ||
| 69 | PA11_PF_LD5, | ||
| 70 | PA12_PF_LD6, | ||
| 71 | PA13_PF_LD7, | ||
| 72 | PA14_PF_LD8, | ||
| 73 | PA15_PF_LD9, | ||
| 74 | PA16_PF_LD10, | ||
| 75 | PA17_PF_LD11, | ||
| 76 | PA18_PF_LD12, | ||
| 77 | PA19_PF_LD13, | ||
| 78 | PA20_PF_LD14, | ||
| 79 | PA21_PF_LD15, | ||
| 80 | PA22_PF_LD16, | ||
| 81 | PA23_PF_LD17, | ||
| 82 | PA28_PF_HSYNC, | ||
| 83 | PA29_PF_VSYNC, | ||
| 84 | PA30_PF_CONTRAST, | ||
| 85 | PA31_PF_OE_ACD, | ||
| 86 | /* SPI1 */ | ||
| 87 | PD28_PF_CSPI1_SS0, | ||
| 88 | PD29_PF_CSPI1_SCLK, | ||
| 89 | PD30_PF_CSPI1_MISO, | ||
| 90 | PD31_PF_CSPI1_MOSI, | ||
| 91 | }; | ||
| 92 | |||
| 93 | static struct gpio_led gpio_leds[] = { | ||
| 94 | { | ||
| 95 | .name = "led1", | ||
| 96 | .default_trigger = "heartbeat", | ||
| 97 | .active_low = 1, | ||
| 98 | .gpio = GPIO_PORTF | 16, | ||
| 99 | }, | ||
| 100 | { | ||
| 101 | .name = "led2", | ||
| 102 | .default_trigger = "none", | ||
| 103 | .active_low = 1, | ||
| 104 | .gpio = GPIO_PORTF | 19, | ||
| 105 | }, | ||
| 106 | { | ||
| 107 | .name = "backlight", | ||
| 108 | .default_trigger = "backlight", | ||
| 109 | .active_low = 0, | ||
| 110 | .gpio = GPIO_PORTE | 5, | ||
| 111 | }, | ||
| 112 | }; | ||
| 113 | |||
| 114 | static struct gpio_led_platform_data gpio_led_info = { | ||
| 115 | .leds = gpio_leds, | ||
| 116 | .num_leds = ARRAY_SIZE(gpio_leds), | ||
| 117 | }; | ||
| 118 | |||
| 119 | static struct platform_device leds_gpio = { | ||
| 120 | .name = "leds-gpio", | ||
| 121 | .id = -1, | ||
| 122 | .dev = { | ||
| 123 | .platform_data = &gpio_led_info, | ||
| 124 | }, | ||
| 125 | }; | ||
| 126 | |||
| 127 | static struct imx_fb_videomode eukrea_mbimx27_modes[] = { | ||
| 128 | { | ||
| 129 | .mode = { | ||
| 130 | .name = "CMO-QGVA", | ||
| 131 | .refresh = 60, | ||
| 132 | .xres = 320, | ||
| 133 | .yres = 240, | ||
| 134 | .pixclock = 156000, | ||
| 135 | .hsync_len = 30, | ||
| 136 | .left_margin = 38, | ||
| 137 | .right_margin = 20, | ||
| 138 | .vsync_len = 3, | ||
| 139 | .upper_margin = 15, | ||
| 140 | .lower_margin = 4, | ||
| 141 | }, | ||
| 142 | .pcr = 0xFAD08B80, | ||
| 143 | .bpp = 16, | ||
| 144 | }, | ||
| 145 | }; | ||
| 146 | |||
| 147 | static struct imx_fb_platform_data eukrea_mbimx27_fb_data = { | ||
| 148 | .mode = eukrea_mbimx27_modes, | ||
| 149 | .num_modes = ARRAY_SIZE(eukrea_mbimx27_modes), | ||
| 150 | |||
| 151 | .pwmr = 0x00A903FF, | ||
| 152 | .lscr1 = 0x00120300, | ||
| 153 | .dmacr = 0x00040060, | ||
| 154 | }; | ||
| 155 | |||
| 156 | static struct imxuart_platform_data uart_pdata[] = { | ||
| 157 | { | ||
| 158 | .flags = IMXUART_HAVE_RTSCTS, | ||
| 159 | }, | ||
| 160 | { | ||
| 161 | .flags = IMXUART_HAVE_RTSCTS, | ||
| 162 | }, | ||
| 163 | }; | ||
| 164 | |||
| 165 | #if defined(CONFIG_TOUCHSCREEN_ADS7846) | ||
| 166 | || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) | ||
| 167 | |||
| 168 | #define ADS7846_PENDOWN (GPIO_PORTD | 25) | ||
| 169 | |||
| 170 | static void ads7846_dev_init(void) | ||
| 171 | { | ||
| 172 | if (gpio_request(ADS7846_PENDOWN, "ADS7846 pendown") < 0) { | ||
| 173 | printk(KERN_ERR "can't get ads746 pen down GPIO\n"); | ||
| 174 | return; | ||
| 175 | } | ||
| 176 | |||
| 177 | gpio_direction_input(ADS7846_PENDOWN); | ||
| 178 | } | ||
| 179 | |||
| 180 | static int ads7846_get_pendown_state(void) | ||
| 181 | { | ||
| 182 | return !gpio_get_value(ADS7846_PENDOWN); | ||
| 183 | } | ||
| 184 | |||
| 185 | static struct ads7846_platform_data ads7846_config __initdata = { | ||
| 186 | .get_pendown_state = ads7846_get_pendown_state, | ||
| 187 | .keep_vref_on = 1, | ||
| 188 | }; | ||
| 189 | |||
| 190 | static struct spi_board_info eukrea_mbimx27_spi_board_info[] __initdata = { | ||
| 191 | [0] = { | ||
| 192 | .modalias = "ads7846", | ||
| 193 | .bus_num = 0, | ||
| 194 | .chip_select = 0, | ||
| 195 | .max_speed_hz = 1500000, | ||
| 196 | .irq = IRQ_GPIOD(25), | ||
| 197 | .platform_data = &ads7846_config, | ||
| 198 | .mode = SPI_MODE_2, | ||
| 199 | }, | ||
| 200 | }; | ||
| 201 | |||
| 202 | static int eukrea_mbimx27_spi_cs[] = {GPIO_PORTD | 28}; | ||
| 203 | |||
| 204 | static struct spi_imx_master eukrea_mbimx27_spi_0_data = { | ||
| 205 | .chipselect = eukrea_mbimx27_spi_cs, | ||
| 206 | .num_chipselect = ARRAY_SIZE(eukrea_mbimx27_spi_cs), | ||
| 207 | }; | ||
| 208 | #endif | ||
| 209 | |||
| 210 | static struct platform_device *platform_devices[] __initdata = { | ||
| 211 | &leds_gpio, | ||
| 212 | }; | ||
| 213 | |||
| 214 | /* | ||
| 215 | * system init for baseboard usage. Will be called by cpuimx27 init. | ||
| 216 | * | ||
| 217 | * Add platform devices present on this baseboard and init | ||
| 218 | * them from CPU side as far as required to use them later on | ||
| 219 | */ | ||
| 220 | void __init eukrea_mbimx27_baseboard_init(void) | ||
| 221 | { | ||
| 222 | mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins, | ||
| 223 | ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27"); | ||
| 224 | |||
| 225 | mxc_register_device(&mxc_uart_device1, &uart_pdata[0]); | ||
| 226 | mxc_register_device(&mxc_uart_device2, &uart_pdata[1]); | ||
| 227 | |||
| 228 | mxc_register_device(&mxc_fb_device, &eukrea_mbimx27_fb_data); | ||
| 229 | mxc_register_device(&mxc_sdhc_device0, NULL); | ||
| 230 | |||
| 231 | #if defined(CONFIG_TOUCHSCREEN_ADS7846) | ||
| 232 | || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) | ||
| 233 | /* SPI and ADS7846 Touchscreen controler init */ | ||
| 234 | mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT); | ||
| 235 | mxc_gpio_mode(GPIO_PORTD | 25 | GPIO_GPIO | GPIO_IN); | ||
| 236 | mxc_register_device(&mxc_spi_device0, &eukrea_mbimx27_spi_0_data); | ||
| 237 | spi_register_board_info(eukrea_mbimx27_spi_board_info, | ||
| 238 | ARRAY_SIZE(eukrea_mbimx27_spi_board_info)); | ||
| 239 | ads7846_dev_init(); | ||
| 240 | #endif | ||
| 241 | |||
| 242 | /* Leds configuration */ | ||
| 243 | mxc_gpio_mode(GPIO_PORTF | 16 | GPIO_GPIO | GPIO_OUT); | ||
| 244 | mxc_gpio_mode(GPIO_PORTF | 19 | GPIO_GPIO | GPIO_OUT); | ||
| 245 | /* Backlight */ | ||
| 246 | mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_OUT); | ||
| 247 | |||
| 248 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | ||
| 249 | } | ||
diff --git a/arch/arm/mach-mx2/generic.c b/arch/arm/mach-mx2/generic.c index 169372f69d8f..ae8f759134d1 100644 --- a/arch/arm/mach-mx2/generic.c +++ b/arch/arm/mach-mx2/generic.c | |||
| @@ -72,6 +72,7 @@ static struct map_desc mxc_io_desc[] __initdata = { | |||
| 72 | void __init mx21_map_io(void) | 72 | void __init mx21_map_io(void) |
| 73 | { | 73 | { |
| 74 | mxc_set_cpu_type(MXC_CPU_MX21); | 74 | mxc_set_cpu_type(MXC_CPU_MX21); |
| 75 | mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR)); | ||
| 75 | 76 | ||
| 76 | iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); | 77 | iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); |
| 77 | } | 78 | } |
| @@ -79,7 +80,18 @@ void __init mx21_map_io(void) | |||
| 79 | void __init mx27_map_io(void) | 80 | void __init mx27_map_io(void) |
| 80 | { | 81 | { |
| 81 | mxc_set_cpu_type(MXC_CPU_MX27); | 82 | mxc_set_cpu_type(MXC_CPU_MX27); |
| 83 | mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR)); | ||
| 82 | 84 | ||
| 83 | iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); | 85 | iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); |
| 84 | } | 86 | } |
| 85 | 87 | ||
| 88 | void __init mx27_init_irq(void) | ||
| 89 | { | ||
| 90 | mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR)); | ||
| 91 | } | ||
| 92 | |||
| 93 | void __init mx21_init_irq(void) | ||
| 94 | { | ||
| 95 | mx27_init_irq(); | ||
| 96 | } | ||
| 97 | |||
diff --git a/arch/arm/mach-mx2/mx21ads.c b/arch/arm/mach-mx2/mx21ads.c index a5ee461cb405..cf5f77cbc2f1 100644 --- a/arch/arm/mach-mx2/mx21ads.c +++ b/arch/arm/mach-mx2/mx21ads.c | |||
| @@ -164,25 +164,33 @@ static void mx21ads_fb_exit(struct platform_device *pdev) | |||
| 164 | * Connected is a portrait Sharp-QVGA display | 164 | * Connected is a portrait Sharp-QVGA display |
| 165 | * of type: LQ035Q7DB02 | 165 | * of type: LQ035Q7DB02 |
| 166 | */ | 166 | */ |
| 167 | static struct imx_fb_platform_data mx21ads_fb_data = { | 167 | static struct imx_fb_videomode mx21ads_modes[] = { |
| 168 | .pixclock = 188679, /* in ps */ | 168 | { |
| 169 | .xres = 240, | 169 | .mode = { |
| 170 | .yres = 320, | 170 | .name = "Sharp-LQ035Q7", |
| 171 | 171 | .refresh = 60, | |
| 172 | .bpp = 16, | 172 | .xres = 240, |
| 173 | .hsync_len = 2, | 173 | .yres = 320, |
| 174 | .left_margin = 6, | 174 | .pixclock = 188679, /* in ps (5.3MHz) */ |
| 175 | .right_margin = 16, | 175 | .hsync_len = 2, |
| 176 | .left_margin = 6, | ||
| 177 | .right_margin = 16, | ||
| 178 | .vsync_len = 1, | ||
| 179 | .upper_margin = 8, | ||
| 180 | .lower_margin = 10, | ||
| 181 | }, | ||
| 182 | .pcr = 0xfb108bc7, | ||
| 183 | .bpp = 16, | ||
| 184 | }, | ||
| 185 | }; | ||
| 176 | 186 | ||
| 177 | .vsync_len = 1, | 187 | static struct imx_fb_platform_data mx21ads_fb_data = { |
| 178 | .upper_margin = 8, | 188 | .mode = mx21ads_modes, |
| 179 | .lower_margin = 10, | 189 | .num_modes = ARRAY_SIZE(mx21ads_modes), |
| 180 | .fixed_screen_cpu = 0, | ||
| 181 | 190 | ||
| 182 | .pcr = 0xFB108BC7, | 191 | .pwmr = 0x00a903ff, |
| 183 | .pwmr = 0x00A901ff, | 192 | .lscr1 = 0x00120300, |
| 184 | .lscr1 = 0x00120300, | 193 | .dmacr = 0x00020008, |
| 185 | .dmacr = 0x00020008, | ||
| 186 | 194 | ||
| 187 | .init = mx21ads_fb_init, | 195 | .init = mx21ads_fb_init, |
| 188 | .exit = mx21ads_fb_exit, | 196 | .exit = mx21ads_fb_exit, |
| @@ -280,7 +288,7 @@ MACHINE_START(MX21ADS, "Freescale i.MX21ADS") | |||
| 280 | .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 288 | .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 281 | .boot_params = PHYS_OFFSET + 0x100, | 289 | .boot_params = PHYS_OFFSET + 0x100, |
| 282 | .map_io = mx21ads_map_io, | 290 | .map_io = mx21ads_map_io, |
| 283 | .init_irq = mxc_init_irq, | 291 | .init_irq = mx21_init_irq, |
| 284 | .init_machine = mx21ads_board_init, | 292 | .init_machine = mx21ads_board_init, |
| 285 | .timer = &mx21ads_timer, | 293 | .timer = &mx21ads_timer, |
| 286 | MACHINE_END | 294 | MACHINE_END |
diff --git a/arch/arm/mach-mx2/mx27ads.c b/arch/arm/mach-mx2/mx27ads.c index 02daddac6995..83e412b713e6 100644 --- a/arch/arm/mach-mx2/mx27ads.c +++ b/arch/arm/mach-mx2/mx27ads.c | |||
| @@ -183,20 +183,29 @@ void lcd_power(int on) | |||
| 183 | __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); | 183 | __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | static struct imx_fb_platform_data mx27ads_fb_data = { | 186 | static struct imx_fb_videomode mx27ads_modes[] = { |
| 187 | .pixclock = 188679, | 187 | { |
| 188 | .xres = 240, | 188 | .mode = { |
| 189 | .yres = 320, | 189 | .name = "Sharp-LQ035Q7", |
| 190 | 190 | .refresh = 60, | |
| 191 | .bpp = 16, | 191 | .xres = 240, |
| 192 | .hsync_len = 1, | 192 | .yres = 320, |
| 193 | .left_margin = 9, | 193 | .pixclock = 188679, /* in ps (5.3MHz) */ |
| 194 | .right_margin = 16, | 194 | .hsync_len = 1, |
| 195 | .left_margin = 9, | ||
| 196 | .right_margin = 16, | ||
| 197 | .vsync_len = 1, | ||
| 198 | .upper_margin = 7, | ||
| 199 | .lower_margin = 9, | ||
| 200 | }, | ||
| 201 | .bpp = 16, | ||
| 202 | .pcr = 0xFB008BC0, | ||
| 203 | }, | ||
| 204 | }; | ||
| 195 | 205 | ||
| 196 | .vsync_len = 1, | 206 | static struct imx_fb_platform_data mx27ads_fb_data = { |
| 197 | .upper_margin = 7, | 207 | .mode = mx27ads_modes, |
| 198 | .lower_margin = 9, | 208 | .num_modes = ARRAY_SIZE(mx27ads_modes), |
| 199 | .fixed_screen_cpu = 0, | ||
| 200 | 209 | ||
| 201 | /* | 210 | /* |
| 202 | * - HSYNC active high | 211 | * - HSYNC active high |
| @@ -207,7 +216,6 @@ static struct imx_fb_platform_data mx27ads_fb_data = { | |||
| 207 | * - data enable low active | 216 | * - data enable low active |
| 208 | * - enable sharp mode | 217 | * - enable sharp mode |
| 209 | */ | 218 | */ |
| 210 | .pcr = 0xFB008BC0, | ||
| 211 | .pwmr = 0x00A903FF, | 219 | .pwmr = 0x00A903FF, |
| 212 | .lscr1 = 0x00120300, | 220 | .lscr1 = 0x00120300, |
| 213 | .dmacr = 0x00020010, | 221 | .dmacr = 0x00020010, |
| @@ -330,7 +338,7 @@ MACHINE_START(MX27ADS, "Freescale i.MX27ADS") | |||
| 330 | .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 338 | .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 331 | .boot_params = PHYS_OFFSET + 0x100, | 339 | .boot_params = PHYS_OFFSET + 0x100, |
| 332 | .map_io = mx27ads_map_io, | 340 | .map_io = mx27ads_map_io, |
| 333 | .init_irq = mxc_init_irq, | 341 | .init_irq = mx27_init_irq, |
| 334 | .init_machine = mx27ads_board_init, | 342 | .init_machine = mx27ads_board_init, |
| 335 | .timer = &mx27ads_timer, | 343 | .timer = &mx27ads_timer, |
| 336 | MACHINE_END | 344 | MACHINE_END |
diff --git a/arch/arm/mach-mx2/mx27lite.c b/arch/arm/mach-mx2/mx27lite.c index 3ae11cb8c04b..82ea227ea0cf 100644 --- a/arch/arm/mach-mx2/mx27lite.c +++ b/arch/arm/mach-mx2/mx27lite.c | |||
| @@ -89,7 +89,7 @@ MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE") | |||
| 89 | .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 89 | .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 90 | .boot_params = PHYS_OFFSET + 0x100, | 90 | .boot_params = PHYS_OFFSET + 0x100, |
| 91 | .map_io = mx27_map_io, | 91 | .map_io = mx27_map_io, |
| 92 | .init_irq = mxc_init_irq, | 92 | .init_irq = mx27_init_irq, |
| 93 | .init_machine = mx27lite_init, | 93 | .init_machine = mx27lite_init, |
| 94 | .timer = &mx27lite_timer, | 94 | .timer = &mx27lite_timer, |
| 95 | MACHINE_END | 95 | MACHINE_END |
diff --git a/arch/arm/mach-mx2/mx27pdk.c b/arch/arm/mach-mx2/mx27pdk.c index 1d9238c7a6c3..6761d1b79e43 100644 --- a/arch/arm/mach-mx2/mx27pdk.c +++ b/arch/arm/mach-mx2/mx27pdk.c | |||
| @@ -89,7 +89,7 @@ MACHINE_START(MX27_3DS, "Freescale MX27PDK") | |||
| 89 | .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 89 | .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 90 | .boot_params = PHYS_OFFSET + 0x100, | 90 | .boot_params = PHYS_OFFSET + 0x100, |
| 91 | .map_io = mx27_map_io, | 91 | .map_io = mx27_map_io, |
| 92 | .init_irq = mxc_init_irq, | 92 | .init_irq = mx27_init_irq, |
| 93 | .init_machine = mx27pdk_init, | 93 | .init_machine = mx27pdk_init, |
| 94 | .timer = &mx27pdk_timer, | 94 | .timer = &mx27pdk_timer, |
| 95 | MACHINE_END | 95 | MACHINE_END |
diff --git a/arch/arm/mach-mx2/pca100.c b/arch/arm/mach-mx2/pca100.c new file mode 100644 index 000000000000..fe5b165b88cc --- /dev/null +++ b/arch/arm/mach-mx2/pca100.c | |||
| @@ -0,0 +1,244 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix | ||
| 3 | * Copyright (C) 2009 Sascha Hauer (kernel@pengutronix.de) | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License | ||
| 7 | * as published by the Free Software Foundation; either version 2 | ||
| 8 | * of the License, or (at your option) any later version. | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
| 17 | * MA 02110-1301, USA. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | #include <linux/i2c.h> | ||
| 23 | #include <linux/i2c/at24.h> | ||
| 24 | #include <linux/dma-mapping.h> | ||
| 25 | #include <linux/spi/spi.h> | ||
| 26 | #include <linux/spi/eeprom.h> | ||
| 27 | #include <linux/irq.h> | ||
| 28 | #include <linux/gpio.h> | ||
| 29 | |||
| 30 | #include <asm/mach/arch.h> | ||
| 31 | #include <asm/mach-types.h> | ||
| 32 | #include <mach/common.h> | ||
| 33 | #include <mach/hardware.h> | ||
| 34 | #include <mach/iomux.h> | ||
| 35 | #include <mach/i2c.h> | ||
| 36 | #include <asm/mach/time.h> | ||
| 37 | #if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) | ||
| 38 | #include <mach/spi.h> | ||
| 39 | #endif | ||
| 40 | #include <mach/imx-uart.h> | ||
| 41 | #include <mach/mxc_nand.h> | ||
| 42 | #include <mach/irqs.h> | ||
| 43 | #include <mach/mmc.h> | ||
| 44 | |||
| 45 | #include "devices.h" | ||
| 46 | |||
| 47 | static int pca100_pins[] = { | ||
| 48 | /* UART1 */ | ||
| 49 | PE12_PF_UART1_TXD, | ||
| 50 | PE13_PF_UART1_RXD, | ||
| 51 | PE14_PF_UART1_CTS, | ||
| 52 | PE15_PF_UART1_RTS, | ||
| 53 | /* SDHC */ | ||
| 54 | PB4_PF_SD2_D0, | ||
| 55 | PB5_PF_SD2_D1, | ||
| 56 | PB6_PF_SD2_D2, | ||
| 57 | PB7_PF_SD2_D3, | ||
| 58 | PB8_PF_SD2_CMD, | ||
| 59 | PB9_PF_SD2_CLK, | ||
| 60 | /* FEC */ | ||
| 61 | PD0_AIN_FEC_TXD0, | ||
| 62 | PD1_AIN_FEC_TXD1, | ||
| 63 | PD2_AIN_FEC_TXD2, | ||
| 64 | PD3_AIN_FEC_TXD3, | ||
| 65 | PD4_AOUT_FEC_RX_ER, | ||
| 66 | PD5_AOUT_FEC_RXD1, | ||
| 67 | PD6_AOUT_FEC_RXD2, | ||
| 68 | PD7_AOUT_FEC_RXD3, | ||
| 69 | PD8_AF_FEC_MDIO, | ||
| 70 | PD9_AIN_FEC_MDC, | ||
| 71 | PD10_AOUT_FEC_CRS, | ||
| 72 | PD11_AOUT_FEC_TX_CLK, | ||
| 73 | PD12_AOUT_FEC_RXD0, | ||
| 74 | PD13_AOUT_FEC_RX_DV, | ||
| 75 | PD14_AOUT_FEC_RX_CLK, | ||
| 76 | PD15_AOUT_FEC_COL, | ||
| 77 | PD16_AIN_FEC_TX_ER, | ||
| 78 | PF23_AIN_FEC_TX_EN, | ||
| 79 | /* SSI1 */ | ||
| 80 | PC20_PF_SSI1_FS, | ||
| 81 | PC21_PF_SSI1_RXD, | ||
| 82 | PC22_PF_SSI1_TXD, | ||
| 83 | PC23_PF_SSI1_CLK, | ||
| 84 | /* onboard I2C */ | ||
| 85 | PC5_PF_I2C2_SDA, | ||
| 86 | PC6_PF_I2C2_SCL, | ||
| 87 | /* external I2C */ | ||
| 88 | PD17_PF_I2C_DATA, | ||
| 89 | PD18_PF_I2C_CLK, | ||
| 90 | /* SPI1 */ | ||
| 91 | PD25_PF_CSPI1_RDY, | ||
| 92 | PD29_PF_CSPI1_SCLK, | ||
| 93 | PD30_PF_CSPI1_MISO, | ||
| 94 | PD31_PF_CSPI1_MOSI, | ||
| 95 | }; | ||
| 96 | |||
| 97 | static struct imxuart_platform_data uart_pdata = { | ||
| 98 | .flags = IMXUART_HAVE_RTSCTS, | ||
| 99 | }; | ||
| 100 | |||
| 101 | static struct mxc_nand_platform_data pca100_nand_board_info = { | ||
| 102 | .width = 1, | ||
| 103 | .hw_ecc = 1, | ||
| 104 | }; | ||
| 105 | |||
| 106 | static struct platform_device *platform_devices[] __initdata = { | ||
| 107 | &mxc_w1_master_device, | ||
| 108 | &mxc_fec_device, | ||
| 109 | }; | ||
| 110 | |||
| 111 | static struct imxi2c_platform_data pca100_i2c_1_data = { | ||
| 112 | .bitrate = 100000, | ||
| 113 | }; | ||
| 114 | |||
| 115 | static struct at24_platform_data board_eeprom = { | ||
| 116 | .byte_len = 4096, | ||
| 117 | .page_size = 32, | ||
| 118 | .flags = AT24_FLAG_ADDR16, | ||
| 119 | }; | ||
| 120 | |||
| 121 | static struct i2c_board_info pca100_i2c_devices[] = { | ||
| 122 | { | ||
| 123 | I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ | ||
| 124 | .platform_data = &board_eeprom, | ||
| 125 | }, { | ||
| 126 | I2C_BOARD_INFO("rtc-pcf8563", 0x51), | ||
| 127 | .type = "pcf8563" | ||
| 128 | }, { | ||
| 129 | I2C_BOARD_INFO("lm75", 0x4a), | ||
| 130 | .type = "lm75" | ||
| 131 | } | ||
| 132 | }; | ||
| 133 | |||
| 134 | #if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) | ||
| 135 | static struct spi_eeprom at25320 = { | ||
| 136 | .name = "at25320an", | ||
| 137 | .byte_len = 4096, | ||
| 138 | .page_size = 32, | ||
| 139 | .flags = EE_ADDR2, | ||
| 140 | }; | ||
| 141 | |||
| 142 | static struct spi_board_info pca100_spi_board_info[] __initdata = { | ||
| 143 | { | ||
| 144 | .modalias = "at25", | ||
| 145 | .max_speed_hz = 30000, | ||
| 146 | .bus_num = 0, | ||
| 147 | .chip_select = 1, | ||
| 148 | .platform_data = &at25320, | ||
| 149 | }, | ||
| 150 | }; | ||
| 151 | |||
| 152 | static int pca100_spi_cs[] = {GPIO_PORTD + 28, GPIO_PORTD + 27}; | ||
| 153 | |||
| 154 | static struct spi_imx_master pca100_spi_0_data = { | ||
| 155 | .chipselect = pca100_spi_cs, | ||
| 156 | .num_chipselect = ARRAY_SIZE(pca100_spi_cs), | ||
| 157 | }; | ||
| 158 | #endif | ||
| 159 | |||
| 160 | static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq, | ||
| 161 | void *data) | ||
| 162 | { | ||
| 163 | int ret; | ||
| 164 | |||
| 165 | ret = request_irq(IRQ_GPIOC(29), detect_irq, | ||
| 166 | IRQF_DISABLED | IRQF_TRIGGER_FALLING, | ||
| 167 | "imx-mmc-detect", data); | ||
| 168 | if (ret) | ||
| 169 | printk(KERN_ERR | ||
| 170 | "pca100: Failed to reuest irq for sd/mmc detection\n"); | ||
| 171 | |||
| 172 | return ret; | ||
| 173 | } | ||
| 174 | |||
| 175 | static void pca100_sdhc2_exit(struct device *dev, void *data) | ||
| 176 | { | ||
| 177 | free_irq(IRQ_GPIOC(29), data); | ||
| 178 | } | ||
| 179 | |||
| 180 | static struct imxmmc_platform_data sdhc_pdata = { | ||
| 181 | .init = pca100_sdhc2_init, | ||
| 182 | .exit = pca100_sdhc2_exit, | ||
| 183 | }; | ||
| 184 | |||
| 185 | static void __init pca100_init(void) | ||
| 186 | { | ||
| 187 | int ret; | ||
| 188 | |||
| 189 | ret = mxc_gpio_setup_multiple_pins(pca100_pins, | ||
| 190 | ARRAY_SIZE(pca100_pins), "PCA100"); | ||
| 191 | if (ret) | ||
| 192 | printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret); | ||
| 193 | |||
| 194 | mxc_register_device(&mxc_uart_device0, &uart_pdata); | ||
| 195 | |||
| 196 | mxc_gpio_mode(GPIO_PORTC | 29 | GPIO_GPIO | GPIO_IN); | ||
| 197 | mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata); | ||
| 198 | |||
| 199 | mxc_register_device(&mxc_nand_device, &pca100_nand_board_info); | ||
| 200 | |||
| 201 | /* only the i2c master 1 is used on this CPU card */ | ||
| 202 | i2c_register_board_info(1, pca100_i2c_devices, | ||
| 203 | ARRAY_SIZE(pca100_i2c_devices)); | ||
| 204 | |||
| 205 | mxc_register_device(&mxc_i2c_device1, &pca100_i2c_1_data); | ||
| 206 | |||
| 207 | mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT); | ||
| 208 | mxc_gpio_mode(GPIO_PORTD | 27 | GPIO_GPIO | GPIO_OUT); | ||
| 209 | |||
| 210 | /* GPIO0_IRQ */ | ||
| 211 | mxc_gpio_mode(GPIO_PORTC | 31 | GPIO_GPIO | GPIO_IN); | ||
| 212 | /* GPIO1_IRQ */ | ||
| 213 | mxc_gpio_mode(GPIO_PORTC | 25 | GPIO_GPIO | GPIO_IN); | ||
| 214 | /* GPIO2_IRQ */ | ||
| 215 | mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_IN); | ||
| 216 | |||
| 217 | #if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) | ||
| 218 | spi_register_board_info(pca100_spi_board_info, | ||
| 219 | ARRAY_SIZE(pca100_spi_board_info)); | ||
| 220 | mxc_register_device(&mxc_spi_device0, &pca100_spi_0_data); | ||
| 221 | #endif | ||
| 222 | |||
| 223 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | ||
| 224 | } | ||
| 225 | |||
| 226 | static void __init pca100_timer_init(void) | ||
| 227 | { | ||
| 228 | mx27_clocks_init(26000000); | ||
| 229 | } | ||
| 230 | |||
| 231 | static struct sys_timer pca100_timer = { | ||
| 232 | .init = pca100_timer_init, | ||
| 233 | }; | ||
| 234 | |||
| 235 | MACHINE_START(PCA100, "phyCARD-i.MX27") | ||
| 236 | .phys_io = AIPI_BASE_ADDR, | ||
| 237 | .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, | ||
| 238 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 239 | .map_io = mx27_map_io, | ||
| 240 | .init_irq = mxc_init_irq, | ||
| 241 | .init_machine = pca100_init, | ||
| 242 | .timer = &pca100_timer, | ||
| 243 | MACHINE_END | ||
| 244 | |||
diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c index a4628d004343..ee65dda584cf 100644 --- a/arch/arm/mach-mx2/pcm038.c +++ b/arch/arm/mach-mx2/pcm038.c | |||
| @@ -186,17 +186,13 @@ static struct at24_platform_data board_eeprom = { | |||
| 186 | }; | 186 | }; |
| 187 | 187 | ||
| 188 | static struct i2c_board_info pcm038_i2c_devices[] = { | 188 | static struct i2c_board_info pcm038_i2c_devices[] = { |
| 189 | [0] = { | 189 | { |
| 190 | I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ | 190 | I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ |
| 191 | .platform_data = &board_eeprom, | 191 | .platform_data = &board_eeprom, |
| 192 | }, | 192 | }, { |
| 193 | [1] = { | 193 | I2C_BOARD_INFO("pcf8563", 0x51), |
| 194 | I2C_BOARD_INFO("rtc-pcf8563", 0x51), | 194 | }, { |
| 195 | .type = "pcf8563" | ||
| 196 | }, | ||
| 197 | [2] = { | ||
| 198 | I2C_BOARD_INFO("lm75", 0x4a), | 195 | I2C_BOARD_INFO("lm75", 0x4a), |
| 199 | .type = "lm75" | ||
| 200 | } | 196 | } |
| 201 | }; | 197 | }; |
| 202 | 198 | ||
| @@ -220,6 +216,9 @@ static void __init pcm038_init(void) | |||
| 220 | 216 | ||
| 221 | mxc_register_device(&mxc_i2c_device1, &pcm038_i2c_1_data); | 217 | mxc_register_device(&mxc_i2c_device1, &pcm038_i2c_1_data); |
| 222 | 218 | ||
| 219 | /* PE18 for user-LED D40 */ | ||
| 220 | mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT); | ||
| 221 | |||
| 223 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | 222 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); |
| 224 | 223 | ||
| 225 | #ifdef CONFIG_MACH_PCM970_BASEBOARD | 224 | #ifdef CONFIG_MACH_PCM970_BASEBOARD |
| @@ -241,7 +240,7 @@ MACHINE_START(PCM038, "phyCORE-i.MX27") | |||
| 241 | .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 240 | .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 242 | .boot_params = PHYS_OFFSET + 0x100, | 241 | .boot_params = PHYS_OFFSET + 0x100, |
| 243 | .map_io = mx27_map_io, | 242 | .map_io = mx27_map_io, |
| 244 | .init_irq = mxc_init_irq, | 243 | .init_irq = mx27_init_irq, |
| 245 | .init_machine = pcm038_init, | 244 | .init_machine = pcm038_init, |
| 246 | .timer = &pcm038_timer, | 245 | .timer = &pcm038_timer, |
| 247 | MACHINE_END | 246 | MACHINE_END |
diff --git a/arch/arm/mach-mx2/pcm970-baseboard.c b/arch/arm/mach-mx2/pcm970-baseboard.c index 6a3acaf57dd4..c261f59b0b4c 100644 --- a/arch/arm/mach-mx2/pcm970-baseboard.c +++ b/arch/arm/mach-mx2/pcm970-baseboard.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
| 20 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/can/platform/sja1000.h> | ||
| 22 | 23 | ||
| 23 | #include <asm/mach/arch.h> | 24 | #include <asm/mach/arch.h> |
| 24 | 25 | ||
| @@ -125,40 +126,96 @@ static struct imxmmc_platform_data sdhc_pdata = { | |||
| 125 | .exit = pcm970_sdhc2_exit, | 126 | .exit = pcm970_sdhc2_exit, |
| 126 | }; | 127 | }; |
| 127 | 128 | ||
| 128 | /* | 129 | static struct imx_fb_videomode pcm970_modes[] = { |
| 129 | * Connected is a portrait Sharp-QVGA display | 130 | { |
| 130 | * of type: LQ035Q7DH06 | 131 | .mode = { |
| 131 | */ | 132 | .name = "Sharp-LQ035Q7", |
| 132 | static struct imx_fb_platform_data pcm038_fb_data = { | 133 | .refresh = 60, |
| 133 | .pixclock = 188679, /* in ps (5.3MHz) */ | 134 | .xres = 240, |
| 134 | .xres = 240, | 135 | .yres = 320, |
| 135 | .yres = 320, | 136 | .pixclock = 188679, /* in ps (5.3MHz) */ |
| 136 | 137 | .hsync_len = 7, | |
| 137 | .bpp = 16, | 138 | .left_margin = 5, |
| 138 | .hsync_len = 7, | 139 | .right_margin = 16, |
| 139 | .left_margin = 5, | 140 | .vsync_len = 1, |
| 140 | .right_margin = 16, | 141 | .upper_margin = 7, |
| 142 | .lower_margin = 9, | ||
| 143 | }, | ||
| 144 | /* | ||
| 145 | * - HSYNC active high | ||
| 146 | * - VSYNC active high | ||
| 147 | * - clk notenabled while idle | ||
| 148 | * - clock not inverted | ||
| 149 | * - data not inverted | ||
| 150 | * - data enable low active | ||
| 151 | * - enable sharp mode | ||
| 152 | */ | ||
| 153 | .pcr = 0xF00080C0, | ||
| 154 | .bpp = 16, | ||
| 155 | }, { | ||
| 156 | .mode = { | ||
| 157 | .name = "TX090", | ||
| 158 | .refresh = 60, | ||
| 159 | .xres = 240, | ||
| 160 | .yres = 320, | ||
| 161 | .pixclock = 38255, | ||
| 162 | .left_margin = 144, | ||
| 163 | .right_margin = 0, | ||
| 164 | .upper_margin = 7, | ||
| 165 | .lower_margin = 40, | ||
| 166 | .hsync_len = 96, | ||
| 167 | .vsync_len = 1, | ||
| 168 | }, | ||
| 169 | /* | ||
| 170 | * - HSYNC active low (1 << 22) | ||
| 171 | * - VSYNC active low (1 << 23) | ||
| 172 | * - clk notenabled while idle | ||
| 173 | * - clock not inverted | ||
| 174 | * - data not inverted | ||
| 175 | * - data enable low active | ||
| 176 | * - enable sharp mode | ||
| 177 | */ | ||
| 178 | .pcr = 0xF0008080 | (1<<22) | (1<<23) | (1<<19), | ||
| 179 | .bpp = 32, | ||
| 180 | }, | ||
| 181 | }; | ||
| 141 | 182 | ||
| 142 | .vsync_len = 1, | 183 | static struct imx_fb_platform_data pcm038_fb_data = { |
| 143 | .upper_margin = 7, | 184 | .mode = pcm970_modes, |
| 144 | .lower_margin = 9, | 185 | .num_modes = ARRAY_SIZE(pcm970_modes), |
| 145 | .fixed_screen_cpu = 0, | ||
| 146 | 186 | ||
| 147 | /* | ||
| 148 | * - HSYNC active high | ||
| 149 | * - VSYNC active high | ||
| 150 | * - clk notenabled while idle | ||
| 151 | * - clock not inverted | ||
| 152 | * - data not inverted | ||
| 153 | * - data enable low active | ||
| 154 | * - enable sharp mode | ||
| 155 | */ | ||
| 156 | .pcr = 0xFA0080C0, | ||
| 157 | .pwmr = 0x00A903FF, | 187 | .pwmr = 0x00A903FF, |
| 158 | .lscr1 = 0x00120300, | 188 | .lscr1 = 0x00120300, |
| 159 | .dmacr = 0x00020010, | 189 | .dmacr = 0x00020010, |
| 160 | }; | 190 | }; |
| 161 | 191 | ||
| 192 | static struct resource pcm970_sja1000_resources[] = { | ||
| 193 | { | ||
| 194 | .start = CS4_BASE_ADDR, | ||
| 195 | .end = CS4_BASE_ADDR + 0x100 - 1, | ||
| 196 | .flags = IORESOURCE_MEM, | ||
| 197 | }, { | ||
| 198 | .start = IRQ_GPIOE(19), | ||
| 199 | .end = IRQ_GPIOE(19), | ||
| 200 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, | ||
| 201 | }, | ||
| 202 | }; | ||
| 203 | |||
| 204 | struct sja1000_platform_data pcm970_sja1000_platform_data = { | ||
| 205 | .clock = 16000000 / 2, | ||
| 206 | .ocr = 0x40 | 0x18, | ||
| 207 | .cdr = 0x40, | ||
| 208 | }; | ||
| 209 | |||
| 210 | static struct platform_device pcm970_sja1000 = { | ||
| 211 | .name = "sja1000_platform", | ||
| 212 | .dev = { | ||
| 213 | .platform_data = &pcm970_sja1000_platform_data, | ||
| 214 | }, | ||
| 215 | .resource = pcm970_sja1000_resources, | ||
| 216 | .num_resources = ARRAY_SIZE(pcm970_sja1000_resources), | ||
| 217 | }; | ||
| 218 | |||
| 162 | /* | 219 | /* |
| 163 | * system init for baseboard usage. Will be called by pcm038 init. | 220 | * system init for baseboard usage. Will be called by pcm038 init. |
| 164 | * | 221 | * |
| @@ -172,4 +229,5 @@ void __init pcm970_baseboard_init(void) | |||
| 172 | 229 | ||
| 173 | mxc_register_device(&mxc_fb_device, &pcm038_fb_data); | 230 | mxc_register_device(&mxc_fb_device, &pcm038_fb_data); |
| 174 | mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata); | 231 | mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata); |
| 232 | platform_device_register(&pcm970_sja1000); | ||
| 175 | } | 233 | } |
diff --git a/arch/arm/mach-mx25/Kconfig b/arch/arm/mach-mx25/Kconfig new file mode 100644 index 000000000000..cc28f56eae80 --- /dev/null +++ b/arch/arm/mach-mx25/Kconfig | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | if ARCH_MX25 | ||
| 2 | |||
| 3 | comment "MX25 platforms:" | ||
| 4 | |||
| 5 | config MACH_MX25_3DS | ||
| 6 | select ARCH_MXC_IOMUX_V3 | ||
| 7 | bool "Support MX25PDK (3DS) Platform" | ||
| 8 | |||
| 9 | endif | ||
diff --git a/arch/arm/mach-mx25/Makefile b/arch/arm/mach-mx25/Makefile new file mode 100644 index 000000000000..fe23836a9f3d --- /dev/null +++ b/arch/arm/mach-mx25/Makefile | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | obj-y := mm.o devices.o | ||
| 2 | obj-$(CONFIG_ARCH_MX25) += clock.o | ||
| 3 | obj-$(CONFIG_MACH_MX25_3DS) += mx25pdk.o | ||
diff --git a/arch/arm/mach-mx25/Makefile.boot b/arch/arm/mach-mx25/Makefile.boot new file mode 100644 index 000000000000..e1dd366f836b --- /dev/null +++ b/arch/arm/mach-mx25/Makefile.boot | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | zreladdr-y := 0x80008000 | ||
| 2 | params_phys-y := 0x80000100 | ||
| 3 | initrd_phys-y := 0x80800000 | ||
diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c new file mode 100644 index 000000000000..ef26951a5275 --- /dev/null +++ b/arch/arm/mach-mx25/clock.c | |||
| @@ -0,0 +1,219 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 by Sascha Hauer, Pengutronix | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU General Public License | ||
| 6 | * as published by the Free Software Foundation; either version 2 | ||
| 7 | * of the License, or (at your option) any later version. | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, write to the Free Software | ||
| 15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
| 16 | * MA 02110-1301, USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/list.h> | ||
| 22 | #include <linux/clk.h> | ||
| 23 | #include <linux/io.h> | ||
| 24 | |||
| 25 | #include <asm/clkdev.h> | ||
| 26 | |||
| 27 | #include <mach/clock.h> | ||
| 28 | #include <mach/hardware.h> | ||
| 29 | #include <mach/common.h> | ||
| 30 | #include <mach/mx25.h> | ||
| 31 | |||
| 32 | #define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR) | ||
| 33 | |||
| 34 | #define CCM_MPCTL 0x00 | ||
| 35 | #define CCM_UPCTL 0x04 | ||
| 36 | #define CCM_CCTL 0x08 | ||
| 37 | #define CCM_CGCR0 0x0C | ||
| 38 | #define CCM_CGCR1 0x10 | ||
| 39 | #define CCM_CGCR2 0x14 | ||
| 40 | #define CCM_PCDR0 0x18 | ||
| 41 | #define CCM_PCDR1 0x1C | ||
| 42 | #define CCM_PCDR2 0x20 | ||
| 43 | #define CCM_PCDR3 0x24 | ||
| 44 | #define CCM_RCSR 0x28 | ||
| 45 | #define CCM_CRDR 0x2C | ||
| 46 | #define CCM_DCVR0 0x30 | ||
| 47 | #define CCM_DCVR1 0x34 | ||
| 48 | #define CCM_DCVR2 0x38 | ||
| 49 | #define CCM_DCVR3 0x3c | ||
| 50 | #define CCM_LTR0 0x40 | ||
| 51 | #define CCM_LTR1 0x44 | ||
| 52 | #define CCM_LTR2 0x48 | ||
| 53 | #define CCM_LTR3 0x4c | ||
| 54 | |||
| 55 | static unsigned long get_rate_mpll(void) | ||
| 56 | { | ||
| 57 | ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL); | ||
| 58 | |||
| 59 | return mxc_decode_pll(mpctl, 24000000); | ||
| 60 | } | ||
| 61 | |||
| 62 | static unsigned long get_rate_upll(void) | ||
| 63 | { | ||
| 64 | ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL); | ||
| 65 | |||
| 66 | return mxc_decode_pll(mpctl, 24000000); | ||
| 67 | } | ||
| 68 | |||
| 69 | unsigned long get_rate_arm(struct clk *clk) | ||
| 70 | { | ||
| 71 | unsigned long cctl = readl(CRM_BASE + CCM_CCTL); | ||
| 72 | unsigned long rate = get_rate_mpll(); | ||
| 73 | |||
| 74 | if (cctl & (1 << 14)) | ||
| 75 | rate = (rate * 3) >> 1; | ||
| 76 | |||
| 77 | return rate / ((cctl >> 30) + 1); | ||
| 78 | } | ||
| 79 | |||
| 80 | static unsigned long get_rate_ahb(struct clk *clk) | ||
| 81 | { | ||
| 82 | unsigned long cctl = readl(CRM_BASE + CCM_CCTL); | ||
| 83 | |||
| 84 | return get_rate_arm(NULL) / (((cctl >> 28) & 0x3) + 1); | ||
| 85 | } | ||
| 86 | |||
| 87 | static unsigned long get_rate_ipg(struct clk *clk) | ||
| 88 | { | ||
| 89 | return get_rate_ahb(NULL) >> 1; | ||
| 90 | } | ||
| 91 | |||
| 92 | static unsigned long get_rate_per(int per) | ||
| 93 | { | ||
| 94 | unsigned long ofs = (per & 0x3) * 8; | ||
| 95 | unsigned long reg = per & ~0x3; | ||
| 96 | unsigned long val = (readl(CRM_BASE + CCM_PCDR0 + reg) >> ofs) & 0x3f; | ||
| 97 | unsigned long fref; | ||
| 98 | |||
| 99 | if (readl(CRM_BASE + 0x64) & (1 << per)) | ||
| 100 | fref = get_rate_upll(); | ||
| 101 | else | ||
| 102 | fref = get_rate_ipg(NULL); | ||
| 103 | |||
| 104 | return fref / (val + 1); | ||
| 105 | } | ||
| 106 | |||
| 107 | static unsigned long get_rate_uart(struct clk *clk) | ||
| 108 | { | ||
| 109 | return get_rate_per(15); | ||
| 110 | } | ||
| 111 | |||
| 112 | static unsigned long get_rate_i2c(struct clk *clk) | ||
| 113 | { | ||
| 114 | return get_rate_per(6); | ||
| 115 | } | ||
| 116 | |||
| 117 | static unsigned long get_rate_nfc(struct clk *clk) | ||
| 118 | { | ||
| 119 | return get_rate_per(8); | ||
| 120 | } | ||
| 121 | |||
| 122 | static unsigned long get_rate_otg(struct clk *clk) | ||
| 123 | { | ||
| 124 | return 48000000; /* FIXME */ | ||
| 125 | } | ||
| 126 | |||
| 127 | static int clk_cgcr_enable(struct clk *clk) | ||
| 128 | { | ||
| 129 | u32 reg; | ||
| 130 | |||
| 131 | reg = __raw_readl(clk->enable_reg); | ||
| 132 | reg |= 1 << clk->enable_shift; | ||
| 133 | __raw_writel(reg, clk->enable_reg); | ||
| 134 | |||
| 135 | return 0; | ||
| 136 | } | ||
| 137 | |||
| 138 | static void clk_cgcr_disable(struct clk *clk) | ||
| 139 | { | ||
| 140 | u32 reg; | ||
| 141 | |||
| 142 | reg = __raw_readl(clk->enable_reg); | ||
| 143 | reg &= ~(1 << clk->enable_shift); | ||
| 144 | __raw_writel(reg, clk->enable_reg); | ||
| 145 | } | ||
| 146 | |||
| 147 | #define DEFINE_CLOCK(name, i, er, es, gr, sr) \ | ||
| 148 | static struct clk name = { \ | ||
| 149 | .id = i, \ | ||
| 150 | .enable_reg = CRM_BASE + er, \ | ||
| 151 | .enable_shift = es, \ | ||
| 152 | .get_rate = gr, \ | ||
| 153 | .set_rate = sr, \ | ||
| 154 | .enable = clk_cgcr_enable, \ | ||
| 155 | .disable = clk_cgcr_disable, \ | ||
| 156 | } | ||
| 157 | |||
| 158 | DEFINE_CLOCK(gpt_clk, 0, CCM_CGCR0, 5, get_rate_ipg, NULL); | ||
| 159 | DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL); | ||
| 160 | DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL); | ||
| 161 | DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL); | ||
| 162 | DEFINE_CLOCK(uart1_clk, 0, CCM_CGCR2, 14, get_rate_uart, NULL); | ||
| 163 | DEFINE_CLOCK(uart2_clk, 0, CCM_CGCR2, 15, get_rate_uart, NULL); | ||
| 164 | DEFINE_CLOCK(uart3_clk, 0, CCM_CGCR2, 16, get_rate_uart, NULL); | ||
| 165 | DEFINE_CLOCK(uart4_clk, 0, CCM_CGCR2, 17, get_rate_uart, NULL); | ||
| 166 | DEFINE_CLOCK(uart5_clk, 0, CCM_CGCR2, 18, get_rate_uart, NULL); | ||
| 167 | DEFINE_CLOCK(nfc_clk, 0, CCM_CGCR0, 8, get_rate_nfc, NULL); | ||
| 168 | DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL); | ||
| 169 | DEFINE_CLOCK(pwm1_clk, 0, CCM_CGCR1, 31, get_rate_ipg, NULL); | ||
| 170 | DEFINE_CLOCK(pwm2_clk, 0, CCM_CGCR2, 0, get_rate_ipg, NULL); | ||
| 171 | DEFINE_CLOCK(pwm3_clk, 0, CCM_CGCR2, 1, get_rate_ipg, NULL); | ||
| 172 | DEFINE_CLOCK(pwm4_clk, 0, CCM_CGCR2, 2, get_rate_ipg, NULL); | ||
| 173 | DEFINE_CLOCK(kpp_clk, 0, CCM_CGCR1, 28, get_rate_ipg, NULL); | ||
| 174 | DEFINE_CLOCK(tsc_clk, 0, CCM_CGCR2, 13, get_rate_ipg, NULL); | ||
| 175 | DEFINE_CLOCK(i2c_clk, 0, CCM_CGCR0, 6, get_rate_i2c, NULL); | ||
| 176 | |||
| 177 | #define _REGISTER_CLOCK(d, n, c) \ | ||
| 178 | { \ | ||
| 179 | .dev_id = d, \ | ||
| 180 | .con_id = n, \ | ||
| 181 | .clk = &c, \ | ||
| 182 | }, | ||
| 183 | |||
| 184 | static struct clk_lookup lookups[] = { | ||
| 185 | _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) | ||
| 186 | _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) | ||
| 187 | _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) | ||
| 188 | _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk) | ||
| 189 | _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk) | ||
| 190 | _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk) | ||
| 191 | _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk) | ||
| 192 | _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk) | ||
| 193 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk) | ||
| 194 | _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) | ||
| 195 | _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk) | ||
| 196 | _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk) | ||
| 197 | _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk) | ||
| 198 | _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk) | ||
| 199 | _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk) | ||
| 200 | _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk) | ||
| 201 | _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk) | ||
| 202 | _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk) | ||
| 203 | _REGISTER_CLOCK("mx25-adc", NULL, tsc_clk) | ||
| 204 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) | ||
| 205 | _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk) | ||
| 206 | _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk) | ||
| 207 | }; | ||
| 208 | |||
| 209 | int __init mx25_clocks_init(unsigned long fref) | ||
| 210 | { | ||
| 211 | int i; | ||
| 212 | |||
| 213 | for (i = 0; i < ARRAY_SIZE(lookups); i++) | ||
| 214 | clkdev_add(&lookups[i]); | ||
| 215 | |||
| 216 | mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); | ||
| 217 | |||
| 218 | return 0; | ||
| 219 | } | ||
diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c new file mode 100644 index 000000000000..eb12de1da42d --- /dev/null +++ b/arch/arm/mach-mx25/devices.c | |||
| @@ -0,0 +1,402 @@ | |||
| 1 | #include <linux/platform_device.h> | ||
| 2 | #include <linux/gpio.h> | ||
| 3 | #include <mach/mx25.h> | ||
| 4 | #include <mach/irqs.h> | ||
| 5 | |||
| 6 | static struct resource uart0[] = { | ||
| 7 | { | ||
| 8 | .start = 0x43f90000, | ||
| 9 | .end = 0x43f93fff, | ||
| 10 | .flags = IORESOURCE_MEM, | ||
| 11 | }, { | ||
| 12 | .start = 45, | ||
| 13 | .end = 45, | ||
| 14 | .flags = IORESOURCE_IRQ, | ||
| 15 | }, | ||
| 16 | }; | ||
| 17 | |||
| 18 | struct platform_device mxc_uart_device0 = { | ||
| 19 | .name = "imx-uart", | ||
| 20 | .id = 0, | ||
| 21 | .resource = uart0, | ||
| 22 | .num_resources = ARRAY_SIZE(uart0), | ||
| 23 | }; | ||
| 24 | |||
| 25 | static struct resource uart1[] = { | ||
| 26 | { | ||
| 27 | .start = 0x43f94000, | ||
| 28 | .end = 0x43f97fff, | ||
| 29 | .flags = IORESOURCE_MEM, | ||
| 30 | }, { | ||
| 31 | .start = 32, | ||
| 32 | .end = 32, | ||
| 33 | .flags = IORESOURCE_IRQ, | ||
| 34 | }, | ||
| 35 | }; | ||
| 36 | |||
| 37 | struct platform_device mxc_uart_device1 = { | ||
| 38 | .name = "imx-uart", | ||
| 39 | .id = 1, | ||
| 40 | .resource = uart1, | ||
| 41 | .num_resources = ARRAY_SIZE(uart1), | ||
| 42 | }; | ||
| 43 | |||
| 44 | static struct resource uart2[] = { | ||
| 45 | { | ||
| 46 | .start = 0x5000c000, | ||
| 47 | .end = 0x5000ffff, | ||
| 48 | .flags = IORESOURCE_MEM, | ||
| 49 | }, { | ||
| 50 | .start = 18, | ||
| 51 | .end = 18, | ||
| 52 | .flags = IORESOURCE_IRQ, | ||
| 53 | }, | ||
| 54 | }; | ||
| 55 | |||
| 56 | struct platform_device mxc_uart_device2 = { | ||
| 57 | .name = "imx-uart", | ||
| 58 | .id = 2, | ||
| 59 | .resource = uart2, | ||
| 60 | .num_resources = ARRAY_SIZE(uart2), | ||
| 61 | }; | ||
| 62 | |||
| 63 | static struct resource uart3[] = { | ||
| 64 | { | ||
| 65 | .start = 0x50008000, | ||
| 66 | .end = 0x5000bfff, | ||
| 67 | .flags = IORESOURCE_MEM, | ||
| 68 | }, { | ||
| 69 | .start = 5, | ||
| 70 | .end = 5, | ||
| 71 | .flags = IORESOURCE_IRQ, | ||
| 72 | }, | ||
| 73 | }; | ||
| 74 | |||
| 75 | struct platform_device mxc_uart_device3 = { | ||
| 76 | .name = "imx-uart", | ||
| 77 | .id = 3, | ||
| 78 | .resource = uart3, | ||
| 79 | .num_resources = ARRAY_SIZE(uart3), | ||
| 80 | }; | ||
| 81 | |||
| 82 | static struct resource uart4[] = { | ||
| 83 | { | ||
| 84 | .start = 0x5002c000, | ||
| 85 | .end = 0x5002ffff, | ||
| 86 | .flags = IORESOURCE_MEM, | ||
| 87 | }, { | ||
| 88 | .start = 40, | ||
| 89 | .end = 40, | ||
| 90 | .flags = IORESOURCE_IRQ, | ||
| 91 | }, | ||
| 92 | }; | ||
| 93 | |||
| 94 | struct platform_device mxc_uart_device4 = { | ||
| 95 | .name = "imx-uart", | ||
| 96 | .id = 4, | ||
| 97 | .resource = uart4, | ||
| 98 | .num_resources = ARRAY_SIZE(uart4), | ||
| 99 | }; | ||
| 100 | |||
| 101 | #define MX25_OTG_BASE_ADDR 0x53FF4000 | ||
| 102 | |||
| 103 | static u64 otg_dmamask = DMA_BIT_MASK(32); | ||
| 104 | |||
| 105 | static struct resource mxc_otg_resources[] = { | ||
| 106 | { | ||
| 107 | .start = MX25_OTG_BASE_ADDR, | ||
| 108 | .end = MX25_OTG_BASE_ADDR + 0x1ff, | ||
| 109 | .flags = IORESOURCE_MEM, | ||
| 110 | }, { | ||
| 111 | .start = 37, | ||
| 112 | .end = 37, | ||
| 113 | .flags = IORESOURCE_IRQ, | ||
| 114 | }, | ||
| 115 | }; | ||
| 116 | |||
| 117 | struct platform_device mxc_otg = { | ||
| 118 | .name = "mxc-ehci", | ||
| 119 | .id = 0, | ||
| 120 | .dev = { | ||
| 121 | .coherent_dma_mask = 0xffffffff, | ||
| 122 | .dma_mask = &otg_dmamask, | ||
| 123 | }, | ||
| 124 | .resource = mxc_otg_resources, | ||
| 125 | .num_resources = ARRAY_SIZE(mxc_otg_resources), | ||
| 126 | }; | ||
| 127 | |||
| 128 | /* OTG gadget device */ | ||
| 129 | struct platform_device otg_udc_device = { | ||
| 130 | .name = "fsl-usb2-udc", | ||
| 131 | .id = -1, | ||
| 132 | .dev = { | ||
| 133 | .dma_mask = &otg_dmamask, | ||
| 134 | .coherent_dma_mask = 0xffffffff, | ||
| 135 | }, | ||
| 136 | .resource = mxc_otg_resources, | ||
| 137 | .num_resources = ARRAY_SIZE(mxc_otg_resources), | ||
| 138 | }; | ||
| 139 | |||
| 140 | static u64 usbh2_dmamask = DMA_BIT_MASK(32); | ||
| 141 | |||
| 142 | static struct resource mxc_usbh2_resources[] = { | ||
| 143 | { | ||
| 144 | .start = MX25_OTG_BASE_ADDR + 0x400, | ||
| 145 | .end = MX25_OTG_BASE_ADDR + 0x5ff, | ||
| 146 | .flags = IORESOURCE_MEM, | ||
| 147 | }, { | ||
| 148 | .start = 35, | ||
| 149 | .end = 35, | ||
| 150 | .flags = IORESOURCE_IRQ, | ||
| 151 | }, | ||
| 152 | }; | ||
| 153 | |||
| 154 | struct platform_device mxc_usbh2 = { | ||
| 155 | .name = "mxc-ehci", | ||
| 156 | .id = 1, | ||
| 157 | .dev = { | ||
| 158 | .coherent_dma_mask = 0xffffffff, | ||
| 159 | .dma_mask = &usbh2_dmamask, | ||
| 160 | }, | ||
| 161 | .resource = mxc_usbh2_resources, | ||
| 162 | .num_resources = ARRAY_SIZE(mxc_usbh2_resources), | ||
| 163 | }; | ||
| 164 | |||
| 165 | static struct resource mxc_spi_resources0[] = { | ||
| 166 | { | ||
| 167 | .start = 0x43fa4000, | ||
| 168 | .end = 0x43fa7fff, | ||
| 169 | .flags = IORESOURCE_MEM, | ||
| 170 | }, { | ||
| 171 | .start = 14, | ||
| 172 | .end = 14, | ||
| 173 | .flags = IORESOURCE_IRQ, | ||
| 174 | }, | ||
| 175 | }; | ||
| 176 | |||
| 177 | struct platform_device mxc_spi_device0 = { | ||
| 178 | .name = "spi_imx", | ||
| 179 | .id = 0, | ||
| 180 | .num_resources = ARRAY_SIZE(mxc_spi_resources0), | ||
| 181 | .resource = mxc_spi_resources0, | ||
| 182 | }; | ||
| 183 | |||
| 184 | static struct resource mxc_spi_resources1[] = { | ||
| 185 | { | ||
| 186 | .start = 0x50010000, | ||
| 187 | .end = 0x50013fff, | ||
| 188 | .flags = IORESOURCE_MEM, | ||
| 189 | }, { | ||
| 190 | .start = 13, | ||
| 191 | .end = 13, | ||
| 192 | .flags = IORESOURCE_IRQ, | ||
| 193 | }, | ||
| 194 | }; | ||
| 195 | |||
| 196 | struct platform_device mxc_spi_device1 = { | ||
| 197 | .name = "spi_imx", | ||
| 198 | .id = 1, | ||
| 199 | .num_resources = ARRAY_SIZE(mxc_spi_resources1), | ||
| 200 | .resource = mxc_spi_resources1, | ||
| 201 | }; | ||
| 202 | |||
| 203 | static struct resource mxc_spi_resources2[] = { | ||
| 204 | { | ||
| 205 | .start = 0x50004000, | ||
| 206 | .end = 0x50007fff, | ||
| 207 | .flags = IORESOURCE_MEM, | ||
| 208 | }, { | ||
| 209 | .start = 0, | ||
| 210 | .end = 0, | ||
| 211 | .flags = IORESOURCE_IRQ, | ||
| 212 | }, | ||
| 213 | }; | ||
| 214 | |||
| 215 | struct platform_device mxc_spi_device2 = { | ||
| 216 | .name = "spi_imx", | ||
| 217 | .id = 2, | ||
| 218 | .num_resources = ARRAY_SIZE(mxc_spi_resources2), | ||
| 219 | .resource = mxc_spi_resources2, | ||
| 220 | }; | ||
| 221 | |||
| 222 | static struct resource mxc_pwm_resources0[] = { | ||
| 223 | { | ||
| 224 | .start = 0x53fe0000, | ||
| 225 | .end = 0x53fe3fff, | ||
| 226 | .flags = IORESOURCE_MEM, | ||
| 227 | }, { | ||
| 228 | .start = 26, | ||
| 229 | .end = 26, | ||
| 230 | .flags = IORESOURCE_IRQ, | ||
| 231 | } | ||
| 232 | }; | ||
| 233 | |||
| 234 | struct platform_device mxc_pwm_device0 = { | ||
| 235 | .name = "mxc_pwm", | ||
| 236 | .id = 0, | ||
| 237 | .num_resources = ARRAY_SIZE(mxc_pwm_resources0), | ||
| 238 | .resource = mxc_pwm_resources0, | ||
| 239 | }; | ||
| 240 | |||
| 241 | static struct resource mxc_pwm_resources1[] = { | ||
| 242 | { | ||
| 243 | .start = 0x53fa0000, | ||
| 244 | .end = 0x53fa3fff, | ||
| 245 | .flags = IORESOURCE_MEM, | ||
| 246 | }, { | ||
| 247 | .start = 36, | ||
| 248 | .end = 36, | ||
| 249 | .flags = IORESOURCE_IRQ, | ||
| 250 | } | ||
| 251 | }; | ||
| 252 | |||
| 253 | struct platform_device mxc_pwm_device1 = { | ||
| 254 | .name = "mxc_pwm", | ||
| 255 | .id = 1, | ||
| 256 | .num_resources = ARRAY_SIZE(mxc_pwm_resources1), | ||
| 257 | .resource = mxc_pwm_resources1, | ||
| 258 | }; | ||
| 259 | |||
| 260 | static struct resource mxc_pwm_resources2[] = { | ||
| 261 | { | ||
| 262 | .start = 0x53fa8000, | ||
| 263 | .end = 0x53fabfff, | ||
| 264 | .flags = IORESOURCE_MEM, | ||
| 265 | }, { | ||
| 266 | .start = 41, | ||
| 267 | .end = 41, | ||
| 268 | .flags = IORESOURCE_IRQ, | ||
| 269 | } | ||
| 270 | }; | ||
| 271 | |||
| 272 | struct platform_device mxc_pwm_device2 = { | ||
| 273 | .name = "mxc_pwm", | ||
| 274 | .id = 2, | ||
| 275 | .num_resources = ARRAY_SIZE(mxc_pwm_resources2), | ||
| 276 | .resource = mxc_pwm_resources2, | ||
| 277 | }; | ||
| 278 | |||
| 279 | static struct resource mxc_keypad_resources[] = { | ||
| 280 | { | ||
| 281 | .start = 0x43fa8000, | ||
| 282 | .end = 0x43fabfff, | ||
| 283 | .flags = IORESOURCE_MEM, | ||
| 284 | }, { | ||
| 285 | .start = 24, | ||
| 286 | .end = 24, | ||
| 287 | .flags = IORESOURCE_IRQ, | ||
| 288 | } | ||
| 289 | }; | ||
| 290 | |||
| 291 | struct platform_device mxc_keypad_device = { | ||
| 292 | .name = "mxc-keypad", | ||
| 293 | .id = -1, | ||
| 294 | .num_resources = ARRAY_SIZE(mxc_keypad_resources), | ||
| 295 | .resource = mxc_keypad_resources, | ||
| 296 | }; | ||
| 297 | |||
| 298 | static struct resource mxc_pwm_resources3[] = { | ||
| 299 | { | ||
| 300 | .start = 0x53fc8000, | ||
| 301 | .end = 0x53fcbfff, | ||
| 302 | .flags = IORESOURCE_MEM, | ||
| 303 | }, { | ||
| 304 | .start = 42, | ||
| 305 | .end = 42, | ||
| 306 | .flags = IORESOURCE_IRQ, | ||
| 307 | } | ||
| 308 | }; | ||
| 309 | |||
| 310 | struct platform_device mxc_pwm_device3 = { | ||
| 311 | .name = "mxc_pwm", | ||
| 312 | .id = 3, | ||
| 313 | .num_resources = ARRAY_SIZE(mxc_pwm_resources3), | ||
| 314 | .resource = mxc_pwm_resources3, | ||
| 315 | }; | ||
| 316 | |||
| 317 | static struct resource mxc_i2c_1_resources[] = { | ||
| 318 | { | ||
| 319 | .start = 0x43f80000, | ||
| 320 | .end = 0x43f83fff, | ||
| 321 | .flags = IORESOURCE_MEM, | ||
| 322 | }, { | ||
| 323 | .start = 3, | ||
| 324 | .end = 3, | ||
| 325 | .flags = IORESOURCE_IRQ, | ||
| 326 | } | ||
| 327 | }; | ||
| 328 | |||
| 329 | struct platform_device mxc_i2c_device0 = { | ||
| 330 | .name = "imx-i2c", | ||
| 331 | .id = 0, | ||
| 332 | .num_resources = ARRAY_SIZE(mxc_i2c_1_resources), | ||
| 333 | .resource = mxc_i2c_1_resources, | ||
| 334 | }; | ||
| 335 | |||
| 336 | static struct resource mxc_i2c_2_resources[] = { | ||
| 337 | { | ||
| 338 | .start = 0x43f98000, | ||
| 339 | .end = 0x43f9bfff, | ||
| 340 | .flags = IORESOURCE_MEM, | ||
| 341 | }, { | ||
| 342 | .start = 4, | ||
| 343 | .end = 4, | ||
| 344 | .flags = IORESOURCE_IRQ, | ||
| 345 | } | ||
| 346 | }; | ||
| 347 | |||
| 348 | struct platform_device mxc_i2c_device1 = { | ||
| 349 | .name = "imx-i2c", | ||
| 350 | .id = 1, | ||
| 351 | .num_resources = ARRAY_SIZE(mxc_i2c_2_resources), | ||
| 352 | .resource = mxc_i2c_2_resources, | ||
| 353 | }; | ||
| 354 | |||
| 355 | static struct resource mxc_i2c_3_resources[] = { | ||
| 356 | { | ||
| 357 | .start = 0x43f84000, | ||
| 358 | .end = 0x43f87fff, | ||
| 359 | .flags = IORESOURCE_MEM, | ||
| 360 | }, { | ||
| 361 | .start = 10, | ||
| 362 | .end = 10, | ||
| 363 | .flags = IORESOURCE_IRQ, | ||
| 364 | } | ||
| 365 | }; | ||
| 366 | |||
| 367 | struct platform_device mxc_i2c_device2 = { | ||
| 368 | .name = "imx-i2c", | ||
| 369 | .id = 2, | ||
| 370 | .num_resources = ARRAY_SIZE(mxc_i2c_3_resources), | ||
| 371 | .resource = mxc_i2c_3_resources, | ||
| 372 | }; | ||
| 373 | |||
| 374 | static struct mxc_gpio_port imx_gpio_ports[] = { | ||
| 375 | { | ||
| 376 | .chip.label = "gpio-0", | ||
| 377 | .base = (void __iomem *)MX25_GPIO1_BASE_ADDR_VIRT, | ||
| 378 | .irq = 52, | ||
| 379 | .virtual_irq_start = MXC_GPIO_IRQ_START, | ||
| 380 | }, { | ||
| 381 | .chip.label = "gpio-1", | ||
| 382 | .base = (void __iomem *)MX25_GPIO2_BASE_ADDR_VIRT, | ||
| 383 | .irq = 51, | ||
| 384 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32, | ||
| 385 | }, { | ||
| 386 | .chip.label = "gpio-2", | ||
| 387 | .base = (void __iomem *)MX25_GPIO3_BASE_ADDR_VIRT, | ||
| 388 | .irq = 16, | ||
| 389 | .virtual_irq_start = MXC_GPIO_IRQ_START + 64, | ||
| 390 | }, { | ||
| 391 | .chip.label = "gpio-3", | ||
| 392 | .base = (void __iomem *)MX25_GPIO4_BASE_ADDR_VIRT, | ||
| 393 | .irq = 23, | ||
| 394 | .virtual_irq_start = MXC_GPIO_IRQ_START + 96, | ||
| 395 | } | ||
| 396 | }; | ||
| 397 | |||
| 398 | int __init mxc_register_gpios(void) | ||
| 399 | { | ||
| 400 | return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports)); | ||
| 401 | } | ||
| 402 | |||
diff --git a/arch/arm/mach-mx25/devices.h b/arch/arm/mach-mx25/devices.h new file mode 100644 index 000000000000..fe6bf88ad1dd --- /dev/null +++ b/arch/arm/mach-mx25/devices.h | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | extern struct platform_device mxc_uart_device0; | ||
| 2 | extern struct platform_device mxc_uart_device1; | ||
| 3 | extern struct platform_device mxc_uart_device2; | ||
| 4 | extern struct platform_device mxc_uart_device3; | ||
| 5 | extern struct platform_device mxc_uart_device4; | ||
| 6 | extern struct platform_device mxc_otg; | ||
| 7 | extern struct platform_device otg_udc_device; | ||
| 8 | extern struct platform_device mxc_usbh2; | ||
| 9 | extern struct platform_device mxc_spi_device0; | ||
| 10 | extern struct platform_device mxc_spi_device1; | ||
| 11 | extern struct platform_device mxc_spi_device2; | ||
| 12 | extern struct platform_device mxc_pwm_device0; | ||
| 13 | extern struct platform_device mxc_pwm_device1; | ||
| 14 | extern struct platform_device mxc_pwm_device2; | ||
| 15 | extern struct platform_device mxc_pwm_device3; | ||
| 16 | extern struct platform_device mxc_keypad_device; | ||
| 17 | extern struct platform_device mxc_i2c_device0; | ||
| 18 | extern struct platform_device mxc_i2c_device1; | ||
| 19 | extern struct platform_device mxc_i2c_device2; | ||
diff --git a/arch/arm/mach-mx25/mm.c b/arch/arm/mach-mx25/mm.c new file mode 100644 index 000000000000..a7e587ff3e9e --- /dev/null +++ b/arch/arm/mach-mx25/mm.c | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 1999,2000 Arm Limited | ||
| 3 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
| 4 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
| 5 | * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 6 | * - add MX31 specific definitions | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/mm.h> | ||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/err.h> | ||
| 26 | |||
| 27 | #include <asm/pgtable.h> | ||
| 28 | #include <asm/mach/map.h> | ||
| 29 | |||
| 30 | #include <mach/common.h> | ||
| 31 | #include <mach/hardware.h> | ||
| 32 | #include <mach/mx25.h> | ||
| 33 | #include <mach/iomux-v3.h> | ||
| 34 | |||
| 35 | /* | ||
| 36 | * This table defines static virtual address mappings for I/O regions. | ||
| 37 | * These are the mappings common across all MX3 boards. | ||
| 38 | */ | ||
| 39 | static struct map_desc mxc_io_desc[] __initdata = { | ||
| 40 | { | ||
| 41 | .virtual = MX25_AVIC_BASE_ADDR_VIRT, | ||
| 42 | .pfn = __phys_to_pfn(MX25_AVIC_BASE_ADDR), | ||
| 43 | .length = MX25_AVIC_SIZE, | ||
| 44 | .type = MT_DEVICE_NONSHARED | ||
| 45 | }, { | ||
| 46 | .virtual = MX25_AIPS1_BASE_ADDR_VIRT, | ||
| 47 | .pfn = __phys_to_pfn(MX25_AIPS1_BASE_ADDR), | ||
| 48 | .length = MX25_AIPS1_SIZE, | ||
| 49 | .type = MT_DEVICE_NONSHARED | ||
| 50 | }, { | ||
| 51 | .virtual = MX25_AIPS2_BASE_ADDR_VIRT, | ||
| 52 | .pfn = __phys_to_pfn(MX25_AIPS2_BASE_ADDR), | ||
| 53 | .length = MX25_AIPS2_SIZE, | ||
| 54 | .type = MT_DEVICE_NONSHARED | ||
| 55 | }, | ||
| 56 | }; | ||
| 57 | |||
| 58 | /* | ||
| 59 | * This function initializes the memory map. It is called during the | ||
| 60 | * system startup to create static physical to virtual memory mappings | ||
| 61 | * for the IO modules. | ||
| 62 | */ | ||
| 63 | void __init mx25_map_io(void) | ||
| 64 | { | ||
| 65 | mxc_set_cpu_type(MXC_CPU_MX25); | ||
| 66 | mxc_iomux_v3_init(MX25_IO_ADDRESS(MX25_IOMUXC_BASE_ADDR)); | ||
| 67 | mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR)); | ||
| 68 | |||
| 69 | iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); | ||
| 70 | } | ||
| 71 | |||
| 72 | void __init mx25_init_irq(void) | ||
| 73 | { | ||
| 74 | mxc_init_irq((void __iomem *)MX25_AVIC_BASE_ADDR_VIRT); | ||
| 75 | } | ||
| 76 | |||
diff --git a/arch/arm/mach-mx25/mx25pdk.c b/arch/arm/mach-mx25/mx25pdk.c new file mode 100644 index 000000000000..92aa4fd19d99 --- /dev/null +++ b/arch/arm/mach-mx25/mx25pdk.c | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | #include <linux/types.h> | ||
| 2 | #include <linux/init.h> | ||
| 3 | #include <linux/clk.h> | ||
| 4 | #include <linux/irq.h> | ||
| 5 | #include <linux/gpio.h> | ||
| 6 | #include <linux/smsc911x.h> | ||
| 7 | #include <linux/platform_device.h> | ||
| 8 | |||
| 9 | #include <mach/hardware.h> | ||
| 10 | #include <asm/mach-types.h> | ||
| 11 | #include <asm/mach/arch.h> | ||
| 12 | #include <asm/mach/time.h> | ||
| 13 | #include <asm/memory.h> | ||
| 14 | #include <asm/mach/map.h> | ||
| 15 | #include <mach/common.h> | ||
| 16 | #include <mach/imx-uart.h> | ||
| 17 | #include <mach/mx25.h> | ||
| 18 | #include <mach/mxc_nand.h> | ||
| 19 | #include "devices.h" | ||
| 20 | #include <mach/iomux-v3.h> | ||
| 21 | |||
| 22 | static struct imxuart_platform_data uart_pdata = { | ||
| 23 | .flags = IMXUART_HAVE_RTSCTS, | ||
| 24 | }; | ||
| 25 | |||
| 26 | static struct mxc_nand_platform_data nand_board_info = { | ||
| 27 | .width = 1, | ||
| 28 | .hw_ecc = 1, | ||
| 29 | }; | ||
| 30 | |||
| 31 | static void __init mx25pdk_init(void) | ||
| 32 | { | ||
| 33 | mxc_register_device(&mxc_uart_device0, &uart_pdata); | ||
| 34 | mxc_register_device(&mxc_usbh2, NULL); | ||
| 35 | mxc_register_device(&mxc_nand_device, &nand_board_info); | ||
| 36 | } | ||
| 37 | |||
| 38 | |||
| 39 | static void __init mx25pdk_timer_init(void) | ||
| 40 | { | ||
| 41 | mx25_clocks_init(26000000); | ||
| 42 | } | ||
| 43 | |||
| 44 | static struct sys_timer mx25pdk_timer = { | ||
| 45 | .init = mx25pdk_timer_init, | ||
| 46 | }; | ||
| 47 | |||
| 48 | MACHINE_START(MX25_3DS, "Freescale MX25PDK (3DS)") | ||
| 49 | /* Maintainer: Freescale Semiconductor, Inc. */ | ||
| 50 | .phys_io = MX25_AIPS1_BASE_ADDR, | ||
| 51 | .io_pg_offst = ((MX25_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | ||
| 52 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 53 | .map_io = mx25_map_io, | ||
| 54 | .init_irq = mx25_init_irq, | ||
| 55 | .init_machine = mx25pdk_init, | ||
| 56 | .timer = &mx25pdk_timer, | ||
| 57 | MACHINE_END | ||
| 58 | |||
diff --git a/arch/arm/mach-mx3/armadillo5x0.c b/arch/arm/mach-mx3/armadillo5x0.c index ee331fd6b1bd..776c0ee1b3cd 100644 --- a/arch/arm/mach-mx3/armadillo5x0.c +++ b/arch/arm/mach-mx3/armadillo5x0.c | |||
| @@ -352,7 +352,7 @@ MACHINE_START(ARMADILLO5X0, "Armadillo-500") | |||
| 352 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 352 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 353 | .boot_params = PHYS_OFFSET + 0x00000100, | 353 | .boot_params = PHYS_OFFSET + 0x00000100, |
| 354 | .map_io = mx31_map_io, | 354 | .map_io = mx31_map_io, |
| 355 | .init_irq = mxc_init_irq, | 355 | .init_irq = mx31_init_irq, |
| 356 | .timer = &armadillo5x0_timer, | 356 | .timer = &armadillo5x0_timer, |
| 357 | .init_machine = armadillo5x0_init, | 357 | .init_machine = armadillo5x0_init, |
| 358 | MACHINE_END | 358 | MACHINE_END |
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c index 577ee83d1f60..fe5c4217322e 100644 --- a/arch/arm/mach-mx3/clock-imx35.c +++ b/arch/arm/mach-mx3/clock-imx35.c | |||
| @@ -273,6 +273,19 @@ static unsigned long get_rate_csi(struct clk *clk) | |||
| 273 | return rate / get_3_3_div((pdr2 >> 16) & 0x3f); | 273 | return rate / get_3_3_div((pdr2 >> 16) & 0x3f); |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | static unsigned long get_rate_otg(struct clk *clk) | ||
| 277 | { | ||
| 278 | unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); | ||
| 279 | unsigned long rate; | ||
| 280 | |||
| 281 | if (pdr4 & (1 << 9)) | ||
| 282 | rate = get_rate_arm(); | ||
| 283 | else | ||
| 284 | rate = get_rate_ppll(); | ||
| 285 | |||
| 286 | return rate / get_3_3_div((pdr4 >> 22) & 0x3f); | ||
| 287 | } | ||
| 288 | |||
| 276 | static unsigned long get_rate_ipg_per(struct clk *clk) | 289 | static unsigned long get_rate_ipg_per(struct clk *clk) |
| 277 | { | 290 | { |
| 278 | unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); | 291 | unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); |
| @@ -365,7 +378,7 @@ DEFINE_CLOCK(ssi2_clk, 1, CCM_CGR2, 14, get_rate_ssi, NULL); | |||
| 365 | DEFINE_CLOCK(uart1_clk, 0, CCM_CGR2, 16, get_rate_uart, NULL); | 378 | DEFINE_CLOCK(uart1_clk, 0, CCM_CGR2, 16, get_rate_uart, NULL); |
| 366 | DEFINE_CLOCK(uart2_clk, 1, CCM_CGR2, 18, get_rate_uart, NULL); | 379 | DEFINE_CLOCK(uart2_clk, 1, CCM_CGR2, 18, get_rate_uart, NULL); |
| 367 | DEFINE_CLOCK(uart3_clk, 2, CCM_CGR2, 20, get_rate_uart, NULL); | 380 | DEFINE_CLOCK(uart3_clk, 2, CCM_CGR2, 20, get_rate_uart, NULL); |
| 368 | DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, NULL, NULL); | 381 | DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, get_rate_otg, NULL); |
| 369 | DEFINE_CLOCK(wdog_clk, 0, CCM_CGR2, 24, NULL, NULL); | 382 | DEFINE_CLOCK(wdog_clk, 0, CCM_CGR2, 24, NULL, NULL); |
| 370 | DEFINE_CLOCK(max_clk, 0, CCM_CGR2, 26, NULL, NULL); | 383 | DEFINE_CLOCK(max_clk, 0, CCM_CGR2, 26, NULL, NULL); |
| 371 | DEFINE_CLOCK(admux_clk, 0, CCM_CGR2, 30, NULL, NULL); | 384 | DEFINE_CLOCK(admux_clk, 0, CCM_CGR2, 30, NULL, NULL); |
| @@ -426,7 +439,10 @@ static struct clk_lookup lookups[] = { | |||
| 426 | _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) | 439 | _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) |
| 427 | _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) | 440 | _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) |
| 428 | _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) | 441 | _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) |
| 429 | _REGISTER_CLOCK(NULL, "usbotg", usbotg_clk) | 442 | _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk) |
| 443 | _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk) | ||
| 444 | _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk) | ||
| 445 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk) | ||
| 430 | _REGISTER_CLOCK("mxc_wdt.0", NULL, wdog_clk) | 446 | _REGISTER_CLOCK("mxc_wdt.0", NULL, wdog_clk) |
| 431 | _REGISTER_CLOCK(NULL, "max", max_clk) | 447 | _REGISTER_CLOCK(NULL, "max", max_clk) |
| 432 | _REGISTER_CLOCK(NULL, "admux", admux_clk) | 448 | _REGISTER_CLOCK(NULL, "admux", admux_clk) |
| @@ -456,7 +472,7 @@ int __init mx35_clocks_init() | |||
| 456 | __raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2); | 472 | __raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2); |
| 457 | __raw_writel(0, CCM_BASE + CCM_CGR3); | 473 | __raw_writel(0, CCM_BASE + CCM_CGR3); |
| 458 | 474 | ||
| 459 | mxc_timer_init(&gpt_clk); | 475 | mxc_timer_init(&gpt_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT); |
| 460 | 476 | ||
| 461 | return 0; | 477 | return 0; |
| 462 | } | 478 | } |
diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c index 8b14239724c9..06bd6180bfc3 100644 --- a/arch/arm/mach-mx3/clock.c +++ b/arch/arm/mach-mx3/clock.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | 29 | ||
| 30 | #include <mach/clock.h> | 30 | #include <mach/clock.h> |
| 31 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
| 32 | #include <mach/mx31.h> | ||
| 32 | #include <mach/common.h> | 33 | #include <mach/common.h> |
| 33 | 34 | ||
| 34 | #include "crm_regs.h" | 35 | #include "crm_regs.h" |
| @@ -402,6 +403,11 @@ static unsigned long clk_ckih_get_rate(struct clk *clk) | |||
| 402 | return ckih_rate; | 403 | return ckih_rate; |
| 403 | } | 404 | } |
| 404 | 405 | ||
| 406 | static unsigned long clk_ckil_get_rate(struct clk *clk) | ||
| 407 | { | ||
| 408 | return CKIL_CLK_FREQ; | ||
| 409 | } | ||
| 410 | |||
| 405 | static struct clk ckih_clk = { | 411 | static struct clk ckih_clk = { |
| 406 | .get_rate = clk_ckih_get_rate, | 412 | .get_rate = clk_ckih_get_rate, |
| 407 | }; | 413 | }; |
| @@ -508,6 +514,7 @@ DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk) | |||
| 508 | DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk); | 514 | DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk); |
| 509 | DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); | 515 | DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); |
| 510 | DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); | 516 | DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); |
| 517 | DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL); | ||
| 511 | 518 | ||
| 512 | #define _REGISTER_CLOCK(d, n, c) \ | 519 | #define _REGISTER_CLOCK(d, n, c) \ |
| 513 | { \ | 520 | { \ |
| @@ -518,9 +525,9 @@ DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); | |||
| 518 | 525 | ||
| 519 | static struct clk_lookup lookups[] = { | 526 | static struct clk_lookup lookups[] = { |
| 520 | _REGISTER_CLOCK(NULL, "emi", emi_clk) | 527 | _REGISTER_CLOCK(NULL, "emi", emi_clk) |
| 521 | _REGISTER_CLOCK(NULL, "cspi", cspi1_clk) | 528 | _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk) |
| 522 | _REGISTER_CLOCK(NULL, "cspi", cspi2_clk) | 529 | _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk) |
| 523 | _REGISTER_CLOCK(NULL, "cspi", cspi3_clk) | 530 | _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk) |
| 524 | _REGISTER_CLOCK(NULL, "gpt", gpt_clk) | 531 | _REGISTER_CLOCK(NULL, "gpt", gpt_clk) |
| 525 | _REGISTER_CLOCK(NULL, "pwm", pwm_clk) | 532 | _REGISTER_CLOCK(NULL, "pwm", pwm_clk) |
| 526 | _REGISTER_CLOCK(NULL, "wdog", wdog_clk) | 533 | _REGISTER_CLOCK(NULL, "wdog", wdog_clk) |
| @@ -531,6 +538,12 @@ static struct clk_lookup lookups[] = { | |||
| 531 | _REGISTER_CLOCK("ipu-core", NULL, ipu_clk) | 538 | _REGISTER_CLOCK("ipu-core", NULL, ipu_clk) |
| 532 | _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk) | 539 | _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk) |
| 533 | _REGISTER_CLOCK(NULL, "kpp", kpp_clk) | 540 | _REGISTER_CLOCK(NULL, "kpp", kpp_clk) |
| 541 | _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk1) | ||
| 542 | _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2) | ||
| 543 | _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1) | ||
| 544 | _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2) | ||
| 545 | _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1) | ||
| 546 | _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2) | ||
| 534 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1) | 547 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1) |
| 535 | _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2) | 548 | _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2) |
| 536 | _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk) | 549 | _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk) |
| @@ -559,6 +572,7 @@ static struct clk_lookup lookups[] = { | |||
| 559 | _REGISTER_CLOCK(NULL, "iim", iim_clk) | 572 | _REGISTER_CLOCK(NULL, "iim", iim_clk) |
| 560 | _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk) | 573 | _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk) |
| 561 | _REGISTER_CLOCK(NULL, "mbx", mbx_clk) | 574 | _REGISTER_CLOCK(NULL, "mbx", mbx_clk) |
| 575 | _REGISTER_CLOCK("mxc_rtc", NULL, ckil_clk) | ||
| 562 | }; | 576 | }; |
| 563 | 577 | ||
| 564 | int __init mx31_clocks_init(unsigned long fref) | 578 | int __init mx31_clocks_init(unsigned long fref) |
| @@ -609,7 +623,7 @@ int __init mx31_clocks_init(unsigned long fref) | |||
| 609 | __raw_writel(reg, MXC_CCM_PMCR1); | 623 | __raw_writel(reg, MXC_CCM_PMCR1); |
| 610 | } | 624 | } |
| 611 | 625 | ||
| 612 | mxc_timer_init(&ipg_clk); | 626 | mxc_timer_init(&ipg_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT); |
| 613 | 627 | ||
| 614 | return 0; | 628 | return 0; |
| 615 | } | 629 | } |
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index 9e87e08fb121..8a577f367250 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c | |||
| @@ -129,19 +129,17 @@ struct platform_device mxc_uart_device4 = { | |||
| 129 | 129 | ||
| 130 | /* GPIO port description */ | 130 | /* GPIO port description */ |
| 131 | static struct mxc_gpio_port imx_gpio_ports[] = { | 131 | static struct mxc_gpio_port imx_gpio_ports[] = { |
| 132 | [0] = { | 132 | { |
| 133 | .chip.label = "gpio-0", | 133 | .chip.label = "gpio-0", |
| 134 | .base = IO_ADDRESS(GPIO1_BASE_ADDR), | 134 | .base = IO_ADDRESS(GPIO1_BASE_ADDR), |
| 135 | .irq = MXC_INT_GPIO1, | 135 | .irq = MXC_INT_GPIO1, |
| 136 | .virtual_irq_start = MXC_GPIO_IRQ_START, | 136 | .virtual_irq_start = MXC_GPIO_IRQ_START, |
| 137 | }, | 137 | }, { |
| 138 | [1] = { | ||
| 139 | .chip.label = "gpio-1", | 138 | .chip.label = "gpio-1", |
| 140 | .base = IO_ADDRESS(GPIO2_BASE_ADDR), | 139 | .base = IO_ADDRESS(GPIO2_BASE_ADDR), |
| 141 | .irq = MXC_INT_GPIO2, | 140 | .irq = MXC_INT_GPIO2, |
| 142 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32, | 141 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32, |
| 143 | }, | 142 | }, { |
| 144 | [2] = { | ||
| 145 | .chip.label = "gpio-2", | 143 | .chip.label = "gpio-2", |
| 146 | .base = IO_ADDRESS(GPIO3_BASE_ADDR), | 144 | .base = IO_ADDRESS(GPIO3_BASE_ADDR), |
| 147 | .irq = MXC_INT_GPIO3, | 145 | .irq = MXC_INT_GPIO3, |
| @@ -173,11 +171,11 @@ static struct resource mxc_nand_resources[] = { | |||
| 173 | { | 171 | { |
| 174 | .start = 0, /* runtime dependent */ | 172 | .start = 0, /* runtime dependent */ |
| 175 | .end = 0, | 173 | .end = 0, |
| 176 | .flags = IORESOURCE_MEM | 174 | .flags = IORESOURCE_MEM, |
| 177 | }, { | 175 | }, { |
| 178 | .start = MXC_INT_NANDFC, | 176 | .start = MXC_INT_NANDFC, |
| 179 | .end = MXC_INT_NANDFC, | 177 | .end = MXC_INT_NANDFC, |
| 180 | .flags = IORESOURCE_IRQ | 178 | .flags = IORESOURCE_IRQ, |
| 181 | }, | 179 | }, |
| 182 | }; | 180 | }; |
| 183 | 181 | ||
| @@ -193,8 +191,7 @@ static struct resource mxc_i2c0_resources[] = { | |||
| 193 | .start = I2C_BASE_ADDR, | 191 | .start = I2C_BASE_ADDR, |
| 194 | .end = I2C_BASE_ADDR + SZ_4K - 1, | 192 | .end = I2C_BASE_ADDR + SZ_4K - 1, |
| 195 | .flags = IORESOURCE_MEM, | 193 | .flags = IORESOURCE_MEM, |
| 196 | }, | 194 | }, { |
| 197 | { | ||
| 198 | .start = MXC_INT_I2C, | 195 | .start = MXC_INT_I2C, |
| 199 | .end = MXC_INT_I2C, | 196 | .end = MXC_INT_I2C, |
| 200 | .flags = IORESOURCE_IRQ, | 197 | .flags = IORESOURCE_IRQ, |
| @@ -213,8 +210,7 @@ static struct resource mxc_i2c1_resources[] = { | |||
| 213 | .start = I2C2_BASE_ADDR, | 210 | .start = I2C2_BASE_ADDR, |
| 214 | .end = I2C2_BASE_ADDR + SZ_4K - 1, | 211 | .end = I2C2_BASE_ADDR + SZ_4K - 1, |
| 215 | .flags = IORESOURCE_MEM, | 212 | .flags = IORESOURCE_MEM, |
| 216 | }, | 213 | }, { |
| 217 | { | ||
| 218 | .start = MXC_INT_I2C2, | 214 | .start = MXC_INT_I2C2, |
| 219 | .end = MXC_INT_I2C2, | 215 | .end = MXC_INT_I2C2, |
| 220 | .flags = IORESOURCE_IRQ, | 216 | .flags = IORESOURCE_IRQ, |
| @@ -233,8 +229,7 @@ static struct resource mxc_i2c2_resources[] = { | |||
| 233 | .start = I2C3_BASE_ADDR, | 229 | .start = I2C3_BASE_ADDR, |
| 234 | .end = I2C3_BASE_ADDR + SZ_4K - 1, | 230 | .end = I2C3_BASE_ADDR + SZ_4K - 1, |
| 235 | .flags = IORESOURCE_MEM, | 231 | .flags = IORESOURCE_MEM, |
| 236 | }, | 232 | }, { |
| 237 | { | ||
| 238 | .start = MXC_INT_I2C3, | 233 | .start = MXC_INT_I2C3, |
| 239 | .end = MXC_INT_I2C3, | 234 | .end = MXC_INT_I2C3, |
| 240 | .flags = IORESOURCE_IRQ, | 235 | .flags = IORESOURCE_IRQ, |
| @@ -371,8 +366,8 @@ struct platform_device mx3_camera = { | |||
| 371 | 366 | ||
| 372 | static struct resource otg_resources[] = { | 367 | static struct resource otg_resources[] = { |
| 373 | { | 368 | { |
| 374 | .start = OTG_BASE_ADDR, | 369 | .start = MX31_OTG_BASE_ADDR, |
| 375 | .end = OTG_BASE_ADDR + 0x1ff, | 370 | .end = MX31_OTG_BASE_ADDR + 0x1ff, |
| 376 | .flags = IORESOURCE_MEM, | 371 | .flags = IORESOURCE_MEM, |
| 377 | }, { | 372 | }, { |
| 378 | .start = MXC_INT_USB3, | 373 | .start = MXC_INT_USB3, |
| @@ -395,16 +390,142 @@ struct platform_device mxc_otg_udc_device = { | |||
| 395 | .num_resources = ARRAY_SIZE(otg_resources), | 390 | .num_resources = ARRAY_SIZE(otg_resources), |
| 396 | }; | 391 | }; |
| 397 | 392 | ||
| 393 | /* OTG host */ | ||
| 394 | struct platform_device mxc_otg_host = { | ||
| 395 | .name = "mxc-ehci", | ||
| 396 | .id = 0, | ||
| 397 | .dev = { | ||
| 398 | .coherent_dma_mask = 0xffffffff, | ||
| 399 | .dma_mask = &otg_dmamask, | ||
| 400 | }, | ||
| 401 | .resource = otg_resources, | ||
| 402 | .num_resources = ARRAY_SIZE(otg_resources), | ||
| 403 | }; | ||
| 404 | |||
| 405 | /* USB host 1 */ | ||
| 406 | |||
| 407 | static u64 usbh1_dmamask = ~(u32)0; | ||
| 408 | |||
| 409 | static struct resource mxc_usbh1_resources[] = { | ||
| 410 | { | ||
| 411 | .start = MX31_OTG_BASE_ADDR + 0x200, | ||
| 412 | .end = MX31_OTG_BASE_ADDR + 0x3ff, | ||
| 413 | .flags = IORESOURCE_MEM, | ||
| 414 | }, { | ||
| 415 | .start = MXC_INT_USB1, | ||
| 416 | .end = MXC_INT_USB1, | ||
| 417 | .flags = IORESOURCE_IRQ, | ||
| 418 | }, | ||
| 419 | }; | ||
| 420 | |||
| 421 | struct platform_device mxc_usbh1 = { | ||
| 422 | .name = "mxc-ehci", | ||
| 423 | .id = 1, | ||
| 424 | .dev = { | ||
| 425 | .coherent_dma_mask = 0xffffffff, | ||
| 426 | .dma_mask = &usbh1_dmamask, | ||
| 427 | }, | ||
| 428 | .resource = mxc_usbh1_resources, | ||
| 429 | .num_resources = ARRAY_SIZE(mxc_usbh1_resources), | ||
| 430 | }; | ||
| 431 | |||
| 432 | /* USB host 2 */ | ||
| 433 | static u64 usbh2_dmamask = ~(u32)0; | ||
| 434 | |||
| 435 | static struct resource mxc_usbh2_resources[] = { | ||
| 436 | { | ||
| 437 | .start = MX31_OTG_BASE_ADDR + 0x400, | ||
| 438 | .end = MX31_OTG_BASE_ADDR + 0x5ff, | ||
| 439 | .flags = IORESOURCE_MEM, | ||
| 440 | }, { | ||
| 441 | .start = MXC_INT_USB2, | ||
| 442 | .end = MXC_INT_USB2, | ||
| 443 | .flags = IORESOURCE_IRQ, | ||
| 444 | }, | ||
| 445 | }; | ||
| 446 | |||
| 447 | struct platform_device mxc_usbh2 = { | ||
| 448 | .name = "mxc-ehci", | ||
| 449 | .id = 2, | ||
| 450 | .dev = { | ||
| 451 | .coherent_dma_mask = 0xffffffff, | ||
| 452 | .dma_mask = &usbh2_dmamask, | ||
| 453 | }, | ||
| 454 | .resource = mxc_usbh2_resources, | ||
| 455 | .num_resources = ARRAY_SIZE(mxc_usbh2_resources), | ||
| 456 | }; | ||
| 457 | |||
| 458 | /* | ||
| 459 | * SPI master controller | ||
| 460 | * 3 channels | ||
| 461 | */ | ||
| 462 | static struct resource imx_spi_0_resources[] = { | ||
| 463 | { | ||
| 464 | .start = CSPI1_BASE_ADDR, | ||
| 465 | .end = CSPI1_BASE_ADDR + SZ_4K - 1, | ||
| 466 | .flags = IORESOURCE_MEM, | ||
| 467 | }, { | ||
| 468 | .start = MXC_INT_CSPI1, | ||
| 469 | .end = MXC_INT_CSPI1, | ||
| 470 | .flags = IORESOURCE_IRQ, | ||
| 471 | }, | ||
| 472 | }; | ||
| 473 | |||
| 474 | static struct resource imx_spi_1_resources[] = { | ||
| 475 | { | ||
| 476 | .start = CSPI2_BASE_ADDR, | ||
| 477 | .end = CSPI2_BASE_ADDR + SZ_4K - 1, | ||
| 478 | .flags = IORESOURCE_MEM, | ||
| 479 | }, { | ||
| 480 | .start = MXC_INT_CSPI2, | ||
| 481 | .end = MXC_INT_CSPI2, | ||
| 482 | .flags = IORESOURCE_IRQ, | ||
| 483 | }, | ||
| 484 | }; | ||
| 485 | |||
| 486 | static struct resource imx_spi_2_resources[] = { | ||
| 487 | { | ||
| 488 | .start = CSPI3_BASE_ADDR, | ||
| 489 | .end = CSPI3_BASE_ADDR + SZ_4K - 1, | ||
| 490 | .flags = IORESOURCE_MEM, | ||
| 491 | }, { | ||
| 492 | .start = MXC_INT_CSPI3, | ||
| 493 | .end = MXC_INT_CSPI3, | ||
| 494 | .flags = IORESOURCE_IRQ, | ||
| 495 | }, | ||
| 496 | }; | ||
| 497 | |||
| 498 | struct platform_device imx_spi_device0 = { | ||
| 499 | .name = "spi_imx", | ||
| 500 | .id = 0, | ||
| 501 | .num_resources = ARRAY_SIZE(imx_spi_0_resources), | ||
| 502 | .resource = imx_spi_0_resources, | ||
| 503 | }; | ||
| 504 | |||
| 505 | struct platform_device imx_spi_device1 = { | ||
| 506 | .name = "spi_imx", | ||
| 507 | .id = 1, | ||
| 508 | .num_resources = ARRAY_SIZE(imx_spi_1_resources), | ||
| 509 | .resource = imx_spi_1_resources, | ||
| 510 | }; | ||
| 511 | |||
| 512 | struct platform_device imx_spi_device2 = { | ||
| 513 | .name = "spi_imx", | ||
| 514 | .id = 2, | ||
| 515 | .num_resources = ARRAY_SIZE(imx_spi_2_resources), | ||
| 516 | .resource = imx_spi_2_resources, | ||
| 517 | }; | ||
| 518 | |||
| 398 | #ifdef CONFIG_ARCH_MX35 | 519 | #ifdef CONFIG_ARCH_MX35 |
| 399 | static struct resource mxc_fec_resources[] = { | 520 | static struct resource mxc_fec_resources[] = { |
| 400 | { | 521 | { |
| 401 | .start = MXC_FEC_BASE_ADDR, | 522 | .start = MXC_FEC_BASE_ADDR, |
| 402 | .end = MXC_FEC_BASE_ADDR + 0xfff, | 523 | .end = MXC_FEC_BASE_ADDR + 0xfff, |
| 403 | .flags = IORESOURCE_MEM | 524 | .flags = IORESOURCE_MEM, |
| 404 | }, { | 525 | }, { |
| 405 | .start = MXC_INT_FEC, | 526 | .start = MXC_INT_FEC, |
| 406 | .end = MXC_INT_FEC, | 527 | .end = MXC_INT_FEC, |
| 407 | .flags = IORESOURCE_IRQ | 528 | .flags = IORESOURCE_IRQ, |
| 408 | }, | 529 | }, |
| 409 | }; | 530 | }; |
| 410 | 531 | ||
| @@ -426,6 +547,14 @@ static int mx3_devices_init(void) | |||
| 426 | if (cpu_is_mx35()) { | 547 | if (cpu_is_mx35()) { |
| 427 | mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR; | 548 | mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR; |
| 428 | mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0xfff; | 549 | mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0xfff; |
| 550 | otg_resources[0].start = MX35_OTG_BASE_ADDR; | ||
| 551 | otg_resources[0].end = MX35_OTG_BASE_ADDR + 0x1ff; | ||
| 552 | otg_resources[1].start = MXC_INT_USBOTG; | ||
| 553 | otg_resources[1].end = MXC_INT_USBOTG; | ||
| 554 | mxc_usbh1_resources[0].start = MX35_OTG_BASE_ADDR + 0x400; | ||
| 555 | mxc_usbh1_resources[0].end = MX35_OTG_BASE_ADDR + 0x5ff; | ||
| 556 | mxc_usbh1_resources[1].start = MXC_INT_USBHS; | ||
| 557 | mxc_usbh1_resources[1].end = MXC_INT_USBHS; | ||
| 429 | } | 558 | } |
| 430 | 559 | ||
| 431 | return 0; | 560 | return 0; |
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h index ffd494ddd4ac..79f2be45d139 100644 --- a/arch/arm/mach-mx3/devices.h +++ b/arch/arm/mach-mx3/devices.h | |||
| @@ -16,5 +16,11 @@ extern struct platform_device mxc_fec_device; | |||
| 16 | extern struct platform_device mxcsdhc_device0; | 16 | extern struct platform_device mxcsdhc_device0; |
| 17 | extern struct platform_device mxcsdhc_device1; | 17 | extern struct platform_device mxcsdhc_device1; |
| 18 | extern struct platform_device mxc_otg_udc_device; | 18 | extern struct platform_device mxc_otg_udc_device; |
| 19 | extern struct platform_device mxc_otg_host; | ||
| 20 | extern struct platform_device mxc_usbh1; | ||
| 21 | extern struct platform_device mxc_usbh2; | ||
| 19 | extern struct platform_device mxc_rnga_device; | 22 | extern struct platform_device mxc_rnga_device; |
| 23 | extern struct platform_device imx_spi_device0; | ||
| 24 | extern struct platform_device imx_spi_device1; | ||
| 25 | extern struct platform_device imx_spi_device2; | ||
| 20 | 26 | ||
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c index 1f5fdd456cb9..ad5a1122d765 100644 --- a/arch/arm/mach-mx3/mm.c +++ b/arch/arm/mach-mx3/mm.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | #include <mach/common.h> | 31 | #include <mach/common.h> |
| 32 | #include <mach/hardware.h> | 32 | #include <mach/hardware.h> |
| 33 | #include <mach/iomux-v3.h> | ||
| 33 | 34 | ||
| 34 | /*! | 35 | /*! |
| 35 | * @file mm.c | 36 | * @file mm.c |
| @@ -75,6 +76,7 @@ static struct map_desc mxc_io_desc[] __initdata = { | |||
| 75 | void __init mx31_map_io(void) | 76 | void __init mx31_map_io(void) |
| 76 | { | 77 | { |
| 77 | mxc_set_cpu_type(MXC_CPU_MX31); | 78 | mxc_set_cpu_type(MXC_CPU_MX31); |
| 79 | mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR)); | ||
| 78 | 80 | ||
| 79 | iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); | 81 | iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); |
| 80 | } | 82 | } |
| @@ -82,10 +84,22 @@ void __init mx31_map_io(void) | |||
| 82 | void __init mx35_map_io(void) | 84 | void __init mx35_map_io(void) |
| 83 | { | 85 | { |
| 84 | mxc_set_cpu_type(MXC_CPU_MX35); | 86 | mxc_set_cpu_type(MXC_CPU_MX35); |
| 87 | mxc_iomux_v3_init(IO_ADDRESS(IOMUXC_BASE_ADDR)); | ||
| 88 | mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR)); | ||
| 85 | 89 | ||
| 86 | iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); | 90 | iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); |
| 87 | } | 91 | } |
| 88 | 92 | ||
| 93 | void __init mx31_init_irq(void) | ||
| 94 | { | ||
| 95 | mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR)); | ||
| 96 | } | ||
| 97 | |||
| 98 | void __init mx35_init_irq(void) | ||
| 99 | { | ||
| 100 | mx31_init_irq(); | ||
| 101 | } | ||
| 102 | |||
| 89 | #ifdef CONFIG_CACHE_L2X0 | 103 | #ifdef CONFIG_CACHE_L2X0 |
| 90 | static int mxc_init_l2x0(void) | 104 | static int mxc_init_l2x0(void) |
| 91 | { | 105 | { |
diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c index 30e2767a78ae..0497c152be18 100644 --- a/arch/arm/mach-mx3/mx31ads.c +++ b/arch/arm/mach-mx3/mx31ads.c | |||
| @@ -517,7 +517,7 @@ static void __init mx31ads_map_io(void) | |||
| 517 | 517 | ||
| 518 | static void __init mx31ads_init_irq(void) | 518 | static void __init mx31ads_init_irq(void) |
| 519 | { | 519 | { |
| 520 | mxc_init_irq(); | 520 | mx31_init_irq(); |
| 521 | mx31ads_init_expio(); | 521 | mx31ads_init_expio(); |
| 522 | } | 522 | } |
| 523 | 523 | ||
diff --git a/arch/arm/mach-mx3/mx31lilly.c b/arch/arm/mach-mx3/mx31lilly.c index 6ab2f163cb95..423025150f6f 100644 --- a/arch/arm/mach-mx3/mx31lilly.c +++ b/arch/arm/mach-mx3/mx31lilly.c | |||
| @@ -148,7 +148,7 @@ MACHINE_START(LILLY1131, "INCO startec LILLY-1131") | |||
| 148 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 148 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 149 | .boot_params = PHYS_OFFSET + 0x100, | 149 | .boot_params = PHYS_OFFSET + 0x100, |
| 150 | .map_io = mx31_map_io, | 150 | .map_io = mx31_map_io, |
| 151 | .init_irq = mxc_init_irq, | 151 | .init_irq = mx31_init_irq, |
| 152 | .init_machine = mx31lilly_board_init, | 152 | .init_machine = mx31lilly_board_init, |
| 153 | .timer = &mx31lilly_timer, | 153 | .timer = &mx31lilly_timer, |
| 154 | MACHINE_END | 154 | MACHINE_END |
diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c index 86fe70fa3e13..a8d57decdfdb 100644 --- a/arch/arm/mach-mx3/mx31lite.c +++ b/arch/arm/mach-mx3/mx31lite.c | |||
| @@ -71,12 +71,11 @@ static struct smsc911x_platform_config smsc911x_config = { | |||
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | static struct resource smsc911x_resources[] = { | 73 | static struct resource smsc911x_resources[] = { |
| 74 | [0] = { | 74 | { |
| 75 | .start = CS4_BASE_ADDR, | 75 | .start = CS4_BASE_ADDR, |
| 76 | .end = CS4_BASE_ADDR + 0x100, | 76 | .end = CS4_BASE_ADDR + 0x100, |
| 77 | .flags = IORESOURCE_MEM, | 77 | .flags = IORESOURCE_MEM, |
| 78 | }, | 78 | }, { |
| 79 | [1] = { | ||
| 80 | .start = IOMUX_TO_IRQ(MX31_PIN_SFS6), | 79 | .start = IOMUX_TO_IRQ(MX31_PIN_SFS6), |
| 81 | .end = IOMUX_TO_IRQ(MX31_PIN_SFS6), | 80 | .end = IOMUX_TO_IRQ(MX31_PIN_SFS6), |
| 82 | .flags = IORESOURCE_IRQ, | 81 | .flags = IORESOURCE_IRQ, |
| @@ -162,7 +161,7 @@ MACHINE_START(MX31LITE, "LogicPD MX31 LITEKIT") | |||
| 162 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 161 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 163 | .boot_params = PHYS_OFFSET + 0x100, | 162 | .boot_params = PHYS_OFFSET + 0x100, |
| 164 | .map_io = mx31lite_map_io, | 163 | .map_io = mx31lite_map_io, |
| 165 | .init_irq = mxc_init_irq, | 164 | .init_irq = mx31_init_irq, |
| 166 | .init_machine = mxc_board_init, | 165 | .init_machine = mxc_board_init, |
| 167 | .timer = &mx31lite_timer, | 166 | .timer = &mx31lite_timer, |
| 168 | MACHINE_END | 167 | MACHINE_END |
diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c index b48581e7dedd..5592cdb8d0ad 100644 --- a/arch/arm/mach-mx3/mx31moboard-devboard.c +++ b/arch/arm/mach-mx3/mx31moboard-devboard.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/fsl_devices.h> | ||
| 20 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
| 21 | #include <linux/init.h> | 20 | #include <linux/init.h> |
| 22 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
| @@ -40,18 +39,6 @@ static unsigned int devboard_pins[] = { | |||
| 40 | MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0, | 39 | MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0, |
| 41 | MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD, | 40 | MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD, |
| 42 | MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29, | 41 | MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29, |
| 43 | /* USB OTG */ | ||
| 44 | MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, | ||
| 45 | MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, | ||
| 46 | MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, | ||
| 47 | MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, | ||
| 48 | MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, | ||
| 49 | MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, | ||
| 50 | MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, | ||
| 51 | MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, | ||
| 52 | MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR, | ||
| 53 | MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP, | ||
| 54 | MX31_PIN_USB_OC__GPIO1_30, | ||
| 55 | }; | 42 | }; |
| 56 | 43 | ||
| 57 | static struct imxuart_platform_data uart_pdata = { | 44 | static struct imxuart_platform_data uart_pdata = { |
| @@ -111,33 +98,6 @@ static struct imxmmc_platform_data sdhc2_pdata = { | |||
| 111 | .exit = devboard_sdhc2_exit, | 98 | .exit = devboard_sdhc2_exit, |
| 112 | }; | 99 | }; |
| 113 | 100 | ||
| 114 | static struct fsl_usb2_platform_data usb_pdata = { | ||
| 115 | .operating_mode = FSL_USB2_DR_DEVICE, | ||
| 116 | .phy_mode = FSL_USB2_PHY_ULPI, | ||
| 117 | }; | ||
| 118 | |||
| 119 | #define OTG_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST) | ||
| 120 | #define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC) | ||
| 121 | |||
| 122 | static void devboard_usbotg_init(void) | ||
| 123 | { | ||
| 124 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, OTG_PAD_CFG); | ||
| 125 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, OTG_PAD_CFG); | ||
| 126 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, OTG_PAD_CFG); | ||
| 127 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, OTG_PAD_CFG); | ||
| 128 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, OTG_PAD_CFG); | ||
| 129 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, OTG_PAD_CFG); | ||
| 130 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, OTG_PAD_CFG); | ||
| 131 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, OTG_PAD_CFG); | ||
| 132 | mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, OTG_PAD_CFG); | ||
| 133 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, OTG_PAD_CFG); | ||
| 134 | mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, OTG_PAD_CFG); | ||
| 135 | mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, OTG_PAD_CFG); | ||
| 136 | |||
| 137 | gpio_request(OTG_EN_B, "usb-udc-en"); | ||
| 138 | gpio_direction_output(OTG_EN_B, 0); | ||
| 139 | } | ||
| 140 | |||
| 141 | /* | 101 | /* |
| 142 | * system init for baseboard usage. Will be called by mx31moboard init. | 102 | * system init for baseboard usage. Will be called by mx31moboard init. |
| 143 | */ | 103 | */ |
| @@ -151,7 +111,4 @@ void __init mx31moboard_devboard_init(void) | |||
| 151 | mxc_register_device(&mxc_uart_device1, &uart_pdata); | 111 | mxc_register_device(&mxc_uart_device1, &uart_pdata); |
| 152 | 112 | ||
| 153 | mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata); | 113 | mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata); |
| 154 | |||
| 155 | devboard_usbotg_init(); | ||
| 156 | mxc_register_device(&mxc_otg_udc_device, &usb_pdata); | ||
| 157 | } | 114 | } |
diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c index 901fb0166c0e..2bfaffb344f0 100644 --- a/arch/arm/mach-mx3/mx31moboard-marxbot.c +++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/fsl_devices.h> | ||
| 20 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
| 21 | #include <linux/init.h> | 20 | #include <linux/init.h> |
| 22 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
| @@ -48,18 +47,8 @@ static unsigned int marxbot_pins[] = { | |||
| 48 | MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC, | 47 | MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC, |
| 49 | MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1, | 48 | MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1, |
| 50 | MX31_PIN_TXD2__GPIO1_28, | 49 | MX31_PIN_TXD2__GPIO1_28, |
| 51 | /* USB OTG */ | 50 | /* dsPIC resets */ |
| 52 | MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, | 51 | MX31_PIN_STXD5__GPIO1_21, MX31_PIN_SRXD5__GPIO1_22, |
| 53 | MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, | ||
| 54 | MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, | ||
| 55 | MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, | ||
| 56 | MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, | ||
| 57 | MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, | ||
| 58 | MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, | ||
| 59 | MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, | ||
| 60 | MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR, | ||
| 61 | MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP, | ||
| 62 | MX31_PIN_USB_OC__GPIO1_30, | ||
| 63 | }; | 52 | }; |
| 64 | 53 | ||
| 65 | #define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR) | 54 | #define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR) |
| @@ -115,31 +104,20 @@ static struct imxmmc_platform_data sdhc2_pdata = { | |||
| 115 | .exit = marxbot_sdhc2_exit, | 104 | .exit = marxbot_sdhc2_exit, |
| 116 | }; | 105 | }; |
| 117 | 106 | ||
| 118 | static struct fsl_usb2_platform_data usb_pdata = { | 107 | #define TRSLAT_RST_B IOMUX_TO_GPIO(MX31_PIN_STXD5) |
| 119 | .operating_mode = FSL_USB2_DR_DEVICE, | 108 | #define DSPICS_RST_B IOMUX_TO_GPIO(MX31_PIN_SRXD5) |
| 120 | .phy_mode = FSL_USB2_PHY_ULPI, | ||
| 121 | }; | ||
| 122 | |||
| 123 | #define OTG_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST) | ||
| 124 | #define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC) | ||
| 125 | 109 | ||
| 126 | static void marxbot_usbotg_init(void) | 110 | static void dspics_resets_init(void) |
| 127 | { | 111 | { |
| 128 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, OTG_PAD_CFG); | 112 | if (!gpio_request(TRSLAT_RST_B, "translator-rst")) { |
| 129 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, OTG_PAD_CFG); | 113 | gpio_direction_output(TRSLAT_RST_B, 1); |
| 130 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, OTG_PAD_CFG); | 114 | gpio_export(TRSLAT_RST_B, false); |
| 131 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, OTG_PAD_CFG); | 115 | } |
| 132 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, OTG_PAD_CFG); | 116 | |
| 133 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, OTG_PAD_CFG); | 117 | if (!gpio_request(DSPICS_RST_B, "dspics-rst")) { |
| 134 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, OTG_PAD_CFG); | 118 | gpio_direction_output(DSPICS_RST_B, 1); |
| 135 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, OTG_PAD_CFG); | 119 | gpio_export(DSPICS_RST_B, false); |
| 136 | mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, OTG_PAD_CFG); | 120 | } |
| 137 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, OTG_PAD_CFG); | ||
| 138 | mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, OTG_PAD_CFG); | ||
| 139 | mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, OTG_PAD_CFG); | ||
| 140 | |||
| 141 | gpio_request(OTG_EN_B, "usb-udc-en"); | ||
| 142 | gpio_direction_output(OTG_EN_B, 0); | ||
| 143 | } | 121 | } |
| 144 | 122 | ||
| 145 | /* | 123 | /* |
| @@ -152,8 +130,7 @@ void __init mx31moboard_marxbot_init(void) | |||
| 152 | mxc_iomux_setup_multiple_pins(marxbot_pins, ARRAY_SIZE(marxbot_pins), | 130 | mxc_iomux_setup_multiple_pins(marxbot_pins, ARRAY_SIZE(marxbot_pins), |
| 153 | "marxbot"); | 131 | "marxbot"); |
| 154 | 132 | ||
| 155 | mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata); | 133 | dspics_resets_init(); |
| 156 | 134 | ||
| 157 | marxbot_usbotg_init(); | 135 | mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata); |
| 158 | mxc_register_device(&mxc_otg_udc_device, &usb_pdata); | ||
| 159 | } | 136 | } |
diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c index 2a2da4739ecf..9243de54041a 100644 --- a/arch/arm/mach-mx3/mx31moboard.c +++ b/arch/arm/mach-mx3/mx31moboard.c | |||
| @@ -16,9 +16,12 @@ | |||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/delay.h> | ||
| 20 | #include <linux/fsl_devices.h> | ||
| 19 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
| 20 | #include <linux/init.h> | 22 | #include <linux/init.h> |
| 21 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
| 24 | #include <linux/leds.h> | ||
| 22 | #include <linux/memory.h> | 25 | #include <linux/memory.h> |
| 23 | #include <linux/mtd/physmap.h> | 26 | #include <linux/mtd/physmap.h> |
| 24 | #include <linux/mtd/partitions.h> | 27 | #include <linux/mtd/partitions.h> |
| @@ -36,6 +39,7 @@ | |||
| 36 | #include <mach/iomux-mx3.h> | 39 | #include <mach/iomux-mx3.h> |
| 37 | #include <mach/i2c.h> | 40 | #include <mach/i2c.h> |
| 38 | #include <mach/mmc.h> | 41 | #include <mach/mmc.h> |
| 42 | #include <mach/mx31.h> | ||
| 39 | 43 | ||
| 40 | #include "devices.h" | 44 | #include "devices.h" |
| 41 | 45 | ||
| @@ -55,6 +59,26 @@ static unsigned int moboard_pins[] = { | |||
| 55 | MX31_PIN_SD1_DATA1__SD1_DATA1, MX31_PIN_SD1_DATA0__SD1_DATA0, | 59 | MX31_PIN_SD1_DATA1__SD1_DATA1, MX31_PIN_SD1_DATA0__SD1_DATA0, |
| 56 | MX31_PIN_SD1_CLK__SD1_CLK, MX31_PIN_SD1_CMD__SD1_CMD, | 60 | MX31_PIN_SD1_CLK__SD1_CLK, MX31_PIN_SD1_CMD__SD1_CMD, |
| 57 | MX31_PIN_ATA_CS0__GPIO3_26, MX31_PIN_ATA_CS1__GPIO3_27, | 61 | MX31_PIN_ATA_CS0__GPIO3_26, MX31_PIN_ATA_CS1__GPIO3_27, |
| 62 | /* USB reset */ | ||
| 63 | MX31_PIN_GPIO1_0__GPIO1_0, | ||
| 64 | /* USB OTG */ | ||
| 65 | MX31_PIN_USBOTG_DATA0__USBOTG_DATA0, | ||
| 66 | MX31_PIN_USBOTG_DATA1__USBOTG_DATA1, | ||
| 67 | MX31_PIN_USBOTG_DATA2__USBOTG_DATA2, | ||
| 68 | MX31_PIN_USBOTG_DATA3__USBOTG_DATA3, | ||
| 69 | MX31_PIN_USBOTG_DATA4__USBOTG_DATA4, | ||
| 70 | MX31_PIN_USBOTG_DATA5__USBOTG_DATA5, | ||
| 71 | MX31_PIN_USBOTG_DATA6__USBOTG_DATA6, | ||
| 72 | MX31_PIN_USBOTG_DATA7__USBOTG_DATA7, | ||
| 73 | MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR, | ||
| 74 | MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP, | ||
| 75 | MX31_PIN_USB_OC__GPIO1_30, | ||
| 76 | /* LEDs */ | ||
| 77 | MX31_PIN_SVEN0__GPIO2_0, MX31_PIN_STX0__GPIO2_1, | ||
| 78 | MX31_PIN_SRX0__GPIO2_2, MX31_PIN_SIMPD0__GPIO2_3, | ||
| 79 | /* SEL */ | ||
| 80 | MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9, | ||
| 81 | MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11, | ||
| 58 | }; | 82 | }; |
| 59 | 83 | ||
| 60 | static struct physmap_flash_data mx31moboard_flash_data = { | 84 | static struct physmap_flash_data mx31moboard_flash_data = { |
| @@ -142,8 +166,109 @@ static struct imxmmc_platform_data sdhc1_pdata = { | |||
| 142 | .exit = moboard_sdhc1_exit, | 166 | .exit = moboard_sdhc1_exit, |
| 143 | }; | 167 | }; |
| 144 | 168 | ||
| 169 | /* | ||
| 170 | * this pin is dedicated for all mx31moboard systems, so we do it here | ||
| 171 | */ | ||
| 172 | #define USB_RESET_B IOMUX_TO_GPIO(MX31_PIN_GPIO1_0) | ||
| 173 | |||
| 174 | static void usb_xcvr_reset(void) | ||
| 175 | { | ||
| 176 | gpio_request(USB_RESET_B, "usb-reset"); | ||
| 177 | gpio_direction_output(USB_RESET_B, 0); | ||
| 178 | mdelay(1); | ||
| 179 | gpio_set_value(USB_RESET_B, 1); | ||
| 180 | } | ||
| 181 | |||
| 182 | #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ | ||
| 183 | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) | ||
| 184 | |||
| 185 | #define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC) | ||
| 186 | |||
| 187 | static void moboard_usbotg_init(void) | ||
| 188 | { | ||
| 189 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG); | ||
| 190 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG); | ||
| 191 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG); | ||
| 192 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG); | ||
| 193 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG); | ||
| 194 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG); | ||
| 195 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG); | ||
| 196 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG); | ||
| 197 | mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG); | ||
| 198 | mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG); | ||
| 199 | mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG); | ||
| 200 | mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG); | ||
| 201 | |||
| 202 | gpio_request(OTG_EN_B, "usb-udc-en"); | ||
| 203 | gpio_direction_output(OTG_EN_B, 0); | ||
| 204 | } | ||
| 205 | |||
| 206 | static struct fsl_usb2_platform_data usb_pdata = { | ||
| 207 | .operating_mode = FSL_USB2_DR_DEVICE, | ||
| 208 | .phy_mode = FSL_USB2_PHY_ULPI, | ||
| 209 | }; | ||
| 210 | |||
| 211 | static struct gpio_led mx31moboard_leds[] = { | ||
| 212 | { | ||
| 213 | .name = "coreboard-led-0:red:running", | ||
| 214 | .default_trigger = "heartbeat", | ||
| 215 | .gpio = IOMUX_TO_GPIO(MX31_PIN_SVEN0), | ||
| 216 | }, { | ||
| 217 | .name = "coreboard-led-1:red", | ||
| 218 | .gpio = IOMUX_TO_GPIO(MX31_PIN_STX0), | ||
| 219 | }, { | ||
| 220 | .name = "coreboard-led-2:red", | ||
| 221 | .gpio = IOMUX_TO_GPIO(MX31_PIN_SRX0), | ||
| 222 | }, { | ||
| 223 | .name = "coreboard-led-3:red", | ||
| 224 | .gpio = IOMUX_TO_GPIO(MX31_PIN_SIMPD0), | ||
| 225 | }, | ||
| 226 | }; | ||
| 227 | |||
| 228 | static struct gpio_led_platform_data mx31moboard_led_pdata = { | ||
| 229 | .num_leds = ARRAY_SIZE(mx31moboard_leds), | ||
| 230 | .leds = mx31moboard_leds, | ||
| 231 | }; | ||
| 232 | |||
| 233 | static struct platform_device mx31moboard_leds_device = { | ||
| 234 | .name = "leds-gpio", | ||
| 235 | .id = -1, | ||
| 236 | .dev = { | ||
| 237 | .platform_data = &mx31moboard_led_pdata, | ||
| 238 | }, | ||
| 239 | }; | ||
| 240 | |||
| 241 | #define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1) | ||
| 242 | #define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1) | ||
| 243 | #define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1) | ||
| 244 | #define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1) | ||
| 245 | |||
| 246 | static void mx31moboard_init_sel_gpios(void) | ||
| 247 | { | ||
| 248 | if (!gpio_request(SEL0, "sel0")) { | ||
| 249 | gpio_direction_input(SEL0); | ||
| 250 | gpio_export(SEL0, true); | ||
| 251 | } | ||
| 252 | |||
| 253 | if (!gpio_request(SEL1, "sel1")) { | ||
| 254 | gpio_direction_input(SEL1); | ||
| 255 | gpio_export(SEL1, true); | ||
| 256 | } | ||
| 257 | |||
| 258 | if (!gpio_request(SEL2, "sel2")) { | ||
| 259 | gpio_direction_input(SEL2); | ||
| 260 | gpio_export(SEL2, true); | ||
| 261 | } | ||
| 262 | |||
| 263 | if (!gpio_request(SEL3, "sel3")) { | ||
| 264 | gpio_direction_input(SEL3); | ||
| 265 | gpio_export(SEL3, true); | ||
| 266 | } | ||
| 267 | } | ||
| 268 | |||
| 145 | static struct platform_device *devices[] __initdata = { | 269 | static struct platform_device *devices[] __initdata = { |
| 146 | &mx31moboard_flash, | 270 | &mx31moboard_flash, |
| 271 | &mx31moboard_leds_device, | ||
| 147 | }; | 272 | }; |
| 148 | 273 | ||
| 149 | static int mx31moboard_baseboard; | 274 | static int mx31moboard_baseboard; |
| @@ -162,11 +287,18 @@ static void __init mxc_board_init(void) | |||
| 162 | mxc_register_device(&mxc_uart_device0, &uart_pdata); | 287 | mxc_register_device(&mxc_uart_device0, &uart_pdata); |
| 163 | mxc_register_device(&mxc_uart_device4, &uart_pdata); | 288 | mxc_register_device(&mxc_uart_device4, &uart_pdata); |
| 164 | 289 | ||
| 290 | mx31moboard_init_sel_gpios(); | ||
| 291 | |||
| 165 | mxc_register_device(&mxc_i2c_device0, &moboard_i2c0_pdata); | 292 | mxc_register_device(&mxc_i2c_device0, &moboard_i2c0_pdata); |
| 166 | mxc_register_device(&mxc_i2c_device1, &moboard_i2c1_pdata); | 293 | mxc_register_device(&mxc_i2c_device1, &moboard_i2c1_pdata); |
| 167 | 294 | ||
| 168 | mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata); | 295 | mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata); |
| 169 | 296 | ||
| 297 | usb_xcvr_reset(); | ||
| 298 | |||
| 299 | moboard_usbotg_init(); | ||
| 300 | mxc_register_device(&mxc_otg_udc_device, &usb_pdata); | ||
| 301 | |||
| 170 | switch (mx31moboard_baseboard) { | 302 | switch (mx31moboard_baseboard) { |
| 171 | case MX31NOBOARD: | 303 | case MX31NOBOARD: |
| 172 | break; | 304 | break; |
| @@ -197,7 +329,7 @@ MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard") | |||
| 197 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 329 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 198 | .boot_params = PHYS_OFFSET + 0x100, | 330 | .boot_params = PHYS_OFFSET + 0x100, |
| 199 | .map_io = mx31_map_io, | 331 | .map_io = mx31_map_io, |
| 200 | .init_irq = mxc_init_irq, | 332 | .init_irq = mx31_init_irq, |
| 201 | .init_machine = mxc_board_init, | 333 | .init_machine = mxc_board_init, |
| 202 | .timer = &mx31moboard_timer, | 334 | .timer = &mx31moboard_timer, |
| 203 | MACHINE_END | 335 | MACHINE_END |
diff --git a/arch/arm/mach-mx3/mx31pdk.c b/arch/arm/mach-mx3/mx31pdk.c index c19838d2e369..0f7a2f06bc2d 100644 --- a/arch/arm/mach-mx3/mx31pdk.c +++ b/arch/arm/mach-mx3/mx31pdk.c | |||
| @@ -265,7 +265,7 @@ MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)") | |||
| 265 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 265 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 266 | .boot_params = PHYS_OFFSET + 0x100, | 266 | .boot_params = PHYS_OFFSET + 0x100, |
| 267 | .map_io = mx31pdk_map_io, | 267 | .map_io = mx31pdk_map_io, |
| 268 | .init_irq = mxc_init_irq, | 268 | .init_irq = mx31_init_irq, |
| 269 | .init_machine = mxc_board_init, | 269 | .init_machine = mxc_board_init, |
| 270 | .timer = &mx31pdk_timer, | 270 | .timer = &mx31pdk_timer, |
| 271 | MACHINE_END | 271 | MACHINE_END |
diff --git a/arch/arm/mach-mx3/mx35pdk.c b/arch/arm/mach-mx3/mx35pdk.c index 6d15374414b9..6ff186e46ceb 100644 --- a/arch/arm/mach-mx3/mx35pdk.c +++ b/arch/arm/mach-mx3/mx35pdk.c | |||
| @@ -98,7 +98,7 @@ MACHINE_START(MX35_3DS, "Freescale MX35PDK") | |||
| 98 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 98 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 99 | .boot_params = PHYS_OFFSET + 0x100, | 99 | .boot_params = PHYS_OFFSET + 0x100, |
| 100 | .map_io = mx35_map_io, | 100 | .map_io = mx35_map_io, |
| 101 | .init_irq = mxc_init_irq, | 101 | .init_irq = mx35_init_irq, |
| 102 | .init_machine = mxc_board_init, | 102 | .init_machine = mxc_board_init, |
| 103 | .timer = &mx35pdk_timer, | 103 | .timer = &mx35pdk_timer, |
| 104 | MACHINE_END | 104 | MACHINE_END |
diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c index 840cfda341d0..6cbaabedf386 100644 --- a/arch/arm/mach-mx3/pcm037.c +++ b/arch/arm/mach-mx3/pcm037.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/spi/spi.h> | 32 | #include <linux/spi/spi.h> |
| 33 | #include <linux/irq.h> | 33 | #include <linux/irq.h> |
| 34 | #include <linux/fsl_devices.h> | 34 | #include <linux/fsl_devices.h> |
| 35 | #include <linux/can/platform/sja1000.h> | ||
| 35 | 36 | ||
| 36 | #include <media/soc_camera.h> | 37 | #include <media/soc_camera.h> |
| 37 | 38 | ||
| @@ -169,6 +170,8 @@ static unsigned int pcm037_pins[] = { | |||
| 169 | MX31_PIN_CSI_MCLK__CSI_MCLK, | 170 | MX31_PIN_CSI_MCLK__CSI_MCLK, |
| 170 | MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, | 171 | MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, |
| 171 | MX31_PIN_CSI_VSYNC__CSI_VSYNC, | 172 | MX31_PIN_CSI_VSYNC__CSI_VSYNC, |
| 173 | /* GPIO */ | ||
| 174 | IOMUX_MODE(MX31_PIN_ATA_DMACK, IOMUX_CONFIG_GPIO), | ||
| 172 | }; | 175 | }; |
| 173 | 176 | ||
| 174 | static struct physmap_flash_data pcm037_flash_data = { | 177 | static struct physmap_flash_data pcm037_flash_data = { |
| @@ -244,12 +247,11 @@ static struct imxuart_platform_data uart_pdata = { | |||
| 244 | }; | 247 | }; |
| 245 | 248 | ||
| 246 | static struct resource smsc911x_resources[] = { | 249 | static struct resource smsc911x_resources[] = { |
| 247 | [0] = { | 250 | { |
| 248 | .start = CS1_BASE_ADDR + 0x300, | 251 | .start = CS1_BASE_ADDR + 0x300, |
| 249 | .end = CS1_BASE_ADDR + 0x300 + SZ_64K - 1, | 252 | .end = CS1_BASE_ADDR + 0x300 + SZ_64K - 1, |
| 250 | .flags = IORESOURCE_MEM, | 253 | .flags = IORESOURCE_MEM, |
| 251 | }, | 254 | }, { |
| 252 | [1] = { | ||
| 253 | .start = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), | 255 | .start = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), |
| 254 | .end = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), | 256 | .end = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), |
| 255 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, | 257 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, |
| @@ -339,8 +341,7 @@ static struct i2c_board_info pcm037_i2c_devices[] = { | |||
| 339 | I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ | 341 | I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ |
| 340 | .platform_data = &board_eeprom, | 342 | .platform_data = &board_eeprom, |
| 341 | }, { | 343 | }, { |
| 342 | I2C_BOARD_INFO("rtc-pcf8563", 0x51), | 344 | I2C_BOARD_INFO("pcf8563", 0x51), |
| 343 | .type = "pcf8563", | ||
| 344 | } | 345 | } |
| 345 | }; | 346 | }; |
| 346 | 347 | ||
| @@ -515,6 +516,33 @@ static struct mx3fb_platform_data mx3fb_pdata = { | |||
| 515 | .num_modes = ARRAY_SIZE(fb_modedb), | 516 | .num_modes = ARRAY_SIZE(fb_modedb), |
| 516 | }; | 517 | }; |
| 517 | 518 | ||
| 519 | static struct resource pcm970_sja1000_resources[] = { | ||
| 520 | { | ||
| 521 | .start = CS5_BASE_ADDR, | ||
| 522 | .end = CS5_BASE_ADDR + 0x100 - 1, | ||
| 523 | .flags = IORESOURCE_MEM, | ||
| 524 | }, { | ||
| 525 | .start = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)), | ||
| 526 | .end = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)), | ||
| 527 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, | ||
| 528 | }, | ||
| 529 | }; | ||
| 530 | |||
| 531 | struct sja1000_platform_data pcm970_sja1000_platform_data = { | ||
| 532 | .clock = 16000000 / 2, | ||
| 533 | .ocr = 0x40 | 0x18, | ||
| 534 | .cdr = 0x40, | ||
| 535 | }; | ||
| 536 | |||
| 537 | static struct platform_device pcm970_sja1000 = { | ||
| 538 | .name = "sja1000_platform", | ||
| 539 | .dev = { | ||
| 540 | .platform_data = &pcm970_sja1000_platform_data, | ||
| 541 | }, | ||
| 542 | .resource = pcm970_sja1000_resources, | ||
| 543 | .num_resources = ARRAY_SIZE(pcm970_sja1000_resources), | ||
| 544 | }; | ||
| 545 | |||
| 518 | /* | 546 | /* |
| 519 | * Board specific initialization. | 547 | * Board specific initialization. |
| 520 | */ | 548 | */ |
| @@ -575,6 +603,8 @@ static void __init mxc_board_init(void) | |||
| 575 | 603 | ||
| 576 | if (!pcm037_camera_alloc_dma(4 * 1024 * 1024)) | 604 | if (!pcm037_camera_alloc_dma(4 * 1024 * 1024)) |
| 577 | mxc_register_device(&mx3_camera, &camera_pdata); | 605 | mxc_register_device(&mx3_camera, &camera_pdata); |
| 606 | |||
| 607 | platform_device_register(&pcm970_sja1000); | ||
| 578 | } | 608 | } |
| 579 | 609 | ||
| 580 | static void __init pcm037_timer_init(void) | 610 | static void __init pcm037_timer_init(void) |
| @@ -592,7 +622,7 @@ MACHINE_START(PCM037, "Phytec Phycore pcm037") | |||
| 592 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 622 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 593 | .boot_params = PHYS_OFFSET + 0x100, | 623 | .boot_params = PHYS_OFFSET + 0x100, |
| 594 | .map_io = mx31_map_io, | 624 | .map_io = mx31_map_io, |
| 595 | .init_irq = mxc_init_irq, | 625 | .init_irq = mx31_init_irq, |
| 596 | .init_machine = mxc_board_init, | 626 | .init_machine = mxc_board_init, |
| 597 | .timer = &pcm037_timer, | 627 | .timer = &pcm037_timer, |
| 598 | MACHINE_END | 628 | MACHINE_END |
diff --git a/arch/arm/mach-mx3/pcm043.c b/arch/arm/mach-mx3/pcm043.c index 8d27c324abf2..e18a224671fa 100644 --- a/arch/arm/mach-mx3/pcm043.c +++ b/arch/arm/mach-mx3/pcm043.c | |||
| @@ -133,8 +133,7 @@ static struct i2c_board_info pcm043_i2c_devices[] = { | |||
| 133 | I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ | 133 | I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ |
| 134 | .platform_data = &board_eeprom, | 134 | .platform_data = &board_eeprom, |
| 135 | }, { | 135 | }, { |
| 136 | I2C_BOARD_INFO("rtc-pcf8563", 0x51), | 136 | I2C_BOARD_INFO("pcf8563", 0x51), |
| 137 | .type = "pcf8563", | ||
| 138 | } | 137 | } |
| 139 | }; | 138 | }; |
| 140 | #endif | 139 | #endif |
| @@ -203,7 +202,8 @@ static struct pad_desc pcm043_pads[] = { | |||
| 203 | MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC, | 202 | MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC, |
| 204 | MX35_PAD_D3_REV__IPU_DISPB_D3_REV, | 203 | MX35_PAD_D3_REV__IPU_DISPB_D3_REV, |
| 205 | MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS, | 204 | MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS, |
| 206 | MX35_PAD_D3_SPL__IPU_DISPB_D3_SPL | 205 | /* gpio */ |
| 206 | MX35_PAD_ATA_CS0__GPIO2_6, | ||
| 207 | }; | 207 | }; |
| 208 | 208 | ||
| 209 | /* | 209 | /* |
| @@ -245,7 +245,7 @@ MACHINE_START(PCM043, "Phytec Phycore pcm043") | |||
| 245 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 245 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 246 | .boot_params = PHYS_OFFSET + 0x100, | 246 | .boot_params = PHYS_OFFSET + 0x100, |
| 247 | .map_io = mx35_map_io, | 247 | .map_io = mx35_map_io, |
| 248 | .init_irq = mxc_init_irq, | 248 | .init_irq = mx35_init_irq, |
| 249 | .init_machine = mxc_board_init, | 249 | .init_machine = mxc_board_init, |
| 250 | .timer = &pcm043_timer, | 250 | .timer = &pcm043_timer, |
| 251 | MACHINE_END | 251 | MACHINE_END |
diff --git a/arch/arm/mach-mx3/qong.c b/arch/arm/mach-mx3/qong.c index 82b31c4ab11f..044511f1b9a9 100644 --- a/arch/arm/mach-mx3/qong.c +++ b/arch/arm/mach-mx3/qong.c | |||
| @@ -81,13 +81,12 @@ static inline void mxc_init_imx_uart(void) | |||
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | static struct resource dnet_resources[] = { | 83 | static struct resource dnet_resources[] = { |
| 84 | [0] = { | 84 | { |
| 85 | .name = "dnet-memory", | 85 | .name = "dnet-memory", |
| 86 | .start = QONG_DNET_BASEADDR, | 86 | .start = QONG_DNET_BASEADDR, |
| 87 | .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1, | 87 | .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1, |
| 88 | .flags = IORESOURCE_MEM, | 88 | .flags = IORESOURCE_MEM, |
| 89 | }, | 89 | }, { |
| 90 | [1] = { | ||
| 91 | .start = QONG_FPGA_IRQ, | 90 | .start = QONG_FPGA_IRQ, |
| 92 | .end = QONG_FPGA_IRQ, | 91 | .end = QONG_FPGA_IRQ, |
| 93 | .flags = IORESOURCE_IRQ, | 92 | .flags = IORESOURCE_IRQ, |
| @@ -280,7 +279,7 @@ MACHINE_START(QONG, "Dave/DENX QongEVB-LITE") | |||
| 280 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 279 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
| 281 | .boot_params = PHYS_OFFSET + 0x100, | 280 | .boot_params = PHYS_OFFSET + 0x100, |
| 282 | .map_io = mx31_map_io, | 281 | .map_io = mx31_map_io, |
| 283 | .init_irq = mxc_init_irq, | 282 | .init_irq = mx31_init_irq, |
| 284 | .init_machine = mxc_board_init, | 283 | .init_machine = mxc_board_init, |
| 285 | .timer = &qong_timer, | 284 | .timer = &qong_timer, |
| 286 | MACHINE_END | 285 | MACHINE_END |
diff --git a/arch/arm/mach-mxc91231/Kconfig b/arch/arm/mach-mxc91231/Kconfig new file mode 100644 index 000000000000..8e5fa38ebb67 --- /dev/null +++ b/arch/arm/mach-mxc91231/Kconfig | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | if ARCH_MXC91231 | ||
| 2 | |||
| 3 | comment "MXC91231 platforms:" | ||
| 4 | |||
| 5 | config MACH_MAGX_ZN5 | ||
| 6 | bool "Support Motorola Zn5 GSM phone" | ||
| 7 | default n | ||
| 8 | help | ||
| 9 | Include support for Motorola Zn5 GSM phone. | ||
| 10 | |||
| 11 | endif | ||
diff --git a/arch/arm/mach-mxc91231/Makefile b/arch/arm/mach-mxc91231/Makefile new file mode 100644 index 000000000000..011d5e197125 --- /dev/null +++ b/arch/arm/mach-mxc91231/Makefile | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | obj-y := mm.o clock.o devices.o system.o iomux.o | ||
| 2 | obj-$(CONFIG_MACH_MAGX_ZN5) += magx-zn5.o | ||
diff --git a/arch/arm/mach-mxc91231/Makefile.boot b/arch/arm/mach-mxc91231/Makefile.boot new file mode 100644 index 000000000000..9939a19d99a1 --- /dev/null +++ b/arch/arm/mach-mxc91231/Makefile.boot | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | zreladdr-y := 0x90008000 | ||
| 2 | params_phys-y := 0x90000100 | ||
| 3 | initrd_phys-y := 0x90800000 | ||
diff --git a/arch/arm/mach-mxc91231/clock.c b/arch/arm/mach-mxc91231/clock.c new file mode 100644 index 000000000000..ecfa37fef8ad --- /dev/null +++ b/arch/arm/mach-mxc91231/clock.c | |||
| @@ -0,0 +1,642 @@ | |||
| 1 | #include <linux/clk.h> | ||
| 2 | #include <linux/kernel.h> | ||
| 3 | #include <linux/init.h> | ||
| 4 | #include <linux/io.h> | ||
| 5 | |||
| 6 | #include <mach/clock.h> | ||
| 7 | #include <mach/hardware.h> | ||
| 8 | #include <mach/common.h> | ||
| 9 | |||
| 10 | #include <asm/clkdev.h> | ||
| 11 | #include <asm/bug.h> | ||
| 12 | #include <asm/div64.h> | ||
| 13 | |||
| 14 | #include "crm_regs.h" | ||
| 15 | |||
| 16 | #define CRM_SMALL_DIVIDER(base, name) \ | ||
| 17 | crm_small_divider(base, \ | ||
| 18 | base ## _ ## name ## _OFFSET, \ | ||
| 19 | base ## _ ## name ## _MASK) | ||
| 20 | #define CRM_1DIVIDER(base, name) \ | ||
| 21 | crm_divider(base, \ | ||
| 22 | base ## _ ## name ## _OFFSET, \ | ||
| 23 | base ## _ ## name ## _MASK, 1) | ||
| 24 | #define CRM_16DIVIDER(base, name) \ | ||
| 25 | crm_divider(base, \ | ||
| 26 | base ## _ ## name ## _OFFSET, \ | ||
| 27 | base ## _ ## name ## _MASK, 16) | ||
| 28 | |||
| 29 | static u32 crm_small_divider(void __iomem *reg, u8 offset, u32 mask) | ||
| 30 | { | ||
| 31 | static const u32 crm_small_dividers[] = { | ||
| 32 | 2, 3, 4, 5, 6, 8, 10, 12 | ||
| 33 | }; | ||
| 34 | u8 idx; | ||
| 35 | |||
| 36 | idx = (__raw_readl(reg) & mask) >> offset; | ||
| 37 | if (idx > 7) | ||
| 38 | return 1; | ||
| 39 | |||
| 40 | return crm_small_dividers[idx]; | ||
| 41 | } | ||
| 42 | |||
| 43 | static u32 crm_divider(void __iomem *reg, u8 offset, u32 mask, u32 z) | ||
| 44 | { | ||
| 45 | u32 div; | ||
| 46 | div = (__raw_readl(reg) & mask) >> offset; | ||
| 47 | return div ? div : z; | ||
| 48 | } | ||
| 49 | |||
| 50 | static int _clk_1bit_enable(struct clk *clk) | ||
| 51 | { | ||
| 52 | u32 reg; | ||
| 53 | |||
| 54 | reg = __raw_readl(clk->enable_reg); | ||
| 55 | reg |= 1 << clk->enable_shift; | ||
| 56 | __raw_writel(reg, clk->enable_reg); | ||
| 57 | |||
| 58 | return 0; | ||
| 59 | } | ||
| 60 | |||
| 61 | static void _clk_1bit_disable(struct clk *clk) | ||
| 62 | { | ||
| 63 | u32 reg; | ||
| 64 | |||
| 65 | reg = __raw_readl(clk->enable_reg); | ||
| 66 | reg &= ~(1 << clk->enable_shift); | ||
| 67 | __raw_writel(reg, clk->enable_reg); | ||
| 68 | } | ||
| 69 | |||
| 70 | static int _clk_3bit_enable(struct clk *clk) | ||
| 71 | { | ||
| 72 | u32 reg; | ||
| 73 | |||
| 74 | reg = __raw_readl(clk->enable_reg); | ||
| 75 | reg |= 0x7 << clk->enable_shift; | ||
| 76 | __raw_writel(reg, clk->enable_reg); | ||
| 77 | |||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 81 | static void _clk_3bit_disable(struct clk *clk) | ||
| 82 | { | ||
| 83 | u32 reg; | ||
| 84 | |||
| 85 | reg = __raw_readl(clk->enable_reg); | ||
| 86 | reg &= ~(0x7 << clk->enable_shift); | ||
| 87 | __raw_writel(reg, clk->enable_reg); | ||
| 88 | } | ||
| 89 | |||
| 90 | static unsigned long ckih_rate; | ||
| 91 | |||
| 92 | static unsigned long clk_ckih_get_rate(struct clk *clk) | ||
| 93 | { | ||
| 94 | return ckih_rate; | ||
| 95 | } | ||
| 96 | |||
| 97 | static struct clk ckih_clk = { | ||
| 98 | .get_rate = clk_ckih_get_rate, | ||
| 99 | }; | ||
| 100 | |||
| 101 | static unsigned long clk_ckih_x2_get_rate(struct clk *clk) | ||
| 102 | { | ||
| 103 | return 2 * clk_get_rate(clk->parent); | ||
| 104 | } | ||
| 105 | |||
| 106 | static struct clk ckih_x2_clk = { | ||
| 107 | .parent = &ckih_clk, | ||
| 108 | .get_rate = clk_ckih_x2_get_rate, | ||
| 109 | }; | ||
| 110 | |||
| 111 | static unsigned long clk_ckil_get_rate(struct clk *clk) | ||
| 112 | { | ||
| 113 | return CKIL_CLK_FREQ; | ||
| 114 | } | ||
| 115 | |||
| 116 | static struct clk ckil_clk = { | ||
| 117 | .get_rate = clk_ckil_get_rate, | ||
| 118 | }; | ||
| 119 | |||
| 120 | /* plls stuff */ | ||
| 121 | static struct clk mcu_pll_clk; | ||
| 122 | static struct clk dsp_pll_clk; | ||
| 123 | static struct clk usb_pll_clk; | ||
| 124 | |||
| 125 | static struct clk *pll_clk(u8 sel) | ||
| 126 | { | ||
| 127 | switch (sel) { | ||
| 128 | case 0: | ||
| 129 | return &mcu_pll_clk; | ||
| 130 | case 1: | ||
| 131 | return &dsp_pll_clk; | ||
| 132 | case 2: | ||
| 133 | return &usb_pll_clk; | ||
| 134 | } | ||
| 135 | BUG(); | ||
| 136 | } | ||
| 137 | |||
| 138 | static void __iomem *pll_base(struct clk *clk) | ||
| 139 | { | ||
| 140 | if (clk == &mcu_pll_clk) | ||
| 141 | return MXC_PLL0_BASE; | ||
| 142 | else if (clk == &dsp_pll_clk) | ||
| 143 | return MXC_PLL1_BASE; | ||
| 144 | else if (clk == &usb_pll_clk) | ||
| 145 | return MXC_PLL2_BASE; | ||
| 146 | BUG(); | ||
| 147 | } | ||
| 148 | |||
| 149 | static unsigned long clk_pll_get_rate(struct clk *clk) | ||
| 150 | { | ||
| 151 | const void __iomem *pllbase; | ||
| 152 | unsigned long dp_op, dp_mfd, dp_mfn, pll_hfsm, ref_clk, mfi; | ||
| 153 | long mfn, mfn_abs, mfd, pdf; | ||
| 154 | s64 temp; | ||
| 155 | pllbase = pll_base(clk); | ||
| 156 | |||
| 157 | pll_hfsm = __raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_HFSM; | ||
| 158 | if (pll_hfsm == 0) { | ||
| 159 | dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); | ||
| 160 | dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); | ||
| 161 | dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); | ||
| 162 | } else { | ||
| 163 | dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP); | ||
| 164 | dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD); | ||
| 165 | dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN); | ||
| 166 | } | ||
| 167 | |||
| 168 | pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; | ||
| 169 | mfi = (dp_op >> MXC_PLL_DP_OP_MFI_OFFSET) & MXC_PLL_DP_OP_PDF_MASK; | ||
| 170 | mfi = (mfi <= 5) ? 5 : mfi; | ||
| 171 | mfd = dp_mfd & MXC_PLL_DP_MFD_MASK; | ||
| 172 | mfn = dp_mfn & MXC_PLL_DP_MFN_MASK; | ||
| 173 | mfn = (mfn <= 0x4000000) ? mfn : (mfn - 0x10000000); | ||
| 174 | |||
| 175 | if (mfn < 0) | ||
| 176 | mfn_abs = -mfn; | ||
| 177 | else | ||
| 178 | mfn_abs = mfn; | ||
| 179 | |||
| 180 | /* XXX: actually this asumes that ckih is fed to pll, but spec says | ||
| 181 | * that ckih_x2 is also possible. need to check this out. | ||
| 182 | */ | ||
| 183 | ref_clk = clk_get_rate(&ckih_clk); | ||
| 184 | |||
| 185 | ref_clk *= 2; | ||
| 186 | ref_clk /= pdf + 1; | ||
| 187 | |||
| 188 | temp = (u64) ref_clk * mfn_abs; | ||
| 189 | do_div(temp, mfd); | ||
| 190 | if (mfn < 0) | ||
| 191 | temp = -temp; | ||
| 192 | temp += ref_clk * mfi; | ||
| 193 | |||
| 194 | return temp; | ||
| 195 | } | ||
| 196 | |||
| 197 | static int clk_pll_enable(struct clk *clk) | ||
| 198 | { | ||
| 199 | void __iomem *ctl; | ||
| 200 | u32 reg; | ||
| 201 | |||
| 202 | ctl = pll_base(clk); | ||
| 203 | reg = __raw_readl(ctl); | ||
| 204 | reg |= (MXC_PLL_DP_CTL_RST | MXC_PLL_DP_CTL_UPEN); | ||
| 205 | __raw_writel(reg, ctl); | ||
| 206 | do { | ||
| 207 | reg = __raw_readl(ctl); | ||
| 208 | } while ((reg & MXC_PLL_DP_CTL_LRF) != MXC_PLL_DP_CTL_LRF); | ||
| 209 | return 0; | ||
| 210 | } | ||
| 211 | |||
| 212 | static void clk_pll_disable(struct clk *clk) | ||
| 213 | { | ||
| 214 | void __iomem *ctl; | ||
| 215 | u32 reg; | ||
| 216 | |||
| 217 | ctl = pll_base(clk); | ||
| 218 | reg = __raw_readl(ctl); | ||
| 219 | reg &= ~(MXC_PLL_DP_CTL_RST | MXC_PLL_DP_CTL_UPEN); | ||
| 220 | __raw_writel(reg, ctl); | ||
| 221 | } | ||
| 222 | |||
| 223 | static struct clk mcu_pll_clk = { | ||
| 224 | .parent = &ckih_clk, | ||
| 225 | .get_rate = clk_pll_get_rate, | ||
| 226 | .enable = clk_pll_enable, | ||
| 227 | .disable = clk_pll_disable, | ||
| 228 | }; | ||
| 229 | |||
| 230 | static struct clk dsp_pll_clk = { | ||
| 231 | .parent = &ckih_clk, | ||
| 232 | .get_rate = clk_pll_get_rate, | ||
| 233 | .enable = clk_pll_enable, | ||
| 234 | .disable = clk_pll_disable, | ||
| 235 | }; | ||
| 236 | |||
| 237 | static struct clk usb_pll_clk = { | ||
| 238 | .parent = &ckih_clk, | ||
| 239 | .get_rate = clk_pll_get_rate, | ||
| 240 | .enable = clk_pll_enable, | ||
| 241 | .disable = clk_pll_disable, | ||
| 242 | }; | ||
| 243 | /* plls stuff end */ | ||
| 244 | |||
| 245 | /* ap_ref_clk stuff */ | ||
| 246 | static struct clk ap_ref_clk; | ||
| 247 | |||
| 248 | static unsigned long clk_ap_ref_get_rate(struct clk *clk) | ||
| 249 | { | ||
| 250 | u32 ascsr, acsr; | ||
| 251 | u8 ap_pat_ref_div_2, ap_isel, acs, ads; | ||
| 252 | |||
| 253 | ascsr = __raw_readl(MXC_CRMAP_ASCSR); | ||
| 254 | acsr = __raw_readl(MXC_CRMAP_ACSR); | ||
| 255 | |||
| 256 | /* 0 for ckih, 1 for ckih*2 */ | ||
| 257 | ap_isel = ascsr & MXC_CRMAP_ASCSR_APISEL; | ||
| 258 | /* reg divider */ | ||
| 259 | ap_pat_ref_div_2 = (ascsr >> MXC_CRMAP_ASCSR_AP_PATDIV2_OFFSET) & 0x1; | ||
| 260 | /* undocumented, 1 for disabling divider */ | ||
| 261 | ads = (acsr >> MXC_CRMAP_ACSR_ADS_OFFSET) & 0x1; | ||
| 262 | /* 0 for pat_ref, 1 for divider out */ | ||
| 263 | acs = acsr & MXC_CRMAP_ACSR_ACS; | ||
| 264 | |||
| 265 | if (acs & !ads) | ||
| 266 | /* use divided clock */ | ||
| 267 | return clk_get_rate(clk->parent) / (ap_pat_ref_div_2 ? 2 : 1); | ||
| 268 | |||
| 269 | return clk_get_rate(clk->parent) * (ap_isel ? 2 : 1); | ||
| 270 | } | ||
| 271 | |||
| 272 | static struct clk ap_ref_clk = { | ||
| 273 | .parent = &ckih_clk, | ||
| 274 | .get_rate = clk_ap_ref_get_rate, | ||
| 275 | }; | ||
| 276 | /* ap_ref_clk stuff end */ | ||
| 277 | |||
| 278 | /* ap_pre_dfs_clk stuff */ | ||
| 279 | static struct clk ap_pre_dfs_clk; | ||
| 280 | |||
| 281 | static unsigned long clk_ap_pre_dfs_get_rate(struct clk *clk) | ||
| 282 | { | ||
| 283 | u32 acsr, ascsr; | ||
| 284 | |||
| 285 | acsr = __raw_readl(MXC_CRMAP_ACSR); | ||
| 286 | ascsr = __raw_readl(MXC_CRMAP_ASCSR); | ||
| 287 | |||
| 288 | if (acsr & MXC_CRMAP_ACSR_ACS) { | ||
| 289 | u8 sel; | ||
| 290 | sel = (ascsr & MXC_CRMAP_ASCSR_APSEL_MASK) >> | ||
| 291 | MXC_CRMAP_ASCSR_APSEL_OFFSET; | ||
| 292 | return clk_get_rate(pll_clk(sel)) / | ||
| 293 | CRM_SMALL_DIVIDER(MXC_CRMAP_ACDR, ARMDIV); | ||
| 294 | } | ||
| 295 | return clk_get_rate(&ap_ref_clk); | ||
| 296 | } | ||
| 297 | |||
| 298 | static struct clk ap_pre_dfs_clk = { | ||
| 299 | .get_rate = clk_ap_pre_dfs_get_rate, | ||
| 300 | }; | ||
| 301 | /* ap_pre_dfs_clk stuff end */ | ||
| 302 | |||
| 303 | /* usb_clk stuff */ | ||
| 304 | static struct clk usb_clk; | ||
| 305 | |||
| 306 | static struct clk *clk_usb_parent(struct clk *clk) | ||
| 307 | { | ||
| 308 | u32 acsr, ascsr; | ||
| 309 | |||
| 310 | acsr = __raw_readl(MXC_CRMAP_ACSR); | ||
| 311 | ascsr = __raw_readl(MXC_CRMAP_ASCSR); | ||
| 312 | |||
| 313 | if (acsr & MXC_CRMAP_ACSR_ACS) { | ||
| 314 | u8 sel; | ||
| 315 | sel = (ascsr & MXC_CRMAP_ASCSR_USBSEL_MASK) >> | ||
| 316 | MXC_CRMAP_ASCSR_USBSEL_OFFSET; | ||
| 317 | return pll_clk(sel); | ||
| 318 | } | ||
| 319 | return &ap_ref_clk; | ||
| 320 | } | ||
| 321 | |||
| 322 | static unsigned long clk_usb_get_rate(struct clk *clk) | ||
| 323 | { | ||
| 324 | return clk_get_rate(clk->parent) / | ||
| 325 | CRM_SMALL_DIVIDER(MXC_CRMAP_ACDER2, USBDIV); | ||
| 326 | } | ||
| 327 | |||
| 328 | static struct clk usb_clk = { | ||
| 329 | .enable_reg = MXC_CRMAP_ACDER2, | ||
| 330 | .enable_shift = MXC_CRMAP_ACDER2_USBEN_OFFSET, | ||
| 331 | .get_rate = clk_usb_get_rate, | ||
| 332 | .enable = _clk_1bit_enable, | ||
| 333 | .disable = _clk_1bit_disable, | ||
| 334 | }; | ||
| 335 | /* usb_clk stuff end */ | ||
| 336 | |||
| 337 | static unsigned long clk_ipg_get_rate(struct clk *clk) | ||
| 338 | { | ||
| 339 | return clk_get_rate(clk->parent) / CRM_16DIVIDER(MXC_CRMAP_ACDR, IPDIV); | ||
| 340 | } | ||
| 341 | |||
| 342 | static unsigned long clk_ahb_get_rate(struct clk *clk) | ||
| 343 | { | ||
| 344 | return clk_get_rate(clk->parent) / | ||
| 345 | CRM_16DIVIDER(MXC_CRMAP_ACDR, AHBDIV); | ||
| 346 | } | ||
| 347 | |||
| 348 | static struct clk ipg_clk = { | ||
| 349 | .parent = &ap_pre_dfs_clk, | ||
| 350 | .get_rate = clk_ipg_get_rate, | ||
| 351 | }; | ||
| 352 | |||
| 353 | static struct clk ahb_clk = { | ||
| 354 | .parent = &ap_pre_dfs_clk, | ||
| 355 | .get_rate = clk_ahb_get_rate, | ||
| 356 | }; | ||
| 357 | |||
| 358 | /* perclk_clk stuff */ | ||
| 359 | static struct clk perclk_clk; | ||
| 360 | |||
| 361 | static unsigned long clk_perclk_get_rate(struct clk *clk) | ||
| 362 | { | ||
| 363 | u32 acder2; | ||
| 364 | |||
| 365 | acder2 = __raw_readl(MXC_CRMAP_ACDER2); | ||
| 366 | if (acder2 & MXC_CRMAP_ACDER2_BAUD_ISEL_MASK) | ||
| 367 | return 2 * clk_get_rate(clk->parent); | ||
| 368 | |||
| 369 | return clk_get_rate(clk->parent); | ||
| 370 | } | ||
| 371 | |||
| 372 | static struct clk perclk_clk = { | ||
| 373 | .parent = &ckih_clk, | ||
| 374 | .get_rate = clk_perclk_get_rate, | ||
| 375 | }; | ||
| 376 | /* perclk_clk stuff end */ | ||
| 377 | |||
| 378 | /* uart_clk stuff */ | ||
| 379 | static struct clk uart_clk[]; | ||
| 380 | |||
| 381 | static unsigned long clk_uart_get_rate(struct clk *clk) | ||
| 382 | { | ||
| 383 | u32 div; | ||
| 384 | |||
| 385 | switch (clk->id) { | ||
| 386 | case 0: | ||
| 387 | case 1: | ||
| 388 | div = CRM_SMALL_DIVIDER(MXC_CRMAP_ACDER2, BAUDDIV); | ||
| 389 | break; | ||
| 390 | case 2: | ||
| 391 | div = CRM_SMALL_DIVIDER(MXC_CRMAP_APRA, UART3DIV); | ||
| 392 | break; | ||
| 393 | default: | ||
| 394 | BUG(); | ||
| 395 | } | ||
| 396 | return clk_get_rate(clk->parent) / div; | ||
| 397 | } | ||
| 398 | |||
| 399 | static struct clk uart_clk[] = { | ||
| 400 | { | ||
| 401 | .id = 0, | ||
| 402 | .parent = &perclk_clk, | ||
| 403 | .enable_reg = MXC_CRMAP_APRA, | ||
| 404 | .enable_shift = MXC_CRMAP_APRA_UART1EN_OFFSET, | ||
| 405 | .get_rate = clk_uart_get_rate, | ||
| 406 | .enable = _clk_1bit_enable, | ||
| 407 | .disable = _clk_1bit_disable, | ||
| 408 | }, { | ||
| 409 | .id = 1, | ||
| 410 | .parent = &perclk_clk, | ||
| 411 | .enable_reg = MXC_CRMAP_APRA, | ||
| 412 | .enable_shift = MXC_CRMAP_APRA_UART2EN_OFFSET, | ||
| 413 | .get_rate = clk_uart_get_rate, | ||
| 414 | .enable = _clk_1bit_enable, | ||
| 415 | .disable = _clk_1bit_disable, | ||
| 416 | }, { | ||
| 417 | .id = 2, | ||
| 418 | .parent = &perclk_clk, | ||
| 419 | .enable_reg = MXC_CRMAP_APRA, | ||
| 420 | .enable_shift = MXC_CRMAP_APRA_UART3EN_OFFSET, | ||
| 421 | .get_rate = clk_uart_get_rate, | ||
| 422 | .enable = _clk_1bit_enable, | ||
| 423 | .disable = _clk_1bit_disable, | ||
| 424 | }, | ||
| 425 | }; | ||
| 426 | /* uart_clk stuff end */ | ||
| 427 | |||
| 428 | /* sdhc_clk stuff */ | ||
| 429 | static struct clk nfc_clk; | ||
| 430 | |||
| 431 | static unsigned long clk_nfc_get_rate(struct clk *clk) | ||
| 432 | { | ||
| 433 | return clk_get_rate(clk->parent) / | ||
| 434 | CRM_1DIVIDER(MXC_CRMAP_ACDER2, NFCDIV); | ||
| 435 | } | ||
| 436 | |||
| 437 | static struct clk nfc_clk = { | ||
| 438 | .parent = &ahb_clk, | ||
| 439 | .enable_reg = MXC_CRMAP_ACDER2, | ||
| 440 | .enable_shift = MXC_CRMAP_ACDER2_NFCEN_OFFSET, | ||
| 441 | .get_rate = clk_nfc_get_rate, | ||
| 442 | .enable = _clk_1bit_enable, | ||
| 443 | .disable = _clk_1bit_disable, | ||
| 444 | }; | ||
| 445 | /* sdhc_clk stuff end */ | ||
| 446 | |||
| 447 | /* sdhc_clk stuff */ | ||
| 448 | static struct clk sdhc_clk[]; | ||
| 449 | |||
| 450 | static struct clk *clk_sdhc_parent(struct clk *clk) | ||
| 451 | { | ||
| 452 | u32 aprb; | ||
| 453 | u8 sel; | ||
| 454 | u32 mask; | ||
| 455 | int offset; | ||
| 456 | |||
| 457 | aprb = __raw_readl(MXC_CRMAP_APRB); | ||
| 458 | |||
| 459 | switch (clk->id) { | ||
| 460 | case 0: | ||
| 461 | mask = MXC_CRMAP_APRB_SDHC1_ISEL_MASK; | ||
| 462 | offset = MXC_CRMAP_APRB_SDHC1_ISEL_OFFSET; | ||
| 463 | break; | ||
| 464 | case 1: | ||
| 465 | mask = MXC_CRMAP_APRB_SDHC2_ISEL_MASK; | ||
| 466 | offset = MXC_CRMAP_APRB_SDHC2_ISEL_OFFSET; | ||
| 467 | break; | ||
| 468 | default: | ||
| 469 | BUG(); | ||
| 470 | } | ||
| 471 | sel = (aprb & mask) >> offset; | ||
| 472 | |||
| 473 | switch (sel) { | ||
| 474 | case 0: | ||
| 475 | return &ckih_clk; | ||
| 476 | case 1: | ||
| 477 | return &ckih_x2_clk; | ||
| 478 | } | ||
| 479 | return &usb_clk; | ||
| 480 | } | ||
| 481 | |||
| 482 | static unsigned long clk_sdhc_get_rate(struct clk *clk) | ||
| 483 | { | ||
| 484 | u32 div; | ||
| 485 | |||
| 486 | switch (clk->id) { | ||
| 487 | case 0: | ||
| 488 | div = CRM_SMALL_DIVIDER(MXC_CRMAP_APRB, SDHC1_DIV); | ||
| 489 | break; | ||
| 490 | case 1: | ||
| 491 | div = CRM_SMALL_DIVIDER(MXC_CRMAP_APRB, SDHC2_DIV); | ||
| 492 | break; | ||
| 493 | default: | ||
| 494 | BUG(); | ||
| 495 | } | ||
| 496 | |||
| 497 | return clk_get_rate(clk->parent) / div; | ||
| 498 | } | ||
| 499 | |||
| 500 | static int clk_sdhc_enable(struct clk *clk) | ||
| 501 | { | ||
| 502 | u32 amlpmre1, aprb; | ||
| 503 | |||
| 504 | amlpmre1 = __raw_readl(MXC_CRMAP_AMLPMRE1); | ||
| 505 | aprb = __raw_readl(MXC_CRMAP_APRB); | ||
| 506 | switch (clk->id) { | ||
| 507 | case 0: | ||
| 508 | amlpmre1 |= (0x7 << MXC_CRMAP_AMLPMRE1_MLPME4_OFFSET); | ||
| 509 | aprb |= (0x1 << MXC_CRMAP_APRB_SDHC1EN_OFFSET); | ||
| 510 | break; | ||
| 511 | case 1: | ||
| 512 | amlpmre1 |= (0x7 << MXC_CRMAP_AMLPMRE1_MLPME5_OFFSET); | ||
| 513 | aprb |= (0x1 << MXC_CRMAP_APRB_SDHC2EN_OFFSET); | ||
| 514 | break; | ||
| 515 | } | ||
| 516 | __raw_writel(amlpmre1, MXC_CRMAP_AMLPMRE1); | ||
| 517 | __raw_writel(aprb, MXC_CRMAP_APRB); | ||
| 518 | return 0; | ||
| 519 | } | ||
| 520 | |||
| 521 | static void clk_sdhc_disable(struct clk *clk) | ||
| 522 | { | ||
| 523 | u32 amlpmre1, aprb; | ||
| 524 | |||
| 525 | amlpmre1 = __raw_readl(MXC_CRMAP_AMLPMRE1); | ||
| 526 | aprb = __raw_readl(MXC_CRMAP_APRB); | ||
| 527 | switch (clk->id) { | ||
| 528 | case 0: | ||
| 529 | amlpmre1 &= ~(0x7 << MXC_CRMAP_AMLPMRE1_MLPME4_OFFSET); | ||
| 530 | aprb &= ~(0x1 << MXC_CRMAP_APRB_SDHC1EN_OFFSET); | ||
| 531 | break; | ||
| 532 | case 1: | ||
| 533 | amlpmre1 &= ~(0x7 << MXC_CRMAP_AMLPMRE1_MLPME5_OFFSET); | ||
| 534 | aprb &= ~(0x1 << MXC_CRMAP_APRB_SDHC2EN_OFFSET); | ||
| 535 | break; | ||
| 536 | } | ||
| 537 | __raw_writel(amlpmre1, MXC_CRMAP_AMLPMRE1); | ||
| 538 | __raw_writel(aprb, MXC_CRMAP_APRB); | ||
| 539 | } | ||
| 540 | |||
| 541 | static struct clk sdhc_clk[] = { | ||
| 542 | { | ||
| 543 | .id = 0, | ||
| 544 | .get_rate = clk_sdhc_get_rate, | ||
| 545 | .enable = clk_sdhc_enable, | ||
| 546 | .disable = clk_sdhc_disable, | ||
| 547 | }, { | ||
| 548 | .id = 1, | ||
| 549 | .get_rate = clk_sdhc_get_rate, | ||
| 550 | .enable = clk_sdhc_enable, | ||
| 551 | .disable = clk_sdhc_disable, | ||
| 552 | }, | ||
| 553 | }; | ||
| 554 | /* sdhc_clk stuff end */ | ||
| 555 | |||
| 556 | /* wdog_clk stuff */ | ||
| 557 | static struct clk wdog_clk[] = { | ||
| 558 | { | ||
| 559 | .id = 0, | ||
| 560 | .parent = &ipg_clk, | ||
| 561 | .enable_reg = MXC_CRMAP_AMLPMRD, | ||
| 562 | .enable_shift = MXC_CRMAP_AMLPMRD_MLPMD7_OFFSET, | ||
| 563 | .enable = _clk_3bit_enable, | ||
| 564 | .disable = _clk_3bit_disable, | ||
| 565 | }, { | ||
| 566 | .id = 1, | ||
| 567 | .parent = &ipg_clk, | ||
| 568 | .enable_reg = MXC_CRMAP_AMLPMRD, | ||
| 569 | .enable_shift = MXC_CRMAP_AMLPMRD_MLPMD3_OFFSET, | ||
| 570 | .enable = _clk_3bit_enable, | ||
| 571 | .disable = _clk_3bit_disable, | ||
| 572 | }, | ||
| 573 | }; | ||
| 574 | /* wdog_clk stuff end */ | ||
| 575 | |||
| 576 | /* gpt_clk stuff */ | ||
| 577 | static struct clk gpt_clk = { | ||
| 578 | .parent = &ipg_clk, | ||
| 579 | .enable_reg = MXC_CRMAP_AMLPMRC, | ||
| 580 | .enable_shift = MXC_CRMAP_AMLPMRC_MLPMC4_OFFSET, | ||
| 581 | .enable = _clk_3bit_enable, | ||
| 582 | .disable = _clk_3bit_disable, | ||
| 583 | }; | ||
| 584 | /* gpt_clk stuff end */ | ||
| 585 | |||
| 586 | /* cspi_clk stuff */ | ||
| 587 | static struct clk cspi_clk[] = { | ||
| 588 | { | ||
| 589 | .id = 0, | ||
| 590 | .parent = &ipg_clk, | ||
| 591 | .enable_reg = MXC_CRMAP_AMLPMRE2, | ||
| 592 | .enable_shift = MXC_CRMAP_AMLPMRE2_MLPME0_OFFSET, | ||
| 593 | .enable = _clk_3bit_enable, | ||
| 594 | .disable = _clk_3bit_disable, | ||
| 595 | }, { | ||
| 596 | .id = 1, | ||
| 597 | .parent = &ipg_clk, | ||
| 598 | .enable_reg = MXC_CRMAP_AMLPMRE1, | ||
| 599 | .enable_shift = MXC_CRMAP_AMLPMRE1_MLPME6_OFFSET, | ||
| 600 | .enable = _clk_3bit_enable, | ||
| 601 | .disable = _clk_3bit_disable, | ||
| 602 | }, | ||
| 603 | }; | ||
| 604 | /* cspi_clk stuff end */ | ||
| 605 | |||
| 606 | #define _REGISTER_CLOCK(d, n, c) \ | ||
| 607 | { \ | ||
| 608 | .dev_id = d, \ | ||
| 609 | .con_id = n, \ | ||
| 610 | .clk = &c, \ | ||
| 611 | }, | ||
| 612 | |||
| 613 | static struct clk_lookup lookups[] = { | ||
| 614 | _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0]) | ||
| 615 | _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1]) | ||
| 616 | _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2]) | ||
| 617 | _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc_clk[0]) | ||
| 618 | _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc_clk[1]) | ||
| 619 | _REGISTER_CLOCK("mxc-wdt.0", NULL, wdog_clk[0]) | ||
| 620 | _REGISTER_CLOCK("spi_imx.0", NULL, cspi_clk[0]) | ||
| 621 | _REGISTER_CLOCK("spi_imx.1", NULL, cspi_clk[1]) | ||
| 622 | }; | ||
| 623 | |||
| 624 | int __init mxc91231_clocks_init(unsigned long fref) | ||
| 625 | { | ||
| 626 | void __iomem *gpt_base; | ||
| 627 | int i; | ||
| 628 | |||
| 629 | ckih_rate = fref; | ||
| 630 | |||
| 631 | usb_clk.parent = clk_usb_parent(&usb_clk); | ||
| 632 | sdhc_clk[0].parent = clk_sdhc_parent(&sdhc_clk[0]); | ||
| 633 | sdhc_clk[1].parent = clk_sdhc_parent(&sdhc_clk[1]); | ||
| 634 | |||
| 635 | for (i = 0; i < ARRAY_SIZE(lookups); i++) | ||
| 636 | clkdev_add(&lookups[i]); | ||
| 637 | |||
| 638 | gpt_base = MXC91231_IO_ADDRESS(MXC91231_GPT1_BASE_ADDR); | ||
| 639 | mxc_timer_init(&gpt_clk, gpt_base, MXC91231_INT_GPT); | ||
| 640 | |||
| 641 | return 0; | ||
| 642 | } | ||
diff --git a/arch/arm/mach-mxc91231/crm_regs.h b/arch/arm/mach-mxc91231/crm_regs.h new file mode 100644 index 000000000000..ce4f59058189 --- /dev/null +++ b/arch/arm/mach-mxc91231/crm_regs.h | |||
| @@ -0,0 +1,399 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2006 Freescale Semiconductor, Inc. | ||
| 3 | * Copyright 2006-2007 Motorola, Inc. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | * | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef _ARCH_ARM_MACH_MXC91231_CRM_REGS_H_ | ||
| 22 | #define _ARCH_ARM_MACH_MXC91231_CRM_REGS_H_ | ||
| 23 | |||
| 24 | #define CKIL_CLK_FREQ 32768 | ||
| 25 | |||
| 26 | #define MXC_CRM_AP_BASE MXC91231_IO_ADDRESS(MXC91231_CRM_AP_BASE_ADDR) | ||
| 27 | #define MXC_CRM_COM_BASE MXC91231_IO_ADDRESS(MXC91231_CRM_COM_BASE_ADDR) | ||
| 28 | #define MXC_DSM_BASE MXC91231_IO_ADDRESS(MXC91231_DSM_BASE_ADDR) | ||
| 29 | #define MXC_PLL0_BASE MXC91231_IO_ADDRESS(MXC91231_PLL0_BASE_ADDR) | ||
| 30 | #define MXC_PLL1_BASE MXC91231_IO_ADDRESS(MXC91231_PLL1_BASE_ADDR) | ||
| 31 | #define MXC_PLL2_BASE MXC91231_IO_ADDRESS(MXC91231_PLL2_BASE_ADDR) | ||
| 32 | #define MXC_CLKCTL_BASE MXC91231_IO_ADDRESS(MXC91231_CLKCTL_BASE_ADDR) | ||
| 33 | |||
| 34 | /* PLL Register Offsets */ | ||
| 35 | #define MXC_PLL_DP_CTL 0x00 | ||
| 36 | #define MXC_PLL_DP_CONFIG 0x04 | ||
| 37 | #define MXC_PLL_DP_OP 0x08 | ||
| 38 | #define MXC_PLL_DP_MFD 0x0C | ||
| 39 | #define MXC_PLL_DP_MFN 0x10 | ||
| 40 | #define MXC_PLL_DP_HFS_OP 0x1C | ||
| 41 | #define MXC_PLL_DP_HFS_MFD 0x20 | ||
| 42 | #define MXC_PLL_DP_HFS_MFN 0x24 | ||
| 43 | |||
| 44 | /* PLL Register Bit definitions */ | ||
| 45 | #define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000 | ||
| 46 | #define MXC_PLL_DP_CTL_ADE 0x800 | ||
| 47 | #define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400 | ||
| 48 | #define MXC_PLL_DP_CTL_HFSM 0x80 | ||
| 49 | #define MXC_PLL_DP_CTL_PRE 0x40 | ||
| 50 | #define MXC_PLL_DP_CTL_UPEN 0x20 | ||
| 51 | #define MXC_PLL_DP_CTL_RST 0x10 | ||
| 52 | #define MXC_PLL_DP_CTL_RCP 0x8 | ||
| 53 | #define MXC_PLL_DP_CTL_PLM 0x4 | ||
| 54 | #define MXC_PLL_DP_CTL_BRM0 0x2 | ||
| 55 | #define MXC_PLL_DP_CTL_LRF 0x1 | ||
| 56 | |||
| 57 | #define MXC_PLL_DP_OP_MFI_OFFSET 4 | ||
| 58 | #define MXC_PLL_DP_OP_MFI_MASK 0xF | ||
| 59 | #define MXC_PLL_DP_OP_PDF_OFFSET 0 | ||
| 60 | #define MXC_PLL_DP_OP_PDF_MASK 0xF | ||
| 61 | |||
| 62 | #define MXC_PLL_DP_MFD_OFFSET 0 | ||
| 63 | #define MXC_PLL_DP_MFD_MASK 0x7FFFFFF | ||
| 64 | |||
| 65 | #define MXC_PLL_DP_MFN_OFFSET 0 | ||
| 66 | #define MXC_PLL_DP_MFN_MASK 0x7FFFFFF | ||
| 67 | |||
| 68 | /* CRM AP Register Offsets */ | ||
| 69 | #define MXC_CRMAP_ASCSR (MXC_CRM_AP_BASE + 0x00) | ||
| 70 | #define MXC_CRMAP_ACDR (MXC_CRM_AP_BASE + 0x04) | ||
| 71 | #define MXC_CRMAP_ACDER1 (MXC_CRM_AP_BASE + 0x08) | ||
| 72 | #define MXC_CRMAP_ACDER2 (MXC_CRM_AP_BASE + 0x0C) | ||
| 73 | #define MXC_CRMAP_ACGCR (MXC_CRM_AP_BASE + 0x10) | ||
| 74 | #define MXC_CRMAP_ACCGCR (MXC_CRM_AP_BASE + 0x14) | ||
| 75 | #define MXC_CRMAP_AMLPMRA (MXC_CRM_AP_BASE + 0x18) | ||
| 76 | #define MXC_CRMAP_AMLPMRB (MXC_CRM_AP_BASE + 0x1C) | ||
| 77 | #define MXC_CRMAP_AMLPMRC (MXC_CRM_AP_BASE + 0x20) | ||
| 78 | #define MXC_CRMAP_AMLPMRD (MXC_CRM_AP_BASE + 0x24) | ||
| 79 | #define MXC_CRMAP_AMLPMRE1 (MXC_CRM_AP_BASE + 0x28) | ||
| 80 | #define MXC_CRMAP_AMLPMRE2 (MXC_CRM_AP_BASE + 0x2C) | ||
| 81 | #define MXC_CRMAP_AMLPMRF (MXC_CRM_AP_BASE + 0x30) | ||
| 82 | #define MXC_CRMAP_AMLPMRG (MXC_CRM_AP_BASE + 0x34) | ||
| 83 | #define MXC_CRMAP_APGCR (MXC_CRM_AP_BASE + 0x38) | ||
| 84 | #define MXC_CRMAP_ACSR (MXC_CRM_AP_BASE + 0x3C) | ||
| 85 | #define MXC_CRMAP_ADCR (MXC_CRM_AP_BASE + 0x40) | ||
| 86 | #define MXC_CRMAP_ACR (MXC_CRM_AP_BASE + 0x44) | ||
| 87 | #define MXC_CRMAP_AMCR (MXC_CRM_AP_BASE + 0x48) | ||
| 88 | #define MXC_CRMAP_APCR (MXC_CRM_AP_BASE + 0x4C) | ||
| 89 | #define MXC_CRMAP_AMORA (MXC_CRM_AP_BASE + 0x50) | ||
| 90 | #define MXC_CRMAP_AMORB (MXC_CRM_AP_BASE + 0x54) | ||
| 91 | #define MXC_CRMAP_AGPR (MXC_CRM_AP_BASE + 0x58) | ||
| 92 | #define MXC_CRMAP_APRA (MXC_CRM_AP_BASE + 0x5C) | ||
| 93 | #define MXC_CRMAP_APRB (MXC_CRM_AP_BASE + 0x60) | ||
| 94 | #define MXC_CRMAP_APOR (MXC_CRM_AP_BASE + 0x64) | ||
| 95 | #define MXC_CRMAP_ADFMR (MXC_CRM_AP_BASE + 0x68) | ||
| 96 | |||
| 97 | /* CRM AP Register Bit definitions */ | ||
| 98 | #define MXC_CRMAP_ASCSR_CRS 0x10000 | ||
| 99 | #define MXC_CRMAP_ASCSR_AP_PATDIV2_OFFSET 15 | ||
| 100 | #define MXC_CRMAP_ASCSR_AP_PATREF_DIV2 0x8000 | ||
| 101 | #define MXC_CRMAP_ASCSR_USBSEL_OFFSET 13 | ||
| 102 | #define MXC_CRMAP_ASCSR_USBSEL_MASK (0x3 << 13) | ||
| 103 | #define MXC_CRMAP_ASCSR_CSISEL_OFFSET 11 | ||
| 104 | #define MXC_CRMAP_ASCSR_CSISEL_MASK (0x3 << 11) | ||
| 105 | #define MXC_CRMAP_ASCSR_SSI2SEL_OFFSET 7 | ||
| 106 | #define MXC_CRMAP_ASCSR_SSI2SEL_MASK (0x3 << 7) | ||
| 107 | #define MXC_CRMAP_ASCSR_SSI1SEL_OFFSET 5 | ||
| 108 | #define MXC_CRMAP_ASCSR_SSI1SEL_MASK (0x3 << 5) | ||
| 109 | #define MXC_CRMAP_ASCSR_APSEL_OFFSET 3 | ||
| 110 | #define MXC_CRMAP_ASCSR_APSEL_MASK (0x3 << 3) | ||
| 111 | #define MXC_CRMAP_ASCSR_AP_PATDIV1_OFFSET 2 | ||
| 112 | #define MXC_CRMAP_ASCSR_AP_PATREF_DIV1 0x4 | ||
| 113 | #define MXC_CRMAP_ASCSR_APISEL 0x1 | ||
| 114 | |||
| 115 | #define MXC_CRMAP_ACDR_ARMDIV_OFFSET 8 | ||
| 116 | #define MXC_CRMAP_ACDR_ARMDIV_MASK (0xF << 8) | ||
| 117 | #define MXC_CRMAP_ACDR_AHBDIV_OFFSET 4 | ||
| 118 | #define MXC_CRMAP_ACDR_AHBDIV_MASK (0xF << 4) | ||
| 119 | #define MXC_CRMAP_ACDR_IPDIV_OFFSET 0 | ||
| 120 | #define MXC_CRMAP_ACDR_IPDIV_MASK 0xF | ||
| 121 | |||
| 122 | #define MXC_CRMAP_ACDER1_CSIEN_OFFSET 30 | ||
| 123 | #define MXC_CRMAP_ACDER1_CSIDIV_OFFSET 24 | ||
| 124 | #define MXC_CRMAP_ACDER1_CSIDIV_MASK (0x3F << 24) | ||
| 125 | #define MXC_CRMAP_ACDER1_SSI2EN_OFFSET 14 | ||
| 126 | #define MXC_CRMAP_ACDER1_SSI2DIV_OFFSET 8 | ||
| 127 | #define MXC_CRMAP_ACDER1_SSI2DIV_MASK (0x3F << 8) | ||
| 128 | #define MXC_CRMAP_ACDER1_SSI1EN_OFFSET 6 | ||
| 129 | #define MXC_CRMAP_ACDER1_SSI1DIV_OFFSET 0 | ||
| 130 | #define MXC_CRMAP_ACDER1_SSI1DIV_MASK 0x3F | ||
| 131 | |||
| 132 | #define MXC_CRMAP_ACDER2_CRCT_CLK_DIV_OFFSET 24 | ||
| 133 | #define MXC_CRMAP_ACDER2_CRCT_CLK_DIV_MASK (0x7 << 24) | ||
| 134 | #define MXC_CRMAP_ACDER2_NFCEN_OFFSET 20 | ||
| 135 | #define MXC_CRMAP_ACDER2_NFCDIV_OFFSET 16 | ||
| 136 | #define MXC_CRMAP_ACDER2_NFCDIV_MASK (0xF << 16) | ||
| 137 | #define MXC_CRMAP_ACDER2_USBEN_OFFSET 12 | ||
| 138 | #define MXC_CRMAP_ACDER2_USBDIV_OFFSET 8 | ||
| 139 | #define MXC_CRMAP_ACDER2_USBDIV_MASK (0xF << 8) | ||
| 140 | #define MXC_CRMAP_ACDER2_BAUD_ISEL_OFFSET 5 | ||
| 141 | #define MXC_CRMAP_ACDER2_BAUD_ISEL_MASK (0x3 << 5) | ||
| 142 | #define MXC_CRMAP_ACDER2_BAUDDIV_OFFSET 0 | ||
| 143 | #define MXC_CRMAP_ACDER2_BAUDDIV_MASK 0xF | ||
| 144 | |||
| 145 | #define MXC_CRMAP_AMLPMRA_MLPMA7_OFFSET 22 | ||
| 146 | #define MXC_CRMAP_AMLPMRA_MLPMA7_MASK (0x7 << 22) | ||
| 147 | #define MXC_CRMAP_AMLPMRA_MLPMA6_OFFSET 19 | ||
| 148 | #define MXC_CRMAP_AMLPMRA_MLPMA6_MASK (0x7 << 19) | ||
| 149 | #define MXC_CRMAP_AMLPMRA_MLPMA4_OFFSET 12 | ||
| 150 | #define MXC_CRMAP_AMLPMRA_MLPMA4_MASK (0x7 << 12) | ||
| 151 | #define MXC_CRMAP_AMLPMRA_MLPMA3_OFFSET 9 | ||
| 152 | #define MXC_CRMAP_AMLPMRA_MLPMA3_MASK (0x7 << 9) | ||
| 153 | #define MXC_CRMAP_AMLPMRA_MLPMA2_OFFSET 6 | ||
| 154 | #define MXC_CRMAP_AMLPMRA_MLPMA2_MASK (0x7 << 6) | ||
| 155 | #define MXC_CRMAP_AMLPMRA_MLPMA1_OFFSET 3 | ||
| 156 | #define MXC_CRMAP_AMLPMRA_MLPMA1_MASK (0x7 << 3) | ||
| 157 | |||
| 158 | #define MXC_CRMAP_AMLPMRB_MLPMB0_OFFSET 0 | ||
| 159 | #define MXC_CRMAP_AMLPMRB_MLPMB0_MASK 0x7 | ||
| 160 | |||
| 161 | #define MXC_CRMAP_AMLPMRC_MLPMC9_OFFSET 28 | ||
| 162 | #define MXC_CRMAP_AMLPMRC_MLPMC9_MASK (0x7 << 28) | ||
| 163 | #define MXC_CRMAP_AMLPMRC_MLPMC7_OFFSET 22 | ||
| 164 | #define MXC_CRMAP_AMLPMRC_MLPMC7_MASK (0x7 << 22) | ||
| 165 | #define MXC_CRMAP_AMLPMRC_MLPMC5_OFFSET 16 | ||
| 166 | #define MXC_CRMAP_AMLPMRC_MLPMC5_MASK (0x7 << 16) | ||
| 167 | #define MXC_CRMAP_AMLPMRC_MLPMC4_OFFSET 12 | ||
| 168 | #define MXC_CRMAP_AMLPMRC_MLPMC4_MASK (0x7 << 12) | ||
| 169 | #define MXC_CRMAP_AMLPMRC_MLPMC3_OFFSET 9 | ||
| 170 | #define MXC_CRMAP_AMLPMRC_MLPMC3_MASK (0x7 << 9) | ||
| 171 | #define MXC_CRMAP_AMLPMRC_MLPMC2_OFFSET 6 | ||
| 172 | #define MXC_CRMAP_AMLPMRC_MLPMC2_MASK (0x7 << 6) | ||
| 173 | #define MXC_CRMAP_AMLPMRC_MLPMC1_OFFSET 3 | ||
| 174 | #define MXC_CRMAP_AMLPMRC_MLPMC1_MASK (0x7 << 3) | ||
| 175 | #define MXC_CRMAP_AMLPMRC_MLPMC0_OFFSET 0 | ||
| 176 | #define MXC_CRMAP_AMLPMRC_MLPMC0_MASK 0x7 | ||
| 177 | |||
| 178 | #define MXC_CRMAP_AMLPMRD_MLPMD7_OFFSET 22 | ||
| 179 | #define MXC_CRMAP_AMLPMRD_MLPMD7_MASK (0x7 << 22) | ||
| 180 | #define MXC_CRMAP_AMLPMRD_MLPMD4_OFFSET 12 | ||
| 181 | #define MXC_CRMAP_AMLPMRD_MLPMD4_MASK (0x7 << 12) | ||
| 182 | #define MXC_CRMAP_AMLPMRD_MLPMD3_OFFSET 9 | ||
| 183 | #define MXC_CRMAP_AMLPMRD_MLPMD3_MASK (0x7 << 9) | ||
| 184 | #define MXC_CRMAP_AMLPMRD_MLPMD2_OFFSET 6 | ||
| 185 | #define MXC_CRMAP_AMLPMRD_MLPMD2_MASK (0x7 << 6) | ||
| 186 | #define MXC_CRMAP_AMLPMRD_MLPMD0_OFFSET 0 | ||
| 187 | #define MXC_CRMAP_AMLPMRD_MLPMD0_MASK 0x7 | ||
| 188 | |||
| 189 | #define MXC_CRMAP_AMLPMRE1_MLPME9_OFFSET 28 | ||
| 190 | #define MXC_CRMAP_AMLPMRE1_MLPME9_MASK (0x7 << 28) | ||
| 191 | #define MXC_CRMAP_AMLPMRE1_MLPME8_OFFSET 25 | ||
| 192 | #define MXC_CRMAP_AMLPMRE1_MLPME8_MASK (0x7 << 25) | ||
| 193 | #define MXC_CRMAP_AMLPMRE1_MLPME7_OFFSET 22 | ||
| 194 | #define MXC_CRMAP_AMLPMRE1_MLPME7_MASK (0x7 << 22) | ||
| 195 | #define MXC_CRMAP_AMLPMRE1_MLPME6_OFFSET 19 | ||
| 196 | #define MXC_CRMAP_AMLPMRE1_MLPME6_MASK (0x7 << 19) | ||
| 197 | #define MXC_CRMAP_AMLPMRE1_MLPME5_OFFSET 16 | ||
| 198 | #define MXC_CRMAP_AMLPMRE1_MLPME5_MASK (0x7 << 16) | ||
| 199 | #define MXC_CRMAP_AMLPMRE1_MLPME4_OFFSET 12 | ||
| 200 | #define MXC_CRMAP_AMLPMRE1_MLPME4_MASK (0x7 << 12) | ||
| 201 | #define MXC_CRMAP_AMLPMRE1_MLPME3_OFFSET 9 | ||
| 202 | #define MXC_CRMAP_AMLPMRE1_MLPME3_MASK (0x7 << 9) | ||
| 203 | #define MXC_CRMAP_AMLPMRE1_MLPME2_OFFSET 6 | ||
| 204 | #define MXC_CRMAP_AMLPMRE1_MLPME2_MASK (0x7 << 6) | ||
| 205 | #define MXC_CRMAP_AMLPMRE1_MLPME1_OFFSET 3 | ||
| 206 | #define MXC_CRMAP_AMLPMRE1_MLPME1_MASK (0x7 << 3) | ||
| 207 | #define MXC_CRMAP_AMLPMRE1_MLPME0_OFFSET 0 | ||
| 208 | #define MXC_CRMAP_AMLPMRE1_MLPME0_MASK 0x7 | ||
| 209 | |||
| 210 | #define MXC_CRMAP_AMLPMRE2_MLPME0_OFFSET 0 | ||
| 211 | #define MXC_CRMAP_AMLPMRE2_MLPME0_MASK 0x7 | ||
| 212 | |||
| 213 | #define MXC_CRMAP_AMLPMRF_MLPMF6_OFFSET 19 | ||
| 214 | #define MXC_CRMAP_AMLPMRF_MLPMF6_MASK (0x7 << 19) | ||
| 215 | #define MXC_CRMAP_AMLPMRF_MLPMF5_OFFSET 16 | ||
| 216 | #define MXC_CRMAP_AMLPMRF_MLPMF5_MASK (0x7 << 16) | ||
| 217 | #define MXC_CRMAP_AMLPMRF_MLPMF3_OFFSET 9 | ||
| 218 | #define MXC_CRMAP_AMLPMRF_MLPMF3_MASK (0x7 << 9) | ||
| 219 | #define MXC_CRMAP_AMLPMRF_MLPMF2_OFFSET 6 | ||
| 220 | #define MXC_CRMAP_AMLPMRF_MLPMF2_MASK (0x7 << 6) | ||
| 221 | #define MXC_CRMAP_AMLPMRF_MLPMF1_OFFSET 3 | ||
| 222 | #define MXC_CRMAP_AMLPMRF_MLPMF1_MASK (0x7 << 3) | ||
| 223 | #define MXC_CRMAP_AMLPMRF_MLPMF0_OFFSET 0 | ||
| 224 | #define MXC_CRMAP_AMLPMRF_MLPMF0_MASK (0x7 << 0) | ||
| 225 | |||
| 226 | #define MXC_CRMAP_AMLPMRG_MLPMG9_OFFSET 28 | ||
| 227 | #define MXC_CRMAP_AMLPMRG_MLPMG9_MASK (0x7 << 28) | ||
| 228 | #define MXC_CRMAP_AMLPMRG_MLPMG7_OFFSET 22 | ||
| 229 | #define MXC_CRMAP_AMLPMRG_MLPMG7_MASK (0x7 << 22) | ||
| 230 | #define MXC_CRMAP_AMLPMRG_MLPMG6_OFFSET 19 | ||
| 231 | #define MXC_CRMAP_AMLPMRG_MLPMG6_MASK (0x7 << 19) | ||
| 232 | #define MXC_CRMAP_AMLPMRG_MLPMG5_OFFSET 16 | ||
| 233 | #define MXC_CRMAP_AMLPMRG_MLPMG5_MASK (0x7 << 16) | ||
| 234 | #define MXC_CRMAP_AMLPMRG_MLPMG4_OFFSET 12 | ||
| 235 | #define MXC_CRMAP_AMLPMRG_MLPMG4_MASK (0x7 << 12) | ||
| 236 | #define MXC_CRMAP_AMLPMRG_MLPMG3_OFFSET 9 | ||
| 237 | #define MXC_CRMAP_AMLPMRG_MLPMG3_MASK (0x7 << 9) | ||
| 238 | #define MXC_CRMAP_AMLPMRG_MLPMG2_OFFSET 6 | ||
| 239 | #define MXC_CRMAP_AMLPMRG_MLPMG2_MASK (0x7 << 6) | ||
| 240 | #define MXC_CRMAP_AMLPMRG_MLPMG1_OFFSET 3 | ||
| 241 | #define MXC_CRMAP_AMLPMRG_MLPMG1_MASK (0x7 << 3) | ||
| 242 | #define MXC_CRMAP_AMLPMRG_MLPMG0_OFFSET 0 | ||
| 243 | #define MXC_CRMAP_AMLPMRG_MLPMG0_MASK 0x7 | ||
| 244 | |||
| 245 | #define MXC_CRMAP_AGPR_IPUPAD_OFFSET 20 | ||
| 246 | #define MXC_CRMAP_AGPR_IPUPAD_MASK (0x7 << 20) | ||
| 247 | |||
| 248 | #define MXC_CRMAP_APRA_EL1TEN_OFFSET 29 | ||
| 249 | #define MXC_CRMAP_APRA_SIMEN_OFFSET 24 | ||
| 250 | #define MXC_CRMAP_APRA_UART3DIV_OFFSET 17 | ||
| 251 | #define MXC_CRMAP_APRA_UART3DIV_MASK (0xF << 17) | ||
| 252 | #define MXC_CRMAP_APRA_UART3EN_OFFSET 16 | ||
| 253 | #define MXC_CRMAP_APRA_SAHARA_DIV2_CLKEN_OFFSET 14 | ||
| 254 | #define MXC_CRMAP_APRA_MQSPIEN_OFFSET 13 | ||
| 255 | #define MXC_CRMAP_APRA_UART2EN_OFFSET 8 | ||
| 256 | #define MXC_CRMAP_APRA_UART1EN_OFFSET 0 | ||
| 257 | |||
| 258 | #define MXC_CRMAP_APRB_SDHC2_ISEL_OFFSET 13 | ||
| 259 | #define MXC_CRMAP_APRB_SDHC2_ISEL_MASK (0x7 << 13) | ||
| 260 | #define MXC_CRMAP_APRB_SDHC2_DIV_OFFSET 9 | ||
| 261 | #define MXC_CRMAP_APRB_SDHC2_DIV_MASK (0xF << 9) | ||
| 262 | #define MXC_CRMAP_APRB_SDHC2EN_OFFSET 8 | ||
| 263 | #define MXC_CRMAP_APRB_SDHC1_ISEL_OFFSET 5 | ||
| 264 | #define MXC_CRMAP_APRB_SDHC1_ISEL_MASK (0x7 << 5) | ||
| 265 | #define MXC_CRMAP_APRB_SDHC1_DIV_OFFSET 1 | ||
| 266 | #define MXC_CRMAP_APRB_SDHC1_DIV_MASK (0xF << 1) | ||
| 267 | #define MXC_CRMAP_APRB_SDHC1EN_OFFSET 0 | ||
| 268 | |||
| 269 | #define MXC_CRMAP_ACSR_ADS_OFFSET 8 | ||
| 270 | #define MXC_CRMAP_ACSR_ADS (0x1 << 8) | ||
| 271 | #define MXC_CRMAP_ACSR_ACS 0x1 | ||
| 272 | |||
| 273 | #define MXC_CRMAP_ADCR_LFDF_0 (0x0 << 8) | ||
| 274 | #define MXC_CRMAP_ADCR_LFDF_2 (0x1 << 8) | ||
| 275 | #define MXC_CRMAP_ADCR_LFDF_4 (0x2 << 8) | ||
| 276 | #define MXC_CRMAP_ADCR_LFDF_8 (0x3 << 8) | ||
| 277 | #define MXC_CRMAP_ADCR_LFDF_OFFSET 8 | ||
| 278 | #define MXC_CRMAP_ADCR_LFDF_MASK (0x3 << 8) | ||
| 279 | #define MXC_CRMAP_ADCR_ALT_PLL 0x80 | ||
| 280 | #define MXC_CRMAP_ADCR_DFS_DIVEN 0x20 | ||
| 281 | #define MXC_CRMAP_ADCR_DIV_BYP 0x2 | ||
| 282 | #define MXC_CRMAP_ADCR_VSTAT 0x8 | ||
| 283 | #define MXC_CRMAP_ADCR_TSTAT 0x10 | ||
| 284 | #define MXC_CRMAP_ADCR_DVFS_VCTRL 0x10 | ||
| 285 | #define MXC_CRMAP_ADCR_CLK_ON 0x40 | ||
| 286 | |||
| 287 | #define MXC_CRMAP_ADFMR_FC_OFFSET 16 | ||
| 288 | #define MXC_CRMAP_ADFMR_FC_MASK (0x1F << 16) | ||
| 289 | #define MXC_CRMAP_ADFMR_MF_OFFSET 1 | ||
| 290 | #define MXC_CRMAP_ADFMR_MF_MASK (0x3FF << 1) | ||
| 291 | #define MXC_CRMAP_ADFMR_DFM_CLK_READY 0x1 | ||
| 292 | #define MXC_CRMAP_ADFMR_DFM_PWR_DOWN 0x8000 | ||
| 293 | |||
| 294 | #define MXC_CRMAP_ACR_CKOHS_HIGH (1 << 18) | ||
| 295 | #define MXC_CRMAP_ACR_CKOS_HIGH (1 << 16) | ||
| 296 | #define MXC_CRMAP_ACR_CKOHS_MASK (0x7 << 12) | ||
| 297 | #define MXC_CRMAP_ACR_CKOHD (1 << 11) | ||
| 298 | #define MXC_CRMAP_ACR_CKOHDIV_MASK (0xF << 8) | ||
| 299 | #define MXC_CRMAP_ACR_CKOHDIV_OFFSET 8 | ||
| 300 | #define MXC_CRMAP_ACR_CKOD (1 << 7) | ||
| 301 | #define MXC_CRMAP_ACR_CKOS_MASK (0x7 << 4) | ||
| 302 | |||
| 303 | /* AP Warm reset */ | ||
| 304 | #define MXC_CRMAP_AMCR_SW_AP (1 << 14) | ||
| 305 | |||
| 306 | /* Bit definitions of ACGCR in CRM_AP for tree level clock gating */ | ||
| 307 | #define MXC_CRMAP_ACGCR_ACG0_STOP_WAIT 0x00000001 | ||
| 308 | #define MXC_CRMAP_ACGCR_ACG0_STOP 0x00000003 | ||
| 309 | #define MXC_CRMAP_ACGCR_ACG0_RUN 0x00000007 | ||
| 310 | #define MXC_CRMAP_ACGCR_ACG0_DISABLED 0x00000000 | ||
| 311 | |||
| 312 | #define MXC_CRMAP_ACGCR_ACG1_STOP_WAIT 0x00000008 | ||
| 313 | #define MXC_CRMAP_ACGCR_ACG1_STOP 0x00000018 | ||
| 314 | #define MXC_CRMAP_ACGCR_ACG1_RUN 0x00000038 | ||
| 315 | #define MXC_CRMAP_ACGCR_ACG1_DISABLED 0x00000000 | ||
| 316 | |||
| 317 | #define MXC_CRMAP_ACGCR_ACG2_STOP_WAIT 0x00000040 | ||
| 318 | #define MXC_CRMAP_ACGCR_ACG2_STOP 0x000000C0 | ||
| 319 | #define MXC_CRMAP_ACGCR_ACG2_RUN 0x000001C0 | ||
| 320 | #define MXC_CRMAP_ACGCR_ACG2_DISABLED 0x00000000 | ||
| 321 | |||
| 322 | #define MXC_CRMAP_ACGCR_ACG3_STOP_WAIT 0x00000200 | ||
| 323 | #define MXC_CRMAP_ACGCR_ACG3_STOP 0x00000600 | ||
| 324 | #define MXC_CRMAP_ACGCR_ACG3_RUN 0x00000E00 | ||
| 325 | #define MXC_CRMAP_ACGCR_ACG3_DISABLED 0x00000000 | ||
| 326 | |||
| 327 | #define MXC_CRMAP_ACGCR_ACG4_STOP_WAIT 0x00001000 | ||
| 328 | #define MXC_CRMAP_ACGCR_ACG4_STOP 0x00003000 | ||
| 329 | #define MXC_CRMAP_ACGCR_ACG4_RUN 0x00007000 | ||
| 330 | #define MXC_CRMAP_ACGCR_ACG4_DISABLED 0x00000000 | ||
| 331 | |||
| 332 | #define MXC_CRMAP_ACGCR_ACG5_STOP_WAIT 0x00010000 | ||
| 333 | #define MXC_CRMAP_ACGCR_ACG5_STOP 0x00030000 | ||
| 334 | #define MXC_CRMAP_ACGCR_ACG5_RUN 0x00070000 | ||
| 335 | #define MXC_CRMAP_ACGCR_ACG5_DISABLED 0x00000000 | ||
| 336 | |||
| 337 | #define MXC_CRMAP_ACGCR_ACG6_STOP_WAIT 0x00080000 | ||
| 338 | #define MXC_CRMAP_ACGCR_ACG6_STOP 0x00180000 | ||
| 339 | #define MXC_CRMAP_ACGCR_ACG6_RUN 0x00380000 | ||
| 340 | #define MXC_CRMAP_ACGCR_ACG6_DISABLED 0x00000000 | ||
| 341 | |||
| 342 | #define NUM_GATE_CTRL 6 | ||
| 343 | |||
| 344 | /* CRM COM Register Offsets */ | ||
| 345 | #define MXC_CRMCOM_CSCR (MXC_CRM_COM_BASE + 0x0C) | ||
| 346 | #define MXC_CRMCOM_CCCR (MXC_CRM_COM_BASE + 0x10) | ||
| 347 | |||
| 348 | /* CRM COM Bit Definitions */ | ||
| 349 | #define MXC_CRMCOM_CSCR_PPD1 0x08000000 | ||
| 350 | #define MXC_CRMCOM_CSCR_CKOHSEL (1 << 18) | ||
| 351 | #define MXC_CRMCOM_CSCR_CKOSEL (1 << 17) | ||
| 352 | #define MXC_CRMCOM_CCCR_CC_DIV_OFFSET 8 | ||
| 353 | #define MXC_CRMCOM_CCCR_CC_DIV_MASK (0x1F << 8) | ||
| 354 | #define MXC_CRMCOM_CCCR_CC_SEL_OFFSET 0 | ||
| 355 | #define MXC_CRMCOM_CCCR_CC_SEL_MASK 0x3 | ||
| 356 | |||
| 357 | /* DSM Register Offsets */ | ||
| 358 | #define MXC_DSM_SLEEP_TIME (MXC_DSM_BASE + 0x0c) | ||
| 359 | #define MXC_DSM_CONTROL0 (MXC_DSM_BASE + 0x20) | ||
| 360 | #define MXC_DSM_CONTROL1 (MXC_DSM_BASE + 0x24) | ||
| 361 | #define MXC_DSM_CTREN (MXC_DSM_BASE + 0x28) | ||
| 362 | #define MXC_DSM_WARM_PER (MXC_DSM_BASE + 0x40) | ||
| 363 | #define MXC_DSM_LOCK_PER (MXC_DSM_BASE + 0x44) | ||
| 364 | #define MXC_DSM_MGPER (MXC_DSM_BASE + 0x4c) | ||
| 365 | #define MXC_DSM_CRM_CONTROL (MXC_DSM_BASE + 0x50) | ||
| 366 | |||
| 367 | /* Bit definitions of various registers in DSM */ | ||
| 368 | #define MXC_DSM_CRM_CTRL_DVFS_BYP 0x00000008 | ||
| 369 | #define MXC_DSM_CRM_CTRL_DVFS_VCTRL 0x00000004 | ||
| 370 | #define MXC_DSM_CRM_CTRL_LPMD1 0x00000002 | ||
| 371 | #define MXC_DSM_CRM_CTRL_LPMD0 0x00000001 | ||
| 372 | #define MXC_DSM_CRM_CTRL_LPMD_STOP_MODE 0x00000000 | ||
| 373 | #define MXC_DSM_CRM_CTRL_LPMD_WAIT_MODE 0x00000001 | ||
| 374 | #define MXC_DSM_CRM_CTRL_LPMD_RUN_MODE 0x00000003 | ||
| 375 | #define MXC_DSM_CONTROL0_STBY_COMMIT_EN 0x00000200 | ||
| 376 | #define MXC_DSM_CONTROL0_MSTR_EN 0x00000001 | ||
| 377 | #define MXC_DSM_CONTROL0_RESTART 0x00000010 | ||
| 378 | /* Counter Block reset */ | ||
| 379 | #define MXC_DSM_CONTROL1_CB_RST 0x00000002 | ||
| 380 | /* State Machine reset */ | ||
| 381 | #define MXC_DSM_CONTROL1_SM_RST 0x00000004 | ||
| 382 | /* Bit needed to reset counter block */ | ||
| 383 | #define MXC_CONTROL1_RST_CNT32 0x00000008 | ||
| 384 | #define MXC_DSM_CONTROL1_RST_CNT32_EN 0x00000800 | ||
| 385 | #define MXC_DSM_CONTROL1_SLEEP 0x00000100 | ||
| 386 | #define MXC_DSM_CONTROL1_WAKEUP_DISABLE 0x00004000 | ||
| 387 | #define MXC_DSM_CTREN_CNT32 0x00000001 | ||
| 388 | |||
| 389 | /* Magic Fix enable bit */ | ||
| 390 | #define MXC_DSM_MGPER_EN_MGFX 0x80000000 | ||
| 391 | #define MXC_DSM_MGPER_PER_MASK 0x000003FF | ||
| 392 | #define MXC_DSM_MGPER_PER(n) (MXC_DSM_MGPER_PER_MASK & n) | ||
| 393 | |||
| 394 | /* Address offsets of the CLKCTL registers */ | ||
| 395 | #define MXC_CLKCTL_GP_CTRL (MXC_CLKCTL_BASE + 0x00) | ||
| 396 | #define MXC_CLKCTL_GP_SER (MXC_CLKCTL_BASE + 0x04) | ||
| 397 | #define MXC_CLKCTL_GP_CER (MXC_CLKCTL_BASE + 0x08) | ||
| 398 | |||
| 399 | #endif /* _ARCH_ARM_MACH_MXC91231_CRM_REGS_H_ */ | ||
diff --git a/arch/arm/mach-mxc91231/devices.c b/arch/arm/mach-mxc91231/devices.c new file mode 100644 index 000000000000..353bd977b393 --- /dev/null +++ b/arch/arm/mach-mxc91231/devices.c | |||
| @@ -0,0 +1,251 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 3 | * Copyright 2008 Sascha Hauer, kernel@pengutronix.de | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License | ||
| 7 | * as published by the Free Software Foundation; either version 2 | ||
| 8 | * of the License, or (at your option) any later version. | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
| 17 | * Boston, MA 02110-1301, USA. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/platform_device.h> | ||
| 22 | #include <linux/serial.h> | ||
| 23 | #include <linux/gpio.h> | ||
| 24 | #include <mach/hardware.h> | ||
| 25 | #include <mach/irqs.h> | ||
| 26 | #include <mach/imx-uart.h> | ||
| 27 | |||
| 28 | static struct resource uart0[] = { | ||
| 29 | { | ||
| 30 | .start = MXC91231_UART1_BASE_ADDR, | ||
| 31 | .end = MXC91231_UART1_BASE_ADDR + 0x0B5, | ||
| 32 | .flags = IORESOURCE_MEM, | ||
| 33 | }, { | ||
| 34 | .start = MXC91231_INT_UART1_RX, | ||
| 35 | .end = MXC91231_INT_UART1_RX, | ||
| 36 | .flags = IORESOURCE_IRQ, | ||
| 37 | }, { | ||
| 38 | .start = MXC91231_INT_UART1_TX, | ||
| 39 | .end = MXC91231_INT_UART1_TX, | ||
| 40 | .flags = IORESOURCE_IRQ, | ||
| 41 | }, { | ||
| 42 | .start = MXC91231_INT_UART1_MINT, | ||
| 43 | .end = MXC91231_INT_UART1_MINT, | ||
| 44 | .flags = IORESOURCE_IRQ, | ||
| 45 | }, | ||
| 46 | }; | ||
| 47 | |||
| 48 | struct platform_device mxc_uart_device0 = { | ||
| 49 | .name = "imx-uart", | ||
| 50 | .id = 0, | ||
| 51 | .resource = uart0, | ||
| 52 | .num_resources = ARRAY_SIZE(uart0), | ||
| 53 | }; | ||
| 54 | |||
| 55 | static struct resource uart1[] = { | ||
| 56 | { | ||
| 57 | .start = MXC91231_UART2_BASE_ADDR, | ||
| 58 | .end = MXC91231_UART2_BASE_ADDR + 0x0B5, | ||
| 59 | .flags = IORESOURCE_MEM, | ||
| 60 | }, { | ||
| 61 | .start = MXC91231_INT_UART2_RX, | ||
| 62 | .end = MXC91231_INT_UART2_RX, | ||
| 63 | .flags = IORESOURCE_IRQ, | ||
| 64 | }, { | ||
| 65 | .start = MXC91231_INT_UART2_TX, | ||
| 66 | .end = MXC91231_INT_UART2_TX, | ||
| 67 | .flags = IORESOURCE_IRQ, | ||
| 68 | }, { | ||
| 69 | .start = MXC91231_INT_UART2_MINT, | ||
| 70 | .end = MXC91231_INT_UART2_MINT, | ||
| 71 | .flags = IORESOURCE_IRQ, | ||
| 72 | }, | ||
| 73 | }; | ||
| 74 | |||
| 75 | struct platform_device mxc_uart_device1 = { | ||
| 76 | .name = "imx-uart", | ||
| 77 | .id = 1, | ||
| 78 | .resource = uart1, | ||
| 79 | .num_resources = ARRAY_SIZE(uart1), | ||
| 80 | }; | ||
| 81 | |||
| 82 | static struct resource uart2[] = { | ||
| 83 | { | ||
| 84 | .start = MXC91231_UART3_BASE_ADDR, | ||
| 85 | .end = MXC91231_UART3_BASE_ADDR + 0x0B5, | ||
| 86 | .flags = IORESOURCE_MEM, | ||
| 87 | }, { | ||
| 88 | .start = MXC91231_INT_UART3_RX, | ||
| 89 | .end = MXC91231_INT_UART3_RX, | ||
| 90 | .flags = IORESOURCE_IRQ, | ||
| 91 | }, { | ||
| 92 | .start = MXC91231_INT_UART3_TX, | ||
| 93 | .end = MXC91231_INT_UART3_TX, | ||
| 94 | .flags = IORESOURCE_IRQ, | ||
| 95 | }, { | ||
| 96 | .start = MXC91231_INT_UART3_MINT, | ||
| 97 | .end = MXC91231_INT_UART3_MINT, | ||
| 98 | .flags = IORESOURCE_IRQ, | ||
| 99 | |||
| 100 | }, | ||
| 101 | }; | ||
| 102 | |||
| 103 | struct platform_device mxc_uart_device2 = { | ||
| 104 | .name = "imx-uart", | ||
| 105 | .id = 2, | ||
| 106 | .resource = uart2, | ||
| 107 | .num_resources = ARRAY_SIZE(uart2), | ||
| 108 | }; | ||
| 109 | |||
| 110 | /* GPIO port description */ | ||
| 111 | static struct mxc_gpio_port mxc_gpio_ports[] = { | ||
| 112 | [0] = { | ||
| 113 | .chip.label = "gpio-0", | ||
| 114 | .base = MXC91231_IO_ADDRESS(MXC91231_GPIO1_AP_BASE_ADDR), | ||
| 115 | .irq = MXC91231_INT_GPIO1, | ||
| 116 | .virtual_irq_start = MXC_GPIO_IRQ_START, | ||
| 117 | }, | ||
| 118 | [1] = { | ||
| 119 | .chip.label = "gpio-1", | ||
| 120 | .base = MXC91231_IO_ADDRESS(MXC91231_GPIO2_AP_BASE_ADDR), | ||
| 121 | .irq = MXC91231_INT_GPIO2, | ||
| 122 | .virtual_irq_start = MXC_GPIO_IRQ_START + 32, | ||
| 123 | }, | ||
| 124 | [2] = { | ||
| 125 | .chip.label = "gpio-2", | ||
| 126 | .base = MXC91231_IO_ADDRESS(MXC91231_GPIO3_AP_BASE_ADDR), | ||
| 127 | .irq = MXC91231_INT_GPIO3, | ||
| 128 | .virtual_irq_start = MXC_GPIO_IRQ_START + 64, | ||
| 129 | }, | ||
| 130 | [3] = { | ||
| 131 | .chip.label = "gpio-3", | ||
| 132 | .base = MXC91231_IO_ADDRESS(MXC91231_GPIO4_SH_BASE_ADDR), | ||
| 133 | .irq = MXC91231_INT_GPIO4, | ||
| 134 | .virtual_irq_start = MXC_GPIO_IRQ_START + 96, | ||
| 135 | }, | ||
| 136 | }; | ||
| 137 | |||
| 138 | int __init mxc_register_gpios(void) | ||
| 139 | { | ||
| 140 | return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports)); | ||
| 141 | } | ||
| 142 | |||
| 143 | static struct resource mxc_nand_resources[] = { | ||
| 144 | { | ||
| 145 | .start = MXC91231_NFC_BASE_ADDR, | ||
| 146 | .end = MXC91231_NFC_BASE_ADDR + 0xfff, | ||
| 147 | .flags = IORESOURCE_MEM | ||
| 148 | }, { | ||
| 149 | .start = MXC91231_INT_NANDFC, | ||
| 150 | .end = MXC91231_INT_NANDFC, | ||
| 151 | .flags = IORESOURCE_IRQ | ||
| 152 | }, | ||
| 153 | }; | ||
| 154 | |||
| 155 | struct platform_device mxc_nand_device = { | ||
| 156 | .name = "mxc_nand", | ||
| 157 | .id = 0, | ||
| 158 | .num_resources = ARRAY_SIZE(mxc_nand_resources), | ||
| 159 | .resource = mxc_nand_resources, | ||
| 160 | }; | ||
| 161 | |||
| 162 | static struct resource mxc_sdhc0_resources[] = { | ||
| 163 | { | ||
| 164 | .start = MXC91231_MMC_SDHC1_BASE_ADDR, | ||
| 165 | .end = MXC91231_MMC_SDHC1_BASE_ADDR + SZ_16K - 1, | ||
| 166 | .flags = IORESOURCE_MEM, | ||
| 167 | }, { | ||
| 168 | .start = MXC91231_INT_MMC_SDHC1, | ||
| 169 | .end = MXC91231_INT_MMC_SDHC1, | ||
| 170 | .flags = IORESOURCE_IRQ, | ||
| 171 | }, | ||
| 172 | }; | ||
| 173 | |||
| 174 | static struct resource mxc_sdhc1_resources[] = { | ||
| 175 | { | ||
| 176 | .start = MXC91231_MMC_SDHC2_BASE_ADDR, | ||
| 177 | .end = MXC91231_MMC_SDHC2_BASE_ADDR + SZ_16K - 1, | ||
| 178 | .flags = IORESOURCE_MEM, | ||
| 179 | }, { | ||
| 180 | .start = MXC91231_INT_MMC_SDHC2, | ||
| 181 | .end = MXC91231_INT_MMC_SDHC2, | ||
| 182 | .flags = IORESOURCE_IRQ, | ||
| 183 | }, | ||
| 184 | }; | ||
| 185 | |||
| 186 | struct platform_device mxc_sdhc_device0 = { | ||
| 187 | .name = "mxc-mmc", | ||
| 188 | .id = 0, | ||
| 189 | .num_resources = ARRAY_SIZE(mxc_sdhc0_resources), | ||
| 190 | .resource = mxc_sdhc0_resources, | ||
| 191 | }; | ||
| 192 | |||
| 193 | struct platform_device mxc_sdhc_device1 = { | ||
| 194 | .name = "mxc-mmc", | ||
| 195 | .id = 1, | ||
| 196 | .num_resources = ARRAY_SIZE(mxc_sdhc1_resources), | ||
| 197 | .resource = mxc_sdhc1_resources, | ||
| 198 | }; | ||
| 199 | |||
| 200 | static struct resource mxc_cspi0_resources[] = { | ||
| 201 | { | ||
| 202 | .start = MXC91231_CSPI1_BASE_ADDR, | ||
| 203 | .end = MXC91231_CSPI1_BASE_ADDR + 0x20, | ||
| 204 | .flags = IORESOURCE_MEM, | ||
| 205 | }, { | ||
| 206 | .start = MXC91231_INT_CSPI1, | ||
| 207 | .end = MXC91231_INT_CSPI1, | ||
| 208 | .flags = IORESOURCE_IRQ, | ||
| 209 | }, | ||
| 210 | }; | ||
| 211 | |||
| 212 | struct platform_device mxc_cspi_device0 = { | ||
| 213 | .name = "spi_imx", | ||
| 214 | .id = 0, | ||
| 215 | .num_resources = ARRAY_SIZE(mxc_cspi0_resources), | ||
| 216 | .resource = mxc_cspi0_resources, | ||
| 217 | }; | ||
| 218 | |||
| 219 | static struct resource mxc_cspi1_resources[] = { | ||
| 220 | { | ||
| 221 | .start = MXC91231_CSPI2_BASE_ADDR, | ||
| 222 | .end = MXC91231_CSPI2_BASE_ADDR + 0x20, | ||
| 223 | .flags = IORESOURCE_MEM, | ||
| 224 | }, { | ||
| 225 | .start = MXC91231_INT_CSPI2, | ||
| 226 | .end = MXC91231_INT_CSPI2, | ||
| 227 | .flags = IORESOURCE_IRQ, | ||
| 228 | }, | ||
| 229 | }; | ||
| 230 | |||
| 231 | struct platform_device mxc_cspi_device1 = { | ||
| 232 | .name = "spi_imx", | ||
| 233 | .id = 1, | ||
| 234 | .num_resources = ARRAY_SIZE(mxc_cspi1_resources), | ||
| 235 | .resource = mxc_cspi1_resources, | ||
| 236 | }; | ||
| 237 | |||
| 238 | static struct resource mxc_wdog0_resources[] = { | ||
| 239 | { | ||
| 240 | .start = MXC91231_WDOG1_BASE_ADDR, | ||
| 241 | .end = MXC91231_WDOG1_BASE_ADDR + 0x10, | ||
| 242 | .flags = IORESOURCE_MEM, | ||
| 243 | }, | ||
| 244 | }; | ||
| 245 | |||
| 246 | struct platform_device mxc_wdog_device0 = { | ||
| 247 | .name = "mxc-wdt", | ||
| 248 | .id = 0, | ||
| 249 | .num_resources = ARRAY_SIZE(mxc_wdog0_resources), | ||
| 250 | .resource = mxc_wdog0_resources, | ||
| 251 | }; | ||
diff --git a/arch/arm/mach-mxc91231/devices.h b/arch/arm/mach-mxc91231/devices.h new file mode 100644 index 000000000000..72a2136ce27d --- /dev/null +++ b/arch/arm/mach-mxc91231/devices.h | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | extern struct platform_device mxc_uart_device0; | ||
| 2 | extern struct platform_device mxc_uart_device1; | ||
| 3 | extern struct platform_device mxc_uart_device2; | ||
| 4 | |||
| 5 | extern struct platform_device mxc_nand_device; | ||
| 6 | |||
| 7 | extern struct platform_device mxc_sdhc_device0; | ||
| 8 | extern struct platform_device mxc_sdhc_device1; | ||
| 9 | |||
| 10 | extern struct platform_device mxc_cspi_device0; | ||
| 11 | extern struct platform_device mxc_cspi_device1; | ||
| 12 | |||
| 13 | extern struct platform_device mxc_wdog_device0; | ||
diff --git a/arch/arm/mach-mxc91231/iomux.c b/arch/arm/mach-mxc91231/iomux.c new file mode 100644 index 000000000000..405d9b19d891 --- /dev/null +++ b/arch/arm/mach-mxc91231/iomux.c | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 3 | * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> | ||
| 4 | * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version 2 | ||
| 9 | * of the License, or (at your option) any later version. | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
| 18 | * MA 02110-1301, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/spinlock.h> | ||
| 23 | #include <linux/io.h> | ||
| 24 | #include <linux/kernel.h> | ||
| 25 | #include <mach/hardware.h> | ||
| 26 | #include <mach/gpio.h> | ||
| 27 | #include <mach/iomux-mxc91231.h> | ||
| 28 | |||
| 29 | /* | ||
| 30 | * IOMUX register (base) addresses | ||
| 31 | */ | ||
| 32 | #define IOMUX_AP_BASE MXC91231_IO_ADDRESS(MXC91231_IOMUX_AP_BASE_ADDR) | ||
| 33 | #define IOMUX_COM_BASE MXC91231_IO_ADDRESS(MXC91231_IOMUX_COM_BASE_ADDR) | ||
| 34 | #define IOMUXSW_AP_MUX_CTL (IOMUX_AP_BASE + 0x000) | ||
| 35 | #define IOMUXSW_SP_MUX_CTL (IOMUX_COM_BASE + 0x000) | ||
| 36 | #define IOMUXSW_PAD_CTL (IOMUX_COM_BASE + 0x200) | ||
| 37 | |||
| 38 | #define IOMUXINT_OBS1 (IOMUX_AP_BASE + 0x600) | ||
| 39 | #define IOMUXINT_OBS2 (IOMUX_AP_BASE + 0x004) | ||
| 40 | |||
| 41 | static DEFINE_SPINLOCK(gpio_mux_lock); | ||
| 42 | |||
| 43 | #define NB_PORTS ((PIN_MAX + 32) / 32) | ||
| 44 | #define PIN_GLOBAL_NUM(pin) \ | ||
| 45 | (((pin & MUX_SIDE_MASK) >> MUX_SIDE_SHIFT)*PIN_AP_MAX + \ | ||
| 46 | ((pin & MUX_REG_MASK) >> MUX_REG_SHIFT)*4 + \ | ||
| 47 | ((pin & MUX_FIELD_MASK) >> MUX_FIELD_SHIFT)) | ||
| 48 | |||
| 49 | unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG]; | ||
| 50 | /* | ||
| 51 | * set the mode for a IOMUX pin. | ||
| 52 | */ | ||
| 53 | int mxc_iomux_mode(const unsigned int pin_mode) | ||
| 54 | { | ||
| 55 | u32 side, field, l, mode, ret = 0; | ||
| 56 | void __iomem *reg; | ||
| 57 | |||
| 58 | side = (pin_mode & MUX_SIDE_MASK) >> MUX_SIDE_SHIFT; | ||
| 59 | switch (side) { | ||
| 60 | case MUX_SIDE_AP: | ||
| 61 | reg = IOMUXSW_AP_MUX_CTL; | ||
| 62 | break; | ||
| 63 | case MUX_SIDE_SP: | ||
| 64 | reg = IOMUXSW_SP_MUX_CTL; | ||
| 65 | break; | ||
| 66 | default: | ||
| 67 | return -EINVAL; | ||
| 68 | } | ||
| 69 | reg += ((pin_mode & MUX_REG_MASK) >> MUX_REG_SHIFT) * 4; | ||
| 70 | field = (pin_mode & MUX_FIELD_MASK) >> MUX_FIELD_SHIFT; | ||
| 71 | mode = (pin_mode & MUX_MODE_MASK) >> MUX_MODE_SHIFT; | ||
| 72 | |||
| 73 | spin_lock(&gpio_mux_lock); | ||
| 74 | |||
| 75 | l = __raw_readl(reg); | ||
| 76 | l &= ~(0xff << (field * 8)); | ||
| 77 | l |= mode << (field * 8); | ||
| 78 | __raw_writel(l, reg); | ||
| 79 | |||
| 80 | spin_unlock(&gpio_mux_lock); | ||
| 81 | |||
| 82 | return ret; | ||
| 83 | } | ||
| 84 | EXPORT_SYMBOL(mxc_iomux_mode); | ||
| 85 | |||
| 86 | /* | ||
| 87 | * This function configures the pad value for a IOMUX pin. | ||
| 88 | */ | ||
| 89 | void mxc_iomux_set_pad(enum iomux_pins pin, u32 config) | ||
| 90 | { | ||
| 91 | u32 padgrp, field, l; | ||
| 92 | void __iomem *reg; | ||
| 93 | |||
| 94 | padgrp = (pin & MUX_PADGRP_MASK) >> MUX_PADGRP_SHIFT; | ||
| 95 | reg = IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4; | ||
| 96 | field = (pin + 2) % 3; | ||
| 97 | |||
| 98 | pr_debug("%s: reg offset = 0x%x, field = %d\n", | ||
| 99 | __func__, (pin + 2) / 3, field); | ||
| 100 | |||
| 101 | spin_lock(&gpio_mux_lock); | ||
| 102 | |||
| 103 | l = __raw_readl(reg); | ||
| 104 | l &= ~(0x1ff << (field * 10)); | ||
| 105 | l |= config << (field * 10); | ||
| 106 | __raw_writel(l, reg); | ||
| 107 | |||
| 108 | spin_unlock(&gpio_mux_lock); | ||
| 109 | } | ||
| 110 | EXPORT_SYMBOL(mxc_iomux_set_pad); | ||
| 111 | |||
| 112 | /* | ||
| 113 | * allocs a single pin: | ||
| 114 | * - reserves the pin so that it is not claimed by another driver | ||
| 115 | * - setups the iomux according to the configuration | ||
| 116 | */ | ||
| 117 | int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label) | ||
| 118 | { | ||
| 119 | unsigned pad = PIN_GLOBAL_NUM(pin_mode); | ||
| 120 | if (pad >= (PIN_MAX + 1)) { | ||
| 121 | printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n", | ||
| 122 | pad, label ? label : "?"); | ||
| 123 | return -EINVAL; | ||
| 124 | } | ||
| 125 | |||
| 126 | if (test_and_set_bit(pad, mxc_pin_alloc_map)) { | ||
| 127 | printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n", | ||
| 128 | pad, label ? label : "?"); | ||
| 129 | return -EBUSY; | ||
| 130 | } | ||
| 131 | mxc_iomux_mode(pin_mode); | ||
| 132 | |||
| 133 | return 0; | ||
| 134 | } | ||
| 135 | EXPORT_SYMBOL(mxc_iomux_alloc_pin); | ||
| 136 | |||
| 137 | int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count, | ||
| 138 | const char *label) | ||
| 139 | { | ||
| 140 | unsigned int *p = pin_list; | ||
| 141 | int i; | ||
| 142 | int ret = -EINVAL; | ||
| 143 | |||
| 144 | for (i = 0; i < count; i++) { | ||
| 145 | ret = mxc_iomux_alloc_pin(*p, label); | ||
| 146 | if (ret) | ||
| 147 | goto setup_error; | ||
| 148 | p++; | ||
| 149 | } | ||
| 150 | return 0; | ||
| 151 | |||
| 152 | setup_error: | ||
| 153 | mxc_iomux_release_multiple_pins(pin_list, i); | ||
| 154 | return ret; | ||
| 155 | } | ||
| 156 | EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins); | ||
| 157 | |||
| 158 | void mxc_iomux_release_pin(const unsigned int pin_mode) | ||
| 159 | { | ||
| 160 | unsigned pad = PIN_GLOBAL_NUM(pin_mode); | ||
| 161 | |||
| 162 | if (pad < (PIN_MAX + 1)) | ||
| 163 | clear_bit(pad, mxc_pin_alloc_map); | ||
| 164 | } | ||
| 165 | EXPORT_SYMBOL(mxc_iomux_release_pin); | ||
| 166 | |||
| 167 | void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count) | ||
| 168 | { | ||
| 169 | unsigned int *p = pin_list; | ||
| 170 | int i; | ||
| 171 | |||
| 172 | for (i = 0; i < count; i++) { | ||
| 173 | mxc_iomux_release_pin(*p); | ||
| 174 | p++; | ||
| 175 | } | ||
| 176 | } | ||
| 177 | EXPORT_SYMBOL(mxc_iomux_release_multiple_pins); | ||
diff --git a/arch/arm/mach-mxc91231/magx-zn5.c b/arch/arm/mach-mxc91231/magx-zn5.c new file mode 100644 index 000000000000..7dbe4ca12efd --- /dev/null +++ b/arch/arm/mach-mxc91231/magx-zn5.c | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2009 Dmitriy Taychenachev <dimichxp@gmail.com> | ||
| 3 | * | ||
| 4 | * This file is released under the GPLv2 or later. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/irq.h> | ||
| 8 | #include <linux/init.h> | ||
| 9 | #include <linux/device.h> | ||
| 10 | |||
| 11 | #include <asm/mach-types.h> | ||
| 12 | #include <asm/mach/time.h> | ||
| 13 | #include <asm/mach/arch.h> | ||
| 14 | |||
| 15 | #include <mach/common.h> | ||
| 16 | #include <mach/hardware.h> | ||
| 17 | #include <mach/iomux-mxc91231.h> | ||
| 18 | #include <mach/mmc.h> | ||
| 19 | #include <mach/imx-uart.h> | ||
| 20 | |||
| 21 | #include "devices.h" | ||
| 22 | |||
| 23 | static struct imxuart_platform_data uart_pdata = { | ||
| 24 | }; | ||
| 25 | |||
| 26 | static struct imxmmc_platform_data sdhc_pdata = { | ||
| 27 | }; | ||
| 28 | |||
| 29 | static void __init zn5_init(void) | ||
| 30 | { | ||
| 31 | pm_power_off = mxc91231_power_off; | ||
| 32 | |||
| 33 | mxc_iomux_alloc_pin(MXC91231_PIN_SP_USB_DAT_VP__RXD2, "uart2-rx"); | ||
| 34 | mxc_iomux_alloc_pin(MXC91231_PIN_SP_USB_SE0_VM__TXD2, "uart2-tx"); | ||
| 35 | |||
| 36 | mxc_register_device(&mxc_uart_device1, &uart_pdata); | ||
| 37 | mxc_register_device(&mxc_uart_device0, &uart_pdata); | ||
| 38 | |||
| 39 | mxc_register_device(&mxc_sdhc_device0, &sdhc_pdata); | ||
| 40 | |||
| 41 | mxc_register_device(&mxc_wdog_device0, NULL); | ||
| 42 | |||
| 43 | return; | ||
| 44 | } | ||
| 45 | |||
| 46 | static void __init zn5_timer_init(void) | ||
| 47 | { | ||
| 48 | mxc91231_clocks_init(26000000); /* 26mhz ckih */ | ||
| 49 | } | ||
| 50 | |||
| 51 | struct sys_timer zn5_timer = { | ||
| 52 | .init = zn5_timer_init, | ||
| 53 | }; | ||
| 54 | |||
| 55 | MACHINE_START(MAGX_ZN5, "Motorola Zn5") | ||
| 56 | .phys_io = MXC91231_AIPS1_BASE_ADDR, | ||
| 57 | .io_pg_offst = ((MXC91231_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | ||
| 58 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 59 | .map_io = mxc91231_map_io, | ||
| 60 | .init_irq = mxc91231_init_irq, | ||
| 61 | .timer = &zn5_timer, | ||
| 62 | .init_machine = zn5_init, | ||
| 63 | MACHINE_END | ||
diff --git a/arch/arm/mach-mxc91231/mm.c b/arch/arm/mach-mxc91231/mm.c new file mode 100644 index 000000000000..6becda3ff331 --- /dev/null +++ b/arch/arm/mach-mxc91231/mm.c | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 1999,2000 Arm Limited | ||
| 3 | * Copyright (C) 2000 Deep Blue Solutions Ltd | ||
| 4 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
| 5 | * Copyright 2004-2005 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 6 | * - add MXC specific definitions | ||
| 7 | * Copyright 2006 Motorola, Inc. | ||
| 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 as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 22 | * | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/mm.h> | ||
| 26 | #include <linux/init.h> | ||
| 27 | #include <mach/hardware.h> | ||
| 28 | #include <mach/common.h> | ||
| 29 | #include <asm/pgtable.h> | ||
| 30 | #include <asm/mach/map.h> | ||
| 31 | |||
| 32 | /* | ||
| 33 | * This structure defines the MXC memory map. | ||
| 34 | */ | ||
| 35 | static struct map_desc mxc_io_desc[] __initdata = { | ||
| 36 | { | ||
| 37 | .virtual = MXC91231_L2CC_BASE_ADDR_VIRT, | ||
| 38 | .pfn = __phys_to_pfn(MXC91231_L2CC_BASE_ADDR), | ||
| 39 | .length = MXC91231_L2CC_SIZE, | ||
| 40 | .type = MT_DEVICE, | ||
| 41 | }, { | ||
| 42 | .virtual = MXC91231_X_MEMC_BASE_ADDR_VIRT, | ||
| 43 | .pfn = __phys_to_pfn(MXC91231_X_MEMC_BASE_ADDR), | ||
| 44 | .length = MXC91231_X_MEMC_SIZE, | ||
| 45 | .type = MT_DEVICE, | ||
| 46 | }, { | ||
| 47 | .virtual = MXC91231_ROMP_BASE_ADDR_VIRT, | ||
| 48 | .pfn = __phys_to_pfn(MXC91231_ROMP_BASE_ADDR), | ||
| 49 | .length = MXC91231_ROMP_SIZE, | ||
| 50 | .type = MT_DEVICE, | ||
| 51 | }, { | ||
| 52 | .virtual = MXC91231_AVIC_BASE_ADDR_VIRT, | ||
| 53 | .pfn = __phys_to_pfn(MXC91231_AVIC_BASE_ADDR), | ||
| 54 | .length = MXC91231_AVIC_SIZE, | ||
| 55 | .type = MT_DEVICE, | ||
| 56 | }, { | ||
| 57 | .virtual = MXC91231_AIPS1_BASE_ADDR_VIRT, | ||
| 58 | .pfn = __phys_to_pfn(MXC91231_AIPS1_BASE_ADDR), | ||
| 59 | .length = MXC91231_AIPS1_SIZE, | ||
| 60 | .type = MT_DEVICE, | ||
| 61 | }, { | ||
| 62 | .virtual = MXC91231_SPBA0_BASE_ADDR_VIRT, | ||
| 63 | .pfn = __phys_to_pfn(MXC91231_SPBA0_BASE_ADDR), | ||
| 64 | .length = MXC91231_SPBA0_SIZE, | ||
| 65 | .type = MT_DEVICE, | ||
| 66 | }, { | ||
| 67 | .virtual = MXC91231_SPBA1_BASE_ADDR_VIRT, | ||
| 68 | .pfn = __phys_to_pfn(MXC91231_SPBA1_BASE_ADDR), | ||
| 69 | .length = MXC91231_SPBA1_SIZE, | ||
| 70 | .type = MT_DEVICE, | ||
| 71 | }, { | ||
| 72 | .virtual = MXC91231_AIPS2_BASE_ADDR_VIRT, | ||
| 73 | .pfn = __phys_to_pfn(MXC91231_AIPS2_BASE_ADDR), | ||
| 74 | .length = MXC91231_AIPS2_SIZE, | ||
| 75 | .type = MT_DEVICE, | ||
| 76 | }, | ||
| 77 | }; | ||
| 78 | |||
| 79 | /* | ||
| 80 | * This function initializes the memory map. It is called during the | ||
| 81 | * system startup to create static physical to virtual memory map for | ||
| 82 | * the IO modules. | ||
| 83 | */ | ||
| 84 | void __init mxc91231_map_io(void) | ||
| 85 | { | ||
| 86 | mxc_set_cpu_type(MXC_CPU_MXC91231); | ||
| 87 | |||
| 88 | iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); | ||
| 89 | } | ||
| 90 | |||
| 91 | void __init mxc91231_init_irq(void) | ||
| 92 | { | ||
| 93 | mxc_init_irq(MXC91231_IO_ADDRESS(MXC91231_AVIC_BASE_ADDR)); | ||
| 94 | } | ||
diff --git a/arch/arm/mach-mxc91231/system.c b/arch/arm/mach-mxc91231/system.c new file mode 100644 index 000000000000..736f7efd874a --- /dev/null +++ b/arch/arm/mach-mxc91231/system.c | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2009 Dmitriy Taychenachev <dimichxp@gmail.com> | ||
| 3 | * | ||
| 4 | * This file is released under the GPLv2 or later. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/delay.h> | ||
| 8 | #include <linux/io.h> | ||
| 9 | |||
| 10 | #include <asm/proc-fns.h> | ||
| 11 | #include <mach/hardware.h> | ||
| 12 | |||
| 13 | #include "crm_regs.h" | ||
| 14 | |||
| 15 | #define WDOG_WCR MXC91231_IO_ADDRESS(MXC91231_WDOG1_BASE_ADDR) | ||
| 16 | #define WDOG_WCR_OUT_ENABLE (1 << 6) | ||
| 17 | #define WDOG_WCR_ASSERT (1 << 5) | ||
| 18 | |||
| 19 | void mxc91231_power_off(void) | ||
| 20 | { | ||
| 21 | u16 wcr; | ||
| 22 | |||
| 23 | wcr = __raw_readw(WDOG_WCR); | ||
| 24 | wcr |= WDOG_WCR_OUT_ENABLE; | ||
| 25 | wcr &= ~WDOG_WCR_ASSERT; | ||
| 26 | __raw_writew(wcr, WDOG_WCR); | ||
| 27 | } | ||
| 28 | |||
| 29 | void mxc91231_arch_reset(char mode, const char *cmd) | ||
| 30 | { | ||
| 31 | u32 amcr; | ||
| 32 | |||
| 33 | /* Reset the AP using CRM */ | ||
| 34 | amcr = __raw_readl(MXC_CRMAP_AMCR); | ||
| 35 | amcr &= ~MXC_CRMAP_AMCR_SW_AP; | ||
| 36 | __raw_writel(amcr, MXC_CRMAP_AMCR); | ||
| 37 | |||
| 38 | mdelay(10); | ||
| 39 | cpu_reset(0); | ||
| 40 | } | ||
| 41 | |||
| 42 | void mxc91231_prepare_idle(void) | ||
| 43 | { | ||
| 44 | u32 crm_ctl; | ||
| 45 | |||
| 46 | /* Go to WAIT mode after WFI */ | ||
| 47 | crm_ctl = __raw_readl(MXC_DSM_CRM_CONTROL); | ||
| 48 | crm_ctl &= ~(MXC_DSM_CRM_CTRL_LPMD0 | MXC_DSM_CRM_CTRL_LPMD1); | ||
| 49 | crm_ctl |= MXC_DSM_CRM_CTRL_LPMD_WAIT_MODE; | ||
| 50 | __raw_writel(crm_ctl, MXC_DSM_CRM_CONTROL); | ||
| 51 | } | ||
diff --git a/arch/arm/mach-netx/include/mach/entry-macro.S b/arch/arm/mach-netx/include/mach/entry-macro.S index a1952a0feda6..844f1f9acbdf 100644 --- a/arch/arm/mach-netx/include/mach/entry-macro.S +++ b/arch/arm/mach-netx/include/mach/entry-macro.S | |||
| @@ -24,15 +24,13 @@ | |||
| 24 | .endm | 24 | .endm |
| 25 | 25 | ||
| 26 | .macro get_irqnr_preamble, base, tmp | 26 | .macro get_irqnr_preamble, base, tmp |
| 27 | ldr \base, =io_p2v(0x001ff000) | ||
| 27 | .endm | 28 | .endm |
| 28 | 29 | ||
| 29 | .macro arch_ret_to_user, tmp1, tmp2 | 30 | .macro arch_ret_to_user, tmp1, tmp2 |
| 30 | .endm | 31 | .endm |
| 31 | 32 | ||
| 32 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | 33 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp |
| 33 | mov \base, #io_p2v(0x00100000) | ||
| 34 | add \base, \base, #0x000ff000 | ||
| 35 | |||
| 36 | ldr \irqstat, [\base, #0] | 34 | ldr \irqstat, [\base, #0] |
| 37 | clz \irqnr, \irqstat | 35 | clz \irqnr, \irqstat |
| 38 | rsb \irqnr, \irqnr, #31 | 36 | rsb \irqnr, \irqnr, #31 |
diff --git a/arch/arm/mach-nomadik/Kconfig b/arch/arm/mach-nomadik/Kconfig new file mode 100644 index 000000000000..2a02b49c40f0 --- /dev/null +++ b/arch/arm/mach-nomadik/Kconfig | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | if ARCH_NOMADIK | ||
| 2 | |||
| 3 | menu "Nomadik boards" | ||
| 4 | |||
| 5 | config MACH_NOMADIK_8815NHK | ||
| 6 | bool "ST 8815 Nomadik Hardware Kit (evaluation board)" | ||
| 7 | select NOMADIK_8815 | ||
| 8 | |||
| 9 | endmenu | ||
| 10 | |||
| 11 | config NOMADIK_8815 | ||
| 12 | bool | ||
| 13 | |||
| 14 | |||
| 15 | config I2C_BITBANG_8815NHK | ||
| 16 | tristate "Driver for bit-bang busses found on the 8815 NHK" | ||
| 17 | depends on I2C && MACH_NOMADIK_8815NHK | ||
| 18 | select I2C_ALGOBIT | ||
| 19 | default y | ||
| 20 | |||
| 21 | endif | ||
diff --git a/arch/arm/mach-nomadik/Makefile b/arch/arm/mach-nomadik/Makefile new file mode 100644 index 000000000000..412040982a40 --- /dev/null +++ b/arch/arm/mach-nomadik/Makefile | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | # | ||
| 2 | # Makefile for the linux kernel. | ||
| 3 | # | ||
| 4 | # Note! Dependencies are done automagically by 'make dep', which also | ||
| 5 | # removes any old dependencies. DON'T put your own dependencies here | ||
| 6 | # unless it's something special (ie not a .c file). | ||
| 7 | |||
| 8 | # Object file lists. | ||
| 9 | |||
| 10 | obj-y += clock.o timer.o gpio.o | ||
| 11 | |||
| 12 | # Cpu revision | ||
| 13 | obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o | ||
| 14 | |||
| 15 | # Specific board support | ||
| 16 | obj-$(CONFIG_MACH_NOMADIK_8815NHK) += board-nhk8815.o | ||
| 17 | |||
| 18 | # Nomadik extra devices | ||
| 19 | obj-$(CONFIG_I2C_BITBANG_8815NHK) += i2c-8815nhk.o | ||
diff --git a/arch/arm/mach-nomadik/Makefile.boot b/arch/arm/mach-nomadik/Makefile.boot new file mode 100644 index 000000000000..c7e75acfe6c9 --- /dev/null +++ b/arch/arm/mach-nomadik/Makefile.boot | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | zreladdr-y := 0x00008000 | ||
| 2 | params_phys-y := 0x00000100 | ||
| 3 | initrd_phys-y := 0x00800000 | ||
| 4 | |||
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c new file mode 100644 index 000000000000..79bdea943eb4 --- /dev/null +++ b/arch/arm/mach-nomadik/board-nhk8815.c | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-nomadik/board-8815nhk.c | ||
| 3 | * | ||
| 4 | * Copyright (C) STMicroelectronics | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2, as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * NHK15 board specifc driver definition | ||
| 11 | */ | ||
| 12 | #include <linux/types.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/amba/bus.h> | ||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/gpio.h> | ||
| 19 | #include <asm/mach-types.h> | ||
| 20 | #include <asm/mach/arch.h> | ||
| 21 | #include <asm/mach/irq.h> | ||
| 22 | #include <mach/setup.h> | ||
| 23 | #include "clock.h" | ||
| 24 | |||
| 25 | #define __MEM_4K_RESOURCE(x) \ | ||
| 26 | .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} | ||
| 27 | |||
| 28 | static struct amba_device uart0_device = { | ||
| 29 | .dev = { .init_name = "uart0" }, | ||
| 30 | __MEM_4K_RESOURCE(NOMADIK_UART0_BASE), | ||
| 31 | .irq = {IRQ_UART0, NO_IRQ}, | ||
| 32 | }; | ||
| 33 | |||
| 34 | static struct amba_device uart1_device = { | ||
| 35 | .dev = { .init_name = "uart1" }, | ||
| 36 | __MEM_4K_RESOURCE(NOMADIK_UART1_BASE), | ||
| 37 | .irq = {IRQ_UART1, NO_IRQ}, | ||
| 38 | }; | ||
| 39 | |||
| 40 | static struct amba_device *amba_devs[] __initdata = { | ||
| 41 | &uart0_device, | ||
| 42 | &uart1_device, | ||
| 43 | }; | ||
| 44 | |||
| 45 | /* We have a fixed clock alone, by now */ | ||
| 46 | static struct clk nhk8815_clk_48 = { | ||
| 47 | .rate = 48*1000*1000, | ||
| 48 | }; | ||
| 49 | |||
| 50 | static struct resource nhk8815_eth_resources[] = { | ||
| 51 | { | ||
| 52 | .name = "smc91x-regs", | ||
| 53 | .start = 0x34000000 + 0x300, | ||
| 54 | .end = 0x34000000 + SZ_64K - 1, | ||
| 55 | .flags = IORESOURCE_MEM, | ||
| 56 | }, { | ||
| 57 | .start = NOMADIK_GPIO_TO_IRQ(115), | ||
| 58 | .end = NOMADIK_GPIO_TO_IRQ(115), | ||
| 59 | .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING, | ||
| 60 | } | ||
| 61 | }; | ||
| 62 | |||
| 63 | static struct platform_device nhk8815_eth_device = { | ||
| 64 | .name = "smc91x", | ||
| 65 | .resource = nhk8815_eth_resources, | ||
| 66 | .num_resources = ARRAY_SIZE(nhk8815_eth_resources), | ||
| 67 | }; | ||
| 68 | |||
| 69 | static int __init nhk8815_eth_init(void) | ||
| 70 | { | ||
| 71 | int gpio_nr = 115; /* hardwired in the board */ | ||
| 72 | int err; | ||
| 73 | |||
| 74 | err = gpio_request(gpio_nr, "eth_irq"); | ||
| 75 | if (!err) err = nmk_gpio_set_mode(gpio_nr, NMK_GPIO_ALT_GPIO); | ||
| 76 | if (!err) err = gpio_direction_input(gpio_nr); | ||
| 77 | if (err) | ||
| 78 | pr_err("Error %i in %s\n", err, __func__); | ||
| 79 | return err; | ||
| 80 | } | ||
| 81 | device_initcall(nhk8815_eth_init); | ||
| 82 | |||
| 83 | static struct platform_device *nhk8815_platform_devices[] __initdata = { | ||
| 84 | &nhk8815_eth_device, | ||
| 85 | /* will add more devices */ | ||
| 86 | }; | ||
| 87 | |||
| 88 | static void __init nhk8815_platform_init(void) | ||
| 89 | { | ||
| 90 | int i; | ||
| 91 | |||
| 92 | cpu8815_platform_init(); | ||
| 93 | platform_add_devices(nhk8815_platform_devices, | ||
| 94 | ARRAY_SIZE(nhk8815_platform_devices)); | ||
| 95 | |||
| 96 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | ||
| 97 | nmdk_clk_create(&nhk8815_clk_48, amba_devs[i]->dev.init_name); | ||
| 98 | amba_device_register(amba_devs[i], &iomem_resource); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | MACHINE_START(NOMADIK, "NHK8815") | ||
| 103 | /* Maintainer: ST MicroElectronics */ | ||
| 104 | .phys_io = NOMADIK_UART0_BASE, | ||
| 105 | .io_pg_offst = (IO_ADDRESS(NOMADIK_UART0_BASE) >> 18) & 0xfffc, | ||
| 106 | .boot_params = 0x100, | ||
| 107 | .map_io = cpu8815_map_io, | ||
| 108 | .init_irq = cpu8815_init_irq, | ||
| 109 | .timer = &nomadik_timer, | ||
| 110 | .init_machine = nhk8815_platform_init, | ||
| 111 | MACHINE_END | ||
diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c new file mode 100644 index 000000000000..9f92502a0083 --- /dev/null +++ b/arch/arm/mach-nomadik/clock.c | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-nomadik/clock.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 Alessandro Rubini | ||
| 5 | */ | ||
| 6 | #include <linux/kernel.h> | ||
| 7 | #include <linux/module.h> | ||
| 8 | #include <linux/errno.h> | ||
| 9 | #include <linux/clk.h> | ||
| 10 | #include <asm/clkdev.h> | ||
| 11 | #include "clock.h" | ||
| 12 | |||
| 13 | /* | ||
| 14 | * The nomadik board uses generic clocks, but the serial pl011 file | ||
| 15 | * calls clk_enable(), clk_disable(), clk_get_rate(), so we provide them | ||
| 16 | */ | ||
| 17 | unsigned long clk_get_rate(struct clk *clk) | ||
| 18 | { | ||
| 19 | return clk->rate; | ||
| 20 | } | ||
| 21 | EXPORT_SYMBOL(clk_get_rate); | ||
| 22 | |||
| 23 | /* enable and disable do nothing */ | ||
| 24 | int clk_enable(struct clk *clk) | ||
| 25 | { | ||
| 26 | return 0; | ||
| 27 | } | ||
| 28 | EXPORT_SYMBOL(clk_enable); | ||
| 29 | |||
| 30 | void clk_disable(struct clk *clk) | ||
| 31 | { | ||
| 32 | } | ||
| 33 | EXPORT_SYMBOL(clk_disable); | ||
| 34 | |||
| 35 | /* Create a clock structure with the given name */ | ||
| 36 | int nmdk_clk_create(struct clk *clk, const char *dev_id) | ||
| 37 | { | ||
| 38 | struct clk_lookup *clkdev; | ||
| 39 | |||
| 40 | clkdev = clkdev_alloc(clk, NULL, dev_id); | ||
| 41 | if (!clkdev) | ||
| 42 | return -ENOMEM; | ||
| 43 | clkdev_add(clkdev); | ||
| 44 | return 0; | ||
| 45 | } | ||
diff --git a/arch/arm/mach-nomadik/clock.h b/arch/arm/mach-nomadik/clock.h new file mode 100644 index 000000000000..235faec7f627 --- /dev/null +++ b/arch/arm/mach-nomadik/clock.h | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | |||
| 2 | /* | ||
| 3 | * linux/arch/arm/mach-nomadik/clock.h | ||
| 4 | * | ||
| 5 | * Copyright (C) 2009 Alessandro Rubini | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | struct clk { | ||
| 12 | unsigned long rate; | ||
| 13 | }; | ||
| 14 | extern int nmdk_clk_create(struct clk *clk, const char *dev_id); | ||
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c new file mode 100644 index 000000000000..f93c59634191 --- /dev/null +++ b/arch/arm/mach-nomadik/cpu-8815.c | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | /* | ||
| 2 | * Copyright STMicroelectronics, 2007. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/types.h> | ||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/device.h> | ||
| 22 | #include <linux/amba/bus.h> | ||
| 23 | #include <linux/gpio.h> | ||
| 24 | |||
| 25 | #include <mach/hardware.h> | ||
| 26 | #include <mach/irqs.h> | ||
| 27 | #include <asm/mach/map.h> | ||
| 28 | #include <asm/hardware/vic.h> | ||
| 29 | |||
| 30 | #include <asm/cacheflush.h> | ||
| 31 | #include <asm/hardware/cache-l2x0.h> | ||
| 32 | |||
| 33 | /* The 8815 has 4 GPIO blocks, let's register them immediately */ | ||
| 34 | static struct nmk_gpio_platform_data cpu8815_gpio[] = { | ||
| 35 | { | ||
| 36 | .name = "GPIO-0-31", | ||
| 37 | .first_gpio = 0, | ||
| 38 | .first_irq = NOMADIK_GPIO_TO_IRQ(0), | ||
| 39 | .parent_irq = IRQ_GPIO0, | ||
| 40 | }, { | ||
| 41 | .name = "GPIO-32-63", | ||
| 42 | .first_gpio = 32, | ||
| 43 | .first_irq = NOMADIK_GPIO_TO_IRQ(32), | ||
| 44 | .parent_irq = IRQ_GPIO1, | ||
| 45 | }, { | ||
| 46 | .name = "GPIO-64-95", | ||
| 47 | .first_gpio = 64, | ||
| 48 | .first_irq = NOMADIK_GPIO_TO_IRQ(64), | ||
| 49 | .parent_irq = IRQ_GPIO2, | ||
| 50 | }, { | ||
| 51 | .name = "GPIO-96-127", /* 124..127 not routed to pin */ | ||
| 52 | .first_gpio = 96, | ||
| 53 | .first_irq = NOMADIK_GPIO_TO_IRQ(96), | ||
| 54 | .parent_irq = IRQ_GPIO3, | ||
| 55 | } | ||
| 56 | }; | ||
| 57 | |||
| 58 | #define __MEM_4K_RESOURCE(x) \ | ||
| 59 | .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} | ||
| 60 | |||
| 61 | static struct amba_device cpu8815_amba_gpio[] = { | ||
| 62 | { | ||
| 63 | .dev = { | ||
| 64 | .init_name = "gpio0", | ||
| 65 | .platform_data = cpu8815_gpio + 0, | ||
| 66 | }, | ||
| 67 | __MEM_4K_RESOURCE(NOMADIK_GPIO0_BASE), | ||
| 68 | }, { | ||
| 69 | .dev = { | ||
| 70 | .init_name = "gpio1", | ||
| 71 | .platform_data = cpu8815_gpio + 1, | ||
| 72 | }, | ||
| 73 | __MEM_4K_RESOURCE(NOMADIK_GPIO1_BASE), | ||
| 74 | }, { | ||
| 75 | .dev = { | ||
| 76 | .init_name = "gpio2", | ||
| 77 | .platform_data = cpu8815_gpio + 2, | ||
| 78 | }, | ||
| 79 | __MEM_4K_RESOURCE(NOMADIK_GPIO2_BASE), | ||
| 80 | }, { | ||
| 81 | .dev = { | ||
| 82 | .init_name = "gpio3", | ||
| 83 | .platform_data = cpu8815_gpio + 3, | ||
| 84 | }, | ||
| 85 | __MEM_4K_RESOURCE(NOMADIK_GPIO3_BASE), | ||
| 86 | }, | ||
| 87 | }; | ||
| 88 | |||
| 89 | static struct amba_device *amba_devs[] __initdata = { | ||
| 90 | cpu8815_amba_gpio + 0, | ||
| 91 | cpu8815_amba_gpio + 1, | ||
| 92 | cpu8815_amba_gpio + 2, | ||
| 93 | cpu8815_amba_gpio + 3, | ||
| 94 | }; | ||
| 95 | |||
| 96 | static int __init cpu8815_init(void) | ||
| 97 | { | ||
| 98 | int i; | ||
| 99 | |||
| 100 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) | ||
| 101 | amba_device_register(amba_devs[i], &iomem_resource); | ||
| 102 | return 0; | ||
| 103 | } | ||
| 104 | arch_initcall(cpu8815_init); | ||
| 105 | |||
| 106 | /* All SoC devices live in the same area (see hardware.h) */ | ||
| 107 | static struct map_desc nomadik_io_desc[] __initdata = { | ||
| 108 | { | ||
| 109 | .virtual = NOMADIK_IO_VIRTUAL, | ||
| 110 | .pfn = __phys_to_pfn(NOMADIK_IO_PHYSICAL), | ||
| 111 | .length = NOMADIK_IO_SIZE, | ||
| 112 | .type = MT_DEVICE, | ||
| 113 | } | ||
| 114 | /* static ram and secured ram may be added later */ | ||
| 115 | }; | ||
| 116 | |||
| 117 | void __init cpu8815_map_io(void) | ||
| 118 | { | ||
| 119 | iotable_init(nomadik_io_desc, ARRAY_SIZE(nomadik_io_desc)); | ||
| 120 | } | ||
| 121 | |||
| 122 | void __init cpu8815_init_irq(void) | ||
| 123 | { | ||
| 124 | /* This modified VIC cell has two register blocks, at 0 and 0x20 */ | ||
| 125 | vic_init(io_p2v(NOMADIK_IC_BASE + 0x00), IRQ_VIC_START + 0, ~0, 0); | ||
| 126 | vic_init(io_p2v(NOMADIK_IC_BASE + 0x20), IRQ_VIC_START + 32, ~0, 0); | ||
| 127 | } | ||
| 128 | |||
| 129 | /* | ||
| 130 | * This function is called from the board init ("init_machine"). | ||
| 131 | */ | ||
| 132 | void __init cpu8815_platform_init(void) | ||
| 133 | { | ||
| 134 | #ifdef CONFIG_CACHE_L2X0 | ||
| 135 | /* At full speed latency must be >=2, so 0x249 in low bits */ | ||
| 136 | l2x0_init(io_p2v(NOMADIK_L2CC_BASE), 0x00730249, 0xfe000fff); | ||
| 137 | #endif | ||
| 138 | return; | ||
| 139 | } | ||
diff --git a/arch/arm/mach-nomadik/gpio.c b/arch/arm/mach-nomadik/gpio.c new file mode 100644 index 000000000000..9a09b2791e03 --- /dev/null +++ b/arch/arm/mach-nomadik/gpio.c | |||
| @@ -0,0 +1,396 @@ | |||
| 1 | /* | ||
| 2 | * Generic GPIO driver for logic cells found in the Nomadik SoC | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008,2009 STMicroelectronics | ||
| 5 | * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it> | ||
| 6 | * Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/amba/bus.h> | ||
| 17 | #include <linux/io.h> | ||
| 18 | #include <linux/gpio.h> | ||
| 19 | #include <linux/spinlock.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/irq.h> | ||
| 22 | |||
| 23 | #include <mach/hardware.h> | ||
| 24 | #include <mach/gpio.h> | ||
| 25 | |||
| 26 | /* | ||
| 27 | * The GPIO module in the Nomadik family of Systems-on-Chip is an | ||
| 28 | * AMBA device, managing 32 pins and alternate functions. The logic block | ||
| 29 | * is currently only used in the Nomadik. | ||
| 30 | * | ||
| 31 | * Symbols in this file are called "nmk_gpio" for "nomadik gpio" | ||
| 32 | */ | ||
| 33 | |||
| 34 | #define NMK_GPIO_PER_CHIP 32 | ||
| 35 | struct nmk_gpio_chip { | ||
| 36 | struct gpio_chip chip; | ||
| 37 | void __iomem *addr; | ||
| 38 | unsigned int parent_irq; | ||
| 39 | spinlock_t *lock; | ||
| 40 | /* Keep track of configured edges */ | ||
| 41 | u32 edge_rising; | ||
| 42 | u32 edge_falling; | ||
| 43 | }; | ||
| 44 | |||
| 45 | /* Mode functions */ | ||
| 46 | int nmk_gpio_set_mode(int gpio, int gpio_mode) | ||
| 47 | { | ||
| 48 | struct nmk_gpio_chip *nmk_chip; | ||
| 49 | unsigned long flags; | ||
| 50 | u32 afunc, bfunc, bit; | ||
| 51 | |||
| 52 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | ||
| 53 | if (!nmk_chip) | ||
| 54 | return -EINVAL; | ||
| 55 | |||
| 56 | bit = 1 << (gpio - nmk_chip->chip.base); | ||
| 57 | |||
| 58 | spin_lock_irqsave(&nmk_chip->lock, flags); | ||
| 59 | afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit; | ||
| 60 | bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit; | ||
| 61 | if (gpio_mode & NMK_GPIO_ALT_A) | ||
| 62 | afunc |= bit; | ||
| 63 | if (gpio_mode & NMK_GPIO_ALT_B) | ||
| 64 | bfunc |= bit; | ||
| 65 | writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA); | ||
| 66 | writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB); | ||
| 67 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | ||
| 68 | |||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | EXPORT_SYMBOL(nmk_gpio_set_mode); | ||
| 72 | |||
| 73 | int nmk_gpio_get_mode(int gpio) | ||
| 74 | { | ||
| 75 | struct nmk_gpio_chip *nmk_chip; | ||
| 76 | u32 afunc, bfunc, bit; | ||
| 77 | |||
| 78 | nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio)); | ||
| 79 | if (!nmk_chip) | ||
| 80 | return -EINVAL; | ||
| 81 | |||
| 82 | bit = 1 << (gpio - nmk_chip->chip.base); | ||
| 83 | |||
| 84 | afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit; | ||
| 85 | bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit; | ||
| 86 | |||
| 87 | return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0); | ||
| 88 | } | ||
| 89 | EXPORT_SYMBOL(nmk_gpio_get_mode); | ||
| 90 | |||
| 91 | |||
| 92 | /* IRQ functions */ | ||
| 93 | static inline int nmk_gpio_get_bitmask(int gpio) | ||
| 94 | { | ||
| 95 | return 1 << (gpio % 32); | ||
| 96 | } | ||
| 97 | |||
| 98 | static void nmk_gpio_irq_ack(unsigned int irq) | ||
| 99 | { | ||
| 100 | int gpio; | ||
| 101 | struct nmk_gpio_chip *nmk_chip; | ||
| 102 | |||
| 103 | gpio = NOMADIK_IRQ_TO_GPIO(irq); | ||
| 104 | nmk_chip = get_irq_chip_data(irq); | ||
| 105 | if (!nmk_chip) | ||
| 106 | return; | ||
| 107 | writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC); | ||
| 108 | } | ||
| 109 | |||
| 110 | static void nmk_gpio_irq_mask(unsigned int irq) | ||
| 111 | { | ||
| 112 | int gpio; | ||
| 113 | struct nmk_gpio_chip *nmk_chip; | ||
| 114 | unsigned long flags; | ||
| 115 | u32 bitmask, reg; | ||
| 116 | |||
| 117 | gpio = NOMADIK_IRQ_TO_GPIO(irq); | ||
| 118 | nmk_chip = get_irq_chip_data(irq); | ||
| 119 | bitmask = nmk_gpio_get_bitmask(gpio); | ||
| 120 | if (!nmk_chip) | ||
| 121 | return; | ||
| 122 | |||
| 123 | /* we must individually clear the two edges */ | ||
| 124 | spin_lock_irqsave(&nmk_chip->lock, flags); | ||
| 125 | if (nmk_chip->edge_rising & bitmask) { | ||
| 126 | reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC); | ||
| 127 | reg &= ~bitmask; | ||
| 128 | writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC); | ||
| 129 | } | ||
| 130 | if (nmk_chip->edge_falling & bitmask) { | ||
| 131 | reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC); | ||
| 132 | reg &= ~bitmask; | ||
| 133 | writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC); | ||
| 134 | } | ||
| 135 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | ||
| 136 | }; | ||
| 137 | |||
| 138 | static void nmk_gpio_irq_unmask(unsigned int irq) | ||
| 139 | { | ||
| 140 | int gpio; | ||
| 141 | struct nmk_gpio_chip *nmk_chip; | ||
| 142 | unsigned long flags; | ||
| 143 | u32 bitmask, reg; | ||
| 144 | |||
| 145 | gpio = NOMADIK_IRQ_TO_GPIO(irq); | ||
| 146 | nmk_chip = get_irq_chip_data(irq); | ||
| 147 | bitmask = nmk_gpio_get_bitmask(gpio); | ||
| 148 | if (!nmk_chip) | ||
| 149 | return; | ||
| 150 | |||
| 151 | /* we must individually set the two edges */ | ||
| 152 | spin_lock_irqsave(&nmk_chip->lock, flags); | ||
| 153 | if (nmk_chip->edge_rising & bitmask) { | ||
| 154 | reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC); | ||
| 155 | reg |= bitmask; | ||
| 156 | writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC); | ||
| 157 | } | ||
| 158 | if (nmk_chip->edge_falling & bitmask) { | ||
| 159 | reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC); | ||
| 160 | reg |= bitmask; | ||
| 161 | writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC); | ||
| 162 | } | ||
| 163 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | ||
| 164 | } | ||
| 165 | |||
| 166 | static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) | ||
| 167 | { | ||
| 168 | int gpio; | ||
| 169 | struct nmk_gpio_chip *nmk_chip; | ||
| 170 | unsigned long flags; | ||
| 171 | u32 bitmask; | ||
| 172 | |||
| 173 | gpio = NOMADIK_IRQ_TO_GPIO(irq); | ||
| 174 | nmk_chip = get_irq_chip_data(irq); | ||
| 175 | bitmask = nmk_gpio_get_bitmask(gpio); | ||
| 176 | if (!nmk_chip) | ||
| 177 | return -EINVAL; | ||
| 178 | |||
| 179 | if (type & IRQ_TYPE_LEVEL_HIGH) | ||
| 180 | return -EINVAL; | ||
| 181 | if (type & IRQ_TYPE_LEVEL_LOW) | ||
| 182 | return -EINVAL; | ||
| 183 | |||
| 184 | spin_lock_irqsave(&nmk_chip->lock, flags); | ||
| 185 | |||
| 186 | nmk_chip->edge_rising &= ~bitmask; | ||
| 187 | if (type & IRQ_TYPE_EDGE_RISING) | ||
| 188 | nmk_chip->edge_rising |= bitmask; | ||
| 189 | writel(nmk_chip->edge_rising, nmk_chip->addr + NMK_GPIO_RIMSC); | ||
| 190 | |||
| 191 | nmk_chip->edge_falling &= ~bitmask; | ||
| 192 | if (type & IRQ_TYPE_EDGE_FALLING) | ||
| 193 | nmk_chip->edge_falling |= bitmask; | ||
| 194 | writel(nmk_chip->edge_falling, nmk_chip->addr + NMK_GPIO_FIMSC); | ||
| 195 | |||
| 196 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | ||
| 197 | |||
| 198 | nmk_gpio_irq_unmask(irq); | ||
| 199 | |||
| 200 | return 0; | ||
| 201 | } | ||
| 202 | |||
| 203 | static struct irq_chip nmk_gpio_irq_chip = { | ||
| 204 | .name = "Nomadik-GPIO", | ||
| 205 | .ack = nmk_gpio_irq_ack, | ||
| 206 | .mask = nmk_gpio_irq_mask, | ||
| 207 | .unmask = nmk_gpio_irq_unmask, | ||
| 208 | .set_type = nmk_gpio_irq_set_type, | ||
| 209 | }; | ||
| 210 | |||
| 211 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
| 212 | { | ||
| 213 | struct nmk_gpio_chip *nmk_chip; | ||
| 214 | struct irq_chip *host_chip; | ||
| 215 | unsigned int gpio_irq; | ||
| 216 | u32 pending; | ||
| 217 | unsigned int first_irq; | ||
| 218 | |||
| 219 | nmk_chip = get_irq_data(irq); | ||
| 220 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); | ||
| 221 | while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) { | ||
| 222 | gpio_irq = first_irq + __ffs(pending); | ||
| 223 | generic_handle_irq(gpio_irq); | ||
| 224 | } | ||
| 225 | if (0) {/* don't ack parent irq, as ack == disable */ | ||
| 226 | host_chip = get_irq_chip(irq); | ||
| 227 | host_chip->ack(irq); | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) | ||
| 232 | { | ||
| 233 | unsigned int first_irq; | ||
| 234 | int i; | ||
| 235 | |||
| 236 | first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); | ||
| 237 | for (i = first_irq; i < first_irq + NMK_GPIO_PER_CHIP; i++) { | ||
| 238 | set_irq_chip(i, &nmk_gpio_irq_chip); | ||
| 239 | set_irq_handler(i, handle_edge_irq); | ||
| 240 | set_irq_flags(i, IRQF_VALID); | ||
| 241 | set_irq_chip_data(i, nmk_chip); | ||
| 242 | } | ||
| 243 | set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler); | ||
| 244 | set_irq_data(nmk_chip->parent_irq, nmk_chip); | ||
| 245 | return 0; | ||
| 246 | } | ||
| 247 | |||
| 248 | /* I/O Functions */ | ||
| 249 | static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset) | ||
| 250 | { | ||
| 251 | struct nmk_gpio_chip *nmk_chip = | ||
| 252 | container_of(chip, struct nmk_gpio_chip, chip); | ||
| 253 | |||
| 254 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC); | ||
| 255 | return 0; | ||
| 256 | } | ||
| 257 | |||
| 258 | static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, | ||
| 259 | int val) | ||
| 260 | { | ||
| 261 | struct nmk_gpio_chip *nmk_chip = | ||
| 262 | container_of(chip, struct nmk_gpio_chip, chip); | ||
| 263 | |||
| 264 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS); | ||
| 265 | return 0; | ||
| 266 | } | ||
| 267 | |||
| 268 | static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset) | ||
| 269 | { | ||
| 270 | struct nmk_gpio_chip *nmk_chip = | ||
| 271 | container_of(chip, struct nmk_gpio_chip, chip); | ||
| 272 | u32 bit = 1 << offset; | ||
| 273 | |||
| 274 | return (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0; | ||
| 275 | } | ||
| 276 | |||
| 277 | static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset, | ||
| 278 | int val) | ||
| 279 | { | ||
| 280 | struct nmk_gpio_chip *nmk_chip = | ||
| 281 | container_of(chip, struct nmk_gpio_chip, chip); | ||
| 282 | u32 bit = 1 << offset; | ||
| 283 | |||
| 284 | if (val) | ||
| 285 | writel(bit, nmk_chip->addr + NMK_GPIO_DATS); | ||
| 286 | else | ||
| 287 | writel(bit, nmk_chip->addr + NMK_GPIO_DATC); | ||
| 288 | } | ||
| 289 | |||
| 290 | /* This structure is replicated for each GPIO block allocated at probe time */ | ||
| 291 | static struct gpio_chip nmk_gpio_template = { | ||
| 292 | .direction_input = nmk_gpio_make_input, | ||
| 293 | .get = nmk_gpio_get_input, | ||
| 294 | .direction_output = nmk_gpio_make_output, | ||
| 295 | .set = nmk_gpio_set_output, | ||
| 296 | .ngpio = NMK_GPIO_PER_CHIP, | ||
| 297 | .can_sleep = 0, | ||
| 298 | }; | ||
| 299 | |||
| 300 | static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id) | ||
| 301 | { | ||
| 302 | struct nmk_gpio_platform_data *pdata; | ||
| 303 | struct nmk_gpio_chip *nmk_chip; | ||
| 304 | struct gpio_chip *chip; | ||
| 305 | int ret; | ||
| 306 | |||
| 307 | pdata = dev->dev.platform_data; | ||
| 308 | ret = amba_request_regions(dev, pdata->name); | ||
| 309 | if (ret) | ||
| 310 | return ret; | ||
| 311 | |||
| 312 | nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); | ||
| 313 | if (!nmk_chip) { | ||
| 314 | ret = -ENOMEM; | ||
| 315 | goto out_amba; | ||
| 316 | } | ||
| 317 | /* | ||
| 318 | * The virt address in nmk_chip->addr is in the nomadik register space, | ||
| 319 | * so we can simply convert the resource address, without remapping | ||
| 320 | */ | ||
| 321 | nmk_chip->addr = io_p2v(dev->res.start); | ||
| 322 | nmk_chip->chip = nmk_gpio_template; | ||
| 323 | nmk_chip->parent_irq = pdata->parent_irq; | ||
| 324 | |||
| 325 | chip = &nmk_chip->chip; | ||
| 326 | chip->base = pdata->first_gpio; | ||
| 327 | chip->label = pdata->name; | ||
| 328 | chip->dev = &dev->dev; | ||
| 329 | chip->owner = THIS_MODULE; | ||
| 330 | |||
| 331 | ret = gpiochip_add(&nmk_chip->chip); | ||
| 332 | if (ret) | ||
| 333 | goto out_free; | ||
| 334 | |||
| 335 | amba_set_drvdata(dev, nmk_chip); | ||
| 336 | |||
| 337 | nmk_gpio_init_irq(nmk_chip); | ||
| 338 | |||
| 339 | dev_info(&dev->dev, "Bits %i-%i at address %p\n", | ||
| 340 | nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr); | ||
| 341 | return 0; | ||
| 342 | |||
| 343 | out_free: | ||
| 344 | kfree(nmk_chip); | ||
| 345 | out_amba: | ||
| 346 | amba_release_regions(dev); | ||
| 347 | dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret, | ||
| 348 | pdata->first_gpio, pdata->first_gpio+31); | ||
| 349 | return ret; | ||
| 350 | } | ||
| 351 | |||
| 352 | static int nmk_gpio_remove(struct amba_device *dev) | ||
| 353 | { | ||
| 354 | struct nmk_gpio_chip *nmk_chip; | ||
| 355 | |||
| 356 | nmk_chip = amba_get_drvdata(dev); | ||
| 357 | gpiochip_remove(&nmk_chip->chip); | ||
| 358 | kfree(nmk_chip); | ||
| 359 | amba_release_regions(dev); | ||
| 360 | return 0; | ||
| 361 | } | ||
| 362 | |||
| 363 | |||
| 364 | /* We have 0x1f080060 and 0x1f180060, accept both using the mask */ | ||
| 365 | static struct amba_id nmk_gpio_ids[] = { | ||
| 366 | { | ||
| 367 | .id = 0x1f080060, | ||
| 368 | .mask = 0xffefffff, | ||
| 369 | }, | ||
| 370 | {0, 0}, | ||
| 371 | }; | ||
| 372 | |||
| 373 | static struct amba_driver nmk_gpio_driver = { | ||
| 374 | .drv = { | ||
| 375 | .owner = THIS_MODULE, | ||
| 376 | .name = "gpio", | ||
| 377 | }, | ||
| 378 | .probe = nmk_gpio_probe, | ||
| 379 | .remove = nmk_gpio_remove, | ||
| 380 | .suspend = NULL, /* to be done */ | ||
| 381 | .resume = NULL, | ||
| 382 | .id_table = nmk_gpio_ids, | ||
| 383 | }; | ||
| 384 | |||
| 385 | static int __init nmk_gpio_init(void) | ||
| 386 | { | ||
| 387 | return amba_driver_register(&nmk_gpio_driver); | ||
| 388 | } | ||
| 389 | |||
| 390 | arch_initcall(nmk_gpio_init); | ||
| 391 | |||
| 392 | MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini"); | ||
| 393 | MODULE_DESCRIPTION("Nomadik GPIO Driver"); | ||
| 394 | MODULE_LICENSE("GPL"); | ||
| 395 | |||
| 396 | |||
diff --git a/arch/arm/mach-nomadik/i2c-8815nhk.c b/arch/arm/mach-nomadik/i2c-8815nhk.c new file mode 100644 index 000000000000..abfe25a08d6b --- /dev/null +++ b/arch/arm/mach-nomadik/i2c-8815nhk.c | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | #include <linux/module.h> | ||
| 2 | #include <linux/init.h> | ||
| 3 | #include <linux/i2c.h> | ||
| 4 | #include <linux/i2c-algo-bit.h> | ||
| 5 | #include <linux/i2c-gpio.h> | ||
| 6 | #include <linux/gpio.h> | ||
| 7 | #include <linux/platform_device.h> | ||
| 8 | |||
| 9 | /* | ||
| 10 | * There are two busses in the 8815NHK. | ||
| 11 | * They could, in theory, be driven by the hardware component, but we | ||
| 12 | * use bit-bang through GPIO by now, to keep things simple | ||
| 13 | */ | ||
| 14 | |||
| 15 | static struct i2c_gpio_platform_data nhk8815_i2c_data0 = { | ||
| 16 | /* keep defaults for timeouts; pins are push-pull bidirectional */ | ||
| 17 | .scl_pin = 62, | ||
| 18 | .sda_pin = 63, | ||
| 19 | }; | ||
| 20 | |||
| 21 | static struct i2c_gpio_platform_data nhk8815_i2c_data1 = { | ||
| 22 | /* keep defaults for timeouts; pins are push-pull bidirectional */ | ||
| 23 | .scl_pin = 53, | ||
| 24 | .sda_pin = 54, | ||
| 25 | }; | ||
| 26 | |||
| 27 | /* first bus: GPIO XX and YY */ | ||
| 28 | static struct platform_device nhk8815_i2c_dev0 = { | ||
| 29 | .name = "i2c-gpio", | ||
| 30 | .id = 0, | ||
| 31 | .dev = { | ||
| 32 | .platform_data = &nhk8815_i2c_data0, | ||
| 33 | }, | ||
| 34 | }; | ||
| 35 | /* second bus: GPIO XX and YY */ | ||
| 36 | static struct platform_device nhk8815_i2c_dev1 = { | ||
| 37 | .name = "i2c-gpio", | ||
| 38 | .id = 1, | ||
| 39 | .dev = { | ||
| 40 | .platform_data = &nhk8815_i2c_data1, | ||
| 41 | }, | ||
| 42 | }; | ||
| 43 | |||
| 44 | static int __init nhk8815_i2c_init(void) | ||
| 45 | { | ||
| 46 | nmk_gpio_set_mode(nhk8815_i2c_data0.scl_pin, NMK_GPIO_ALT_GPIO); | ||
| 47 | nmk_gpio_set_mode(nhk8815_i2c_data0.sda_pin, NMK_GPIO_ALT_GPIO); | ||
| 48 | platform_device_register(&nhk8815_i2c_dev0); | ||
| 49 | |||
| 50 | nmk_gpio_set_mode(nhk8815_i2c_data1.scl_pin, NMK_GPIO_ALT_GPIO); | ||
| 51 | nmk_gpio_set_mode(nhk8815_i2c_data1.sda_pin, NMK_GPIO_ALT_GPIO); | ||
| 52 | platform_device_register(&nhk8815_i2c_dev1); | ||
| 53 | |||
| 54 | return 0; | ||
| 55 | } | ||
| 56 | |||
| 57 | static void __exit nhk8815_i2c_exit(void) | ||
| 58 | { | ||
| 59 | platform_device_unregister(&nhk8815_i2c_dev0); | ||
| 60 | platform_device_unregister(&nhk8815_i2c_dev1); | ||
| 61 | return; | ||
| 62 | } | ||
| 63 | |||
| 64 | module_init(nhk8815_i2c_init); | ||
| 65 | module_exit(nhk8815_i2c_exit); | ||
diff --git a/arch/arm/mach-nomadik/include/mach/clkdev.h b/arch/arm/mach-nomadik/include/mach/clkdev.h new file mode 100644 index 000000000000..04b37a89801c --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/clkdev.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | #ifndef __ASM_MACH_CLKDEV_H | ||
| 2 | #define __ASM_MACH_CLKDEV_H | ||
| 3 | |||
| 4 | #define __clk_get(clk) ({ 1; }) | ||
| 5 | #define __clk_put(clk) do { } while (0) | ||
| 6 | |||
| 7 | #endif | ||
diff --git a/arch/arm/mach-nomadik/include/mach/debug-macro.S b/arch/arm/mach-nomadik/include/mach/debug-macro.S new file mode 100644 index 000000000000..e876990e1569 --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/debug-macro.S | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | /* | ||
| 2 | * Debugging macro include header | ||
| 3 | * | ||
| 4 | * Copyright (C) 1994-1999 Russell King | ||
| 5 | * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | */ | ||
| 12 | |||
| 13 | .macro addruart,rx | ||
| 14 | mrc p15, 0, \rx, c1, c0 | ||
| 15 | tst \rx, #1 @ MMU enabled? | ||
| 16 | moveq \rx, #0x10000000 @ physical base address | ||
| 17 | movne \rx, #0xf0000000 @ virtual base | ||
| 18 | add \rx, \rx, #0x00100000 | ||
| 19 | add \rx, \rx, #0x000fb000 | ||
| 20 | .endm | ||
| 21 | |||
| 22 | #include <asm/hardware/debug-pl01x.S> | ||
diff --git a/arch/arm/mach-nomadik/include/mach/entry-macro.S b/arch/arm/mach-nomadik/include/mach/entry-macro.S new file mode 100644 index 000000000000..49f1aa3bb420 --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/entry-macro.S | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | /* | ||
| 2 | * Low-level IRQ helper macros for Nomadik platforms | ||
| 3 | * | ||
| 4 | * This file is licensed under the terms of the GNU General Public | ||
| 5 | * License version 2. This program is licensed "as is" without any | ||
| 6 | * warranty of any kind, whether express or implied. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <mach/hardware.h> | ||
| 10 | #include <mach/irqs.h> | ||
| 11 | |||
| 12 | .macro disable_fiq | ||
| 13 | .endm | ||
| 14 | |||
| 15 | .macro get_irqnr_preamble, base, tmp | ||
| 16 | ldr \base, =IO_ADDRESS(NOMADIK_IC_BASE) | ||
| 17 | .endm | ||
| 18 | |||
| 19 | .macro arch_ret_to_user, tmp1, tmp2 | ||
| 20 | .endm | ||
| 21 | |||
| 22 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
| 23 | |||
| 24 | /* This stanza gets the irq mask from one of two status registers */ | ||
| 25 | mov \irqnr, #0 | ||
| 26 | ldr \irqstat, [\base, #VIC_REG_IRQSR0] @ get masked status | ||
| 27 | cmp \irqstat, #0 | ||
| 28 | bne 1001f | ||
| 29 | add \irqnr, \irqnr, #32 | ||
| 30 | ldr \irqstat, [\base, #VIC_REG_IRQSR1] @ get masked status | ||
| 31 | |||
| 32 | 1001: tst \irqstat, #15 | ||
| 33 | bne 1002f | ||
| 34 | add \irqnr, \irqnr, #4 | ||
| 35 | movs \irqstat, \irqstat, lsr #4 | ||
| 36 | bne 1001b | ||
| 37 | 1002: tst \irqstat, #1 | ||
| 38 | bne 1003f | ||
| 39 | add \irqnr, \irqnr, #1 | ||
| 40 | movs \irqstat, \irqstat, lsr #1 | ||
| 41 | bne 1002b | ||
| 42 | 1003: /* EQ will be set if no irqs pending */ | ||
| 43 | .endm | ||
diff --git a/arch/arm/mach-nomadik/include/mach/gpio.h b/arch/arm/mach-nomadik/include/mach/gpio.h new file mode 100644 index 000000000000..61577c9f9a7d --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/gpio.h | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | /* | ||
| 2 | * Structures and registers for GPIO access in the Nomadik SoC | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 STMicroelectronics | ||
| 5 | * Author: Prafulla WADASKAR <prafulla.wadaskar@st.com> | ||
| 6 | * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | #ifndef __ASM_ARCH_GPIO_H | ||
| 13 | #define __ASM_ARCH_GPIO_H | ||
| 14 | |||
| 15 | #include <asm-generic/gpio.h> | ||
| 16 | |||
| 17 | /* | ||
| 18 | * These currently cause a function call to happen, they may be optimized | ||
| 19 | * if needed by adding cpu-specific defines to identify blocks | ||
| 20 | * (see mach-pxa/include/mach/gpio.h as an example using GPLR etc) | ||
| 21 | */ | ||
| 22 | #define gpio_get_value __gpio_get_value | ||
| 23 | #define gpio_set_value __gpio_set_value | ||
| 24 | #define gpio_cansleep __gpio_cansleep | ||
| 25 | #define gpio_to_irq __gpio_to_irq | ||
| 26 | |||
| 27 | /* | ||
| 28 | * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving | ||
| 29 | * the "gpio" namespace for generic and cross-machine functions | ||
| 30 | */ | ||
| 31 | |||
| 32 | /* Register in the logic block */ | ||
| 33 | #define NMK_GPIO_DAT 0x00 | ||
| 34 | #define NMK_GPIO_DATS 0x04 | ||
| 35 | #define NMK_GPIO_DATC 0x08 | ||
| 36 | #define NMK_GPIO_PDIS 0x0c | ||
| 37 | #define NMK_GPIO_DIR 0x10 | ||
| 38 | #define NMK_GPIO_DIRS 0x14 | ||
| 39 | #define NMK_GPIO_DIRC 0x18 | ||
| 40 | #define NMK_GPIO_SLPC 0x1c | ||
| 41 | #define NMK_GPIO_AFSLA 0x20 | ||
| 42 | #define NMK_GPIO_AFSLB 0x24 | ||
| 43 | |||
| 44 | #define NMK_GPIO_RIMSC 0x40 | ||
| 45 | #define NMK_GPIO_FIMSC 0x44 | ||
| 46 | #define NMK_GPIO_IS 0x48 | ||
| 47 | #define NMK_GPIO_IC 0x4c | ||
| 48 | #define NMK_GPIO_RWIMSC 0x50 | ||
| 49 | #define NMK_GPIO_FWIMSC 0x54 | ||
| 50 | #define NMK_GPIO_WKS 0x58 | ||
| 51 | |||
| 52 | /* Alternate functions: function C is set in hw by setting both A and B */ | ||
| 53 | #define NMK_GPIO_ALT_GPIO 0 | ||
| 54 | #define NMK_GPIO_ALT_A 1 | ||
| 55 | #define NMK_GPIO_ALT_B 2 | ||
| 56 | #define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B) | ||
| 57 | |||
| 58 | extern int nmk_gpio_set_mode(int gpio, int gpio_mode); | ||
| 59 | extern int nmk_gpio_get_mode(int gpio); | ||
| 60 | |||
| 61 | /* | ||
| 62 | * Platform data to register a block: only the initial gpio/irq number. | ||
| 63 | */ | ||
| 64 | struct nmk_gpio_platform_data { | ||
| 65 | char *name; | ||
| 66 | int first_gpio; | ||
| 67 | int first_irq; | ||
| 68 | int parent_irq; | ||
| 69 | }; | ||
| 70 | |||
| 71 | #endif /* __ASM_ARCH_GPIO_H */ | ||
diff --git a/arch/arm/mach-nomadik/include/mach/hardware.h b/arch/arm/mach-nomadik/include/mach/hardware.h new file mode 100644 index 000000000000..6316dba3bfc8 --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/hardware.h | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | /* | ||
| 2 | * This file contains the hardware definitions of the Nomadik. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * YOU should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 17 | */ | ||
| 18 | #ifndef __ASM_ARCH_HARDWARE_H | ||
| 19 | #define __ASM_ARCH_HARDWARE_H | ||
| 20 | |||
| 21 | /* Nomadik registers live from 0x1000.0000 to 0x1023.0000 -- currently */ | ||
| 22 | #define NOMADIK_IO_VIRTUAL 0xF0000000 /* VA of IO */ | ||
| 23 | #define NOMADIK_IO_PHYSICAL 0x10000000 /* PA of IO */ | ||
| 24 | #define NOMADIK_IO_SIZE 0x00300000 /* 3MB for all regs */ | ||
| 25 | |||
| 26 | /* used in C code, so cast to proper type */ | ||
| 27 | #define io_p2v(x) ((void __iomem *)(x) \ | ||
| 28 | - NOMADIK_IO_PHYSICAL + NOMADIK_IO_VIRTUAL) | ||
| 29 | #define io_v2p(x) ((unsigned long)(x) \ | ||
| 30 | - NOMADIK_IO_VIRTUAL + NOMADIK_IO_PHYSICAL) | ||
| 31 | |||
| 32 | /* used in asm code, so no casts */ | ||
| 33 | #define IO_ADDRESS(x) ((x) - NOMADIK_IO_PHYSICAL + NOMADIK_IO_VIRTUAL) | ||
| 34 | |||
| 35 | /* | ||
| 36 | * Base address defination for Nomadik Onchip Logic Block | ||
| 37 | */ | ||
| 38 | #define NOMADIK_FSMC_BASE 0x10100000 /* FSMC registers */ | ||
| 39 | #define NOMADIK_SDRAMC_BASE 0x10110000 /* SDRAM Controller */ | ||
| 40 | #define NOMADIK_CLCDC_BASE 0x10120000 /* CLCD Controller */ | ||
| 41 | #define NOMADIK_MDIF_BASE 0x10120000 /* MDIF */ | ||
| 42 | #define NOMADIK_DMA0_BASE 0x10130000 /* DMA0 Controller */ | ||
| 43 | #define NOMADIK_IC_BASE 0x10140000 /* Vectored Irq Controller */ | ||
| 44 | #define NOMADIK_DMA1_BASE 0x10150000 /* DMA1 Controller */ | ||
| 45 | #define NOMADIK_USB_BASE 0x10170000 /* USB-OTG conf reg base */ | ||
| 46 | #define NOMADIK_CRYP_BASE 0x10180000 /* Crypto processor */ | ||
| 47 | #define NOMADIK_SHA1_BASE 0x10190000 /* SHA-1 Processor */ | ||
| 48 | #define NOMADIK_XTI_BASE 0x101A0000 /* XTI */ | ||
| 49 | #define NOMADIK_RNG_BASE 0x101B0000 /* Random number generator */ | ||
| 50 | #define NOMADIK_SRC_BASE 0x101E0000 /* SRC base */ | ||
| 51 | #define NOMADIK_WDOG_BASE 0x101E1000 /* Watchdog */ | ||
| 52 | #define NOMADIK_MTU0_BASE 0x101E2000 /* Multiple Timer 0 */ | ||
| 53 | #define NOMADIK_MTU1_BASE 0x101E3000 /* Multiple Timer 1 */ | ||
| 54 | #define NOMADIK_GPIO0_BASE 0x101E4000 /* GPIO0 */ | ||
| 55 | #define NOMADIK_GPIO1_BASE 0x101E5000 /* GPIO1 */ | ||
| 56 | #define NOMADIK_GPIO2_BASE 0x101E6000 /* GPIO2 */ | ||
| 57 | #define NOMADIK_GPIO3_BASE 0x101E7000 /* GPIO3 */ | ||
| 58 | #define NOMADIK_RTC_BASE 0x101E8000 /* Real Time Clock base */ | ||
| 59 | #define NOMADIK_PMU_BASE 0x101E9000 /* Power Management Unit */ | ||
| 60 | #define NOMADIK_OWM_BASE 0x101EA000 /* One wire master */ | ||
| 61 | #define NOMADIK_SCR_BASE 0x101EF000 /* Secure Control registers */ | ||
| 62 | #define NOMADIK_MSP2_BASE 0x101F0000 /* MSP 2 interface */ | ||
| 63 | #define NOMADIK_MSP1_BASE 0x101F1000 /* MSP 1 interface */ | ||
| 64 | #define NOMADIK_UART2_BASE 0x101F2000 /* UART 2 interface */ | ||
| 65 | #define NOMADIK_SSIRx_BASE 0x101F3000 /* SSI 8-ch rx interface */ | ||
| 66 | #define NOMADIK_SSITx_BASE 0x101F4000 /* SSI 8-ch tx interface */ | ||
| 67 | #define NOMADIK_MSHC_BASE 0x101F5000 /* Memory Stick(Pro) Host */ | ||
| 68 | #define NOMADIK_SDI_BASE 0x101F6000 /* SD-card/MM-Card */ | ||
| 69 | #define NOMADIK_I2C1_BASE 0x101F7000 /* I2C1 interface */ | ||
| 70 | #define NOMADIK_I2C0_BASE 0x101F8000 /* I2C0 interface */ | ||
| 71 | #define NOMADIK_MSP0_BASE 0x101F9000 /* MSP 0 interface */ | ||
| 72 | #define NOMADIK_FIRDA_BASE 0x101FA000 /* FIrDA interface */ | ||
| 73 | #define NOMADIK_UART1_BASE 0x101FB000 /* UART 1 interface */ | ||
| 74 | #define NOMADIK_SSP_BASE 0x101FC000 /* SSP interface */ | ||
| 75 | #define NOMADIK_UART0_BASE 0x101FD000 /* UART 0 interface */ | ||
| 76 | #define NOMADIK_SGA_BASE 0x101FE000 /* SGA interface */ | ||
| 77 | #define NOMADIK_L2CC_BASE 0x10210000 /* L2 Cache controller */ | ||
| 78 | |||
| 79 | /* Other ranges, not for p2v/v2p */ | ||
| 80 | #define NOMADIK_BACKUP_RAM 0x80010000 | ||
| 81 | #define NOMADIK_EBROM 0x80000000 /* Embedded boot ROM */ | ||
| 82 | #define NOMADIK_HAMACV_DMEM_BASE 0xA0100000 /* HAMACV Data Memory Start */ | ||
| 83 | #define NOMADIK_HAMACV_DMEM_END 0xA01FFFFF /* HAMACV Data Memory End */ | ||
| 84 | #define NOMADIK_HAMACA_DMEM 0xA0200000 /* HAMACA Data Memory Space */ | ||
| 85 | |||
| 86 | #define NOMADIK_FSMC_VA IO_ADDRESS(NOMADIK_FSMC_BASE) | ||
| 87 | #define NOMADIK_MTU0_VA IO_ADDRESS(NOMADIK_MTU0_BASE) | ||
| 88 | #define NOMADIK_MTU1_VA IO_ADDRESS(NOMADIK_MTU1_BASE) | ||
| 89 | |||
| 90 | #endif /* __ASM_ARCH_HARDWARE_H */ | ||
diff --git a/arch/arm/mach-nomadik/include/mach/io.h b/arch/arm/mach-nomadik/include/mach/io.h new file mode 100644 index 000000000000..2e1eca1b8243 --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/io.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/mach-nomadik/include/mach/io.h (copied from mach-sa1100) | ||
| 3 | * | ||
| 4 | * Copyright (C) 1997-1999 Russell King | ||
| 5 | * | ||
| 6 | * Modifications: | ||
| 7 | * 06-12-1997 RMK Created. | ||
| 8 | * 07-04-1999 RMK Major cleanup | ||
| 9 | */ | ||
| 10 | #ifndef __ASM_ARM_ARCH_IO_H | ||
| 11 | #define __ASM_ARM_ARCH_IO_H | ||
| 12 | |||
| 13 | #define IO_SPACE_LIMIT 0xffffffff | ||
| 14 | |||
| 15 | /* | ||
| 16 | * We don't actually have real ISA nor PCI buses, but there is so many | ||
| 17 | * drivers out there that might just work if we fake them... | ||
| 18 | */ | ||
| 19 | #define __io(a) __typesafe_io(a) | ||
| 20 | #define __mem_pci(a) (a) | ||
| 21 | |||
| 22 | #endif | ||
diff --git a/arch/arm/mach-nomadik/include/mach/irqs.h b/arch/arm/mach-nomadik/include/mach/irqs.h new file mode 100644 index 000000000000..8faabc560398 --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/irqs.h | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | /* | ||
| 2 | * mach-nomadik/include/mach/irqs.h | ||
| 3 | * | ||
| 4 | * Copyright (C) ST Microelectronics | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | */ | ||
| 20 | #ifndef __ASM_ARCH_IRQS_H | ||
| 21 | #define __ASM_ARCH_IRQS_H | ||
| 22 | |||
| 23 | #include <mach/hardware.h> | ||
| 24 | |||
| 25 | #define IRQ_VIC_START 0 /* first VIC interrupt is 0 */ | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Interrupt numbers generic for all Nomadik Chip cuts | ||
| 29 | */ | ||
| 30 | #define IRQ_WATCHDOG 0 | ||
| 31 | #define IRQ_SOFTINT 1 | ||
| 32 | #define IRQ_CRYPTO 2 | ||
| 33 | #define IRQ_OWM 3 | ||
| 34 | #define IRQ_MTU0 4 | ||
| 35 | #define IRQ_MTU1 5 | ||
| 36 | #define IRQ_GPIO0 6 | ||
| 37 | #define IRQ_GPIO1 7 | ||
| 38 | #define IRQ_GPIO2 8 | ||
| 39 | #define IRQ_GPIO3 9 | ||
| 40 | #define IRQ_RTC_RTT 10 | ||
| 41 | #define IRQ_SSP 11 | ||
| 42 | #define IRQ_UART0 12 | ||
| 43 | #define IRQ_DMA1 13 | ||
| 44 | #define IRQ_CLCD_MDIF 14 | ||
| 45 | #define IRQ_DMA0 15 | ||
| 46 | #define IRQ_PWRFAIL 16 | ||
| 47 | #define IRQ_UART1 17 | ||
| 48 | #define IRQ_FIRDA 18 | ||
| 49 | #define IRQ_MSP0 19 | ||
| 50 | #define IRQ_I2C0 20 | ||
| 51 | #define IRQ_I2C1 21 | ||
| 52 | #define IRQ_SDMMC 22 | ||
| 53 | #define IRQ_USBOTG 23 | ||
| 54 | #define IRQ_SVA_IT0 24 | ||
| 55 | #define IRQ_SVA_IT1 25 | ||
| 56 | #define IRQ_SAA_IT0 26 | ||
| 57 | #define IRQ_SAA_IT1 27 | ||
| 58 | #define IRQ_UART2 28 | ||
| 59 | #define IRQ_MSP2 31 | ||
| 60 | #define IRQ_L2CC 48 | ||
| 61 | #define IRQ_HPI 49 | ||
| 62 | #define IRQ_SKE 50 | ||
| 63 | #define IRQ_KP 51 | ||
| 64 | #define IRQ_MEMST 54 | ||
| 65 | #define IRQ_SGA_IT 58 | ||
| 66 | #define IRQ_USBM 60 | ||
| 67 | #define IRQ_MSP1 62 | ||
| 68 | |||
| 69 | #define NOMADIK_SOC_NR_IRQS 64 | ||
| 70 | |||
| 71 | /* After chip-specific IRQ numbers we have the GPIO ones */ | ||
| 72 | #define NOMADIK_NR_GPIO 128 /* last 4 not wired to pins */ | ||
| 73 | #define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + NOMADIK_SOC_NR_IRQS) | ||
| 74 | #define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - NOMADIK_SOC_NR_IRQS) | ||
| 75 | #define NR_IRQS NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO) | ||
| 76 | |||
| 77 | /* Following two are used by entry_macro.S, to access our dual-vic */ | ||
| 78 | #define VIC_REG_IRQSR0 0 | ||
| 79 | #define VIC_REG_IRQSR1 0x20 | ||
| 80 | |||
| 81 | #endif /* __ASM_ARCH_IRQS_H */ | ||
| 82 | |||
diff --git a/arch/arm/mach-nomadik/include/mach/memory.h b/arch/arm/mach-nomadik/include/mach/memory.h new file mode 100644 index 000000000000..1e5689d98ecd --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/memory.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* | ||
| 2 | * mach-nomadik/include/mach/memory.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 1999 ARM Limited | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | */ | ||
| 20 | #ifndef __ASM_ARCH_MEMORY_H | ||
| 21 | #define __ASM_ARCH_MEMORY_H | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Physical DRAM offset. | ||
| 25 | */ | ||
| 26 | #define PHYS_OFFSET UL(0x00000000) | ||
| 27 | |||
| 28 | #endif | ||
diff --git a/arch/arm/mach-nomadik/include/mach/mtu.h b/arch/arm/mach-nomadik/include/mach/mtu.h new file mode 100644 index 000000000000..76da7f085330 --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/mtu.h | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | #ifndef __ASM_ARCH_MTU_H | ||
| 2 | #define __ASM_ARCH_MTU_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * The MTU device hosts four different counters, with 4 set of | ||
| 6 | * registers. These are register names. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #define MTU_IMSC 0x00 /* Interrupt mask set/clear */ | ||
| 10 | #define MTU_RIS 0x04 /* Raw interrupt status */ | ||
| 11 | #define MTU_MIS 0x08 /* Masked interrupt status */ | ||
| 12 | #define MTU_ICR 0x0C /* Interrupt clear register */ | ||
| 13 | |||
| 14 | /* per-timer registers take 0..3 as argument */ | ||
| 15 | #define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */ | ||
| 16 | #define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */ | ||
| 17 | #define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */ | ||
| 18 | #define MTU_BGLR(x) (0x10 + 0x10 * (x) + 0x0c) /* At next overflow */ | ||
| 19 | |||
| 20 | /* bits for the control register */ | ||
| 21 | #define MTU_CRn_ENA 0x80 | ||
| 22 | #define MTU_CRn_PERIODIC 0x40 /* if 0 = free-running */ | ||
| 23 | #define MTU_CRn_PRESCALE_MASK 0x0c | ||
| 24 | #define MTU_CRn_PRESCALE_1 0x00 | ||
| 25 | #define MTU_CRn_PRESCALE_16 0x04 | ||
| 26 | #define MTU_CRn_PRESCALE_256 0x08 | ||
| 27 | #define MTU_CRn_32BITS 0x02 | ||
| 28 | #define MTU_CRn_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR*/ | ||
| 29 | |||
| 30 | /* Other registers are usual amba/primecell registers, currently not used */ | ||
| 31 | #define MTU_ITCR 0xff0 | ||
| 32 | #define MTU_ITOP 0xff4 | ||
| 33 | |||
| 34 | #define MTU_PERIPH_ID0 0xfe0 | ||
| 35 | #define MTU_PERIPH_ID1 0xfe4 | ||
| 36 | #define MTU_PERIPH_ID2 0xfe8 | ||
| 37 | #define MTU_PERIPH_ID3 0xfeC | ||
| 38 | |||
| 39 | #define MTU_PCELL0 0xff0 | ||
| 40 | #define MTU_PCELL1 0xff4 | ||
| 41 | #define MTU_PCELL2 0xff8 | ||
| 42 | #define MTU_PCELL3 0xffC | ||
| 43 | |||
| 44 | #endif /* __ASM_ARCH_MTU_H */ | ||
| 45 | |||
diff --git a/arch/arm/mach-nomadik/include/mach/setup.h b/arch/arm/mach-nomadik/include/mach/setup.h new file mode 100644 index 000000000000..a4e468cf63da --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/setup.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | |||
| 2 | /* | ||
| 3 | * These symbols are needed for board-specific files to call their | ||
| 4 | * own cpu-specific files | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef __ASM_ARCH_SETUP_H | ||
| 8 | #define __ASM_ARCH_SETUP_H | ||
| 9 | |||
| 10 | #include <asm/mach/time.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | |||
| 13 | #ifdef CONFIG_NOMADIK_8815 | ||
| 14 | |||
| 15 | extern void cpu8815_map_io(void); | ||
| 16 | extern void cpu8815_platform_init(void); | ||
| 17 | extern void cpu8815_init_irq(void); | ||
| 18 | extern struct sys_timer nomadik_timer; | ||
| 19 | |||
| 20 | #endif /* NOMADIK_8815 */ | ||
| 21 | |||
| 22 | #endif /* __ASM_ARCH_SETUP_H */ | ||
diff --git a/arch/arm/mach-nomadik/include/mach/system.h b/arch/arm/mach-nomadik/include/mach/system.h new file mode 100644 index 000000000000..7119f688116e --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/system.h | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | /* | ||
| 2 | * mach-nomadik/include/mach/system.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 STMicroelectronics | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | */ | ||
| 20 | #ifndef __ASM_ARCH_SYSTEM_H | ||
| 21 | #define __ASM_ARCH_SYSTEM_H | ||
| 22 | |||
| 23 | #include <linux/io.h> | ||
| 24 | #include <mach/hardware.h> | ||
| 25 | |||
| 26 | static inline void arch_idle(void) | ||
| 27 | { | ||
| 28 | /* | ||
| 29 | * This should do all the clock switching | ||
| 30 | * and wait for interrupt tricks | ||
| 31 | */ | ||
| 32 | cpu_do_idle(); | ||
| 33 | } | ||
| 34 | |||
| 35 | static inline void arch_reset(char mode, const char *cmd) | ||
| 36 | { | ||
| 37 | void __iomem *src_rstsr = io_p2v(NOMADIK_SRC_BASE + 0x18); | ||
| 38 | |||
| 39 | /* FIXME: use egpio when implemented */ | ||
| 40 | |||
| 41 | /* Write anything to Reset status register */ | ||
| 42 | writel(1, src_rstsr); | ||
| 43 | } | ||
| 44 | |||
| 45 | #endif | ||
diff --git a/arch/arm/mach-nomadik/include/mach/timex.h b/arch/arm/mach-nomadik/include/mach/timex.h new file mode 100644 index 000000000000..318b8896ce96 --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/timex.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #ifndef __ASM_ARCH_TIMEX_H | ||
| 2 | #define __ASM_ARCH_TIMEX_H | ||
| 3 | |||
| 4 | #define CLOCK_TICK_RATE 2400000 | ||
| 5 | |||
| 6 | #endif | ||
diff --git a/arch/arm/mach-nomadik/include/mach/uncompress.h b/arch/arm/mach-nomadik/include/mach/uncompress.h new file mode 100644 index 000000000000..071003bc8456 --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/uncompress.h | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008 STMicroelectronics | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef __ASM_ARCH_UNCOMPRESS_H | ||
| 20 | #define __ASM_ARCH_UNCOMPRESS_H | ||
| 21 | |||
| 22 | #include <asm/setup.h> | ||
| 23 | #include <asm/io.h> | ||
| 24 | #include <mach/hardware.h> | ||
| 25 | |||
| 26 | /* we need the constants in amba/serial.h, but it refers to amba_device */ | ||
| 27 | struct amba_device; | ||
| 28 | #include <linux/amba/serial.h> | ||
| 29 | |||
| 30 | #define NOMADIK_UART_DR 0x101FB000 | ||
| 31 | #define NOMADIK_UART_LCRH 0x101FB02c | ||
| 32 | #define NOMADIK_UART_CR 0x101FB030 | ||
| 33 | #define NOMADIK_UART_FR 0x101FB018 | ||
| 34 | |||
| 35 | static void putc(const char c) | ||
| 36 | { | ||
| 37 | /* Do nothing if the UART is not enabled. */ | ||
| 38 | if (!(readb(NOMADIK_UART_CR) & UART01x_CR_UARTEN)) | ||
| 39 | return; | ||
| 40 | |||
| 41 | if (c == '\n') | ||
| 42 | putc('\r'); | ||
| 43 | |||
| 44 | while (readb(NOMADIK_UART_FR) & UART01x_FR_TXFF) | ||
| 45 | barrier(); | ||
| 46 | writeb(c, NOMADIK_UART_DR); | ||
| 47 | } | ||
| 48 | |||
| 49 | static void flush(void) | ||
| 50 | { | ||
| 51 | if (!(readb(NOMADIK_UART_CR) & UART01x_CR_UARTEN)) | ||
| 52 | return; | ||
| 53 | while (readb(NOMADIK_UART_FR) & UART01x_FR_BUSY) | ||
| 54 | barrier(); | ||
| 55 | } | ||
| 56 | |||
| 57 | static inline void arch_decomp_setup(void) | ||
| 58 | { | ||
| 59 | } | ||
| 60 | |||
| 61 | #define arch_decomp_wdog() /* nothing to do here */ | ||
| 62 | |||
| 63 | #endif /* __ASM_ARCH_UNCOMPRESS_H */ | ||
diff --git a/arch/arm/mach-nomadik/include/mach/vmalloc.h b/arch/arm/mach-nomadik/include/mach/vmalloc.h new file mode 100644 index 000000000000..be12e31ea528 --- /dev/null +++ b/arch/arm/mach-nomadik/include/mach/vmalloc.h | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | |||
| 2 | #define VMALLOC_END 0xe8000000 | ||
diff --git a/arch/arm/mach-nomadik/timer.c b/arch/arm/mach-nomadik/timer.c new file mode 100644 index 000000000000..d1738e7061d4 --- /dev/null +++ b/arch/arm/mach-nomadik/timer.c | |||
| @@ -0,0 +1,164 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-nomadik/timer.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 STMicroelectronics | ||
| 5 | * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2, as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/interrupt.h> | ||
| 13 | #include <linux/irq.h> | ||
| 14 | #include <linux/io.h> | ||
| 15 | #include <linux/clockchips.h> | ||
| 16 | #include <linux/jiffies.h> | ||
| 17 | #include <asm/mach/time.h> | ||
| 18 | #include <mach/mtu.h> | ||
| 19 | |||
| 20 | #define TIMER_CTRL 0x80 /* No divisor */ | ||
| 21 | #define TIMER_PERIODIC 0x40 | ||
| 22 | #define TIMER_SZ32BIT 0x02 | ||
| 23 | |||
| 24 | /* Initial value for SRC control register: all timers use MXTAL/8 source */ | ||
| 25 | #define SRC_CR_INIT_MASK 0x00007fff | ||
| 26 | #define SRC_CR_INIT_VAL 0x2aaa8000 | ||
| 27 | |||
| 28 | static u32 nmdk_count; /* accumulated count */ | ||
| 29 | static u32 nmdk_cycle; /* write-once */ | ||
| 30 | static __iomem void *mtu_base; | ||
| 31 | |||
| 32 | /* | ||
| 33 | * clocksource: the MTU device is a decrementing counters, so we negate | ||
| 34 | * the value being read. | ||
| 35 | */ | ||
| 36 | static cycle_t nmdk_read_timer(struct clocksource *cs) | ||
| 37 | { | ||
| 38 | u32 count = readl(mtu_base + MTU_VAL(0)); | ||
| 39 | return nmdk_count + nmdk_cycle - count; | ||
| 40 | |||
| 41 | } | ||
| 42 | |||
| 43 | static struct clocksource nmdk_clksrc = { | ||
| 44 | .name = "mtu_0", | ||
| 45 | .rating = 120, | ||
| 46 | .read = nmdk_read_timer, | ||
| 47 | .shift = 20, | ||
| 48 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
| 49 | }; | ||
| 50 | |||
| 51 | /* | ||
| 52 | * Clockevent device: currently only periodic mode is supported | ||
| 53 | */ | ||
| 54 | static void nmdk_clkevt_mode(enum clock_event_mode mode, | ||
| 55 | struct clock_event_device *dev) | ||
| 56 | { | ||
| 57 | unsigned long flags; | ||
| 58 | |||
| 59 | switch (mode) { | ||
| 60 | case CLOCK_EVT_MODE_PERIODIC: | ||
| 61 | /* enable interrupts -- and count current value? */ | ||
| 62 | raw_local_irq_save(flags); | ||
| 63 | writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC); | ||
| 64 | raw_local_irq_restore(flags); | ||
| 65 | break; | ||
| 66 | case CLOCK_EVT_MODE_ONESHOT: | ||
| 67 | BUG(); /* Not supported, yet */ | ||
| 68 | /* FALLTHROUGH */ | ||
| 69 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
| 70 | case CLOCK_EVT_MODE_UNUSED: | ||
| 71 | /* disable irq */ | ||
| 72 | raw_local_irq_save(flags); | ||
| 73 | writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC); | ||
| 74 | raw_local_irq_restore(flags); | ||
| 75 | break; | ||
| 76 | case CLOCK_EVT_MODE_RESUME: | ||
| 77 | break; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | static struct clock_event_device nmdk_clkevt = { | ||
| 82 | .name = "mtu_0", | ||
| 83 | .features = CLOCK_EVT_FEAT_PERIODIC, | ||
| 84 | .shift = 32, | ||
| 85 | .rating = 100, | ||
| 86 | .set_mode = nmdk_clkevt_mode, | ||
| 87 | }; | ||
| 88 | |||
| 89 | /* | ||
| 90 | * IRQ Handler for the timer 0 of the MTU block. The irq is not shared | ||
| 91 | * as we are the only users of mtu0 by now. | ||
| 92 | */ | ||
| 93 | static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id) | ||
| 94 | { | ||
| 95 | /* ack: "interrupt clear register" */ | ||
| 96 | writel( 1 << 0, mtu_base + MTU_ICR); | ||
| 97 | |||
| 98 | /* we can't count lost ticks, unfortunately */ | ||
| 99 | nmdk_count += nmdk_cycle; | ||
| 100 | nmdk_clkevt.event_handler(&nmdk_clkevt); | ||
| 101 | |||
| 102 | return IRQ_HANDLED; | ||
| 103 | } | ||
| 104 | |||
| 105 | /* | ||
| 106 | * Set up timer interrupt, and return the current time in seconds. | ||
| 107 | */ | ||
| 108 | static struct irqaction nmdk_timer_irq = { | ||
| 109 | .name = "Nomadik Timer Tick", | ||
| 110 | .flags = IRQF_DISABLED | IRQF_TIMER, | ||
| 111 | .handler = nmdk_timer_interrupt, | ||
| 112 | }; | ||
| 113 | |||
| 114 | static void nmdk_timer_reset(void) | ||
| 115 | { | ||
| 116 | u32 cr; | ||
| 117 | |||
| 118 | writel(0, mtu_base + MTU_CR(0)); /* off */ | ||
| 119 | |||
| 120 | /* configure load and background-load, and fire it up */ | ||
| 121 | writel(nmdk_cycle, mtu_base + MTU_LR(0)); | ||
| 122 | writel(nmdk_cycle, mtu_base + MTU_BGLR(0)); | ||
| 123 | cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS; | ||
| 124 | writel(cr, mtu_base + MTU_CR(0)); | ||
| 125 | writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); | ||
| 126 | } | ||
| 127 | |||
| 128 | static void __init nmdk_timer_init(void) | ||
| 129 | { | ||
| 130 | u32 src_cr; | ||
| 131 | unsigned long rate; | ||
| 132 | int bits; | ||
| 133 | |||
| 134 | rate = CLOCK_TICK_RATE; /* 2.4MHz */ | ||
| 135 | nmdk_cycle = (rate + HZ/2) / HZ; | ||
| 136 | |||
| 137 | /* Configure timer sources in "system reset controller" ctrl reg */ | ||
| 138 | src_cr = readl(io_p2v(NOMADIK_SRC_BASE)); | ||
| 139 | src_cr &= SRC_CR_INIT_MASK; | ||
| 140 | src_cr |= SRC_CR_INIT_VAL; | ||
| 141 | writel(src_cr, io_p2v(NOMADIK_SRC_BASE)); | ||
| 142 | |||
| 143 | /* Save global pointer to mtu, used by functions above */ | ||
| 144 | mtu_base = io_p2v(NOMADIK_MTU0_BASE); | ||
| 145 | |||
| 146 | /* Init the timer and register clocksource */ | ||
| 147 | nmdk_timer_reset(); | ||
| 148 | |||
| 149 | nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift); | ||
| 150 | bits = 8*sizeof(nmdk_count); | ||
| 151 | nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits); | ||
| 152 | |||
| 153 | clocksource_register(&nmdk_clksrc); | ||
| 154 | |||
| 155 | /* Register irq and clockevents */ | ||
| 156 | setup_irq(IRQ_MTU0, &nmdk_timer_irq); | ||
| 157 | nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift); | ||
| 158 | nmdk_clkevt.cpumask = cpumask_of(0); | ||
| 159 | clockevents_register_device(&nmdk_clkevt); | ||
| 160 | } | ||
| 161 | |||
| 162 | struct sys_timer nomadik_timer = { | ||
| 163 | .init = nmdk_timer_init, | ||
| 164 | }; | ||
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index b0c7402248f7..1b223076ceb7 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c | |||
| @@ -39,7 +39,7 @@ static struct platform_device *sdp4430_devices[] __initdata = { | |||
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | static struct omap_uart_config sdp4430_uart_config __initdata = { | 41 | static struct omap_uart_config sdp4430_uart_config __initdata = { |
| 42 | .enabled_uarts = (1 << 0) | (1 << 1) | (1 << 2), | 42 | .enabled_uarts = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3), |
| 43 | }; | 43 | }; |
| 44 | 44 | ||
| 45 | static struct omap_lcd_config sdp4430_lcd_config __initdata = { | 45 | static struct omap_lcd_config sdp4430_lcd_config __initdata = { |
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index 99b6e1546311..a846aa1ebb4d 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c | |||
| @@ -128,6 +128,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | |||
| 128 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | 128 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, |
| 129 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | 129 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, |
| 130 | .ops = &omap2_mcbsp_ops, | 130 | .ops = &omap2_mcbsp_ops, |
| 131 | .buffer_size = 0x6F, | ||
| 131 | }, | 132 | }, |
| 132 | { | 133 | { |
| 133 | .phys_base = OMAP34XX_MCBSP2_BASE, | 134 | .phys_base = OMAP34XX_MCBSP2_BASE, |
| @@ -136,6 +137,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | |||
| 136 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | 137 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, |
| 137 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | 138 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, |
| 138 | .ops = &omap2_mcbsp_ops, | 139 | .ops = &omap2_mcbsp_ops, |
| 140 | .buffer_size = 0x3FF, | ||
| 139 | }, | 141 | }, |
| 140 | { | 142 | { |
| 141 | .phys_base = OMAP34XX_MCBSP3_BASE, | 143 | .phys_base = OMAP34XX_MCBSP3_BASE, |
| @@ -144,6 +146,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | |||
| 144 | .rx_irq = INT_24XX_MCBSP3_IRQ_RX, | 146 | .rx_irq = INT_24XX_MCBSP3_IRQ_RX, |
| 145 | .tx_irq = INT_24XX_MCBSP3_IRQ_TX, | 147 | .tx_irq = INT_24XX_MCBSP3_IRQ_TX, |
| 146 | .ops = &omap2_mcbsp_ops, | 148 | .ops = &omap2_mcbsp_ops, |
| 149 | .buffer_size = 0x6F, | ||
| 147 | }, | 150 | }, |
| 148 | { | 151 | { |
| 149 | .phys_base = OMAP34XX_MCBSP4_BASE, | 152 | .phys_base = OMAP34XX_MCBSP4_BASE, |
| @@ -152,6 +155,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | |||
| 152 | .rx_irq = INT_24XX_MCBSP4_IRQ_RX, | 155 | .rx_irq = INT_24XX_MCBSP4_IRQ_RX, |
| 153 | .tx_irq = INT_24XX_MCBSP4_IRQ_TX, | 156 | .tx_irq = INT_24XX_MCBSP4_IRQ_TX, |
| 154 | .ops = &omap2_mcbsp_ops, | 157 | .ops = &omap2_mcbsp_ops, |
| 158 | .buffer_size = 0x6F, | ||
| 155 | }, | 159 | }, |
| 156 | { | 160 | { |
| 157 | .phys_base = OMAP34XX_MCBSP5_BASE, | 161 | .phys_base = OMAP34XX_MCBSP5_BASE, |
| @@ -160,6 +164,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | |||
| 160 | .rx_irq = INT_24XX_MCBSP5_IRQ_RX, | 164 | .rx_irq = INT_24XX_MCBSP5_IRQ_RX, |
| 161 | .tx_irq = INT_24XX_MCBSP5_IRQ_TX, | 165 | .tx_irq = INT_24XX_MCBSP5_IRQ_TX, |
| 162 | .ops = &omap2_mcbsp_ops, | 166 | .ops = &omap2_mcbsp_ops, |
| 167 | .buffer_size = 0x6F, | ||
| 163 | }, | 168 | }, |
| 164 | }; | 169 | }; |
| 165 | #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) | 170 | #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) |
| @@ -168,6 +173,42 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | |||
| 168 | #define OMAP34XX_MCBSP_PDATA_SZ 0 | 173 | #define OMAP34XX_MCBSP_PDATA_SZ 0 |
| 169 | #endif | 174 | #endif |
| 170 | 175 | ||
| 176 | static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = { | ||
| 177 | { | ||
| 178 | .phys_base = OMAP44XX_MCBSP1_BASE, | ||
| 179 | .dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX, | ||
| 180 | .dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX, | ||
| 181 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | ||
| 182 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | ||
| 183 | .ops = &omap2_mcbsp_ops, | ||
| 184 | }, | ||
| 185 | { | ||
| 186 | .phys_base = OMAP44XX_MCBSP2_BASE, | ||
| 187 | .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX, | ||
| 188 | .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX, | ||
| 189 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | ||
| 190 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | ||
| 191 | .ops = &omap2_mcbsp_ops, | ||
| 192 | }, | ||
| 193 | { | ||
| 194 | .phys_base = OMAP44XX_MCBSP3_BASE, | ||
| 195 | .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX, | ||
| 196 | .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX, | ||
| 197 | .rx_irq = INT_24XX_MCBSP3_IRQ_RX, | ||
| 198 | .tx_irq = INT_24XX_MCBSP3_IRQ_TX, | ||
| 199 | .ops = &omap2_mcbsp_ops, | ||
| 200 | }, | ||
| 201 | { | ||
| 202 | .phys_base = OMAP44XX_MCBSP4_BASE, | ||
| 203 | .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX, | ||
| 204 | .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX, | ||
| 205 | .rx_irq = INT_24XX_MCBSP4_IRQ_RX, | ||
| 206 | .tx_irq = INT_24XX_MCBSP4_IRQ_TX, | ||
| 207 | .ops = &omap2_mcbsp_ops, | ||
| 208 | }, | ||
| 209 | }; | ||
| 210 | #define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata) | ||
| 211 | |||
| 171 | static int __init omap2_mcbsp_init(void) | 212 | static int __init omap2_mcbsp_init(void) |
| 172 | { | 213 | { |
| 173 | if (cpu_is_omap2420()) | 214 | if (cpu_is_omap2420()) |
| @@ -176,6 +217,8 @@ static int __init omap2_mcbsp_init(void) | |||
| 176 | omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ; | 217 | omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ; |
| 177 | if (cpu_is_omap34xx()) | 218 | if (cpu_is_omap34xx()) |
| 178 | omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ; | 219 | omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ; |
| 220 | if (cpu_is_omap44xx()) | ||
| 221 | omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ; | ||
| 179 | 222 | ||
| 180 | mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), | 223 | mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), |
| 181 | GFP_KERNEL); | 224 | GFP_KERNEL); |
| @@ -191,6 +234,9 @@ static int __init omap2_mcbsp_init(void) | |||
| 191 | if (cpu_is_omap34xx()) | 234 | if (cpu_is_omap34xx()) |
| 192 | omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, | 235 | omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, |
| 193 | OMAP34XX_MCBSP_PDATA_SZ); | 236 | OMAP34XX_MCBSP_PDATA_SZ); |
| 237 | if (cpu_is_omap44xx()) | ||
| 238 | omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata, | ||
| 239 | OMAP44XX_MCBSP_PDATA_SZ); | ||
| 194 | 240 | ||
| 195 | return omap_mcbsp_init(); | 241 | return omap_mcbsp_init(); |
| 196 | } | 242 | } |
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index a7421a50410b..ce22344b94e7 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
| @@ -109,6 +109,16 @@ static struct plat_serial8250_port serial_platform_data2[] = { | |||
| 109 | .regshift = 2, | 109 | .regshift = 2, |
| 110 | .uartclk = OMAP24XX_BASE_BAUD * 16, | 110 | .uartclk = OMAP24XX_BASE_BAUD * 16, |
| 111 | }, { | 111 | }, { |
| 112 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 113 | .membase = IO_ADDRESS(OMAP_UART4_BASE), | ||
| 114 | .mapbase = OMAP_UART4_BASE, | ||
| 115 | .irq = 70, | ||
| 116 | .flags = UPF_BOOT_AUTOCONF, | ||
| 117 | .iotype = UPIO_MEM, | ||
| 118 | .regshift = 2, | ||
| 119 | .uartclk = OMAP24XX_BASE_BAUD * 16, | ||
| 120 | }, { | ||
| 121 | #endif | ||
| 112 | .flags = 0 | 122 | .flags = 0 |
| 113 | } | 123 | } |
| 114 | }; | 124 | }; |
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index 2c7035d8dcbf..c3d513cad5ac 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig | |||
| @@ -89,6 +89,27 @@ config MACH_EDMINI_V2 | |||
| 89 | Say 'Y' here if you want your kernel to support the | 89 | Say 'Y' here if you want your kernel to support the |
| 90 | LaCie Ethernet Disk mini V2. | 90 | LaCie Ethernet Disk mini V2. |
| 91 | 91 | ||
| 92 | config MACH_D2NET | ||
| 93 | bool "LaCie d2 Network" | ||
| 94 | select I2C_BOARDINFO | ||
| 95 | help | ||
| 96 | Say 'Y' here if you want your kernel to support the | ||
| 97 | LaCie d2 Network NAS. | ||
| 98 | |||
| 99 | config MACH_BIGDISK | ||
| 100 | bool "LaCie Big Disk Network" | ||
| 101 | select I2C_BOARDINFO | ||
| 102 | help | ||
| 103 | Say 'Y' here if you want your kernel to support the | ||
| 104 | LaCie Big Disk Network NAS. | ||
| 105 | |||
| 106 | config MACH_NET2BIG | ||
| 107 | bool "LaCie 2Big Network" | ||
| 108 | select I2C_BOARDINFO | ||
| 109 | help | ||
| 110 | Say 'Y' here if you want your kernel to support the | ||
| 111 | LaCie 2Big Network NAS. | ||
| 112 | |||
| 92 | config MACH_MSS2 | 113 | config MACH_MSS2 |
| 93 | bool "Maxtor Shared Storage II" | 114 | bool "Maxtor Shared Storage II" |
| 94 | help | 115 | help |
diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile index edc38e2c856f..89772fcd65c7 100644 --- a/arch/arm/mach-orion5x/Makefile +++ b/arch/arm/mach-orion5x/Makefile | |||
| @@ -12,6 +12,9 @@ obj-$(CONFIG_MACH_WRT350N_V2) += wrt350n-v2-setup.o | |||
| 12 | obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o | 12 | obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o |
| 13 | obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o | 13 | obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o |
| 14 | obj-$(CONFIG_MACH_EDMINI_V2) += edmini_v2-setup.o | 14 | obj-$(CONFIG_MACH_EDMINI_V2) += edmini_v2-setup.o |
| 15 | obj-$(CONFIG_MACH_D2NET) += d2net-setup.o | ||
| 16 | obj-$(CONFIG_MACH_BIGDISK) += d2net-setup.o | ||
| 17 | obj-$(CONFIG_MACH_NET2BIG) += net2big-setup.o | ||
| 15 | obj-$(CONFIG_MACH_MSS2) += mss2-setup.o | 18 | obj-$(CONFIG_MACH_MSS2) += mss2-setup.o |
| 16 | obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o | 19 | obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o |
| 17 | obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o | 20 | obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o |
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c index d78731edebb6..1a5d6a0e2602 100644 --- a/arch/arm/mach-orion5x/addr-map.c +++ b/arch/arm/mach-orion5x/addr-map.c | |||
| @@ -84,7 +84,8 @@ static int __init orion5x_cpu_win_can_remap(int win) | |||
| 84 | orion5x_pcie_id(&dev, &rev); | 84 | orion5x_pcie_id(&dev, &rev); |
| 85 | if ((dev == MV88F5281_DEV_ID && win < 4) | 85 | if ((dev == MV88F5281_DEV_ID && win < 4) |
| 86 | || (dev == MV88F5182_DEV_ID && win < 2) | 86 | || (dev == MV88F5182_DEV_ID && win < 2) |
| 87 | || (dev == MV88F5181_DEV_ID && win < 2)) | 87 | || (dev == MV88F5181_DEV_ID && win < 2) |
| 88 | || (dev == MV88F6183_DEV_ID && win < 4)) | ||
| 88 | return 1; | 89 | return 1; |
| 89 | 90 | ||
| 90 | return 0; | 91 | return 0; |
diff --git a/arch/arm/mach-orion5x/d2net-setup.c b/arch/arm/mach-orion5x/d2net-setup.c new file mode 100644 index 000000000000..9d4bf763f25b --- /dev/null +++ b/arch/arm/mach-orion5x/d2net-setup.c | |||
| @@ -0,0 +1,365 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/mach-orion5x/d2net-setup.c | ||
| 3 | * | ||
| 4 | * LaCie d2Network and Big Disk Network NAS setup | ||
| 5 | * | ||
| 6 | * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com> | ||
| 7 | * | ||
| 8 | * This file is licensed under the terms of the GNU General Public | ||
| 9 | * License version 2. This program is licensed "as is" without any | ||
| 10 | * warranty of any kind, whether express or implied. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/pci.h> | ||
| 17 | #include <linux/irq.h> | ||
| 18 | #include <linux/mtd/physmap.h> | ||
| 19 | #include <linux/mv643xx_eth.h> | ||
| 20 | #include <linux/leds.h> | ||
| 21 | #include <linux/gpio_keys.h> | ||
| 22 | #include <linux/input.h> | ||
| 23 | #include <linux/i2c.h> | ||
| 24 | #include <linux/ata_platform.h> | ||
| 25 | #include <linux/gpio.h> | ||
| 26 | #include <asm/mach-types.h> | ||
| 27 | #include <asm/mach/arch.h> | ||
| 28 | #include <asm/mach/pci.h> | ||
| 29 | #include <mach/orion5x.h> | ||
| 30 | #include "common.h" | ||
| 31 | #include "mpp.h" | ||
| 32 | |||
| 33 | /***************************************************************************** | ||
| 34 | * LaCie d2 Network Info | ||
| 35 | ****************************************************************************/ | ||
| 36 | |||
| 37 | /* | ||
| 38 | * 512KB NOR flash Device bus boot chip select | ||
| 39 | */ | ||
| 40 | |||
| 41 | #define D2NET_NOR_BOOT_BASE 0xfff80000 | ||
| 42 | #define D2NET_NOR_BOOT_SIZE SZ_512K | ||
| 43 | |||
| 44 | /***************************************************************************** | ||
| 45 | * 512KB NOR Flash on Boot Device | ||
| 46 | ****************************************************************************/ | ||
| 47 | |||
| 48 | /* | ||
| 49 | * TODO: Check write support on flash MX29LV400CBTC-70G | ||
| 50 | */ | ||
| 51 | |||
| 52 | static struct mtd_partition d2net_partitions[] = { | ||
| 53 | { | ||
| 54 | .name = "Full512kb", | ||
| 55 | .size = MTDPART_SIZ_FULL, | ||
| 56 | .offset = 0, | ||
| 57 | .mask_flags = MTD_WRITEABLE, | ||
| 58 | }, | ||
| 59 | }; | ||
| 60 | |||
| 61 | static struct physmap_flash_data d2net_nor_flash_data = { | ||
| 62 | .width = 1, | ||
| 63 | .parts = d2net_partitions, | ||
| 64 | .nr_parts = ARRAY_SIZE(d2net_partitions), | ||
| 65 | }; | ||
| 66 | |||
| 67 | static struct resource d2net_nor_flash_resource = { | ||
| 68 | .flags = IORESOURCE_MEM, | ||
| 69 | .start = D2NET_NOR_BOOT_BASE, | ||
| 70 | .end = D2NET_NOR_BOOT_BASE | ||
| 71 | + D2NET_NOR_BOOT_SIZE - 1, | ||
| 72 | }; | ||
| 73 | |||
| 74 | static struct platform_device d2net_nor_flash = { | ||
| 75 | .name = "physmap-flash", | ||
| 76 | .id = 0, | ||
| 77 | .dev = { | ||
| 78 | .platform_data = &d2net_nor_flash_data, | ||
| 79 | }, | ||
| 80 | .num_resources = 1, | ||
| 81 | .resource = &d2net_nor_flash_resource, | ||
| 82 | }; | ||
| 83 | |||
| 84 | /***************************************************************************** | ||
| 85 | * Ethernet | ||
| 86 | ****************************************************************************/ | ||
| 87 | |||
| 88 | static struct mv643xx_eth_platform_data d2net_eth_data = { | ||
| 89 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), | ||
| 90 | }; | ||
| 91 | |||
| 92 | /***************************************************************************** | ||
| 93 | * I2C devices | ||
| 94 | ****************************************************************************/ | ||
| 95 | |||
| 96 | /* | ||
| 97 | * i2c addr | chip | description | ||
| 98 | * 0x32 | Ricoh 5C372b | RTC | ||
| 99 | * 0x3e | GMT G762 | PWM fan controller | ||
| 100 | * 0x50 | HT24LC08 | eeprom (1kB) | ||
| 101 | * | ||
| 102 | * TODO: Add G762 support to the g760a driver. | ||
| 103 | */ | ||
| 104 | static struct i2c_board_info __initdata d2net_i2c_devices[] = { | ||
| 105 | { | ||
| 106 | I2C_BOARD_INFO("rs5c372b", 0x32), | ||
| 107 | }, { | ||
| 108 | I2C_BOARD_INFO("24c08", 0x50), | ||
| 109 | }, | ||
| 110 | }; | ||
| 111 | |||
| 112 | /***************************************************************************** | ||
| 113 | * SATA | ||
| 114 | ****************************************************************************/ | ||
| 115 | |||
| 116 | static struct mv_sata_platform_data d2net_sata_data = { | ||
| 117 | .n_ports = 2, | ||
| 118 | }; | ||
| 119 | |||
| 120 | #define D2NET_GPIO_SATA0_POWER 3 | ||
| 121 | #define D2NET_GPIO_SATA1_POWER 12 | ||
| 122 | |||
| 123 | static void __init d2net_sata_power_init(void) | ||
| 124 | { | ||
| 125 | int err; | ||
| 126 | |||
| 127 | err = gpio_request(D2NET_GPIO_SATA0_POWER, "SATA0 power"); | ||
| 128 | if (err == 0) { | ||
| 129 | err = gpio_direction_output(D2NET_GPIO_SATA0_POWER, 1); | ||
| 130 | if (err) | ||
| 131 | gpio_free(D2NET_GPIO_SATA0_POWER); | ||
| 132 | } | ||
| 133 | if (err) | ||
| 134 | pr_err("d2net: failed to configure SATA0 power GPIO\n"); | ||
| 135 | |||
| 136 | err = gpio_request(D2NET_GPIO_SATA1_POWER, "SATA1 power"); | ||
| 137 | if (err == 0) { | ||
| 138 | err = gpio_direction_output(D2NET_GPIO_SATA1_POWER, 1); | ||
| 139 | if (err) | ||
| 140 | gpio_free(D2NET_GPIO_SATA1_POWER); | ||
| 141 | } | ||
| 142 | if (err) | ||
| 143 | pr_err("d2net: failed to configure SATA1 power GPIO\n"); | ||
| 144 | } | ||
| 145 | |||
| 146 | /***************************************************************************** | ||
| 147 | * GPIO LED's | ||
| 148 | ****************************************************************************/ | ||
| 149 | |||
| 150 | /* | ||
| 151 | * The blue front LED is wired to the CPLD and can blink in relation with the | ||
| 152 | * SATA activity. This feature is disabled to make this LED compatible with | ||
| 153 | * the leds-gpio driver: MPP14 and MPP15 are configured to act like output | ||
| 154 | * GPIO's and have to stay in an active state. This is needed to set the blue | ||
| 155 | * LED in a "fix on" state regardless of the SATA activity. | ||
| 156 | * | ||
| 157 | * The following array detail the different LED registers and the combination | ||
| 158 | * of their possible values: | ||
| 159 | * | ||
| 160 | * led_off | blink_ctrl | SATA active | LED state | ||
| 161 | * | | | | ||
| 162 | * 1 | x | x | off | ||
| 163 | * 0 | 0 | 0 | off | ||
| 164 | * 0 | 1 | 0 | blink (rate 300ms) | ||
| 165 | * 0 | x | 1 | on | ||
| 166 | * | ||
| 167 | * Notes: The blue and the red front LED's can't be on at the same time. | ||
| 168 | * Red LED have priority. | ||
| 169 | */ | ||
| 170 | |||
| 171 | #define D2NET_GPIO_RED_LED 6 | ||
| 172 | #define D2NET_GPIO_BLUE_LED_BLINK_CTRL 16 | ||
| 173 | #define D2NET_GPIO_BLUE_LED_OFF 23 | ||
| 174 | #define D2NET_GPIO_SATA0_ACT 14 | ||
| 175 | #define D2NET_GPIO_SATA1_ACT 15 | ||
| 176 | |||
| 177 | static struct gpio_led d2net_leds[] = { | ||
| 178 | { | ||
| 179 | .name = "d2net:blue:power", | ||
| 180 | .gpio = D2NET_GPIO_BLUE_LED_OFF, | ||
| 181 | .active_low = 1, | ||
| 182 | }, | ||
| 183 | { | ||
| 184 | .name = "d2net:red:fail", | ||
| 185 | .gpio = D2NET_GPIO_RED_LED, | ||
| 186 | }, | ||
| 187 | }; | ||
| 188 | |||
| 189 | static struct gpio_led_platform_data d2net_led_data = { | ||
| 190 | .num_leds = ARRAY_SIZE(d2net_leds), | ||
| 191 | .leds = d2net_leds, | ||
| 192 | }; | ||
| 193 | |||
| 194 | static struct platform_device d2net_gpio_leds = { | ||
| 195 | .name = "leds-gpio", | ||
| 196 | .id = -1, | ||
| 197 | .dev = { | ||
| 198 | .platform_data = &d2net_led_data, | ||
| 199 | }, | ||
| 200 | }; | ||
| 201 | |||
| 202 | static void __init d2net_gpio_leds_init(void) | ||
| 203 | { | ||
| 204 | /* Configure GPIO over MPP max number. */ | ||
| 205 | orion_gpio_set_valid(D2NET_GPIO_BLUE_LED_OFF, 1); | ||
| 206 | |||
| 207 | if (gpio_request(D2NET_GPIO_SATA0_ACT, "LED SATA0 activity") != 0) | ||
| 208 | return; | ||
| 209 | if (gpio_direction_output(D2NET_GPIO_SATA0_ACT, 1) != 0) | ||
| 210 | goto err_free_1; | ||
| 211 | if (gpio_request(D2NET_GPIO_SATA1_ACT, "LED SATA1 activity") != 0) | ||
| 212 | goto err_free_1; | ||
| 213 | if (gpio_direction_output(D2NET_GPIO_SATA1_ACT, 1) != 0) | ||
| 214 | goto err_free_2; | ||
| 215 | platform_device_register(&d2net_gpio_leds); | ||
| 216 | return; | ||
| 217 | |||
| 218 | err_free_2: | ||
| 219 | gpio_free(D2NET_GPIO_SATA1_ACT); | ||
| 220 | err_free_1: | ||
| 221 | gpio_free(D2NET_GPIO_SATA0_ACT); | ||
| 222 | return; | ||
| 223 | } | ||
| 224 | |||
| 225 | /**************************************************************************** | ||
| 226 | * GPIO keys | ||
| 227 | ****************************************************************************/ | ||
| 228 | |||
| 229 | #define D2NET_GPIO_PUSH_BUTTON 18 | ||
| 230 | #define D2NET_GPIO_POWER_SWITCH_ON 8 | ||
| 231 | #define D2NET_GPIO_POWER_SWITCH_OFF 9 | ||
| 232 | |||
| 233 | #define D2NET_SWITCH_POWER_ON 0x1 | ||
| 234 | #define D2NET_SWITCH_POWER_OFF 0x2 | ||
| 235 | |||
| 236 | static struct gpio_keys_button d2net_buttons[] = { | ||
| 237 | { | ||
| 238 | .type = EV_SW, | ||
| 239 | .code = D2NET_SWITCH_POWER_OFF, | ||
| 240 | .gpio = D2NET_GPIO_POWER_SWITCH_OFF, | ||
| 241 | .desc = "Power rocker switch (auto|off)", | ||
| 242 | .active_low = 0, | ||
| 243 | }, | ||
| 244 | { | ||
| 245 | .type = EV_SW, | ||
| 246 | .code = D2NET_SWITCH_POWER_ON, | ||
| 247 | .gpio = D2NET_GPIO_POWER_SWITCH_ON, | ||
| 248 | .desc = "Power rocker switch (on|auto)", | ||
| 249 | .active_low = 0, | ||
| 250 | }, | ||
| 251 | { | ||
| 252 | .type = EV_KEY, | ||
| 253 | .code = KEY_POWER, | ||
| 254 | .gpio = D2NET_GPIO_PUSH_BUTTON, | ||
| 255 | .desc = "Front Push Button", | ||
| 256 | .active_low = 0, | ||
| 257 | }, | ||
| 258 | }; | ||
| 259 | |||
| 260 | static struct gpio_keys_platform_data d2net_button_data = { | ||
| 261 | .buttons = d2net_buttons, | ||
| 262 | .nbuttons = ARRAY_SIZE(d2net_buttons), | ||
| 263 | }; | ||
| 264 | |||
| 265 | static struct platform_device d2net_gpio_buttons = { | ||
| 266 | .name = "gpio-keys", | ||
| 267 | .id = -1, | ||
| 268 | .dev = { | ||
| 269 | .platform_data = &d2net_button_data, | ||
| 270 | }, | ||
| 271 | }; | ||
| 272 | |||
| 273 | /***************************************************************************** | ||
| 274 | * General Setup | ||
| 275 | ****************************************************************************/ | ||
| 276 | |||
| 277 | static struct orion5x_mpp_mode d2net_mpp_modes[] __initdata = { | ||
| 278 | { 0, MPP_GPIO }, /* Board ID (bit 0) */ | ||
| 279 | { 1, MPP_GPIO }, /* Board ID (bit 1) */ | ||
| 280 | { 2, MPP_GPIO }, /* Board ID (bit 2) */ | ||
| 281 | { 3, MPP_GPIO }, /* SATA 0 power */ | ||
| 282 | { 4, MPP_UNUSED }, | ||
| 283 | { 5, MPP_GPIO }, /* Fan fail detection */ | ||
| 284 | { 6, MPP_GPIO }, /* Red front LED */ | ||
| 285 | { 7, MPP_UNUSED }, | ||
| 286 | { 8, MPP_GPIO }, /* Rear power switch (on|auto) */ | ||
| 287 | { 9, MPP_GPIO }, /* Rear power switch (auto|off) */ | ||
| 288 | { 10, MPP_UNUSED }, | ||
| 289 | { 11, MPP_UNUSED }, | ||
| 290 | { 12, MPP_GPIO }, /* SATA 1 power */ | ||
| 291 | { 13, MPP_UNUSED }, | ||
| 292 | { 14, MPP_GPIO }, /* SATA 0 active */ | ||
| 293 | { 15, MPP_GPIO }, /* SATA 1 active */ | ||
| 294 | { 16, MPP_GPIO }, /* Blue front LED blink control */ | ||
| 295 | { 17, MPP_UNUSED }, | ||
| 296 | { 18, MPP_GPIO }, /* Front button (0 = Released, 1 = Pushed ) */ | ||
| 297 | { 19, MPP_UNUSED }, | ||
| 298 | { -1 } | ||
| 299 | /* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */ | ||
| 300 | /* 23: Blue front LED off */ | ||
| 301 | /* 24: Inhibit board power off (0 = Disabled, 1 = Enabled) */ | ||
| 302 | }; | ||
| 303 | |||
| 304 | static void __init d2net_init(void) | ||
| 305 | { | ||
| 306 | /* | ||
| 307 | * Setup basic Orion functions. Need to be called early. | ||
| 308 | */ | ||
| 309 | orion5x_init(); | ||
| 310 | |||
| 311 | orion5x_mpp_conf(d2net_mpp_modes); | ||
| 312 | |||
| 313 | /* | ||
| 314 | * Configure peripherals. | ||
| 315 | */ | ||
| 316 | orion5x_ehci0_init(); | ||
| 317 | orion5x_eth_init(&d2net_eth_data); | ||
| 318 | orion5x_i2c_init(); | ||
| 319 | orion5x_uart0_init(); | ||
| 320 | |||
| 321 | d2net_sata_power_init(); | ||
| 322 | orion5x_sata_init(&d2net_sata_data); | ||
| 323 | |||
| 324 | orion5x_setup_dev_boot_win(D2NET_NOR_BOOT_BASE, | ||
| 325 | D2NET_NOR_BOOT_SIZE); | ||
| 326 | platform_device_register(&d2net_nor_flash); | ||
| 327 | |||
| 328 | platform_device_register(&d2net_gpio_buttons); | ||
| 329 | |||
| 330 | d2net_gpio_leds_init(); | ||
| 331 | |||
| 332 | pr_notice("d2net: Flash write are not yet supported.\n"); | ||
| 333 | |||
| 334 | i2c_register_board_info(0, d2net_i2c_devices, | ||
| 335 | ARRAY_SIZE(d2net_i2c_devices)); | ||
| 336 | } | ||
| 337 | |||
| 338 | /* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */ | ||
| 339 | |||
| 340 | #ifdef CONFIG_MACH_D2NET | ||
| 341 | MACHINE_START(D2NET, "LaCie d2 Network") | ||
| 342 | .phys_io = ORION5X_REGS_PHYS_BASE, | ||
| 343 | .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, | ||
| 344 | .boot_params = 0x00000100, | ||
| 345 | .init_machine = d2net_init, | ||
| 346 | .map_io = orion5x_map_io, | ||
| 347 | .init_irq = orion5x_init_irq, | ||
| 348 | .timer = &orion5x_timer, | ||
| 349 | .fixup = tag_fixup_mem32, | ||
| 350 | MACHINE_END | ||
| 351 | #endif | ||
| 352 | |||
| 353 | #ifdef CONFIG_MACH_BIGDISK | ||
| 354 | MACHINE_START(BIGDISK, "LaCie Big Disk Network") | ||
| 355 | .phys_io = ORION5X_REGS_PHYS_BASE, | ||
| 356 | .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, | ||
| 357 | .boot_params = 0x00000100, | ||
| 358 | .init_machine = d2net_init, | ||
| 359 | .map_io = orion5x_map_io, | ||
| 360 | .init_irq = orion5x_init_irq, | ||
| 361 | .timer = &orion5x_timer, | ||
| 362 | .fixup = tag_fixup_mem32, | ||
| 363 | MACHINE_END | ||
| 364 | #endif | ||
| 365 | |||
diff --git a/arch/arm/mach-orion5x/net2big-setup.c b/arch/arm/mach-orion5x/net2big-setup.c new file mode 100644 index 000000000000..7bd6283476f9 --- /dev/null +++ b/arch/arm/mach-orion5x/net2big-setup.c | |||
| @@ -0,0 +1,431 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/mach-orion5x/net2big-setup.c | ||
| 3 | * | ||
| 4 | * LaCie 2Big Network NAS setup | ||
| 5 | * | ||
| 6 | * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com> | ||
| 7 | * | ||
| 8 | * This file is licensed under the terms of the GNU General Public | ||
| 9 | * License version 2. This program is licensed "as is" without any | ||
| 10 | * warranty of any kind, whether express or implied. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/mtd/physmap.h> | ||
| 17 | #include <linux/mv643xx_eth.h> | ||
| 18 | #include <linux/leds.h> | ||
| 19 | #include <linux/gpio_keys.h> | ||
| 20 | #include <linux/input.h> | ||
| 21 | #include <linux/i2c.h> | ||
| 22 | #include <linux/ata_platform.h> | ||
| 23 | #include <linux/gpio.h> | ||
| 24 | #include <linux/delay.h> | ||
| 25 | #include <asm/mach-types.h> | ||
| 26 | #include <asm/mach/arch.h> | ||
| 27 | #include <mach/orion5x.h> | ||
| 28 | #include "common.h" | ||
| 29 | #include "mpp.h" | ||
| 30 | |||
| 31 | /***************************************************************************** | ||
| 32 | * LaCie 2Big Network Info | ||
| 33 | ****************************************************************************/ | ||
| 34 | |||
| 35 | /* | ||
| 36 | * 512KB NOR flash Device bus boot chip select | ||
| 37 | */ | ||
| 38 | |||
| 39 | #define NET2BIG_NOR_BOOT_BASE 0xfff80000 | ||
| 40 | #define NET2BIG_NOR_BOOT_SIZE SZ_512K | ||
| 41 | |||
| 42 | /***************************************************************************** | ||
| 43 | * 512KB NOR Flash on Boot Device | ||
| 44 | ****************************************************************************/ | ||
| 45 | |||
| 46 | /* | ||
| 47 | * TODO: Check write support on flash MX29LV400CBTC-70G | ||
| 48 | */ | ||
| 49 | |||
| 50 | static struct mtd_partition net2big_partitions[] = { | ||
| 51 | { | ||
| 52 | .name = "Full512kb", | ||
| 53 | .size = MTDPART_SIZ_FULL, | ||
| 54 | .offset = 0x00000000, | ||
| 55 | .mask_flags = MTD_WRITEABLE, | ||
| 56 | }, | ||
| 57 | }; | ||
| 58 | |||
| 59 | static struct physmap_flash_data net2big_nor_flash_data = { | ||
| 60 | .width = 1, | ||
| 61 | .parts = net2big_partitions, | ||
| 62 | .nr_parts = ARRAY_SIZE(net2big_partitions), | ||
| 63 | }; | ||
| 64 | |||
| 65 | static struct resource net2big_nor_flash_resource = { | ||
| 66 | .flags = IORESOURCE_MEM, | ||
| 67 | .start = NET2BIG_NOR_BOOT_BASE, | ||
| 68 | .end = NET2BIG_NOR_BOOT_BASE | ||
| 69 | + NET2BIG_NOR_BOOT_SIZE - 1, | ||
| 70 | }; | ||
| 71 | |||
| 72 | static struct platform_device net2big_nor_flash = { | ||
| 73 | .name = "physmap-flash", | ||
| 74 | .id = 0, | ||
| 75 | .dev = { | ||
| 76 | .platform_data = &net2big_nor_flash_data, | ||
| 77 | }, | ||
| 78 | .num_resources = 1, | ||
| 79 | .resource = &net2big_nor_flash_resource, | ||
| 80 | }; | ||
| 81 | |||
| 82 | /***************************************************************************** | ||
| 83 | * Ethernet | ||
| 84 | ****************************************************************************/ | ||
| 85 | |||
| 86 | static struct mv643xx_eth_platform_data net2big_eth_data = { | ||
| 87 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), | ||
| 88 | }; | ||
| 89 | |||
| 90 | /***************************************************************************** | ||
| 91 | * I2C devices | ||
| 92 | ****************************************************************************/ | ||
| 93 | |||
| 94 | /* | ||
| 95 | * i2c addr | chip | description | ||
| 96 | * 0x32 | Ricoh 5C372b | RTC | ||
| 97 | * 0x50 | HT24LC08 | eeprom (1kB) | ||
| 98 | */ | ||
| 99 | static struct i2c_board_info __initdata net2big_i2c_devices[] = { | ||
| 100 | { | ||
| 101 | I2C_BOARD_INFO("rs5c372b", 0x32), | ||
| 102 | }, { | ||
| 103 | I2C_BOARD_INFO("24c08", 0x50), | ||
| 104 | }, | ||
| 105 | }; | ||
| 106 | |||
| 107 | /***************************************************************************** | ||
| 108 | * SATA | ||
| 109 | ****************************************************************************/ | ||
| 110 | |||
| 111 | static struct mv_sata_platform_data net2big_sata_data = { | ||
| 112 | .n_ports = 2, | ||
| 113 | }; | ||
| 114 | |||
| 115 | #define NET2BIG_GPIO_SATA_POWER_REQ 19 | ||
| 116 | #define NET2BIG_GPIO_SATA0_POWER 23 | ||
| 117 | #define NET2BIG_GPIO_SATA1_POWER 25 | ||
| 118 | |||
| 119 | static void __init net2big_sata_power_init(void) | ||
| 120 | { | ||
| 121 | int err; | ||
| 122 | |||
| 123 | /* Configure GPIOs over MPP max number. */ | ||
| 124 | orion_gpio_set_valid(NET2BIG_GPIO_SATA0_POWER, 1); | ||
| 125 | orion_gpio_set_valid(NET2BIG_GPIO_SATA1_POWER, 1); | ||
| 126 | |||
| 127 | err = gpio_request(NET2BIG_GPIO_SATA0_POWER, "SATA0 power status"); | ||
| 128 | if (err == 0) { | ||
| 129 | err = gpio_direction_input(NET2BIG_GPIO_SATA0_POWER); | ||
| 130 | if (err) | ||
| 131 | gpio_free(NET2BIG_GPIO_SATA0_POWER); | ||
| 132 | } | ||
| 133 | if (err) { | ||
| 134 | pr_err("net2big: failed to setup SATA0 power GPIO\n"); | ||
| 135 | return; | ||
| 136 | } | ||
| 137 | |||
| 138 | err = gpio_request(NET2BIG_GPIO_SATA1_POWER, "SATA1 power status"); | ||
| 139 | if (err == 0) { | ||
| 140 | err = gpio_direction_input(NET2BIG_GPIO_SATA1_POWER); | ||
| 141 | if (err) | ||
| 142 | gpio_free(NET2BIG_GPIO_SATA1_POWER); | ||
| 143 | } | ||
| 144 | if (err) { | ||
| 145 | pr_err("net2big: failed to setup SATA1 power GPIO\n"); | ||
| 146 | goto err_free_1; | ||
| 147 | } | ||
| 148 | |||
| 149 | err = gpio_request(NET2BIG_GPIO_SATA_POWER_REQ, "SATA power request"); | ||
| 150 | if (err == 0) { | ||
| 151 | err = gpio_direction_output(NET2BIG_GPIO_SATA_POWER_REQ, 0); | ||
| 152 | if (err) | ||
| 153 | gpio_free(NET2BIG_GPIO_SATA_POWER_REQ); | ||
| 154 | } | ||
| 155 | if (err) { | ||
| 156 | pr_err("net2big: failed to setup SATA power request GPIO\n"); | ||
| 157 | goto err_free_2; | ||
| 158 | } | ||
| 159 | |||
| 160 | if (gpio_get_value(NET2BIG_GPIO_SATA0_POWER) && | ||
| 161 | gpio_get_value(NET2BIG_GPIO_SATA1_POWER)) { | ||
| 162 | return; | ||
| 163 | } | ||
| 164 | |||
| 165 | /* | ||
| 166 | * SATA power up on both disk is done by pulling high the CPLD power | ||
| 167 | * request line. The 300ms delay is related to the CPLD clock and is | ||
| 168 | * needed to be sure that the CPLD has take into account the low line | ||
| 169 | * status. | ||
| 170 | */ | ||
| 171 | msleep(300); | ||
| 172 | gpio_set_value(NET2BIG_GPIO_SATA_POWER_REQ, 1); | ||
| 173 | pr_info("net2big: power up SATA hard disks\n"); | ||
| 174 | |||
| 175 | return; | ||
| 176 | |||
| 177 | err_free_2: | ||
| 178 | gpio_free(NET2BIG_GPIO_SATA1_POWER); | ||
| 179 | err_free_1: | ||
| 180 | gpio_free(NET2BIG_GPIO_SATA0_POWER); | ||
| 181 | |||
| 182 | return; | ||
| 183 | } | ||
| 184 | |||
| 185 | /***************************************************************************** | ||
| 186 | * GPIO LEDs | ||
| 187 | ****************************************************************************/ | ||
| 188 | |||
| 189 | /* | ||
| 190 | * The power front LEDs (blue and red) and SATA red LEDs are controlled via a | ||
| 191 | * single GPIO line and are compatible with the leds-gpio driver. | ||
| 192 | * | ||
| 193 | * The SATA blue LEDs have some hardware blink capabilities which are detailled | ||
| 194 | * in the following array: | ||
| 195 | * | ||
| 196 | * SATAx blue LED | SATAx activity | LED state | ||
| 197 | * | | | ||
| 198 | * 0 | 0 | blink (rate 300ms) | ||
| 199 | * 1 | 0 | off | ||
| 200 | * ? | 1 | on | ||
| 201 | * | ||
| 202 | * Notes: The blue and the red front LED's can't be on at the same time. | ||
| 203 | * Blue LED have priority. | ||
| 204 | */ | ||
| 205 | |||
| 206 | #define NET2BIG_GPIO_PWR_RED_LED 6 | ||
| 207 | #define NET2BIG_GPIO_PWR_BLUE_LED 16 | ||
| 208 | #define NET2BIG_GPIO_PWR_LED_BLINK_STOP 7 | ||
| 209 | |||
| 210 | #define NET2BIG_GPIO_SATA0_RED_LED 11 | ||
| 211 | #define NET2BIG_GPIO_SATA1_RED_LED 10 | ||
| 212 | |||
| 213 | #define NET2BIG_GPIO_SATA0_BLUE_LED 17 | ||
| 214 | #define NET2BIG_GPIO_SATA1_BLUE_LED 13 | ||
| 215 | |||
| 216 | static struct gpio_led net2big_leds[] = { | ||
| 217 | { | ||
| 218 | .name = "net2big:red:power", | ||
| 219 | .gpio = NET2BIG_GPIO_PWR_RED_LED, | ||
| 220 | }, | ||
| 221 | { | ||
| 222 | .name = "net2big:blue:power", | ||
| 223 | .gpio = NET2BIG_GPIO_PWR_BLUE_LED, | ||
| 224 | }, | ||
| 225 | { | ||
| 226 | .name = "net2big:red:sata0", | ||
| 227 | .gpio = NET2BIG_GPIO_SATA0_RED_LED, | ||
| 228 | }, | ||
| 229 | { | ||
| 230 | .name = "net2big:red:sata1", | ||
| 231 | .gpio = NET2BIG_GPIO_SATA1_RED_LED, | ||
| 232 | }, | ||
| 233 | }; | ||
| 234 | |||
| 235 | static struct gpio_led_platform_data net2big_led_data = { | ||
| 236 | .num_leds = ARRAY_SIZE(net2big_leds), | ||
| 237 | .leds = net2big_leds, | ||
| 238 | }; | ||
| 239 | |||
| 240 | static struct platform_device net2big_gpio_leds = { | ||
| 241 | .name = "leds-gpio", | ||
| 242 | .id = -1, | ||
| 243 | .dev = { | ||
| 244 | .platform_data = &net2big_led_data, | ||
| 245 | }, | ||
| 246 | }; | ||
| 247 | |||
| 248 | static void __init net2big_gpio_leds_init(void) | ||
| 249 | { | ||
| 250 | int err; | ||
| 251 | |||
| 252 | /* Stop initial CPLD slow red/blue blinking on power LED. */ | ||
| 253 | err = gpio_request(NET2BIG_GPIO_PWR_LED_BLINK_STOP, | ||
| 254 | "Power LED blink stop"); | ||
| 255 | if (err == 0) { | ||
| 256 | err = gpio_direction_output(NET2BIG_GPIO_PWR_LED_BLINK_STOP, 1); | ||
| 257 | if (err) | ||
| 258 | gpio_free(NET2BIG_GPIO_PWR_LED_BLINK_STOP); | ||
| 259 | } | ||
| 260 | if (err) | ||
| 261 | pr_err("net2big: failed to setup power LED blink GPIO\n"); | ||
| 262 | |||
| 263 | /* | ||
| 264 | * Configure SATA0 and SATA1 blue LEDs to blink in relation with the | ||
| 265 | * hard disk activity. | ||
| 266 | */ | ||
| 267 | err = gpio_request(NET2BIG_GPIO_SATA0_BLUE_LED, | ||
| 268 | "SATA0 blue LED control"); | ||
| 269 | if (err == 0) { | ||
| 270 | err = gpio_direction_output(NET2BIG_GPIO_SATA0_BLUE_LED, 1); | ||
| 271 | if (err) | ||
| 272 | gpio_free(NET2BIG_GPIO_SATA0_BLUE_LED); | ||
| 273 | } | ||
| 274 | if (err) | ||
| 275 | pr_err("net2big: failed to setup SATA0 blue LED GPIO\n"); | ||
| 276 | |||
| 277 | err = gpio_request(NET2BIG_GPIO_SATA1_BLUE_LED, | ||
| 278 | "SATA1 blue LED control"); | ||
| 279 | if (err == 0) { | ||
| 280 | err = gpio_direction_output(NET2BIG_GPIO_SATA1_BLUE_LED, 1); | ||
| 281 | if (err) | ||
| 282 | gpio_free(NET2BIG_GPIO_SATA1_BLUE_LED); | ||
| 283 | } | ||
| 284 | if (err) | ||
| 285 | pr_err("net2big: failed to setup SATA1 blue LED GPIO\n"); | ||
| 286 | |||
| 287 | platform_device_register(&net2big_gpio_leds); | ||
| 288 | } | ||
| 289 | |||
| 290 | /**************************************************************************** | ||
| 291 | * GPIO keys | ||
| 292 | ****************************************************************************/ | ||
| 293 | |||
| 294 | #define NET2BIG_GPIO_PUSH_BUTTON 18 | ||
| 295 | #define NET2BIG_GPIO_POWER_SWITCH_ON 8 | ||
| 296 | #define NET2BIG_GPIO_POWER_SWITCH_OFF 9 | ||
| 297 | |||
| 298 | #define NET2BIG_SWITCH_POWER_ON 0x1 | ||
| 299 | #define NET2BIG_SWITCH_POWER_OFF 0x2 | ||
| 300 | |||
| 301 | static struct gpio_keys_button net2big_buttons[] = { | ||
| 302 | { | ||
| 303 | .type = EV_SW, | ||
| 304 | .code = NET2BIG_SWITCH_POWER_OFF, | ||
| 305 | .gpio = NET2BIG_GPIO_POWER_SWITCH_OFF, | ||
| 306 | .desc = "Power rocker switch (auto|off)", | ||
| 307 | .active_low = 0, | ||
| 308 | }, | ||
| 309 | { | ||
| 310 | .type = EV_SW, | ||
| 311 | .code = NET2BIG_SWITCH_POWER_ON, | ||
| 312 | .gpio = NET2BIG_GPIO_POWER_SWITCH_ON, | ||
| 313 | .desc = "Power rocker switch (on|auto)", | ||
| 314 | .active_low = 0, | ||
| 315 | }, | ||
| 316 | { | ||
| 317 | .type = EV_KEY, | ||
| 318 | .code = KEY_POWER, | ||
| 319 | .gpio = NET2BIG_GPIO_PUSH_BUTTON, | ||
| 320 | .desc = "Front Push Button", | ||
| 321 | .active_low = 0, | ||
| 322 | }, | ||
| 323 | }; | ||
| 324 | |||
| 325 | static struct gpio_keys_platform_data net2big_button_data = { | ||
| 326 | .buttons = net2big_buttons, | ||
| 327 | .nbuttons = ARRAY_SIZE(net2big_buttons), | ||
| 328 | }; | ||
| 329 | |||
| 330 | static struct platform_device net2big_gpio_buttons = { | ||
| 331 | .name = "gpio-keys", | ||
| 332 | .id = -1, | ||
| 333 | .dev = { | ||
| 334 | .platform_data = &net2big_button_data, | ||
| 335 | }, | ||
| 336 | }; | ||
| 337 | |||
| 338 | /***************************************************************************** | ||
| 339 | * General Setup | ||
| 340 | ****************************************************************************/ | ||
| 341 | |||
| 342 | static struct orion5x_mpp_mode net2big_mpp_modes[] __initdata = { | ||
| 343 | { 0, MPP_GPIO }, /* Raid mode (bit 0) */ | ||
| 344 | { 1, MPP_GPIO }, /* USB port 2 fuse (0 = Fail, 1 = Ok) */ | ||
| 345 | { 2, MPP_GPIO }, /* Raid mode (bit 1) */ | ||
| 346 | { 3, MPP_GPIO }, /* Board ID (bit 0) */ | ||
| 347 | { 4, MPP_GPIO }, /* Fan activity (0 = Off, 1 = On) */ | ||
| 348 | { 5, MPP_GPIO }, /* Fan fail detection */ | ||
| 349 | { 6, MPP_GPIO }, /* Red front LED (0 = Off, 1 = On) */ | ||
| 350 | { 7, MPP_GPIO }, /* Disable initial blinking on front LED */ | ||
| 351 | { 8, MPP_GPIO }, /* Rear power switch (on|auto) */ | ||
| 352 | { 9, MPP_GPIO }, /* Rear power switch (auto|off) */ | ||
| 353 | { 10, MPP_GPIO }, /* SATA 1 red LED (0 = Off, 1 = On) */ | ||
| 354 | { 11, MPP_GPIO }, /* SATA 0 red LED (0 = Off, 1 = On) */ | ||
| 355 | { 12, MPP_GPIO }, /* Board ID (bit 1) */ | ||
| 356 | { 13, MPP_GPIO }, /* SATA 1 blue LED blink control */ | ||
| 357 | { 14, MPP_SATA_LED }, | ||
| 358 | { 15, MPP_SATA_LED }, | ||
| 359 | { 16, MPP_GPIO }, /* Blue front LED control */ | ||
| 360 | { 17, MPP_GPIO }, /* SATA 0 blue LED blink control */ | ||
| 361 | { 18, MPP_GPIO }, /* Front button (0 = Released, 1 = Pushed ) */ | ||
| 362 | { 19, MPP_GPIO }, /* SATA{0,1} power On/Off request */ | ||
| 363 | { -1 } | ||
| 364 | /* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */ | ||
| 365 | /* 23: SATA 0 power status */ | ||
| 366 | /* 24: Board power off */ | ||
| 367 | /* 25: SATA 1 power status */ | ||
| 368 | }; | ||
| 369 | |||
| 370 | #define NET2BIG_GPIO_POWER_OFF 24 | ||
| 371 | |||
| 372 | static void net2big_power_off(void) | ||
| 373 | { | ||
| 374 | gpio_set_value(NET2BIG_GPIO_POWER_OFF, 1); | ||
| 375 | } | ||
| 376 | |||
| 377 | static void __init net2big_init(void) | ||
| 378 | { | ||
| 379 | /* | ||
| 380 | * Setup basic Orion functions. Need to be called early. | ||
| 381 | */ | ||
| 382 | orion5x_init(); | ||
| 383 | |||
| 384 | orion5x_mpp_conf(net2big_mpp_modes); | ||
| 385 | |||
| 386 | /* | ||
| 387 | * Configure peripherals. | ||
| 388 | */ | ||
| 389 | orion5x_ehci0_init(); | ||
| 390 | orion5x_ehci1_init(); | ||
| 391 | orion5x_eth_init(&net2big_eth_data); | ||
| 392 | orion5x_i2c_init(); | ||
| 393 | orion5x_uart0_init(); | ||
| 394 | orion5x_xor_init(); | ||
| 395 | |||
| 396 | net2big_sata_power_init(); | ||
| 397 | orion5x_sata_init(&net2big_sata_data); | ||
| 398 | |||
| 399 | orion5x_setup_dev_boot_win(NET2BIG_NOR_BOOT_BASE, | ||
| 400 | NET2BIG_NOR_BOOT_SIZE); | ||
| 401 | platform_device_register(&net2big_nor_flash); | ||
| 402 | |||
| 403 | platform_device_register(&net2big_gpio_buttons); | ||
| 404 | net2big_gpio_leds_init(); | ||
| 405 | |||
| 406 | i2c_register_board_info(0, net2big_i2c_devices, | ||
| 407 | ARRAY_SIZE(net2big_i2c_devices)); | ||
| 408 | |||
| 409 | orion_gpio_set_valid(NET2BIG_GPIO_POWER_OFF, 1); | ||
| 410 | |||
| 411 | if (gpio_request(NET2BIG_GPIO_POWER_OFF, "power-off") == 0 && | ||
| 412 | gpio_direction_output(NET2BIG_GPIO_POWER_OFF, 0) == 0) | ||
| 413 | pm_power_off = net2big_power_off; | ||
| 414 | else | ||
| 415 | pr_err("net2big: failed to configure power-off GPIO\n"); | ||
| 416 | |||
| 417 | pr_notice("net2big: Flash writing is not yet supported.\n"); | ||
| 418 | } | ||
| 419 | |||
| 420 | /* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */ | ||
| 421 | MACHINE_START(NET2BIG, "LaCie 2Big Network") | ||
| 422 | .phys_io = ORION5X_REGS_PHYS_BASE, | ||
| 423 | .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, | ||
| 424 | .boot_params = 0x00000100, | ||
| 425 | .init_machine = net2big_init, | ||
| 426 | .map_io = orion5x_map_io, | ||
| 427 | .init_irq = orion5x_init_irq, | ||
| 428 | .timer = &orion5x_timer, | ||
| 429 | .fixup = tag_fixup_mem32, | ||
| 430 | MACHINE_END | ||
| 431 | |||
diff --git a/arch/arm/mach-pxa/include/mach/audio.h b/arch/arm/mach-pxa/include/mach/audio.h index 16eb02552d5d..a3449e35a6f5 100644 --- a/arch/arm/mach-pxa/include/mach/audio.h +++ b/arch/arm/mach-pxa/include/mach/audio.h | |||
| @@ -3,10 +3,12 @@ | |||
| 3 | 3 | ||
| 4 | #include <sound/core.h> | 4 | #include <sound/core.h> |
| 5 | #include <sound/pcm.h> | 5 | #include <sound/pcm.h> |
| 6 | #include <sound/ac97_codec.h> | ||
| 6 | 7 | ||
| 7 | /* | 8 | /* |
| 8 | * @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95) | 9 | * @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95) |
| 9 | * a -1 value means no gpio will be used for reset | 10 | * a -1 value means no gpio will be used for reset |
| 11 | * @codec_pdata: AC97 codec platform_data | ||
| 10 | 12 | ||
| 11 | * reset_gpio should only be specified for pxa27x CPUs where a silicon | 13 | * reset_gpio should only be specified for pxa27x CPUs where a silicon |
| 12 | * bug prevents correct operation of the reset line. If not specified, | 14 | * bug prevents correct operation of the reset line. If not specified, |
| @@ -20,6 +22,7 @@ typedef struct { | |||
| 20 | void (*resume)(void *); | 22 | void (*resume)(void *); |
| 21 | void *priv; | 23 | void *priv; |
| 22 | int reset_gpio; | 24 | int reset_gpio; |
| 25 | void *codec_pdata[AC97_BUS_MAX_DEVICES]; | ||
| 23 | } pxa2xx_audio_ops_t; | 26 | } pxa2xx_audio_ops_t; |
| 24 | 27 | ||
| 25 | extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops); | 28 | extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops); |
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c index 2546c066cd6e..629e05d1196e 100644 --- a/arch/arm/mach-pxa/sharpsl_pm.c +++ b/arch/arm/mach-pxa/sharpsl_pm.c | |||
| @@ -678,8 +678,8 @@ static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enab | |||
| 678 | dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n"); | 678 | dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n"); |
| 679 | } | 679 | } |
| 680 | 680 | ||
| 681 | if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) || (sharpsl_fatal_check() < 0) ) | 681 | if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) || |
| 682 | { | 682 | (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL))) { |
| 683 | dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n"); | 683 | dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n"); |
| 684 | corgi_goto_sleep(alarm_time, alarm_enable, state); | 684 | corgi_goto_sleep(alarm_time, alarm_enable, state); |
| 685 | return 1; | 685 | return 1; |
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig index d4cfa2145386..dfc9b0bc6eb2 100644 --- a/arch/arm/mach-realview/Kconfig +++ b/arch/arm/mach-realview/Kconfig | |||
| @@ -75,7 +75,7 @@ config MACH_REALVIEW_PBX | |||
| 75 | 75 | ||
| 76 | config REALVIEW_HIGH_PHYS_OFFSET | 76 | config REALVIEW_HIGH_PHYS_OFFSET |
| 77 | bool "High physical base address for the RealView platform" | 77 | bool "High physical base address for the RealView platform" |
| 78 | depends on !MACH_REALVIEW_PB1176 | 78 | depends on MMU && !MACH_REALVIEW_PB1176 |
| 79 | default y | 79 | default y |
| 80 | help | 80 | help |
| 81 | RealView boards other than PB1176 have the RAM available at | 81 | RealView boards other than PB1176 have the RAM available at |
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index facbd49eec67..dc3519c50ab2 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
| @@ -221,6 +221,9 @@ arch_initcall(realview_i2c_init); | |||
| 221 | 221 | ||
| 222 | #define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET) | 222 | #define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET) |
| 223 | 223 | ||
| 224 | /* | ||
| 225 | * This is only used if GPIOLIB support is disabled | ||
| 226 | */ | ||
| 224 | static unsigned int realview_mmc_status(struct device *dev) | 227 | static unsigned int realview_mmc_status(struct device *dev) |
| 225 | { | 228 | { |
| 226 | struct amba_device *adev = container_of(dev, struct amba_device, dev); | 229 | struct amba_device *adev = container_of(dev, struct amba_device, dev); |
| @@ -237,11 +240,15 @@ static unsigned int realview_mmc_status(struct device *dev) | |||
| 237 | struct mmc_platform_data realview_mmc0_plat_data = { | 240 | struct mmc_platform_data realview_mmc0_plat_data = { |
| 238 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | 241 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, |
| 239 | .status = realview_mmc_status, | 242 | .status = realview_mmc_status, |
| 243 | .gpio_wp = 17, | ||
| 244 | .gpio_cd = 16, | ||
| 240 | }; | 245 | }; |
| 241 | 246 | ||
| 242 | struct mmc_platform_data realview_mmc1_plat_data = { | 247 | struct mmc_platform_data realview_mmc1_plat_data = { |
| 243 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | 248 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, |
| 244 | .status = realview_mmc_status, | 249 | .status = realview_mmc_status, |
| 250 | .gpio_wp = 19, | ||
| 251 | .gpio_cd = 18, | ||
| 245 | }; | 252 | }; |
| 246 | 253 | ||
| 247 | /* | 254 | /* |
diff --git a/arch/arm/mach-realview/include/mach/gpio.h b/arch/arm/mach-realview/include/mach/gpio.h new file mode 100644 index 000000000000..94ff27678a46 --- /dev/null +++ b/arch/arm/mach-realview/include/mach/gpio.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #include <asm-generic/gpio.h> | ||
| 2 | |||
| 3 | #define gpio_get_value __gpio_get_value | ||
| 4 | #define gpio_set_value __gpio_set_value | ||
| 5 | #define gpio_cansleep __gpio_cansleep | ||
| 6 | #define gpio_to_irq __gpio_to_irq | ||
diff --git a/arch/arm/mach-realview/include/mach/hardware.h b/arch/arm/mach-realview/include/mach/hardware.h index b42c14f89acb..8a638d15797f 100644 --- a/arch/arm/mach-realview/include/mach/hardware.h +++ b/arch/arm/mach-realview/include/mach/hardware.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <asm/sizes.h> | 25 | #include <asm/sizes.h> |
| 26 | 26 | ||
| 27 | /* macro to get at IO space when running virtually */ | 27 | /* macro to get at IO space when running virtually */ |
| 28 | #ifdef CONFIG_MMU | ||
| 28 | /* | 29 | /* |
| 29 | * Statically mapped addresses: | 30 | * Statically mapped addresses: |
| 30 | * | 31 | * |
| @@ -33,6 +34,9 @@ | |||
| 33 | * 1fxx xxxx -> fexx xxxx | 34 | * 1fxx xxxx -> fexx xxxx |
| 34 | */ | 35 | */ |
| 35 | #define IO_ADDRESS(x) (((x) & 0x03ffffff) + 0xfb000000) | 36 | #define IO_ADDRESS(x) (((x) & 0x03ffffff) + 0xfb000000) |
| 37 | #else | ||
| 38 | #define IO_ADDRESS(x) (x) | ||
| 39 | #endif | ||
| 36 | #define __io_address(n) __io(IO_ADDRESS(n)) | 40 | #define __io_address(n) __io(IO_ADDRESS(n)) |
| 37 | 41 | ||
| 38 | #endif | 42 | #endif |
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index ac0e83f1cc3a..a88458b4799d 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <mach/hardware.h> | 20 | #include <mach/hardware.h> |
| 21 | #include <asm/mach-types.h> | 21 | #include <asm/mach-types.h> |
| 22 | #include <asm/localtimer.h> | 22 | #include <asm/localtimer.h> |
| 23 | #include <asm/unified.h> | ||
| 23 | 24 | ||
| 24 | #include <mach/board-eb.h> | 25 | #include <mach/board-eb.h> |
| 25 | #include <mach/board-pb11mp.h> | 26 | #include <mach/board-pb11mp.h> |
| @@ -137,26 +138,19 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
| 137 | 138 | ||
| 138 | static void __init poke_milo(void) | 139 | static void __init poke_milo(void) |
| 139 | { | 140 | { |
| 140 | extern void secondary_startup(void); | ||
| 141 | |||
| 142 | /* nobody is to be released from the pen yet */ | 141 | /* nobody is to be released from the pen yet */ |
| 143 | pen_release = -1; | 142 | pen_release = -1; |
| 144 | 143 | ||
| 145 | /* | 144 | /* |
| 146 | * write the address of secondary startup into the system-wide | 145 | * Write the address of secondary startup into the system-wide flags |
| 147 | * flags register, then clear the bottom two bits, which is what | 146 | * register. The BootMonitor waits for this register to become |
| 148 | * BootMonitor is waiting for | 147 | * non-zero. |
| 149 | */ | 148 | */ |
| 150 | #if 1 | ||
| 151 | #define REALVIEW_SYS_FLAGSS_OFFSET 0x30 | 149 | #define REALVIEW_SYS_FLAGSS_OFFSET 0x30 |
| 152 | __raw_writel(virt_to_phys(realview_secondary_startup), | ||
| 153 | __io_address(REALVIEW_SYS_BASE) + | ||
| 154 | REALVIEW_SYS_FLAGSS_OFFSET); | ||
| 155 | #define REALVIEW_SYS_FLAGSC_OFFSET 0x34 | 150 | #define REALVIEW_SYS_FLAGSC_OFFSET 0x34 |
| 156 | __raw_writel(3, | 151 | __raw_writel(BSYM(virt_to_phys(realview_secondary_startup)), |
| 157 | __io_address(REALVIEW_SYS_BASE) + | 152 | __io_address(REALVIEW_SYS_BASE) + |
| 158 | REALVIEW_SYS_FLAGSC_OFFSET); | 153 | REALVIEW_SYS_FLAGSS_OFFSET); |
| 159 | #endif | ||
| 160 | 154 | ||
| 161 | mb(); | 155 | mb(); |
| 162 | } | 156 | } |
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 8dfa44e08a94..abd13b448671 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/sysdev.h> | 24 | #include <linux/sysdev.h> |
| 25 | #include <linux/amba/bus.h> | 25 | #include <linux/amba/bus.h> |
| 26 | #include <linux/amba/pl061.h> | ||
| 26 | #include <linux/io.h> | 27 | #include <linux/io.h> |
| 27 | 28 | ||
| 28 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
| @@ -113,6 +114,21 @@ static void __init realview_eb_map_io(void) | |||
| 113 | iotable_init(realview_eb11mp_io_desc, ARRAY_SIZE(realview_eb11mp_io_desc)); | 114 | iotable_init(realview_eb11mp_io_desc, ARRAY_SIZE(realview_eb11mp_io_desc)); |
| 114 | } | 115 | } |
| 115 | 116 | ||
| 117 | static struct pl061_platform_data gpio0_plat_data = { | ||
| 118 | .gpio_base = 0, | ||
| 119 | .irq_base = -1, | ||
| 120 | }; | ||
| 121 | |||
| 122 | static struct pl061_platform_data gpio1_plat_data = { | ||
| 123 | .gpio_base = 8, | ||
| 124 | .irq_base = -1, | ||
| 125 | }; | ||
| 126 | |||
| 127 | static struct pl061_platform_data gpio2_plat_data = { | ||
| 128 | .gpio_base = 16, | ||
| 129 | .irq_base = -1, | ||
| 130 | }; | ||
| 131 | |||
| 116 | /* | 132 | /* |
| 117 | * RealView EB AMBA devices | 133 | * RealView EB AMBA devices |
| 118 | */ | 134 | */ |
| @@ -189,9 +205,9 @@ AMBA_DEVICE(clcd, "dev:20", EB_CLCD, &clcd_plat_data); | |||
| 189 | AMBA_DEVICE(dmac, "dev:30", DMAC, NULL); | 205 | AMBA_DEVICE(dmac, "dev:30", DMAC, NULL); |
| 190 | AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); | 206 | AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); |
| 191 | AMBA_DEVICE(wdog, "dev:e1", EB_WATCHDOG, NULL); | 207 | AMBA_DEVICE(wdog, "dev:e1", EB_WATCHDOG, NULL); |
| 192 | AMBA_DEVICE(gpio0, "dev:e4", EB_GPIO0, NULL); | 208 | AMBA_DEVICE(gpio0, "dev:e4", EB_GPIO0, &gpio0_plat_data); |
| 193 | AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); | 209 | AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data); |
| 194 | AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); | 210 | AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data); |
| 195 | AMBA_DEVICE(rtc, "dev:e8", EB_RTC, NULL); | 211 | AMBA_DEVICE(rtc, "dev:e8", EB_RTC, NULL); |
| 196 | AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); | 212 | AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); |
| 197 | AMBA_DEVICE(uart0, "dev:f1", EB_UART0, NULL); | 213 | AMBA_DEVICE(uart0, "dev:f1", EB_UART0, NULL); |
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index 25efe71a67c7..17fbb0e889b6 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/sysdev.h> | 24 | #include <linux/sysdev.h> |
| 25 | #include <linux/amba/bus.h> | 25 | #include <linux/amba/bus.h> |
| 26 | #include <linux/amba/pl061.h> | ||
| 26 | #include <linux/io.h> | 27 | #include <linux/io.h> |
| 27 | 28 | ||
| 28 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
| @@ -107,6 +108,21 @@ static void __init realview_pb1176_map_io(void) | |||
| 107 | iotable_init(realview_pb1176_io_desc, ARRAY_SIZE(realview_pb1176_io_desc)); | 108 | iotable_init(realview_pb1176_io_desc, ARRAY_SIZE(realview_pb1176_io_desc)); |
| 108 | } | 109 | } |
| 109 | 110 | ||
| 111 | static struct pl061_platform_data gpio0_plat_data = { | ||
| 112 | .gpio_base = 0, | ||
| 113 | .irq_base = -1, | ||
| 114 | }; | ||
| 115 | |||
| 116 | static struct pl061_platform_data gpio1_plat_data = { | ||
| 117 | .gpio_base = 8, | ||
| 118 | .irq_base = -1, | ||
| 119 | }; | ||
| 120 | |||
| 121 | static struct pl061_platform_data gpio2_plat_data = { | ||
| 122 | .gpio_base = 16, | ||
| 123 | .irq_base = -1, | ||
| 124 | }; | ||
| 125 | |||
| 110 | /* | 126 | /* |
| 111 | * RealView PB1176 AMBA devices | 127 | * RealView PB1176 AMBA devices |
| 112 | */ | 128 | */ |
| @@ -164,9 +180,9 @@ AMBA_DEVICE(uart3, "fpga:09", PB1176_UART3, NULL); | |||
| 164 | AMBA_DEVICE(smc, "dev:00", PB1176_SMC, NULL); | 180 | AMBA_DEVICE(smc, "dev:00", PB1176_SMC, NULL); |
| 165 | AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); | 181 | AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); |
| 166 | AMBA_DEVICE(wdog, "dev:e1", PB1176_WATCHDOG, NULL); | 182 | AMBA_DEVICE(wdog, "dev:e1", PB1176_WATCHDOG, NULL); |
| 167 | AMBA_DEVICE(gpio0, "dev:e4", PB1176_GPIO0, NULL); | 183 | AMBA_DEVICE(gpio0, "dev:e4", PB1176_GPIO0, &gpio0_plat_data); |
| 168 | AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); | 184 | AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data); |
| 169 | AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); | 185 | AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data); |
| 170 | AMBA_DEVICE(rtc, "dev:e8", PB1176_RTC, NULL); | 186 | AMBA_DEVICE(rtc, "dev:e8", PB1176_RTC, NULL); |
| 171 | AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); | 187 | AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); |
| 172 | AMBA_DEVICE(uart0, "dev:f1", PB1176_UART0, NULL); | 188 | AMBA_DEVICE(uart0, "dev:f1", PB1176_UART0, NULL); |
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index dc4b16943907..fdd042b85f40 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/sysdev.h> | 24 | #include <linux/sysdev.h> |
| 25 | #include <linux/amba/bus.h> | 25 | #include <linux/amba/bus.h> |
| 26 | #include <linux/amba/pl061.h> | ||
| 26 | #include <linux/io.h> | 27 | #include <linux/io.h> |
| 27 | 28 | ||
| 28 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
| @@ -108,6 +109,21 @@ static void __init realview_pb11mp_map_io(void) | |||
| 108 | iotable_init(realview_pb11mp_io_desc, ARRAY_SIZE(realview_pb11mp_io_desc)); | 109 | iotable_init(realview_pb11mp_io_desc, ARRAY_SIZE(realview_pb11mp_io_desc)); |
| 109 | } | 110 | } |
| 110 | 111 | ||
| 112 | static struct pl061_platform_data gpio0_plat_data = { | ||
| 113 | .gpio_base = 0, | ||
| 114 | .irq_base = -1, | ||
| 115 | }; | ||
| 116 | |||
| 117 | static struct pl061_platform_data gpio1_plat_data = { | ||
| 118 | .gpio_base = 8, | ||
| 119 | .irq_base = -1, | ||
| 120 | }; | ||
| 121 | |||
| 122 | static struct pl061_platform_data gpio2_plat_data = { | ||
| 123 | .gpio_base = 16, | ||
| 124 | .irq_base = -1, | ||
| 125 | }; | ||
| 126 | |||
| 111 | /* | 127 | /* |
| 112 | * RealView PB11MPCore AMBA devices | 128 | * RealView PB11MPCore AMBA devices |
| 113 | */ | 129 | */ |
| @@ -166,9 +182,9 @@ AMBA_DEVICE(uart3, "fpga:09", PB11MP_UART3, NULL); | |||
| 166 | AMBA_DEVICE(smc, "dev:00", PB11MP_SMC, NULL); | 182 | AMBA_DEVICE(smc, "dev:00", PB11MP_SMC, NULL); |
| 167 | AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); | 183 | AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); |
| 168 | AMBA_DEVICE(wdog, "dev:e1", PB11MP_WATCHDOG, NULL); | 184 | AMBA_DEVICE(wdog, "dev:e1", PB11MP_WATCHDOG, NULL); |
| 169 | AMBA_DEVICE(gpio0, "dev:e4", PB11MP_GPIO0, NULL); | 185 | AMBA_DEVICE(gpio0, "dev:e4", PB11MP_GPIO0, &gpio0_plat_data); |
| 170 | AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); | 186 | AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data); |
| 171 | AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); | 187 | AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data); |
| 172 | AMBA_DEVICE(rtc, "dev:e8", PB11MP_RTC, NULL); | 188 | AMBA_DEVICE(rtc, "dev:e8", PB11MP_RTC, NULL); |
| 173 | AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); | 189 | AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); |
| 174 | AMBA_DEVICE(uart0, "dev:f1", PB11MP_UART0, NULL); | 190 | AMBA_DEVICE(uart0, "dev:f1", PB11MP_UART0, NULL); |
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index d6ac1eb86576..70bba9900d97 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/sysdev.h> | 24 | #include <linux/sysdev.h> |
| 25 | #include <linux/amba/bus.h> | 25 | #include <linux/amba/bus.h> |
| 26 | #include <linux/amba/pl061.h> | ||
| 26 | #include <linux/io.h> | 27 | #include <linux/io.h> |
| 27 | 28 | ||
| 28 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
| @@ -98,6 +99,21 @@ static void __init realview_pba8_map_io(void) | |||
| 98 | iotable_init(realview_pba8_io_desc, ARRAY_SIZE(realview_pba8_io_desc)); | 99 | iotable_init(realview_pba8_io_desc, ARRAY_SIZE(realview_pba8_io_desc)); |
| 99 | } | 100 | } |
| 100 | 101 | ||
| 102 | static struct pl061_platform_data gpio0_plat_data = { | ||
| 103 | .gpio_base = 0, | ||
| 104 | .irq_base = -1, | ||
| 105 | }; | ||
| 106 | |||
| 107 | static struct pl061_platform_data gpio1_plat_data = { | ||
| 108 | .gpio_base = 8, | ||
| 109 | .irq_base = -1, | ||
| 110 | }; | ||
| 111 | |||
| 112 | static struct pl061_platform_data gpio2_plat_data = { | ||
| 113 | .gpio_base = 16, | ||
| 114 | .irq_base = -1, | ||
| 115 | }; | ||
| 116 | |||
| 101 | /* | 117 | /* |
| 102 | * RealView PBA8Core AMBA devices | 118 | * RealView PBA8Core AMBA devices |
| 103 | */ | 119 | */ |
| @@ -156,9 +172,9 @@ AMBA_DEVICE(uart3, "fpga:09", PBA8_UART3, NULL); | |||
| 156 | AMBA_DEVICE(smc, "dev:00", PBA8_SMC, NULL); | 172 | AMBA_DEVICE(smc, "dev:00", PBA8_SMC, NULL); |
| 157 | AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); | 173 | AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); |
| 158 | AMBA_DEVICE(wdog, "dev:e1", PBA8_WATCHDOG, NULL); | 174 | AMBA_DEVICE(wdog, "dev:e1", PBA8_WATCHDOG, NULL); |
| 159 | AMBA_DEVICE(gpio0, "dev:e4", PBA8_GPIO0, NULL); | 175 | AMBA_DEVICE(gpio0, "dev:e4", PBA8_GPIO0, &gpio0_plat_data); |
| 160 | AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); | 176 | AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data); |
| 161 | AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); | 177 | AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data); |
| 162 | AMBA_DEVICE(rtc, "dev:e8", PBA8_RTC, NULL); | 178 | AMBA_DEVICE(rtc, "dev:e8", PBA8_RTC, NULL); |
| 163 | AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); | 179 | AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); |
| 164 | AMBA_DEVICE(uart0, "dev:f1", PBA8_UART0, NULL); | 180 | AMBA_DEVICE(uart0, "dev:f1", PBA8_UART0, NULL); |
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c index ede2a57240a3..ce6c5d25fbef 100644 --- a/arch/arm/mach-realview/realview_pbx.c +++ b/arch/arm/mach-realview/realview_pbx.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 23 | #include <linux/sysdev.h> | 23 | #include <linux/sysdev.h> |
| 24 | #include <linux/amba/bus.h> | 24 | #include <linux/amba/bus.h> |
| 25 | #include <linux/amba/pl061.h> | ||
| 25 | #include <linux/io.h> | 26 | #include <linux/io.h> |
| 26 | 27 | ||
| 27 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
| @@ -118,6 +119,21 @@ static void __init realview_pbx_map_io(void) | |||
| 118 | iotable_init(realview_local_io_desc, ARRAY_SIZE(realview_local_io_desc)); | 119 | iotable_init(realview_local_io_desc, ARRAY_SIZE(realview_local_io_desc)); |
| 119 | } | 120 | } |
| 120 | 121 | ||
| 122 | static struct pl061_platform_data gpio0_plat_data = { | ||
| 123 | .gpio_base = 0, | ||
| 124 | .irq_base = -1, | ||
| 125 | }; | ||
| 126 | |||
| 127 | static struct pl061_platform_data gpio1_plat_data = { | ||
| 128 | .gpio_base = 8, | ||
| 129 | .irq_base = -1, | ||
| 130 | }; | ||
| 131 | |||
| 132 | static struct pl061_platform_data gpio2_plat_data = { | ||
| 133 | .gpio_base = 16, | ||
| 134 | .irq_base = -1, | ||
| 135 | }; | ||
| 136 | |||
| 121 | /* | 137 | /* |
| 122 | * RealView PBXCore AMBA devices | 138 | * RealView PBXCore AMBA devices |
| 123 | */ | 139 | */ |
| @@ -176,9 +192,9 @@ AMBA_DEVICE(uart3, "fpga:09", PBX_UART3, NULL); | |||
| 176 | AMBA_DEVICE(smc, "dev:00", PBX_SMC, NULL); | 192 | AMBA_DEVICE(smc, "dev:00", PBX_SMC, NULL); |
| 177 | AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); | 193 | AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); |
| 178 | AMBA_DEVICE(wdog, "dev:e1", PBX_WATCHDOG, NULL); | 194 | AMBA_DEVICE(wdog, "dev:e1", PBX_WATCHDOG, NULL); |
| 179 | AMBA_DEVICE(gpio0, "dev:e4", PBX_GPIO0, NULL); | 195 | AMBA_DEVICE(gpio0, "dev:e4", PBX_GPIO0, &gpio0_plat_data); |
| 180 | AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); | 196 | AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data); |
| 181 | AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); | 197 | AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data); |
| 182 | AMBA_DEVICE(rtc, "dev:e8", PBX_RTC, NULL); | 198 | AMBA_DEVICE(rtc, "dev:e8", PBX_RTC, NULL); |
| 183 | AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); | 199 | AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); |
| 184 | AMBA_DEVICE(uart0, "dev:f1", PBX_UART0, NULL); | 200 | AMBA_DEVICE(uart0, "dev:f1", PBX_UART0, NULL); |
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 41bb65d5b91f..d8c023d4df30 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig | |||
| @@ -12,6 +12,7 @@ config CPU_S3C2410 | |||
| 12 | select S3C2410_GPIO | 12 | select S3C2410_GPIO |
| 13 | select CPU_LLSERIAL_S3C2410 | 13 | select CPU_LLSERIAL_S3C2410 |
| 14 | select S3C2410_PM if PM | 14 | select S3C2410_PM if PM |
| 15 | select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX | ||
| 15 | help | 16 | help |
| 16 | Support for S3C2410 and S3C2410A family from the S3C24XX line | 17 | Support for S3C2410 and S3C2410A family from the S3C24XX line |
| 17 | of Samsung Mobile CPUs. | 18 | of Samsung Mobile CPUs. |
| @@ -45,6 +46,22 @@ config MACH_BAST_IDE | |||
| 45 | Internal node for machines with an BAST style IDE | 46 | Internal node for machines with an BAST style IDE |
| 46 | interface | 47 | interface |
| 47 | 48 | ||
| 49 | # cpu frequency scaling support | ||
| 50 | |||
| 51 | config S3C2410_CPUFREQ | ||
| 52 | bool | ||
| 53 | depends on CPU_FREQ_S3C24XX && CPU_S3C2410 | ||
| 54 | select S3C2410_CPUFREQ_UTILS | ||
| 55 | help | ||
| 56 | CPU Frequency scaling support for S3C2410 | ||
| 57 | |||
| 58 | config S3C2410_PLLTABLE | ||
| 59 | bool | ||
| 60 | depends on S3C2410_CPUFREQ && CPU_FREQ_S3C24XX_PLL | ||
| 61 | default y | ||
| 62 | help | ||
| 63 | Select the PLL table for the S3C2410 | ||
| 64 | |||
| 48 | menu "S3C2410 Machines" | 65 | menu "S3C2410 Machines" |
| 49 | 66 | ||
| 50 | config ARCH_SMDK2410 | 67 | config ARCH_SMDK2410 |
| @@ -79,6 +96,7 @@ config MACH_N30 | |||
| 79 | config ARCH_BAST | 96 | config ARCH_BAST |
| 80 | bool "Simtec Electronics BAST (EB2410ITX)" | 97 | bool "Simtec Electronics BAST (EB2410ITX)" |
| 81 | select CPU_S3C2410 | 98 | select CPU_S3C2410 |
| 99 | select S3C2410_IOTIMING if S3C2410_CPUFREQ | ||
| 82 | select PM_SIMTEC if PM | 100 | select PM_SIMTEC if PM |
| 83 | select SIMTEC_NOR | 101 | select SIMTEC_NOR |
| 84 | select MACH_BAST_IDE | 102 | select MACH_BAST_IDE |
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index fca02f82711c..2ab5ba4b266f 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile | |||
| @@ -15,6 +15,8 @@ obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o | |||
| 15 | obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o | 15 | obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o |
| 16 | obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o | 16 | obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o |
| 17 | obj-$(CONFIG_S3C2410_GPIO) += gpio.o | 17 | obj-$(CONFIG_S3C2410_GPIO) += gpio.o |
| 18 | obj-$(CONFIG_S3C2410_CPUFREQ) += cpu-freq.o | ||
| 19 | obj-$(CONFIG_S3C2410_PLLTABLE) += pll.o | ||
| 18 | 20 | ||
| 19 | # Machine support | 21 | # Machine support |
| 20 | 22 | ||
diff --git a/arch/arm/mach-s3c2410/cpu-freq.c b/arch/arm/mach-s3c2410/cpu-freq.c new file mode 100644 index 000000000000..9d1186877d08 --- /dev/null +++ b/arch/arm/mach-s3c2410/cpu-freq.c | |||
| @@ -0,0 +1,159 @@ | |||
| 1 | /* linux/arch/arm/mach-s3c2410/cpu-freq.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2006,2008 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * | ||
| 7 | * S3C2410 CPU Frequency scaling | ||
| 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 | #include <linux/init.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/ioport.h> | ||
| 18 | #include <linux/cpufreq.h> | ||
| 19 | #include <linux/sysdev.h> | ||
| 20 | #include <linux/clk.h> | ||
| 21 | #include <linux/err.h> | ||
| 22 | #include <linux/io.h> | ||
| 23 | |||
| 24 | #include <asm/mach/arch.h> | ||
| 25 | #include <asm/mach/map.h> | ||
| 26 | |||
| 27 | #include <mach/regs-clock.h> | ||
| 28 | |||
| 29 | #include <plat/cpu.h> | ||
| 30 | #include <plat/clock.h> | ||
| 31 | #include <plat/cpu-freq-core.h> | ||
| 32 | |||
| 33 | /* Note, 2410A has an extra mode for 1:4:4 ratio, bit 2 of CLKDIV */ | ||
| 34 | |||
| 35 | static void s3c2410_cpufreq_setdivs(struct s3c_cpufreq_config *cfg) | ||
| 36 | { | ||
| 37 | u32 clkdiv = 0; | ||
| 38 | |||
| 39 | if (cfg->divs.h_divisor == 2) | ||
| 40 | clkdiv |= S3C2410_CLKDIVN_HDIVN; | ||
| 41 | |||
| 42 | if (cfg->divs.p_divisor != cfg->divs.h_divisor) | ||
| 43 | clkdiv |= S3C2410_CLKDIVN_PDIVN; | ||
| 44 | |||
| 45 | __raw_writel(clkdiv, S3C2410_CLKDIVN); | ||
| 46 | } | ||
| 47 | |||
| 48 | static int s3c2410_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg) | ||
| 49 | { | ||
| 50 | unsigned long hclk, fclk, pclk; | ||
| 51 | unsigned int hdiv, pdiv; | ||
| 52 | unsigned long hclk_max; | ||
| 53 | |||
| 54 | fclk = cfg->freq.fclk; | ||
| 55 | hclk_max = cfg->max.hclk; | ||
| 56 | |||
| 57 | cfg->freq.armclk = fclk; | ||
| 58 | |||
| 59 | s3c_freq_dbg("%s: fclk is %lu, max hclk %lu\n", | ||
| 60 | __func__, fclk, hclk_max); | ||
| 61 | |||
| 62 | hdiv = (fclk > cfg->max.hclk) ? 2 : 1; | ||
| 63 | hclk = fclk / hdiv; | ||
| 64 | |||
| 65 | if (hclk > cfg->max.hclk) { | ||
| 66 | s3c_freq_dbg("%s: hclk too big\n", __func__); | ||
| 67 | return -EINVAL; | ||
| 68 | } | ||
| 69 | |||
| 70 | pdiv = (hclk > cfg->max.pclk) ? 2 : 1; | ||
| 71 | pclk = hclk / pdiv; | ||
| 72 | |||
| 73 | if (pclk > cfg->max.pclk) { | ||
| 74 | s3c_freq_dbg("%s: pclk too big\n", __func__); | ||
| 75 | return -EINVAL; | ||
| 76 | } | ||
| 77 | |||
| 78 | pdiv *= hdiv; | ||
| 79 | |||
| 80 | /* record the result */ | ||
| 81 | cfg->divs.p_divisor = pdiv; | ||
| 82 | cfg->divs.h_divisor = hdiv; | ||
| 83 | |||
| 84 | return 0 ; | ||
| 85 | } | ||
| 86 | |||
| 87 | static struct s3c_cpufreq_info s3c2410_cpufreq_info = { | ||
| 88 | .max = { | ||
| 89 | .fclk = 200000000, | ||
| 90 | .hclk = 100000000, | ||
| 91 | .pclk = 50000000, | ||
| 92 | }, | ||
| 93 | |||
| 94 | /* transition latency is about 5ms worst-case, so | ||
| 95 | * set 10ms to be sure */ | ||
| 96 | .latency = 10000000, | ||
| 97 | |||
| 98 | .locktime_m = 150, | ||
| 99 | .locktime_u = 150, | ||
| 100 | .locktime_bits = 12, | ||
| 101 | |||
| 102 | .need_pll = 1, | ||
| 103 | |||
| 104 | .name = "s3c2410", | ||
| 105 | .calc_iotiming = s3c2410_iotiming_calc, | ||
| 106 | .set_iotiming = s3c2410_iotiming_set, | ||
| 107 | .get_iotiming = s3c2410_iotiming_get, | ||
| 108 | .resume_clocks = s3c2410_setup_clocks, | ||
| 109 | |||
| 110 | .set_fvco = s3c2410_set_fvco, | ||
| 111 | .set_refresh = s3c2410_cpufreq_setrefresh, | ||
| 112 | .set_divs = s3c2410_cpufreq_setdivs, | ||
| 113 | .calc_divs = s3c2410_cpufreq_calcdivs, | ||
| 114 | |||
| 115 | .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs), | ||
| 116 | }; | ||
| 117 | |||
| 118 | static int s3c2410_cpufreq_add(struct sys_device *sysdev) | ||
| 119 | { | ||
| 120 | return s3c_cpufreq_register(&s3c2410_cpufreq_info); | ||
| 121 | } | ||
| 122 | |||
| 123 | static struct sysdev_driver s3c2410_cpufreq_driver = { | ||
| 124 | .add = s3c2410_cpufreq_add, | ||
| 125 | }; | ||
| 126 | |||
| 127 | static int __init s3c2410_cpufreq_init(void) | ||
| 128 | { | ||
| 129 | return sysdev_driver_register(&s3c2410_sysclass, | ||
| 130 | &s3c2410_cpufreq_driver); | ||
| 131 | } | ||
| 132 | |||
| 133 | arch_initcall(s3c2410_cpufreq_init); | ||
| 134 | |||
| 135 | static int s3c2410a_cpufreq_add(struct sys_device *sysdev) | ||
| 136 | { | ||
| 137 | /* alter the maximum freq settings for S3C2410A. If a board knows | ||
| 138 | * it only has a maximum of 200, then it should register its own | ||
| 139 | * limits. */ | ||
| 140 | |||
| 141 | s3c2410_cpufreq_info.max.fclk = 266000000; | ||
| 142 | s3c2410_cpufreq_info.max.hclk = 133000000; | ||
| 143 | s3c2410_cpufreq_info.max.pclk = 66500000; | ||
| 144 | s3c2410_cpufreq_info.name = "s3c2410a"; | ||
| 145 | |||
| 146 | return s3c2410_cpufreq_add(sysdev); | ||
| 147 | } | ||
| 148 | |||
| 149 | static struct sysdev_driver s3c2410a_cpufreq_driver = { | ||
| 150 | .add = s3c2410a_cpufreq_add, | ||
| 151 | }; | ||
| 152 | |||
| 153 | static int __init s3c2410a_cpufreq_init(void) | ||
| 154 | { | ||
| 155 | return sysdev_driver_register(&s3c2410a_sysclass, | ||
| 156 | &s3c2410a_cpufreq_driver); | ||
| 157 | } | ||
| 158 | |||
| 159 | arch_initcall(s3c2410a_cpufreq_init); | ||
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index dbf96e60d992..63b753f56c64 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c | |||
| @@ -164,6 +164,17 @@ static int __init s3c2410_dma_drvinit(void) | |||
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | arch_initcall(s3c2410_dma_drvinit); | 166 | arch_initcall(s3c2410_dma_drvinit); |
| 167 | |||
| 168 | static struct sysdev_driver s3c2410a_dma_driver = { | ||
| 169 | .add = s3c2410_dma_add, | ||
| 170 | }; | ||
| 171 | |||
| 172 | static int __init s3c2410a_dma_drvinit(void) | ||
| 173 | { | ||
| 174 | return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_dma_driver); | ||
| 175 | } | ||
| 176 | |||
| 177 | arch_initcall(s3c2410a_dma_drvinit); | ||
| 167 | #endif | 178 | #endif |
| 168 | 179 | ||
| 169 | #if defined(CONFIG_CPU_S3C2442) | 180 | #if defined(CONFIG_CPU_S3C2442) |
diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h index 2a2384ffa7b1..6c12c6312ad8 100644 --- a/arch/arm/mach-s3c2410/include/mach/irqs.h +++ b/arch/arm/mach-s3c2410/include/mach/irqs.h | |||
| @@ -164,6 +164,12 @@ | |||
| 164 | #define IRQ_S3CUART_TX3 IRQ_S3C2443_TX3 | 164 | #define IRQ_S3CUART_TX3 IRQ_S3C2443_TX3 |
| 165 | #define IRQ_S3CUART_ERR3 IRQ_S3C2443_ERR3 | 165 | #define IRQ_S3CUART_ERR3 IRQ_S3C2443_ERR3 |
| 166 | 166 | ||
| 167 | #ifdef CONFIG_CPU_S3C2440 | ||
| 168 | #define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97 | ||
| 169 | #else | ||
| 170 | #define IRQ_S3C244x_AC97 IRQ_S3C2443_AC97 | ||
| 171 | #endif | ||
| 172 | |||
| 167 | /* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */ | 173 | /* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */ |
| 168 | #define FIQ_START IRQ_EINT0 | 174 | #define FIQ_START IRQ_EINT0 |
| 169 | 175 | ||
diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h index e99b212cb1ca..b049e61460b6 100644 --- a/arch/arm/mach-s3c2410/include/mach/map.h +++ b/arch/arm/mach-s3c2410/include/mach/map.h | |||
| @@ -67,6 +67,13 @@ | |||
| 67 | #define S3C2443_PA_HSMMC (0x4A800000) | 67 | #define S3C2443_PA_HSMMC (0x4A800000) |
| 68 | #define S3C2443_SZ_HSMMC (256) | 68 | #define S3C2443_SZ_HSMMC (256) |
| 69 | 69 | ||
| 70 | /* S3C2412 memory and IO controls */ | ||
| 71 | #define S3C2412_PA_SSMC (0x4F000000) | ||
| 72 | #define S3C2412_VA_SSMC S3C_ADDR_CPU(0x00000000) | ||
| 73 | |||
| 74 | #define S3C2412_PA_EBI (0x48800000) | ||
| 75 | #define S3C2412_VA_EBI S3C_ADDR_CPU(0x00010000) | ||
| 76 | |||
| 70 | /* physical addresses of all the chip-select areas */ | 77 | /* physical addresses of all the chip-select areas */ |
| 71 | 78 | ||
| 72 | #define S3C2410_CS0 (0x00000000) | 79 | #define S3C2410_CS0 (0x00000000) |
| @@ -103,5 +110,6 @@ | |||
| 103 | #define S3C_PA_UART S3C24XX_PA_UART | 110 | #define S3C_PA_UART S3C24XX_PA_UART |
| 104 | #define S3C_PA_USBHOST S3C2410_PA_USBHOST | 111 | #define S3C_PA_USBHOST S3C2410_PA_USBHOST |
| 105 | #define S3C_PA_HSMMC0 S3C2443_PA_HSMMC | 112 | #define S3C_PA_HSMMC0 S3C2443_PA_HSMMC |
| 113 | #define S3C_PA_NAND S3C24XX_PA_NAND | ||
| 106 | 114 | ||
| 107 | #endif /* __ASM_ARCH_MAP_H */ | 115 | #endif /* __ASM_ARCH_MAP_H */ |
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h index b278d0c45ccf..f6e8eec879c8 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h | |||
| @@ -328,13 +328,15 @@ | |||
| 328 | 328 | ||
| 329 | #define S3C2410_GPD8_VD16 (0x02 << 16) | 329 | #define S3C2410_GPD8_VD16 (0x02 << 16) |
| 330 | #define S3C2400_GPD8_TOUT3 (0x02 << 16) | 330 | #define S3C2400_GPD8_TOUT3 (0x02 << 16) |
| 331 | #define S3C2440_GPD8_SPIMISO1 (0x03 << 16) | ||
| 331 | 332 | ||
| 332 | #define S3C2410_GPD9_VD17 (0x02 << 18) | 333 | #define S3C2410_GPD9_VD17 (0x02 << 18) |
| 333 | #define S3C2400_GPD9_TCLK0 (0x02 << 18) | 334 | #define S3C2400_GPD9_TCLK0 (0x02 << 18) |
| 334 | #define S3C2410_GPD9_MASK (0x03 << 18) | 335 | #define S3C2440_GPD9_SPIMOSI1 (0x03 << 18) |
| 335 | 336 | ||
| 336 | #define S3C2410_GPD10_VD18 (0x02 << 20) | 337 | #define S3C2410_GPD10_VD18 (0x02 << 20) |
| 337 | #define S3C2400_GPD10_nWAIT (0x02 << 20) | 338 | #define S3C2400_GPD10_nWAIT (0x02 << 20) |
| 339 | #define S3C2440_GPD10_SPICLK1 (0x03 << 20) | ||
| 338 | 340 | ||
| 339 | #define S3C2410_GPD11_VD19 (0x02 << 22) | 341 | #define S3C2410_GPD11_VD19 (0x02 << 22) |
| 340 | 342 | ||
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-mem.h index 57759804e2fa..7f7c52947963 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-mem.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-mem.h | |||
| @@ -73,6 +73,16 @@ | |||
| 73 | #define S3C2410_BWSCON_WS7 (1<<30) | 73 | #define S3C2410_BWSCON_WS7 (1<<30) |
| 74 | #define S3C2410_BWSCON_ST7 (1<<31) | 74 | #define S3C2410_BWSCON_ST7 (1<<31) |
| 75 | 75 | ||
| 76 | /* accesor functions for getting BANK(n) configuration. (n != 0) */ | ||
| 77 | |||
| 78 | #define S3C2410_BWSCON_GET(_bwscon, _bank) (((_bwscon) >> ((_bank) * 4)) & 0xf) | ||
| 79 | |||
| 80 | #define S3C2410_BWSCON_DW8 (0) | ||
| 81 | #define S3C2410_BWSCON_DW16 (1) | ||
| 82 | #define S3C2410_BWSCON_DW32 (2) | ||
| 83 | #define S3C2410_BWSCON_WS (1 << 2) | ||
| 84 | #define S3C2410_BWSCON_ST (1 << 3) | ||
| 85 | |||
| 76 | /* memory set (rom, ram) */ | 86 | /* memory set (rom, ram) */ |
| 77 | #define S3C2410_BANKCON0 S3C2410_MEMREG(0x0004) | 87 | #define S3C2410_BANKCON0 S3C2410_MEMREG(0x0004) |
| 78 | #define S3C2410_BANKCON1 S3C2410_MEMREG(0x0008) | 88 | #define S3C2410_BANKCON1 S3C2410_MEMREG(0x0008) |
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h index a4bf27123170..fb6352515090 100644 --- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h +++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h | |||
| @@ -14,9 +14,11 @@ | |||
| 14 | #ifndef __ASM_ARM_REGS_S3C2412_MEM | 14 | #ifndef __ASM_ARM_REGS_S3C2412_MEM |
| 15 | #define __ASM_ARM_REGS_S3C2412_MEM | 15 | #define __ASM_ARM_REGS_S3C2412_MEM |
| 16 | 16 | ||
| 17 | #ifndef S3C2412_MEMREG | ||
| 18 | #define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x)) | 17 | #define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x)) |
| 19 | #endif | 18 | #define S3C2412_EBIREG(x) (S3C2412_VA_EBI + (x)) |
| 19 | |||
| 20 | #define S3C2412_SSMCREG(x) (S3C2412_VA_SSMC + (x)) | ||
| 21 | #define S3C2412_SSMC(x, o) (S3C2412_SSMCREG((x * 0x20) + (o))) | ||
| 20 | 22 | ||
| 21 | #define S3C2412_BANKCFG S3C2412_MEMREG(0x00) | 23 | #define S3C2412_BANKCFG S3C2412_MEMREG(0x00) |
| 22 | #define S3C2412_BANKCON1 S3C2412_MEMREG(0x04) | 24 | #define S3C2412_BANKCON1 S3C2412_MEMREG(0x04) |
| @@ -26,4 +28,21 @@ | |||
| 26 | #define S3C2412_REFRESH S3C2412_MEMREG(0x10) | 28 | #define S3C2412_REFRESH S3C2412_MEMREG(0x10) |
| 27 | #define S3C2412_TIMEOUT S3C2412_MEMREG(0x14) | 29 | #define S3C2412_TIMEOUT S3C2412_MEMREG(0x14) |
| 28 | 30 | ||
| 31 | /* EBI control registers */ | ||
| 32 | |||
| 33 | #define S3C2412_EBI_PR S3C2412_EBIREG(0x00) | ||
| 34 | #define S3C2412_EBI_BANKCFG S3C2412_EBIREG(0x04) | ||
| 35 | |||
| 36 | /* SSMC control registers */ | ||
| 37 | |||
| 38 | #define S3C2412_SSMC_BANK(x) S3C2412_SSMC(x, 0x00) | ||
| 39 | #define S3C2412_SMIDCYR(x) S3C2412_SSMC(x, 0x00) | ||
| 40 | #define S3C2412_SMBWSTRD(x) S3C2412_SSMC(x, 0x04) | ||
| 41 | #define S3C2412_SMBWSTWRR(x) S3C2412_SSMC(x, 0x08) | ||
| 42 | #define S3C2412_SMBWSTOENR(x) S3C2412_SSMC(x, 0x0C) | ||
| 43 | #define S3C2412_SMBWSTWENR(x) S3C2412_SSMC(x, 0x10) | ||
| 44 | #define S3C2412_SMBCR(x) S3C2412_SSMC(x, 0x14) | ||
| 45 | #define S3C2412_SMBSR(x) S3C2412_SSMC(x, 0x18) | ||
| 46 | #define S3C2412_SMBWSTBRDR(x) S3C2412_SSMC(x, 0x1C) | ||
| 47 | |||
| 29 | #endif /* __ASM_ARM_REGS_S3C2412_MEM */ | 48 | #endif /* __ASM_ARM_REGS_S3C2412_MEM */ |
diff --git a/arch/arm/mach-s3c2410/include/mach/spi.h b/arch/arm/mach-s3c2410/include/mach/spi.h index 1d300fb112b1..193b39d654ed 100644 --- a/arch/arm/mach-s3c2410/include/mach/spi.h +++ b/arch/arm/mach-s3c2410/include/mach/spi.h | |||
| @@ -30,4 +30,7 @@ extern void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi, | |||
| 30 | extern void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi, | 30 | extern void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi, |
| 31 | int enable); | 31 | int enable); |
| 32 | 32 | ||
| 33 | extern void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi, | ||
| 34 | int enable); | ||
| 35 | |||
| 33 | #endif /* __ASM_ARCH_SPI_H */ | 36 | #endif /* __ASM_ARCH_SPI_H */ |
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index 92150399563b..5e2f35332056 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c | |||
| @@ -39,9 +39,22 @@ static struct sysdev_driver s3c2410_irq_driver = { | |||
| 39 | .resume = s3c24xx_irq_resume, | 39 | .resume = s3c24xx_irq_resume, |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | static int s3c2410_irq_init(void) | 42 | static int __init s3c2410_irq_init(void) |
| 43 | { | 43 | { |
| 44 | return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver); | 44 | return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | arch_initcall(s3c2410_irq_init); | 47 | arch_initcall(s3c2410_irq_init); |
| 48 | |||
| 49 | static struct sysdev_driver s3c2410a_irq_driver = { | ||
| 50 | .add = s3c2410_irq_add, | ||
| 51 | .suspend = s3c24xx_irq_suspend, | ||
| 52 | .resume = s3c24xx_irq_resume, | ||
| 53 | }; | ||
| 54 | |||
| 55 | static int __init s3c2410a_irq_init(void) | ||
| 56 | { | ||
| 57 | return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_irq_driver); | ||
| 58 | } | ||
| 59 | |||
| 60 | arch_initcall(s3c2410a_irq_init); | ||
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index ce3baba2cd7f..647c9adb018f 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #include <mach/regs-mem.h> | 45 | #include <mach/regs-mem.h> |
| 46 | #include <mach/regs-lcd.h> | 46 | #include <mach/regs-lcd.h> |
| 47 | 47 | ||
| 48 | #include <plat/hwmon.h> | ||
| 48 | #include <plat/nand.h> | 49 | #include <plat/nand.h> |
| 49 | #include <plat/iic.h> | 50 | #include <plat/iic.h> |
| 50 | #include <mach/fb.h> | 51 | #include <mach/fb.h> |
| @@ -59,6 +60,7 @@ | |||
| 59 | #include <plat/clock.h> | 60 | #include <plat/clock.h> |
| 60 | #include <plat/devs.h> | 61 | #include <plat/devs.h> |
| 61 | #include <plat/cpu.h> | 62 | #include <plat/cpu.h> |
| 63 | #include <plat/cpu-freq.h> | ||
| 62 | 64 | ||
| 63 | #include "usb-simtec.h" | 65 | #include "usb-simtec.h" |
| 64 | #include "nor-simtec.h" | 66 | #include "nor-simtec.h" |
| @@ -547,7 +549,35 @@ static struct i2c_board_info bast_i2c_devs[] __initdata = { | |||
| 547 | }, | 549 | }, |
| 548 | }; | 550 | }; |
| 549 | 551 | ||
| 552 | static struct s3c_hwmon_pdata bast_hwmon_info = { | ||
| 553 | /* LCD contrast (0-6.6V) */ | ||
| 554 | .in[0] = &(struct s3c_hwmon_chcfg) { | ||
| 555 | .name = "lcd-contrast", | ||
| 556 | .mult = 3300, | ||
| 557 | .div = 512, | ||
| 558 | }, | ||
| 559 | /* LED current feedback */ | ||
| 560 | .in[1] = &(struct s3c_hwmon_chcfg) { | ||
| 561 | .name = "led-feedback", | ||
| 562 | .mult = 3300, | ||
| 563 | .div = 1024, | ||
| 564 | }, | ||
| 565 | /* LCD feedback (0-6.6V) */ | ||
| 566 | .in[2] = &(struct s3c_hwmon_chcfg) { | ||
| 567 | .name = "lcd-feedback", | ||
| 568 | .mult = 3300, | ||
| 569 | .div = 512, | ||
| 570 | }, | ||
| 571 | /* Vcore (1.8-2.0V), Vref 3.3V */ | ||
| 572 | .in[3] = &(struct s3c_hwmon_chcfg) { | ||
| 573 | .name = "vcore", | ||
| 574 | .mult = 3300, | ||
| 575 | .div = 1024, | ||
| 576 | }, | ||
| 577 | }; | ||
| 578 | |||
| 550 | /* Standard BAST devices */ | 579 | /* Standard BAST devices */ |
| 580 | // cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0 | ||
| 551 | 581 | ||
| 552 | static struct platform_device *bast_devices[] __initdata = { | 582 | static struct platform_device *bast_devices[] __initdata = { |
| 553 | &s3c_device_usb, | 583 | &s3c_device_usb, |
| @@ -556,6 +586,8 @@ static struct platform_device *bast_devices[] __initdata = { | |||
| 556 | &s3c_device_i2c0, | 586 | &s3c_device_i2c0, |
| 557 | &s3c_device_rtc, | 587 | &s3c_device_rtc, |
| 558 | &s3c_device_nand, | 588 | &s3c_device_nand, |
| 589 | &s3c_device_adc, | ||
| 590 | &s3c_device_hwmon, | ||
| 559 | &bast_device_dm9k, | 591 | &bast_device_dm9k, |
| 560 | &bast_device_asix, | 592 | &bast_device_asix, |
| 561 | &bast_device_axpp, | 593 | &bast_device_axpp, |
| @@ -570,6 +602,12 @@ static struct clk *bast_clocks[] __initdata = { | |||
| 570 | &s3c24xx_uclk, | 602 | &s3c24xx_uclk, |
| 571 | }; | 603 | }; |
| 572 | 604 | ||
| 605 | static struct s3c_cpufreq_board __initdata bast_cpufreq = { | ||
| 606 | .refresh = 7800, /* 7.8usec */ | ||
| 607 | .auto_io = 1, | ||
| 608 | .need_io = 1, | ||
| 609 | }; | ||
| 610 | |||
| 573 | static void __init bast_map_io(void) | 611 | static void __init bast_map_io(void) |
| 574 | { | 612 | { |
| 575 | /* initialise the clocks */ | 613 | /* initialise the clocks */ |
| @@ -588,6 +626,7 @@ static void __init bast_map_io(void) | |||
| 588 | s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks)); | 626 | s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks)); |
| 589 | 627 | ||
| 590 | s3c_device_nand.dev.platform_data = &bast_nand_info; | 628 | s3c_device_nand.dev.platform_data = &bast_nand_info; |
| 629 | s3c_device_hwmon.dev.platform_data = &bast_hwmon_info; | ||
| 591 | 630 | ||
| 592 | s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); | 631 | s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); |
| 593 | s3c24xx_init_clocks(0); | 632 | s3c24xx_init_clocks(0); |
| @@ -608,6 +647,8 @@ static void __init bast_init(void) | |||
| 608 | 647 | ||
| 609 | usb_simtec_init(); | 648 | usb_simtec_init(); |
| 610 | nor_simtec_init(); | 649 | nor_simtec_init(); |
| 650 | |||
| 651 | s3c_cpufreq_setboard(&bast_cpufreq); | ||
| 611 | } | 652 | } |
| 612 | 653 | ||
| 613 | MACHINE_START(BAST, "Simtec-BAST") | 654 | MACHINE_START(BAST, "Simtec-BAST") |
diff --git a/arch/arm/mach-s3c2410/pll.c b/arch/arm/mach-s3c2410/pll.c new file mode 100644 index 000000000000..f178c2fd9d85 --- /dev/null +++ b/arch/arm/mach-s3c2410/pll.c | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | /* arch/arm/mach-s3c2410/pll.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2006,2007 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * Vincent Sanders <vince@arm.linux.org.uk> | ||
| 7 | * | ||
| 8 | * S3C2410 CPU PLL tables | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/types.h> | ||
| 26 | #include <linux/kernel.h> | ||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/sysdev.h> | ||
| 29 | #include <linux/list.h> | ||
| 30 | #include <linux/clk.h> | ||
| 31 | #include <linux/err.h> | ||
| 32 | |||
| 33 | #include <plat/cpu.h> | ||
| 34 | #include <plat/cpu-freq-core.h> | ||
| 35 | |||
| 36 | static struct cpufreq_frequency_table pll_vals_12MHz[] = { | ||
| 37 | { .frequency = 34000000, .index = PLLVAL(82, 2, 3), }, | ||
| 38 | { .frequency = 45000000, .index = PLLVAL(82, 1, 3), }, | ||
| 39 | { .frequency = 51000000, .index = PLLVAL(161, 3, 3), }, | ||
| 40 | { .frequency = 48000000, .index = PLLVAL(120, 2, 3), }, | ||
| 41 | { .frequency = 56000000, .index = PLLVAL(142, 2, 3), }, | ||
| 42 | { .frequency = 68000000, .index = PLLVAL(82, 2, 2), }, | ||
| 43 | { .frequency = 79000000, .index = PLLVAL(71, 1, 2), }, | ||
| 44 | { .frequency = 85000000, .index = PLLVAL(105, 2, 2), }, | ||
| 45 | { .frequency = 90000000, .index = PLLVAL(112, 2, 2), }, | ||
| 46 | { .frequency = 101000000, .index = PLLVAL(127, 2, 2), }, | ||
| 47 | { .frequency = 113000000, .index = PLLVAL(105, 1, 2), }, | ||
| 48 | { .frequency = 118000000, .index = PLLVAL(150, 2, 2), }, | ||
| 49 | { .frequency = 124000000, .index = PLLVAL(116, 1, 2), }, | ||
| 50 | { .frequency = 135000000, .index = PLLVAL(82, 2, 1), }, | ||
| 51 | { .frequency = 147000000, .index = PLLVAL(90, 2, 1), }, | ||
| 52 | { .frequency = 152000000, .index = PLLVAL(68, 1, 1), }, | ||
| 53 | { .frequency = 158000000, .index = PLLVAL(71, 1, 1), }, | ||
| 54 | { .frequency = 170000000, .index = PLLVAL(77, 1, 1), }, | ||
| 55 | { .frequency = 180000000, .index = PLLVAL(82, 1, 1), }, | ||
| 56 | { .frequency = 186000000, .index = PLLVAL(85, 1, 1), }, | ||
| 57 | { .frequency = 192000000, .index = PLLVAL(88, 1, 1), }, | ||
| 58 | { .frequency = 203000000, .index = PLLVAL(161, 3, 1), }, | ||
| 59 | |||
| 60 | /* 2410A extras */ | ||
| 61 | |||
| 62 | { .frequency = 210000000, .index = PLLVAL(132, 2, 1), }, | ||
| 63 | { .frequency = 226000000, .index = PLLVAL(105, 1, 1), }, | ||
| 64 | { .frequency = 266000000, .index = PLLVAL(125, 1, 1), }, | ||
| 65 | { .frequency = 268000000, .index = PLLVAL(126, 1, 1), }, | ||
| 66 | { .frequency = 270000000, .index = PLLVAL(127, 1, 1), }, | ||
| 67 | }; | ||
| 68 | |||
| 69 | static int s3c2410_plls_add(struct sys_device *dev) | ||
| 70 | { | ||
| 71 | return s3c_plltab_register(pll_vals_12MHz, ARRAY_SIZE(pll_vals_12MHz)); | ||
| 72 | } | ||
| 73 | |||
| 74 | static struct sysdev_driver s3c2410_plls_drv = { | ||
| 75 | .add = s3c2410_plls_add, | ||
| 76 | }; | ||
| 77 | |||
| 78 | static int __init s3c2410_pll_init(void) | ||
| 79 | { | ||
| 80 | return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_plls_drv); | ||
| 81 | |||
| 82 | } | ||
| 83 | |||
| 84 | arch_initcall(s3c2410_pll_init); | ||
| 85 | |||
| 86 | static struct sysdev_driver s3c2410a_plls_drv = { | ||
| 87 | .add = s3c2410_plls_add, | ||
| 88 | }; | ||
| 89 | |||
| 90 | static int __init s3c2410a_pll_init(void) | ||
| 91 | { | ||
| 92 | return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_plls_drv); | ||
| 93 | } | ||
| 94 | |||
| 95 | arch_initcall(s3c2410a_pll_init); | ||
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c index 143e08a599d4..966119c8efee 100644 --- a/arch/arm/mach-s3c2410/pm.c +++ b/arch/arm/mach-s3c2410/pm.c | |||
| @@ -119,6 +119,18 @@ static int __init s3c2410_pm_drvinit(void) | |||
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | arch_initcall(s3c2410_pm_drvinit); | 121 | arch_initcall(s3c2410_pm_drvinit); |
| 122 | |||
| 123 | static struct sysdev_driver s3c2410a_pm_driver = { | ||
| 124 | .add = s3c2410_pm_add, | ||
| 125 | .resume = s3c2410_pm_resume, | ||
| 126 | }; | ||
| 127 | |||
| 128 | static int __init s3c2410a_pm_drvinit(void) | ||
| 129 | { | ||
| 130 | return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_pm_driver); | ||
| 131 | } | ||
| 132 | |||
| 133 | arch_initcall(s3c2410a_pm_drvinit); | ||
| 122 | #endif | 134 | #endif |
| 123 | 135 | ||
| 124 | #if defined(CONFIG_CPU_S3C2440) | 136 | #if defined(CONFIG_CPU_S3C2440) |
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c index feb141b1f915..91ba42f688ac 100644 --- a/arch/arm/mach-s3c2410/s3c2410.c +++ b/arch/arm/mach-s3c2410/s3c2410.c | |||
| @@ -105,17 +105,33 @@ void __init_or_cpufreq s3c2410_setup_clocks(void) | |||
| 105 | s3c24xx_setup_clocks(fclk, hclk, pclk); | 105 | s3c24xx_setup_clocks(fclk, hclk, pclk); |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | /* fake ARMCLK for use with cpufreq, etc. */ | ||
| 109 | |||
| 110 | static struct clk s3c2410_armclk = { | ||
| 111 | .name = "armclk", | ||
| 112 | .parent = &clk_f, | ||
| 113 | .id = -1, | ||
| 114 | }; | ||
| 115 | |||
| 108 | void __init s3c2410_init_clocks(int xtal) | 116 | void __init s3c2410_init_clocks(int xtal) |
| 109 | { | 117 | { |
| 110 | s3c24xx_register_baseclocks(xtal); | 118 | s3c24xx_register_baseclocks(xtal); |
| 111 | s3c2410_setup_clocks(); | 119 | s3c2410_setup_clocks(); |
| 112 | s3c2410_baseclk_add(); | 120 | s3c2410_baseclk_add(); |
| 121 | s3c24xx_register_clock(&s3c2410_armclk); | ||
| 113 | } | 122 | } |
| 114 | 123 | ||
| 115 | struct sysdev_class s3c2410_sysclass = { | 124 | struct sysdev_class s3c2410_sysclass = { |
| 116 | .name = "s3c2410-core", | 125 | .name = "s3c2410-core", |
| 117 | }; | 126 | }; |
| 118 | 127 | ||
| 128 | /* Note, we would have liked to name this s3c2410-core, but we cannot | ||
| 129 | * register two sysdev_class with the same name. | ||
| 130 | */ | ||
| 131 | struct sysdev_class s3c2410a_sysclass = { | ||
| 132 | .name = "s3c2410a-core", | ||
| 133 | }; | ||
| 134 | |||
| 119 | static struct sys_device s3c2410_sysdev = { | 135 | static struct sys_device s3c2410_sysdev = { |
| 120 | .cls = &s3c2410_sysclass, | 136 | .cls = &s3c2410_sysclass, |
| 121 | }; | 137 | }; |
| @@ -133,9 +149,22 @@ static int __init s3c2410_core_init(void) | |||
| 133 | 149 | ||
| 134 | core_initcall(s3c2410_core_init); | 150 | core_initcall(s3c2410_core_init); |
| 135 | 151 | ||
| 152 | static int __init s3c2410a_core_init(void) | ||
| 153 | { | ||
| 154 | return sysdev_class_register(&s3c2410a_sysclass); | ||
| 155 | } | ||
| 156 | |||
| 157 | core_initcall(s3c2410a_core_init); | ||
| 158 | |||
| 136 | int __init s3c2410_init(void) | 159 | int __init s3c2410_init(void) |
| 137 | { | 160 | { |
| 138 | printk("S3C2410: Initialising architecture\n"); | 161 | printk("S3C2410: Initialising architecture\n"); |
| 139 | 162 | ||
| 140 | return sysdev_register(&s3c2410_sysdev); | 163 | return sysdev_register(&s3c2410_sysdev); |
| 141 | } | 164 | } |
| 165 | |||
| 166 | int __init s3c2410a_init(void) | ||
| 167 | { | ||
| 168 | s3c2410_sysdev.cls = &s3c2410a_sysclass; | ||
| 169 | return s3c2410_init(); | ||
| 170 | } | ||
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig index 63586ffd0ae7..35c1bde89cf2 100644 --- a/arch/arm/mach-s3c2412/Kconfig +++ b/arch/arm/mach-s3c2412/Kconfig | |||
| @@ -32,6 +32,15 @@ config S3C2412_PM | |||
| 32 | help | 32 | help |
| 33 | Internal config node to apply S3C2412 power management | 33 | Internal config node to apply S3C2412 power management |
| 34 | 34 | ||
| 35 | # Note, the S3C2412 IOtiming support is in plat-s3c24xx | ||
| 36 | |||
| 37 | config S3C2412_CPUFREQ | ||
| 38 | bool | ||
| 39 | depends on CPU_FREQ_S3C24XX && CPU_S3C2412 | ||
| 40 | select S3C2412_IOTIMING | ||
| 41 | default y | ||
| 42 | help | ||
| 43 | CPU Frequency scaling support for S3C2412 and S3C2413 SoC CPUs. | ||
| 35 | 44 | ||
| 36 | menu "S3C2412 Machines" | 45 | menu "S3C2412 Machines" |
| 37 | 46 | ||
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile index 20918d5dc6a9..530ec46cbaea 100644 --- a/arch/arm/mach-s3c2412/Makefile +++ b/arch/arm/mach-s3c2412/Makefile | |||
| @@ -15,6 +15,7 @@ obj-$(CONFIG_CPU_S3C2412) += clock.o | |||
| 15 | obj-$(CONFIG_CPU_S3C2412) += gpio.o | 15 | obj-$(CONFIG_CPU_S3C2412) += gpio.o |
| 16 | obj-$(CONFIG_S3C2412_DMA) += dma.o | 16 | obj-$(CONFIG_S3C2412_DMA) += dma.o |
| 17 | obj-$(CONFIG_S3C2412_PM) += pm.o sleep.o | 17 | obj-$(CONFIG_S3C2412_PM) += pm.o sleep.o |
| 18 | obj-$(CONFIG_S3C2412_CPUFREQ) += cpu-freq.o | ||
| 18 | 19 | ||
| 19 | # Machine support | 20 | # Machine support |
| 20 | 21 | ||
diff --git a/arch/arm/mach-s3c2412/cpu-freq.c b/arch/arm/mach-s3c2412/cpu-freq.c new file mode 100644 index 000000000000..eb3ea1721335 --- /dev/null +++ b/arch/arm/mach-s3c2412/cpu-freq.c | |||
| @@ -0,0 +1,257 @@ | |||
| 1 | /* linux/arch/arm/mach-s3c2412/cpu-freq.c | ||
| 2 | * | ||
| 3 | * Copyright 2008 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * | ||
| 7 | * S3C2412 CPU Frequency scalling | ||
| 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 | #include <linux/init.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/ioport.h> | ||
| 18 | #include <linux/cpufreq.h> | ||
| 19 | #include <linux/sysdev.h> | ||
| 20 | #include <linux/delay.h> | ||
| 21 | #include <linux/clk.h> | ||
| 22 | #include <linux/err.h> | ||
| 23 | #include <linux/io.h> | ||
| 24 | |||
| 25 | #include <asm/mach/arch.h> | ||
| 26 | #include <asm/mach/map.h> | ||
| 27 | |||
| 28 | #include <mach/regs-clock.h> | ||
| 29 | #include <mach/regs-s3c2412-mem.h> | ||
| 30 | |||
| 31 | #include <plat/cpu.h> | ||
| 32 | #include <plat/clock.h> | ||
| 33 | #include <plat/cpu-freq-core.h> | ||
| 34 | |||
| 35 | /* our clock resources. */ | ||
| 36 | static struct clk *xtal; | ||
| 37 | static struct clk *fclk; | ||
| 38 | static struct clk *hclk; | ||
| 39 | static struct clk *armclk; | ||
| 40 | |||
| 41 | /* HDIV: 1, 2, 3, 4, 6, 8 */ | ||
| 42 | |||
| 43 | static int s3c2412_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg) | ||
| 44 | { | ||
| 45 | unsigned int hdiv, pdiv, armdiv, dvs; | ||
| 46 | unsigned long hclk, fclk, armclk, armdiv_clk; | ||
| 47 | unsigned long hclk_max; | ||
| 48 | |||
| 49 | fclk = cfg->freq.fclk; | ||
| 50 | armclk = cfg->freq.armclk; | ||
| 51 | hclk_max = cfg->max.hclk; | ||
| 52 | |||
| 53 | /* We can't run hclk above armclk as at the best we have to | ||
| 54 | * have armclk and hclk in dvs mode. */ | ||
| 55 | |||
| 56 | if (hclk_max > armclk) | ||
| 57 | hclk_max = armclk; | ||
| 58 | |||
| 59 | s3c_freq_dbg("%s: fclk=%lu, armclk=%lu, hclk_max=%lu\n", | ||
| 60 | __func__, fclk, armclk, hclk_max); | ||
| 61 | s3c_freq_dbg("%s: want f=%lu, arm=%lu, h=%lu, p=%lu\n", | ||
| 62 | __func__, cfg->freq.fclk, cfg->freq.armclk, | ||
| 63 | cfg->freq.hclk, cfg->freq.pclk); | ||
| 64 | |||
| 65 | armdiv = fclk / armclk; | ||
| 66 | |||
| 67 | if (armdiv < 1) | ||
| 68 | armdiv = 1; | ||
| 69 | if (armdiv > 2) | ||
| 70 | armdiv = 2; | ||
| 71 | |||
| 72 | cfg->divs.arm_divisor = armdiv; | ||
| 73 | armdiv_clk = fclk / armdiv; | ||
| 74 | |||
| 75 | hdiv = armdiv_clk / hclk_max; | ||
| 76 | if (hdiv < 1) | ||
| 77 | hdiv = 1; | ||
| 78 | |||
| 79 | cfg->freq.hclk = hclk = armdiv_clk / hdiv; | ||
| 80 | |||
| 81 | /* set dvs depending on whether we reached armclk or not. */ | ||
| 82 | cfg->divs.dvs = dvs = armclk < armdiv_clk; | ||
| 83 | |||
| 84 | /* update the actual armclk we achieved. */ | ||
| 85 | cfg->freq.armclk = dvs ? hclk : armdiv_clk; | ||
| 86 | |||
| 87 | s3c_freq_dbg("%s: armclk %lu, hclk %lu, armdiv %d, hdiv %d, dvs %d\n", | ||
| 88 | __func__, armclk, hclk, armdiv, hdiv, cfg->divs.dvs); | ||
| 89 | |||
| 90 | if (hdiv > 4) | ||
| 91 | goto invalid; | ||
| 92 | |||
| 93 | pdiv = (hclk > cfg->max.pclk) ? 2 : 1; | ||
| 94 | |||
| 95 | if ((hclk / pdiv) > cfg->max.pclk) | ||
| 96 | pdiv++; | ||
| 97 | |||
| 98 | cfg->freq.pclk = hclk / pdiv; | ||
| 99 | |||
| 100 | s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv); | ||
| 101 | |||
| 102 | if (pdiv > 2) | ||
| 103 | goto invalid; | ||
| 104 | |||
| 105 | pdiv *= hdiv; | ||
| 106 | |||
| 107 | /* store the result, and then return */ | ||
| 108 | |||
| 109 | cfg->divs.h_divisor = hdiv * armdiv; | ||
| 110 | cfg->divs.p_divisor = pdiv * armdiv; | ||
| 111 | |||
| 112 | return 0; | ||
| 113 | |||
| 114 | invalid: | ||
| 115 | return -EINVAL; | ||
| 116 | } | ||
| 117 | |||
| 118 | static void s3c2412_cpufreq_setdivs(struct s3c_cpufreq_config *cfg) | ||
| 119 | { | ||
| 120 | unsigned long clkdiv; | ||
| 121 | unsigned long olddiv; | ||
| 122 | |||
| 123 | olddiv = clkdiv = __raw_readl(S3C2410_CLKDIVN); | ||
| 124 | |||
| 125 | /* clear off current clock info */ | ||
| 126 | |||
| 127 | clkdiv &= ~S3C2412_CLKDIVN_ARMDIVN; | ||
| 128 | clkdiv &= ~S3C2412_CLKDIVN_HDIVN_MASK; | ||
| 129 | clkdiv &= ~S3C2412_CLKDIVN_PDIVN; | ||
| 130 | |||
| 131 | if (cfg->divs.arm_divisor == 2) | ||
| 132 | clkdiv |= S3C2412_CLKDIVN_ARMDIVN; | ||
| 133 | |||
| 134 | clkdiv |= ((cfg->divs.h_divisor / cfg->divs.arm_divisor) - 1); | ||
| 135 | |||
| 136 | if (cfg->divs.p_divisor != cfg->divs.h_divisor) | ||
| 137 | clkdiv |= S3C2412_CLKDIVN_PDIVN; | ||
| 138 | |||
| 139 | s3c_freq_dbg("%s: div %08lx => %08lx\n", __func__, olddiv, clkdiv); | ||
| 140 | __raw_writel(clkdiv, S3C2410_CLKDIVN); | ||
| 141 | |||
| 142 | clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk); | ||
| 143 | } | ||
| 144 | |||
| 145 | static void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg) | ||
| 146 | { | ||
| 147 | struct s3c_cpufreq_board *board = cfg->board; | ||
| 148 | unsigned long refresh; | ||
| 149 | |||
| 150 | s3c_freq_dbg("%s: refresh %u ns, hclk %lu\n", __func__, | ||
| 151 | board->refresh, cfg->freq.hclk); | ||
| 152 | |||
| 153 | /* Reduce both the refresh time (in ns) and the frequency (in MHz) | ||
| 154 | * by 10 each to ensure that we do not overflow 32 bit numbers. This | ||
| 155 | * should work for HCLK up to 133MHz and refresh period up to 30usec. | ||
| 156 | */ | ||
| 157 | |||
| 158 | refresh = (board->refresh / 10); | ||
| 159 | refresh *= (cfg->freq.hclk / 100); | ||
| 160 | refresh /= (1 * 1000 * 1000); /* 10^6 */ | ||
| 161 | |||
| 162 | s3c_freq_dbg("%s: setting refresh 0x%08lx\n", __func__, refresh); | ||
| 163 | __raw_writel(refresh, S3C2412_REFRESH); | ||
| 164 | } | ||
| 165 | |||
| 166 | /* set the default cpu frequency information, based on an 200MHz part | ||
| 167 | * as we have no other way of detecting the speed rating in software. | ||
| 168 | */ | ||
| 169 | |||
| 170 | static struct s3c_cpufreq_info s3c2412_cpufreq_info = { | ||
| 171 | .max = { | ||
| 172 | .fclk = 200000000, | ||
| 173 | .hclk = 100000000, | ||
| 174 | .pclk = 50000000, | ||
| 175 | }, | ||
| 176 | |||
| 177 | .latency = 5000000, /* 5ms */ | ||
| 178 | |||
| 179 | .locktime_m = 150, | ||
| 180 | .locktime_u = 150, | ||
| 181 | .locktime_bits = 16, | ||
| 182 | |||
| 183 | .name = "s3c2412", | ||
| 184 | .set_refresh = s3c2412_cpufreq_setrefresh, | ||
| 185 | .set_divs = s3c2412_cpufreq_setdivs, | ||
| 186 | .calc_divs = s3c2412_cpufreq_calcdivs, | ||
| 187 | |||
| 188 | .calc_iotiming = s3c2412_iotiming_calc, | ||
| 189 | .set_iotiming = s3c2412_iotiming_set, | ||
| 190 | .get_iotiming = s3c2412_iotiming_get, | ||
| 191 | |||
| 192 | .resume_clocks = s3c2412_setup_clocks, | ||
| 193 | |||
| 194 | .debug_io_show = s3c_cpufreq_debugfs_call(s3c2412_iotiming_debugfs), | ||
| 195 | }; | ||
| 196 | |||
| 197 | static int s3c2412_cpufreq_add(struct sys_device *sysdev) | ||
| 198 | { | ||
| 199 | unsigned long fclk_rate; | ||
| 200 | |||
| 201 | hclk = clk_get(NULL, "hclk"); | ||
| 202 | if (IS_ERR(hclk)) { | ||
| 203 | printk(KERN_ERR "%s: cannot find hclk clock\n", __func__); | ||
| 204 | return -ENOENT; | ||
| 205 | } | ||
| 206 | |||
| 207 | fclk = clk_get(NULL, "fclk"); | ||
| 208 | if (IS_ERR(fclk)) { | ||
| 209 | printk(KERN_ERR "%s: cannot find fclk clock\n", __func__); | ||
| 210 | goto err_fclk; | ||
| 211 | } | ||
| 212 | |||
| 213 | fclk_rate = clk_get_rate(fclk); | ||
| 214 | if (fclk_rate > 200000000) { | ||
| 215 | printk(KERN_INFO | ||
| 216 | "%s: fclk %ld MHz, assuming 266MHz capable part\n", | ||
| 217 | __func__, fclk_rate / 1000000); | ||
| 218 | s3c2412_cpufreq_info.max.fclk = 266000000; | ||
| 219 | s3c2412_cpufreq_info.max.hclk = 133000000; | ||
| 220 | s3c2412_cpufreq_info.max.pclk = 66000000; | ||
| 221 | } | ||
| 222 | |||
| 223 | armclk = clk_get(NULL, "armclk"); | ||
| 224 | if (IS_ERR(armclk)) { | ||
| 225 | printk(KERN_ERR "%s: cannot find arm clock\n", __func__); | ||
| 226 | goto err_armclk; | ||
| 227 | } | ||
| 228 | |||
| 229 | xtal = clk_get(NULL, "xtal"); | ||
| 230 | if (IS_ERR(xtal)) { | ||
| 231 | printk(KERN_ERR "%s: cannot find xtal clock\n", __func__); | ||
| 232 | goto err_xtal; | ||
| 233 | } | ||
| 234 | |||
| 235 | return s3c_cpufreq_register(&s3c2412_cpufreq_info); | ||
| 236 | |||
| 237 | err_xtal: | ||
| 238 | clk_put(armclk); | ||
| 239 | err_armclk: | ||
| 240 | clk_put(fclk); | ||
| 241 | err_fclk: | ||
| 242 | clk_put(hclk); | ||
| 243 | |||
| 244 | return -ENOENT; | ||
| 245 | } | ||
| 246 | |||
| 247 | static struct sysdev_driver s3c2412_cpufreq_driver = { | ||
| 248 | .add = s3c2412_cpufreq_add, | ||
| 249 | }; | ||
| 250 | |||
| 251 | static int s3c2412_cpufreq_init(void) | ||
| 252 | { | ||
| 253 | return sysdev_driver_register(&s3c2412_sysclass, | ||
| 254 | &s3c2412_cpufreq_driver); | ||
| 255 | } | ||
| 256 | |||
| 257 | arch_initcall(s3c2412_cpufreq_init); | ||
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c index 5b5aba69ec3f..bef39f77729d 100644 --- a/arch/arm/mach-s3c2412/s3c2412.c +++ b/arch/arm/mach-s3c2412/s3c2412.c | |||
| @@ -69,6 +69,18 @@ static struct map_desc s3c2412_iodesc[] __initdata = { | |||
| 69 | IODESC_ENT(CLKPWR), | 69 | IODESC_ENT(CLKPWR), |
| 70 | IODESC_ENT(TIMER), | 70 | IODESC_ENT(TIMER), |
| 71 | IODESC_ENT(WATCHDOG), | 71 | IODESC_ENT(WATCHDOG), |
| 72 | { | ||
| 73 | .virtual = (unsigned long)S3C2412_VA_SSMC, | ||
| 74 | .pfn = __phys_to_pfn(S3C2412_PA_SSMC), | ||
| 75 | .length = SZ_1M, | ||
| 76 | .type = MT_DEVICE, | ||
| 77 | }, | ||
| 78 | { | ||
| 79 | .virtual = (unsigned long)S3C2412_VA_EBI, | ||
| 80 | .pfn = __phys_to_pfn(S3C2412_PA_EBI), | ||
| 81 | .length = SZ_1M, | ||
| 82 | .type = MT_DEVICE, | ||
| 83 | }, | ||
| 72 | }; | 84 | }; |
| 73 | 85 | ||
| 74 | /* uart registration process */ | 86 | /* uart registration process */ |
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig index 8cfeaec37306..8ae1b288f7fa 100644 --- a/arch/arm/mach-s3c2440/Kconfig +++ b/arch/arm/mach-s3c2440/Kconfig | |||
| @@ -33,6 +33,7 @@ config MACH_ANUBIS | |||
| 33 | select PM_SIMTEC if PM | 33 | select PM_SIMTEC if PM |
| 34 | select HAVE_PATA_PLATFORM | 34 | select HAVE_PATA_PLATFORM |
| 35 | select S3C24XX_GPIO_EXTRA64 | 35 | select S3C24XX_GPIO_EXTRA64 |
| 36 | select S3C2440_XTAL_12000000 | ||
| 36 | select S3C_DEV_USB_HOST | 37 | select S3C_DEV_USB_HOST |
| 37 | help | 38 | help |
| 38 | Say Y here if you are using the Simtec Electronics ANUBIS | 39 | Say Y here if you are using the Simtec Electronics ANUBIS |
| @@ -44,6 +45,8 @@ config MACH_OSIRIS | |||
| 44 | select S3C24XX_DCLK | 45 | select S3C24XX_DCLK |
| 45 | select PM_SIMTEC if PM | 46 | select PM_SIMTEC if PM |
| 46 | select S3C24XX_GPIO_EXTRA128 | 47 | select S3C24XX_GPIO_EXTRA128 |
| 48 | select S3C2440_XTAL_12000000 | ||
| 49 | select S3C2410_IOTIMING if S3C2440_CPUFREQ | ||
| 47 | select S3C_DEV_USB_HOST | 50 | select S3C_DEV_USB_HOST |
| 48 | help | 51 | help |
| 49 | Say Y here if you are using the Simtec IM2440D20 module, also | 52 | Say Y here if you are using the Simtec IM2440D20 module, also |
| @@ -52,6 +55,7 @@ config MACH_OSIRIS | |||
| 52 | config MACH_RX3715 | 55 | config MACH_RX3715 |
| 53 | bool "HP iPAQ rx3715" | 56 | bool "HP iPAQ rx3715" |
| 54 | select CPU_S3C2440 | 57 | select CPU_S3C2440 |
| 58 | select S3C2440_XTAL_16934400 | ||
| 55 | select PM_H1940 if PM | 59 | select PM_H1940 if PM |
| 56 | help | 60 | help |
| 57 | Say Y here if you are using the HP iPAQ rx3715. | 61 | Say Y here if you are using the HP iPAQ rx3715. |
| @@ -59,6 +63,7 @@ config MACH_RX3715 | |||
| 59 | config ARCH_S3C2440 | 63 | config ARCH_S3C2440 |
| 60 | bool "SMDK2440" | 64 | bool "SMDK2440" |
| 61 | select CPU_S3C2440 | 65 | select CPU_S3C2440 |
| 66 | select S3C2440_XTAL_16934400 | ||
| 62 | select MACH_SMDK | 67 | select MACH_SMDK |
| 63 | select S3C_DEV_USB_HOST | 68 | select S3C_DEV_USB_HOST |
| 64 | help | 69 | help |
| @@ -67,6 +72,7 @@ config ARCH_S3C2440 | |||
| 67 | config MACH_NEXCODER_2440 | 72 | config MACH_NEXCODER_2440 |
| 68 | bool "NexVision NEXCODER 2440 Light Board" | 73 | bool "NexVision NEXCODER 2440 Light Board" |
| 69 | select CPU_S3C2440 | 74 | select CPU_S3C2440 |
| 75 | select S3C2440_XTAL_12000000 | ||
| 70 | select S3C_DEV_USB_HOST | 76 | select S3C_DEV_USB_HOST |
| 71 | help | 77 | help |
| 72 | Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board | 78 | Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board |
| @@ -75,6 +81,7 @@ config SMDK2440_CPU2440 | |||
| 75 | bool "SMDK2440 with S3C2440 CPU module" | 81 | bool "SMDK2440 with S3C2440 CPU module" |
| 76 | depends on ARCH_S3C2440 | 82 | depends on ARCH_S3C2440 |
| 77 | default y if ARCH_S3C2440 | 83 | default y if ARCH_S3C2440 |
| 84 | select S3C2440_XTAL_16934400 | ||
| 78 | select CPU_S3C2440 | 85 | select CPU_S3C2440 |
| 79 | 86 | ||
| 80 | config MACH_AT2440EVB | 87 | config MACH_AT2440EVB |
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c index cba064b49a64..2105a41281a4 100644 --- a/arch/arm/mach-s3c2440/mach-osiris.c +++ b/arch/arm/mach-s3c2440/mach-osiris.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <asm/irq.h> | 34 | #include <asm/irq.h> |
| 35 | #include <asm/mach-types.h> | 35 | #include <asm/mach-types.h> |
| 36 | 36 | ||
| 37 | #include <plat/cpu-freq.h> | ||
| 37 | #include <plat/regs-serial.h> | 38 | #include <plat/regs-serial.h> |
| 38 | #include <mach/regs-gpio.h> | 39 | #include <mach/regs-gpio.h> |
| 39 | #include <mach/regs-mem.h> | 40 | #include <mach/regs-mem.h> |
| @@ -351,6 +352,12 @@ static struct clk *osiris_clocks[] __initdata = { | |||
| 351 | &s3c24xx_uclk, | 352 | &s3c24xx_uclk, |
| 352 | }; | 353 | }; |
| 353 | 354 | ||
| 355 | static struct s3c_cpufreq_board __initdata osiris_cpufreq = { | ||
| 356 | .refresh = 7800, /* refresh period is 7.8usec */ | ||
| 357 | .auto_io = 1, | ||
| 358 | .need_io = 1, | ||
| 359 | }; | ||
| 360 | |||
| 354 | static void __init osiris_map_io(void) | 361 | static void __init osiris_map_io(void) |
| 355 | { | 362 | { |
| 356 | unsigned long flags; | 363 | unsigned long flags; |
| @@ -402,6 +409,8 @@ static void __init osiris_init(void) | |||
| 402 | 409 | ||
| 403 | s3c_i2c0_set_platdata(NULL); | 410 | s3c_i2c0_set_platdata(NULL); |
| 404 | 411 | ||
| 412 | s3c_cpufreq_setboard(&osiris_cpufreq); | ||
| 413 | |||
| 405 | i2c_register_board_info(0, osiris_i2c_devs, | 414 | i2c_register_board_info(0, osiris_i2c_devs, |
| 406 | ARRAY_SIZE(osiris_i2c_devs)); | 415 | ARRAY_SIZE(osiris_i2c_devs)); |
| 407 | 416 | ||
diff --git a/arch/arm/mach-s3c24a0/include/mach/map.h b/arch/arm/mach-s3c24a0/include/mach/map.h index a01132717e34..79e4d93ea2b6 100644 --- a/arch/arm/mach-s3c24a0/include/mach/map.h +++ b/arch/arm/mach-s3c24a0/include/mach/map.h | |||
| @@ -81,5 +81,6 @@ | |||
| 81 | 81 | ||
| 82 | #define S3C_PA_UART S3C24A0_PA_UART | 82 | #define S3C_PA_UART S3C24A0_PA_UART |
| 83 | #define S3C_PA_IIC S3C24A0_PA_IIC | 83 | #define S3C_PA_IIC S3C24A0_PA_IIC |
| 84 | #define S3C_PA_NAND S3C24XX_PA_NAND | ||
| 84 | 85 | ||
| 85 | #endif /* __ASM_ARCH_24A0_MAP_H */ | 86 | #endif /* __ASM_ARCH_24A0_MAP_H */ |
diff --git a/arch/arm/mach-s3c6400/include/mach/map.h b/arch/arm/mach-s3c6400/include/mach/map.h index 5057d9948d35..fc8b223bad4f 100644 --- a/arch/arm/mach-s3c6400/include/mach/map.h +++ b/arch/arm/mach-s3c6400/include/mach/map.h | |||
| @@ -38,18 +38,21 @@ | |||
| 38 | #define S3C_VA_UART2 S3C_VA_UARTx(2) | 38 | #define S3C_VA_UART2 S3C_VA_UARTx(2) |
| 39 | #define S3C_VA_UART3 S3C_VA_UARTx(3) | 39 | #define S3C_VA_UART3 S3C_VA_UARTx(3) |
| 40 | 40 | ||
| 41 | #define S3C64XX_PA_NAND (0x70200000) | ||
| 41 | #define S3C64XX_PA_FB (0x77100000) | 42 | #define S3C64XX_PA_FB (0x77100000) |
| 42 | #define S3C64XX_PA_USB_HSOTG (0x7C000000) | 43 | #define S3C64XX_PA_USB_HSOTG (0x7C000000) |
| 43 | #define S3C64XX_PA_WATCHDOG (0x7E004000) | 44 | #define S3C64XX_PA_WATCHDOG (0x7E004000) |
| 44 | #define S3C64XX_PA_SYSCON (0x7E00F000) | 45 | #define S3C64XX_PA_SYSCON (0x7E00F000) |
| 46 | #define S3C64XX_PA_AC97 (0x7F001000) | ||
| 45 | #define S3C64XX_PA_IIS0 (0x7F002000) | 47 | #define S3C64XX_PA_IIS0 (0x7F002000) |
| 46 | #define S3C64XX_PA_IIS1 (0x7F003000) | 48 | #define S3C64XX_PA_IIS1 (0x7F003000) |
| 47 | #define S3C64XX_PA_TIMER (0x7F006000) | 49 | #define S3C64XX_PA_TIMER (0x7F006000) |
| 48 | #define S3C64XX_PA_IIC0 (0x7F004000) | 50 | #define S3C64XX_PA_IIC0 (0x7F004000) |
| 51 | #define S3C64XX_PA_IISV4 (0x7F00D000) | ||
| 49 | #define S3C64XX_PA_IIC1 (0x7F00F000) | 52 | #define S3C64XX_PA_IIC1 (0x7F00F000) |
| 50 | 53 | ||
| 51 | #define S3C64XX_PA_GPIO (0x7F008000) | 54 | #define S3C64XX_PA_GPIO (0x7F008000) |
| 52 | #define S3C64XX_VA_GPIO S3C_ADDR(0x00500000) | 55 | #define S3C64XX_VA_GPIO S3C_ADDR_CPU(0x00000000) |
| 53 | #define S3C64XX_SZ_GPIO SZ_4K | 56 | #define S3C64XX_SZ_GPIO SZ_4K |
| 54 | 57 | ||
| 55 | #define S3C64XX_PA_SDRAM (0x50000000) | 58 | #define S3C64XX_PA_SDRAM (0x50000000) |
| @@ -57,7 +60,7 @@ | |||
| 57 | #define S3C64XX_PA_VIC1 (0x71300000) | 60 | #define S3C64XX_PA_VIC1 (0x71300000) |
| 58 | 61 | ||
| 59 | #define S3C64XX_PA_MODEM (0x74108000) | 62 | #define S3C64XX_PA_MODEM (0x74108000) |
| 60 | #define S3C64XX_VA_MODEM S3C_ADDR(0x00600000) | 63 | #define S3C64XX_VA_MODEM S3C_ADDR_CPU(0x00100000) |
| 61 | 64 | ||
| 62 | #define S3C64XX_PA_USBHOST (0x74300000) | 65 | #define S3C64XX_PA_USBHOST (0x74300000) |
| 63 | 66 | ||
| @@ -72,6 +75,7 @@ | |||
| 72 | #define S3C_PA_HSMMC2 S3C64XX_PA_HSMMC2 | 75 | #define S3C_PA_HSMMC2 S3C64XX_PA_HSMMC2 |
| 73 | #define S3C_PA_IIC S3C64XX_PA_IIC0 | 76 | #define S3C_PA_IIC S3C64XX_PA_IIC0 |
| 74 | #define S3C_PA_IIC1 S3C64XX_PA_IIC1 | 77 | #define S3C_PA_IIC1 S3C64XX_PA_IIC1 |
| 78 | #define S3C_PA_NAND S3C64XX_PA_NAND | ||
| 75 | #define S3C_PA_FB S3C64XX_PA_FB | 79 | #define S3C_PA_FB S3C64XX_PA_FB |
| 76 | #define S3C_PA_USBHOST S3C64XX_PA_USBHOST | 80 | #define S3C_PA_USBHOST S3C64XX_PA_USBHOST |
| 77 | #define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG | 81 | #define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG |
diff --git a/arch/arm/mach-s3c6400/s3c6400.c b/arch/arm/mach-s3c6400/s3c6400.c index 1ece887d90bb..b42bdd0f2138 100644 --- a/arch/arm/mach-s3c6400/s3c6400.c +++ b/arch/arm/mach-s3c6400/s3c6400.c | |||
| @@ -48,6 +48,8 @@ void __init s3c6400_map_io(void) | |||
| 48 | 48 | ||
| 49 | /* the i2c devices are directly compatible with s3c2440 */ | 49 | /* the i2c devices are directly compatible with s3c2440 */ |
| 50 | s3c_i2c0_setname("s3c2440-i2c"); | 50 | s3c_i2c0_setname("s3c2440-i2c"); |
| 51 | |||
| 52 | s3c_device_nand.name = "s3c6400-nand"; | ||
| 51 | } | 53 | } |
| 52 | 54 | ||
| 53 | void __init s3c6400_init_clocks(int xtal) | 55 | void __init s3c6400_init_clocks(int xtal) |
diff --git a/arch/arm/mach-s3c6410/Kconfig b/arch/arm/mach-s3c6410/Kconfig index e63aac7f4e5a..f9d0f09f9761 100644 --- a/arch/arm/mach-s3c6410/Kconfig +++ b/arch/arm/mach-s3c6410/Kconfig | |||
| @@ -97,3 +97,13 @@ config MACH_NCP | |||
| 97 | select S3C64XX_SETUP_I2C1 | 97 | select S3C64XX_SETUP_I2C1 |
| 98 | help | 98 | help |
| 99 | Machine support for the Samsung NCP | 99 | Machine support for the Samsung NCP |
| 100 | |||
| 101 | config MACH_HMT | ||
| 102 | bool "Airgoo HMT" | ||
| 103 | select CPU_S3C6410 | ||
| 104 | select S3C_DEV_FB | ||
| 105 | select S3C_DEV_USB_HOST | ||
| 106 | select S3C64XX_SETUP_FB_24BPP | ||
| 107 | select HAVE_PWM | ||
| 108 | help | ||
| 109 | Machine support for the Airgoo HMT | ||
diff --git a/arch/arm/mach-s3c6410/Makefile b/arch/arm/mach-s3c6410/Makefile index 6f9deac88612..3e48c3dbf973 100644 --- a/arch/arm/mach-s3c6410/Makefile +++ b/arch/arm/mach-s3c6410/Makefile | |||
| @@ -23,5 +23,4 @@ obj-$(CONFIG_S3C6410_SETUP_SDHCI) += setup-sdhci.o | |||
| 23 | obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o | 23 | obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o |
| 24 | obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o | 24 | obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o |
| 25 | obj-$(CONFIG_MACH_NCP) += mach-ncp.o | 25 | obj-$(CONFIG_MACH_NCP) += mach-ncp.o |
| 26 | 26 | obj-$(CONFIG_MACH_HMT) += mach-hmt.o | |
| 27 | |||
diff --git a/arch/arm/mach-s3c6410/cpu.c b/arch/arm/mach-s3c6410/cpu.c index ade904de8895..9b67c663d9d8 100644 --- a/arch/arm/mach-s3c6410/cpu.c +++ b/arch/arm/mach-s3c6410/cpu.c | |||
| @@ -62,6 +62,8 @@ void __init s3c6410_map_io(void) | |||
| 62 | /* the i2c devices are directly compatible with s3c2440 */ | 62 | /* the i2c devices are directly compatible with s3c2440 */ |
| 63 | s3c_i2c0_setname("s3c2440-i2c"); | 63 | s3c_i2c0_setname("s3c2440-i2c"); |
| 64 | s3c_i2c1_setname("s3c2440-i2c"); | 64 | s3c_i2c1_setname("s3c2440-i2c"); |
| 65 | |||
| 66 | s3c_device_nand.name = "s3c6400-nand"; | ||
| 65 | } | 67 | } |
| 66 | 68 | ||
| 67 | void __init s3c6410_init_clocks(int xtal) | 69 | void __init s3c6410_init_clocks(int xtal) |
diff --git a/arch/arm/mach-s3c6410/mach-hmt.c b/arch/arm/mach-s3c6410/mach-hmt.c new file mode 100644 index 000000000000..c5741056193f --- /dev/null +++ b/arch/arm/mach-s3c6410/mach-hmt.c | |||
| @@ -0,0 +1,276 @@ | |||
| 1 | /* mach-hmt.c - Platform code for Airgoo HMT | ||
| 2 | * | ||
| 3 | * Copyright 2009 Peter Korsgaard <jacmet@sunsite.dk> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/serial_core.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | #include <linux/io.h> | ||
| 16 | #include <linux/i2c.h> | ||
| 17 | #include <linux/fb.h> | ||
| 18 | #include <linux/gpio.h> | ||
| 19 | #include <linux/delay.h> | ||
| 20 | #include <linux/leds.h> | ||
| 21 | #include <linux/pwm_backlight.h> | ||
| 22 | #include <linux/mtd/mtd.h> | ||
| 23 | #include <linux/mtd/partitions.h> | ||
| 24 | |||
| 25 | #include <asm/mach/arch.h> | ||
| 26 | #include <asm/mach/map.h> | ||
| 27 | #include <asm/mach/irq.h> | ||
| 28 | |||
| 29 | #include <mach/hardware.h> | ||
| 30 | #include <mach/regs-fb.h> | ||
| 31 | #include <mach/map.h> | ||
| 32 | |||
| 33 | #include <asm/irq.h> | ||
| 34 | #include <asm/mach-types.h> | ||
| 35 | |||
| 36 | #include <plat/regs-serial.h> | ||
| 37 | #include <plat/iic.h> | ||
| 38 | #include <plat/fb.h> | ||
| 39 | #include <plat/nand.h> | ||
| 40 | |||
| 41 | #include <plat/s3c6410.h> | ||
| 42 | #include <plat/clock.h> | ||
| 43 | #include <plat/devs.h> | ||
| 44 | #include <plat/cpu.h> | ||
| 45 | |||
| 46 | #define UCON S3C2410_UCON_DEFAULT | ||
| 47 | #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE) | ||
| 48 | #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) | ||
| 49 | |||
| 50 | static struct s3c2410_uartcfg hmt_uartcfgs[] __initdata = { | ||
| 51 | [0] = { | ||
| 52 | .hwport = 0, | ||
| 53 | .flags = 0, | ||
| 54 | .ucon = UCON, | ||
| 55 | .ulcon = ULCON, | ||
| 56 | .ufcon = UFCON, | ||
| 57 | }, | ||
| 58 | [1] = { | ||
| 59 | .hwport = 1, | ||
| 60 | .flags = 0, | ||
| 61 | .ucon = UCON, | ||
| 62 | .ulcon = ULCON, | ||
| 63 | .ufcon = UFCON, | ||
| 64 | }, | ||
| 65 | [2] = { | ||
| 66 | .hwport = 2, | ||
| 67 | .flags = 0, | ||
| 68 | .ucon = UCON, | ||
| 69 | .ulcon = ULCON, | ||
| 70 | .ufcon = UFCON, | ||
| 71 | }, | ||
| 72 | }; | ||
| 73 | |||
| 74 | static int hmt_bl_init(struct device *dev) | ||
| 75 | { | ||
| 76 | int ret; | ||
| 77 | |||
| 78 | ret = gpio_request(S3C64XX_GPB(4), "lcd backlight enable"); | ||
| 79 | if (!ret) | ||
| 80 | ret = gpio_direction_output(S3C64XX_GPB(4), 0); | ||
| 81 | |||
| 82 | return ret; | ||
| 83 | } | ||
| 84 | |||
| 85 | static int hmt_bl_notify(int brightness) | ||
| 86 | { | ||
| 87 | /* | ||
| 88 | * translate from CIELUV/CIELAB L*->brightness, E.G. from | ||
| 89 | * perceived luminance to light output. Assumes range 0..25600 | ||
| 90 | */ | ||
| 91 | if (brightness < 0x800) { | ||
| 92 | /* Y = Yn * L / 903.3 */ | ||
| 93 | brightness = (100*256 * brightness + 231245/2) / 231245; | ||
| 94 | } else { | ||
| 95 | /* Y = Yn * ((L + 16) / 116 )^3 */ | ||
| 96 | int t = (brightness*4 + 16*1024 + 58)/116; | ||
| 97 | brightness = 25 * ((t * t * t + 0x100000/2) / 0x100000); | ||
| 98 | } | ||
| 99 | |||
| 100 | gpio_set_value(S3C64XX_GPB(4), brightness); | ||
| 101 | |||
| 102 | return brightness; | ||
| 103 | } | ||
| 104 | |||
| 105 | static void hmt_bl_exit(struct device *dev) | ||
| 106 | { | ||
| 107 | gpio_free(S3C64XX_GPB(4)); | ||
| 108 | } | ||
| 109 | |||
| 110 | static struct platform_pwm_backlight_data hmt_backlight_data = { | ||
| 111 | .pwm_id = 1, | ||
| 112 | .max_brightness = 100 * 256, | ||
| 113 | .dft_brightness = 40 * 256, | ||
| 114 | .pwm_period_ns = 1000000000 / (100 * 256 * 20), | ||
| 115 | .init = hmt_bl_init, | ||
| 116 | .notify = hmt_bl_notify, | ||
| 117 | .exit = hmt_bl_exit, | ||
| 118 | |||
| 119 | }; | ||
| 120 | |||
| 121 | static struct platform_device hmt_backlight_device = { | ||
| 122 | .name = "pwm-backlight", | ||
| 123 | .dev = { | ||
| 124 | .parent = &s3c_device_timer[1].dev, | ||
| 125 | .platform_data = &hmt_backlight_data, | ||
| 126 | }, | ||
| 127 | }; | ||
| 128 | |||
| 129 | static struct s3c_fb_pd_win hmt_fb_win0 = { | ||
| 130 | .win_mode = { | ||
| 131 | .pixclock = 41094, | ||
| 132 | .left_margin = 8, | ||
| 133 | .right_margin = 13, | ||
| 134 | .upper_margin = 7, | ||
| 135 | .lower_margin = 5, | ||
| 136 | .hsync_len = 3, | ||
| 137 | .vsync_len = 1, | ||
| 138 | .xres = 800, | ||
| 139 | .yres = 480, | ||
| 140 | }, | ||
| 141 | .max_bpp = 32, | ||
| 142 | .default_bpp = 16, | ||
| 143 | }; | ||
| 144 | |||
| 145 | /* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */ | ||
| 146 | static struct s3c_fb_platdata hmt_lcd_pdata __initdata = { | ||
| 147 | .setup_gpio = s3c64xx_fb_gpio_setup_24bpp, | ||
| 148 | .win[0] = &hmt_fb_win0, | ||
| 149 | .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB, | ||
| 150 | .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC, | ||
| 151 | }; | ||
| 152 | |||
| 153 | static struct mtd_partition hmt_nand_part[] = { | ||
| 154 | [0] = { | ||
| 155 | .name = "uboot", | ||
| 156 | .size = SZ_512K, | ||
| 157 | .offset = 0, | ||
| 158 | }, | ||
| 159 | [1] = { | ||
| 160 | .name = "uboot-env1", | ||
| 161 | .size = SZ_256K, | ||
| 162 | .offset = SZ_512K, | ||
| 163 | }, | ||
| 164 | [2] = { | ||
| 165 | .name = "uboot-env2", | ||
| 166 | .size = SZ_256K, | ||
| 167 | .offset = SZ_512K + SZ_256K, | ||
| 168 | }, | ||
| 169 | [3] = { | ||
| 170 | .name = "kernel", | ||
| 171 | .size = SZ_2M, | ||
| 172 | .offset = SZ_1M, | ||
| 173 | }, | ||
| 174 | [4] = { | ||
| 175 | .name = "rootfs", | ||
| 176 | .size = MTDPART_SIZ_FULL, | ||
| 177 | .offset = SZ_1M + SZ_2M, | ||
| 178 | }, | ||
| 179 | }; | ||
| 180 | |||
| 181 | static struct s3c2410_nand_set hmt_nand_sets[] = { | ||
| 182 | [0] = { | ||
| 183 | .name = "nand", | ||
| 184 | .nr_chips = 1, | ||
| 185 | .nr_partitions = ARRAY_SIZE(hmt_nand_part), | ||
| 186 | .partitions = hmt_nand_part, | ||
| 187 | }, | ||
| 188 | }; | ||
| 189 | |||
| 190 | static struct s3c2410_platform_nand hmt_nand_info = { | ||
| 191 | .tacls = 25, | ||
| 192 | .twrph0 = 55, | ||
| 193 | .twrph1 = 40, | ||
| 194 | .nr_sets = ARRAY_SIZE(hmt_nand_sets), | ||
| 195 | .sets = hmt_nand_sets, | ||
| 196 | }; | ||
| 197 | |||
| 198 | static struct gpio_led hmt_leds[] = { | ||
| 199 | { /* left function keys */ | ||
| 200 | .name = "left:blue", | ||
| 201 | .gpio = S3C64XX_GPO(12), | ||
| 202 | .default_trigger = "default-on", | ||
| 203 | }, | ||
| 204 | { /* right function keys - red */ | ||
| 205 | .name = "right:red", | ||
| 206 | .gpio = S3C64XX_GPO(13), | ||
| 207 | }, | ||
| 208 | { /* right function keys - green */ | ||
| 209 | .name = "right:green", | ||
| 210 | .gpio = S3C64XX_GPO(14), | ||
| 211 | }, | ||
| 212 | { /* right function keys - blue */ | ||
| 213 | .name = "right:blue", | ||
| 214 | .gpio = S3C64XX_GPO(15), | ||
| 215 | .default_trigger = "default-on", | ||
| 216 | }, | ||
| 217 | }; | ||
| 218 | |||
| 219 | static struct gpio_led_platform_data hmt_led_data = { | ||
| 220 | .num_leds = ARRAY_SIZE(hmt_leds), | ||
| 221 | .leds = hmt_leds, | ||
| 222 | }; | ||
| 223 | |||
| 224 | static struct platform_device hmt_leds_device = { | ||
| 225 | .name = "leds-gpio", | ||
| 226 | .id = -1, | ||
| 227 | .dev.platform_data = &hmt_led_data, | ||
| 228 | }; | ||
| 229 | |||
| 230 | static struct map_desc hmt_iodesc[] = {}; | ||
| 231 | |||
| 232 | static struct platform_device *hmt_devices[] __initdata = { | ||
| 233 | &s3c_device_i2c0, | ||
| 234 | &s3c_device_nand, | ||
| 235 | &s3c_device_fb, | ||
| 236 | &s3c_device_usb, | ||
| 237 | &s3c_device_timer[1], | ||
| 238 | &hmt_backlight_device, | ||
| 239 | &hmt_leds_device, | ||
| 240 | }; | ||
| 241 | |||
| 242 | static void __init hmt_map_io(void) | ||
| 243 | { | ||
| 244 | s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc)); | ||
| 245 | s3c24xx_init_clocks(12000000); | ||
| 246 | s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs)); | ||
| 247 | } | ||
| 248 | |||
| 249 | static void __init hmt_machine_init(void) | ||
| 250 | { | ||
| 251 | s3c_i2c0_set_platdata(NULL); | ||
| 252 | s3c_fb_set_platdata(&hmt_lcd_pdata); | ||
| 253 | s3c_device_nand.dev.platform_data = &hmt_nand_info; | ||
| 254 | |||
| 255 | gpio_request(S3C64XX_GPC(7), "usb power"); | ||
| 256 | gpio_direction_output(S3C64XX_GPC(7), 0); | ||
| 257 | gpio_request(S3C64XX_GPM(0), "usb power"); | ||
| 258 | gpio_direction_output(S3C64XX_GPM(0), 1); | ||
| 259 | gpio_request(S3C64XX_GPK(7), "usb power"); | ||
| 260 | gpio_direction_output(S3C64XX_GPK(7), 1); | ||
| 261 | gpio_request(S3C64XX_GPF(13), "usb power"); | ||
| 262 | gpio_direction_output(S3C64XX_GPF(13), 1); | ||
| 263 | |||
| 264 | platform_add_devices(hmt_devices, ARRAY_SIZE(hmt_devices)); | ||
| 265 | } | ||
| 266 | |||
| 267 | MACHINE_START(HMT, "Airgoo-HMT") | ||
| 268 | /* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */ | ||
| 269 | .phys_io = S3C_PA_UART & 0xfff00000, | ||
| 270 | .io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc, | ||
| 271 | .boot_params = S3C64XX_PA_SDRAM + 0x100, | ||
| 272 | .init_irq = s3c6410_init_irq, | ||
| 273 | .map_io = hmt_map_io, | ||
| 274 | .init_machine = hmt_machine_init, | ||
| 275 | .timer = &s3c24xx_timer, | ||
| 276 | MACHINE_END | ||
diff --git a/arch/arm/mach-s3c6410/mach-ncp.c b/arch/arm/mach-s3c6410/mach-ncp.c index 6030636f8548..55e9bbfaf68b 100644 --- a/arch/arm/mach-s3c6410/mach-ncp.c +++ b/arch/arm/mach-s3c6410/mach-ncp.c | |||
| @@ -79,7 +79,7 @@ static struct platform_device *ncp_devices[] __initdata = { | |||
| 79 | &s3c_device_i2c0, | 79 | &s3c_device_i2c0, |
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | struct map_desc ncp_iodesc[] = {}; | 82 | static struct map_desc ncp_iodesc[] __initdata = {}; |
| 83 | 83 | ||
| 84 | static void __init ncp_map_io(void) | 84 | static void __init ncp_map_io(void) |
| 85 | { | 85 | { |
diff --git a/arch/arm/mach-s3c6410/mach-smdk6410.c b/arch/arm/mach-s3c6410/mach-smdk6410.c index bc9a7dea567f..ea51dbe76e3e 100644 --- a/arch/arm/mach-s3c6410/mach-smdk6410.c +++ b/arch/arm/mach-s3c6410/mach-smdk6410.c | |||
| @@ -65,16 +65,30 @@ static struct s3c2410_uartcfg smdk6410_uartcfgs[] __initdata = { | |||
| 65 | [0] = { | 65 | [0] = { |
| 66 | .hwport = 0, | 66 | .hwport = 0, |
| 67 | .flags = 0, | 67 | .flags = 0, |
| 68 | .ucon = 0x3c5, | 68 | .ucon = UCON, |
| 69 | .ulcon = 0x03, | 69 | .ulcon = ULCON, |
| 70 | .ufcon = 0x51, | 70 | .ufcon = UFCON, |
| 71 | }, | 71 | }, |
| 72 | [1] = { | 72 | [1] = { |
| 73 | .hwport = 1, | 73 | .hwport = 1, |
| 74 | .flags = 0, | 74 | .flags = 0, |
| 75 | .ucon = 0x3c5, | 75 | .ucon = UCON, |
| 76 | .ulcon = 0x03, | 76 | .ulcon = ULCON, |
| 77 | .ufcon = 0x51, | 77 | .ufcon = UFCON, |
| 78 | }, | ||
| 79 | [2] = { | ||
| 80 | .hwport = 2, | ||
| 81 | .flags = 0, | ||
| 82 | .ucon = UCON, | ||
| 83 | .ulcon = ULCON, | ||
| 84 | .ufcon = UFCON, | ||
| 85 | }, | ||
| 86 | [3] = { | ||
| 87 | .hwport = 3, | ||
| 88 | .flags = 0, | ||
| 89 | .ucon = UCON, | ||
| 90 | .ulcon = ULCON, | ||
| 91 | .ufcon = UFCON, | ||
| 78 | }, | 92 | }, |
| 79 | }; | 93 | }; |
| 80 | 94 | ||
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig new file mode 100644 index 000000000000..b1a4ba504416 --- /dev/null +++ b/arch/arm/mach-s5pc100/Kconfig | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | # arch/arm/mach-s5pc100/Kconfig | ||
| 2 | # | ||
| 3 | # Copyright 2009 Samsung Electronics Co. | ||
| 4 | # Byungho Min <bhmin@samsung.com> | ||
| 5 | # | ||
| 6 | # Licensed under GPLv2 | ||
| 7 | |||
| 8 | # Configuration options for the S5PC100 CPU | ||
| 9 | |||
| 10 | config CPU_S5PC100 | ||
| 11 | bool | ||
| 12 | select CPU_S5PC100_INIT | ||
| 13 | select CPU_S5PC100_CLOCK | ||
| 14 | help | ||
| 15 | Enable S5PC100 CPU support | ||
| 16 | |||
| 17 | config MACH_SMDKC100 | ||
| 18 | bool "SMDKC100" | ||
| 19 | select CPU_S5PC100 | ||
| 20 | select S5PC1XX_SETUP_I2C1 | ||
| 21 | help | ||
| 22 | Machine support for the Samsung SMDKC100 | ||
diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile new file mode 100644 index 000000000000..afc89b381d7a --- /dev/null +++ b/arch/arm/mach-s5pc100/Makefile | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | # arch/arm/mach-s5pc100/Makefile | ||
| 2 | # | ||
| 3 | # Copyright 2009 Samsung Electronics Co. | ||
| 4 | # | ||
| 5 | # Licensed under GPLv2 | ||
| 6 | |||
| 7 | obj-y := | ||
| 8 | obj-m := | ||
| 9 | obj-n := | ||
| 10 | obj- := | ||
| 11 | |||
| 12 | # Core support for S5PC100 system | ||
| 13 | |||
| 14 | obj-$(CONFIG_CPU_S5PC100) += cpu.o | ||
| 15 | |||
| 16 | # machine support | ||
| 17 | obj-$(CONFIG_MACH_SMDKC100) += mach-smdkc100.o | ||
diff --git a/arch/arm/mach-s5pc100/Makefile.boot b/arch/arm/mach-s5pc100/Makefile.boot new file mode 100644 index 000000000000..ff90aa13bd67 --- /dev/null +++ b/arch/arm/mach-s5pc100/Makefile.boot | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | zreladdr-y := 0x20008000 | ||
| 2 | params_phys-y := 0x20000100 | ||
diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c new file mode 100644 index 000000000000..0e718890da32 --- /dev/null +++ b/arch/arm/mach-s5pc100/cpu.c | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | /* linux/arch/arm/mach-s5pc100/cpu.c | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * Based on mach-s3c6410/cpu.c | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/types.h> | ||
| 15 | #include <linux/interrupt.h> | ||
| 16 | #include <linux/list.h> | ||
| 17 | #include <linux/timer.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/clk.h> | ||
| 20 | #include <linux/io.h> | ||
| 21 | #include <linux/sysdev.h> | ||
| 22 | #include <linux/serial_core.h> | ||
| 23 | #include <linux/platform_device.h> | ||
| 24 | |||
| 25 | #include <asm/mach/arch.h> | ||
| 26 | #include <asm/mach/map.h> | ||
| 27 | #include <asm/mach/irq.h> | ||
| 28 | |||
| 29 | #include <mach/hardware.h> | ||
| 30 | #include <mach/map.h> | ||
| 31 | #include <asm/irq.h> | ||
| 32 | |||
| 33 | #include <plat/cpu-freq.h> | ||
| 34 | #include <plat/regs-serial.h> | ||
| 35 | |||
| 36 | #include <plat/cpu.h> | ||
| 37 | #include <plat/devs.h> | ||
| 38 | #include <plat/clock.h> | ||
| 39 | #include <plat/sdhci.h> | ||
| 40 | #include <plat/iic-core.h> | ||
| 41 | #include <plat/s5pc100.h> | ||
| 42 | |||
| 43 | /* Initial IO mappings */ | ||
| 44 | |||
| 45 | static struct map_desc s5pc100_iodesc[] __initdata = { | ||
| 46 | }; | ||
| 47 | |||
| 48 | /* s5pc100_map_io | ||
| 49 | * | ||
| 50 | * register the standard cpu IO areas | ||
| 51 | */ | ||
| 52 | |||
| 53 | void __init s5pc100_map_io(void) | ||
| 54 | { | ||
| 55 | iotable_init(s5pc100_iodesc, ARRAY_SIZE(s5pc100_iodesc)); | ||
| 56 | |||
| 57 | /* initialise device information early */ | ||
| 58 | } | ||
| 59 | |||
| 60 | void __init s5pc100_init_clocks(int xtal) | ||
| 61 | { | ||
| 62 | printk(KERN_DEBUG "%s: initialising clocks\n", __func__); | ||
| 63 | s3c24xx_register_baseclocks(xtal); | ||
| 64 | s5pc1xx_register_clocks(); | ||
| 65 | s5pc100_register_clocks(); | ||
| 66 | s5pc100_setup_clocks(); | ||
| 67 | } | ||
| 68 | |||
| 69 | void __init s5pc100_init_irq(void) | ||
| 70 | { | ||
| 71 | u32 vic_valid[] = {~0, ~0, ~0}; | ||
| 72 | |||
| 73 | /* VIC0, VIC1, and VIC2 are fully populated. */ | ||
| 74 | s5pc1xx_init_irq(vic_valid, ARRAY_SIZE(vic_valid)); | ||
| 75 | } | ||
| 76 | |||
| 77 | struct sysdev_class s5pc100_sysclass = { | ||
| 78 | .name = "s5pc100-core", | ||
| 79 | }; | ||
| 80 | |||
| 81 | static struct sys_device s5pc100_sysdev = { | ||
| 82 | .cls = &s5pc100_sysclass, | ||
| 83 | }; | ||
| 84 | |||
| 85 | static int __init s5pc100_core_init(void) | ||
| 86 | { | ||
| 87 | return sysdev_class_register(&s5pc100_sysclass); | ||
| 88 | } | ||
| 89 | |||
| 90 | core_initcall(s5pc100_core_init); | ||
| 91 | |||
| 92 | int __init s5pc100_init(void) | ||
| 93 | { | ||
| 94 | printk(KERN_DEBUG "S5PC100: Initialising architecture\n"); | ||
| 95 | |||
| 96 | return sysdev_register(&s5pc100_sysdev); | ||
| 97 | } | ||
diff --git a/arch/arm/mach-s5pc100/include/mach/debug-macro.S b/arch/arm/mach-s5pc100/include/mach/debug-macro.S new file mode 100644 index 000000000000..9d142ccf654b --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/debug-macro.S | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* arch/arm/mach-s5pc100/include/mach/debug-macro.S | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * | ||
| 7 | * Based on mach-s3c6400/include/mach/debug-macro.S | ||
| 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 | /* pull in the relevant register and map files. */ | ||
| 15 | |||
| 16 | #include <mach/map.h> | ||
| 17 | #include <plat/regs-serial.h> | ||
| 18 | |||
| 19 | /* note, for the boot process to work we have to keep the UART | ||
| 20 | * virtual address aligned to an 1MiB boundary for the L1 | ||
| 21 | * mapping the head code makes. We keep the UART virtual address | ||
| 22 | * aligned and add in the offset when we load the value here. | ||
| 23 | */ | ||
| 24 | |||
| 25 | .macro addruart, rx | ||
| 26 | mrc p15, 0, \rx, c1, c0 | ||
| 27 | tst \rx, #1 | ||
| 28 | ldreq \rx, = S3C_PA_UART | ||
| 29 | ldrne \rx, = (S3C_VA_UART + S3C_PA_UART & 0xfffff) | ||
| 30 | add \rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART) | ||
| 31 | .endm | ||
| 32 | |||
| 33 | /* include the reset of the code which will do the work, we're only | ||
| 34 | * compiling for a single cpu processor type so the default of s3c2440 | ||
| 35 | * will be fine with us. | ||
| 36 | */ | ||
| 37 | |||
| 38 | #include <plat/debug-macro.S> | ||
diff --git a/arch/arm/mach-s5pc100/include/mach/entry-macro.S b/arch/arm/mach-s5pc100/include/mach/entry-macro.S new file mode 100644 index 000000000000..67131939e626 --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/entry-macro.S | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* arch/arm/mach-s5pc100/include/mach/entry-macro.S | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * Based on mach-s3c6400/include/mach/entry-macro.S | ||
| 7 | * | ||
| 8 | * Low-level IRQ helper macros for the Samsung S5PC1XX series | ||
| 9 | * | ||
| 10 | * This file is licensed under the terms of the GNU General Public | ||
| 11 | * License version 2. This program is licensed "as is" without any | ||
| 12 | * warranty of any kind, whether express or implied. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <asm/hardware/vic.h> | ||
| 16 | #include <mach/map.h> | ||
| 17 | #include <plat/irqs.h> | ||
| 18 | |||
| 19 | .macro disable_fiq | ||
| 20 | .endm | ||
| 21 | |||
| 22 | .macro get_irqnr_preamble, base, tmp | ||
| 23 | ldr \base, =S3C_VA_VIC0 | ||
| 24 | .endm | ||
| 25 | |||
| 26 | .macro arch_ret_to_user, tmp1, tmp2 | ||
| 27 | .endm | ||
| 28 | |||
| 29 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
| 30 | |||
| 31 | @ check the vic0 | ||
| 32 | mov \irqnr, # S3C_IRQ_OFFSET + 31 | ||
| 33 | ldr \irqstat, [ \base, # VIC_IRQ_STATUS ] | ||
| 34 | teq \irqstat, #0 | ||
| 35 | |||
| 36 | @ otherwise try vic1 | ||
| 37 | addeq \tmp, \base, #(S3C_VA_VIC1 - S3C_VA_VIC0) | ||
| 38 | addeq \irqnr, \irqnr, #32 | ||
| 39 | ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ] | ||
| 40 | teqeq \irqstat, #0 | ||
| 41 | |||
| 42 | @ otherwise try vic2 | ||
| 43 | addeq \tmp, \base, #(S3C_VA_VIC2 - S3C_VA_VIC0) | ||
| 44 | addeq \irqnr, \irqnr, #32 | ||
| 45 | ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ] | ||
| 46 | teqeq \irqstat, #0 | ||
| 47 | |||
| 48 | clzne \irqstat, \irqstat | ||
| 49 | subne \irqnr, \irqnr, \irqstat | ||
| 50 | .endm | ||
diff --git a/arch/arm/mach-s5pc100/include/mach/gpio-core.h b/arch/arm/mach-s5pc100/include/mach/gpio-core.h new file mode 100644 index 000000000000..ad28d8ec8a78 --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/gpio-core.h | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* arch/arm/mach-s5pc100/include/mach/gpio-core.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC100 - GPIO core support | ||
| 7 | * | ||
| 8 | * Based on mach-s3c6400/include/mach/gpio-core.h | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __ASM_ARCH_GPIO_CORE_H | ||
| 16 | #define __ASM_ARCH_GPIO_CORE_H __FILE__ | ||
| 17 | |||
| 18 | /* currently we just include the platform support */ | ||
| 19 | #include <plat/gpio-core.h> | ||
| 20 | |||
| 21 | #endif /* __ASM_ARCH_GPIO_CORE_H */ | ||
diff --git a/arch/arm/mach-s5pc100/include/mach/gpio.h b/arch/arm/mach-s5pc100/include/mach/gpio.h new file mode 100644 index 000000000000..c74fc93d7d15 --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/gpio.h | |||
| @@ -0,0 +1,146 @@ | |||
| 1 | /* arch/arm/mach-s5pc100/include/mach/gpio.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC100 - GPIO lib support | ||
| 7 | * | ||
| 8 | * Base on mach-s3c6400/include/mach/gpio.h | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #define gpio_get_value __gpio_get_value | ||
| 16 | #define gpio_set_value __gpio_set_value | ||
| 17 | #define gpio_cansleep __gpio_cansleep | ||
| 18 | #define gpio_to_irq __gpio_to_irq | ||
| 19 | |||
| 20 | /* GPIO bank sizes */ | ||
| 21 | #define S5PC1XX_GPIO_A0_NR (8) | ||
| 22 | #define S5PC1XX_GPIO_A1_NR (5) | ||
| 23 | #define S5PC1XX_GPIO_B_NR (8) | ||
| 24 | #define S5PC1XX_GPIO_C_NR (5) | ||
| 25 | #define S5PC1XX_GPIO_D_NR (7) | ||
| 26 | #define S5PC1XX_GPIO_E0_NR (8) | ||
| 27 | #define S5PC1XX_GPIO_E1_NR (6) | ||
| 28 | #define S5PC1XX_GPIO_F0_NR (8) | ||
| 29 | #define S5PC1XX_GPIO_F1_NR (8) | ||
| 30 | #define S5PC1XX_GPIO_F2_NR (8) | ||
| 31 | #define S5PC1XX_GPIO_F3_NR (4) | ||
| 32 | #define S5PC1XX_GPIO_G0_NR (8) | ||
| 33 | #define S5PC1XX_GPIO_G1_NR (3) | ||
| 34 | #define S5PC1XX_GPIO_G2_NR (7) | ||
| 35 | #define S5PC1XX_GPIO_G3_NR (7) | ||
| 36 | #define S5PC1XX_GPIO_H0_NR (8) | ||
| 37 | #define S5PC1XX_GPIO_H1_NR (8) | ||
| 38 | #define S5PC1XX_GPIO_H2_NR (8) | ||
| 39 | #define S5PC1XX_GPIO_H3_NR (8) | ||
| 40 | #define S5PC1XX_GPIO_I_NR (8) | ||
| 41 | #define S5PC1XX_GPIO_J0_NR (8) | ||
| 42 | #define S5PC1XX_GPIO_J1_NR (5) | ||
| 43 | #define S5PC1XX_GPIO_J2_NR (8) | ||
| 44 | #define S5PC1XX_GPIO_J3_NR (8) | ||
| 45 | #define S5PC1XX_GPIO_J4_NR (4) | ||
| 46 | #define S5PC1XX_GPIO_K0_NR (8) | ||
| 47 | #define S5PC1XX_GPIO_K1_NR (6) | ||
| 48 | #define S5PC1XX_GPIO_K2_NR (8) | ||
| 49 | #define S5PC1XX_GPIO_K3_NR (8) | ||
| 50 | #define S5PC1XX_GPIO_MP00_NR (8) | ||
| 51 | #define S5PC1XX_GPIO_MP01_NR (8) | ||
| 52 | #define S5PC1XX_GPIO_MP02_NR (8) | ||
| 53 | #define S5PC1XX_GPIO_MP03_NR (8) | ||
| 54 | #define S5PC1XX_GPIO_MP04_NR (5) | ||
| 55 | |||
| 56 | /* GPIO bank numbes */ | ||
| 57 | |||
| 58 | /* CONFIG_S3C_GPIO_SPACE allows the user to select extra | ||
| 59 | * space for debugging purposes so that any accidental | ||
| 60 | * change from one gpio bank to another can be caught. | ||
| 61 | */ | ||
| 62 | |||
| 63 | #define S5PC1XX_GPIO_NEXT(__gpio) \ | ||
| 64 | ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1) | ||
| 65 | |||
| 66 | enum s3c_gpio_number { | ||
| 67 | S5PC1XX_GPIO_A0_START = 0, | ||
| 68 | S5PC1XX_GPIO_A1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A0), | ||
| 69 | S5PC1XX_GPIO_B_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A1), | ||
| 70 | S5PC1XX_GPIO_C_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_B), | ||
| 71 | S5PC1XX_GPIO_D_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_C), | ||
| 72 | S5PC1XX_GPIO_E0_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_D), | ||
| 73 | S5PC1XX_GPIO_E1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_E0), | ||
| 74 | S5PC1XX_GPIO_F0_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_E1), | ||
| 75 | S5PC1XX_GPIO_F1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F0), | ||
| 76 | S5PC1XX_GPIO_F2_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F1), | ||
| 77 | S5PC1XX_GPIO_F3_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F2), | ||
| 78 | S5PC1XX_GPIO_G0_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F3), | ||
| 79 | S5PC1XX_GPIO_G1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G0), | ||
| 80 | S5PC1XX_GPIO_G2_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G1), | ||
| 81 | S5PC1XX_GPIO_G3_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G2), | ||
| 82 | S5PC1XX_GPIO_H0_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G3), | ||
| 83 | S5PC1XX_GPIO_H1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H0), | ||
| 84 | S5PC1XX_GPIO_H2_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H1), | ||
| 85 | S5PC1XX_GPIO_H3_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H2), | ||
| 86 | S5PC1XX_GPIO_I_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H3), | ||
| 87 | S5PC1XX_GPIO_J0_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_I), | ||
| 88 | S5PC1XX_GPIO_J1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J0), | ||
| 89 | S5PC1XX_GPIO_J2_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J1), | ||
| 90 | S5PC1XX_GPIO_J3_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J2), | ||
| 91 | S5PC1XX_GPIO_J4_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J3), | ||
| 92 | S5PC1XX_GPIO_K0_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J4), | ||
| 93 | S5PC1XX_GPIO_K1_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K0), | ||
| 94 | S5PC1XX_GPIO_K2_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K1), | ||
| 95 | S5PC1XX_GPIO_K3_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K2), | ||
| 96 | S5PC1XX_GPIO_MP00_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K3), | ||
| 97 | S5PC1XX_GPIO_MP01_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP00), | ||
| 98 | S5PC1XX_GPIO_MP02_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP01), | ||
| 99 | S5PC1XX_GPIO_MP03_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP02), | ||
| 100 | S5PC1XX_GPIO_MP04_START = S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP03), | ||
| 101 | }; | ||
| 102 | |||
| 103 | /* S5PC1XX GPIO number definitions. */ | ||
| 104 | #define S5PC1XX_GPA0(_nr) (S5PC1XX_GPIO_A0_START + (_nr)) | ||
| 105 | #define S5PC1XX_GPA1(_nr) (S5PC1XX_GPIO_A1_START + (_nr)) | ||
| 106 | #define S5PC1XX_GPB(_nr) (S5PC1XX_GPIO_B_START + (_nr)) | ||
| 107 | #define S5PC1XX_GPC(_nr) (S5PC1XX_GPIO_C_START + (_nr)) | ||
| 108 | #define S5PC1XX_GPD(_nr) (S5PC1XX_GPIO_D_START + (_nr)) | ||
| 109 | #define S5PC1XX_GPE0(_nr) (S5PC1XX_GPIO_E0_START + (_nr)) | ||
| 110 | #define S5PC1XX_GPE1(_nr) (S5PC1XX_GPIO_E1_START + (_nr)) | ||
| 111 | #define S5PC1XX_GPF0(_nr) (S5PC1XX_GPIO_F0_START + (_nr)) | ||
| 112 | #define S5PC1XX_GPF1(_nr) (S5PC1XX_GPIO_F1_START + (_nr)) | ||
| 113 | #define S5PC1XX_GPF2(_nr) (S5PC1XX_GPIO_F2_START + (_nr)) | ||
| 114 | #define S5PC1XX_GPF3(_nr) (S5PC1XX_GPIO_F3_START + (_nr)) | ||
| 115 | #define S5PC1XX_GPG0(_nr) (S5PC1XX_GPIO_G0_START + (_nr)) | ||
| 116 | #define S5PC1XX_GPG1(_nr) (S5PC1XX_GPIO_G1_START + (_nr)) | ||
| 117 | #define S5PC1XX_GPG2(_nr) (S5PC1XX_GPIO_G2_START + (_nr)) | ||
| 118 | #define S5PC1XX_GPG3(_nr) (S5PC1XX_GPIO_G3_START + (_nr)) | ||
| 119 | #define S5PC1XX_GPH0(_nr) (S5PC1XX_GPIO_H0_START + (_nr)) | ||
| 120 | #define S5PC1XX_GPH1(_nr) (S5PC1XX_GPIO_H1_START + (_nr)) | ||
| 121 | #define S5PC1XX_GPH2(_nr) (S5PC1XX_GPIO_H2_START + (_nr)) | ||
| 122 | #define S5PC1XX_GPH3(_nr) (S5PC1XX_GPIO_H3_START + (_nr)) | ||
| 123 | #define S5PC1XX_GPI(_nr) (S5PC1XX_GPIO_I_START + (_nr)) | ||
| 124 | #define S5PC1XX_GPJ0(_nr) (S5PC1XX_GPIO_J0_START + (_nr)) | ||
| 125 | #define S5PC1XX_GPJ1(_nr) (S5PC1XX_GPIO_J1_START + (_nr)) | ||
| 126 | #define S5PC1XX_GPJ2(_nr) (S5PC1XX_GPIO_J2_START + (_nr)) | ||
| 127 | #define S5PC1XX_GPJ3(_nr) (S5PC1XX_GPIO_J3_START + (_nr)) | ||
| 128 | #define S5PC1XX_GPJ4(_nr) (S5PC1XX_GPIO_J4_START + (_nr)) | ||
| 129 | #define S5PC1XX_GPK0(_nr) (S5PC1XX_GPIO_K0_START + (_nr)) | ||
| 130 | #define S5PC1XX_GPK1(_nr) (S5PC1XX_GPIO_K1_START + (_nr)) | ||
| 131 | #define S5PC1XX_GPK2(_nr) (S5PC1XX_GPIO_K2_START + (_nr)) | ||
| 132 | #define S5PC1XX_GPK3(_nr) (S5PC1XX_GPIO_K3_START + (_nr)) | ||
| 133 | #define S5PC1XX_MP00(_nr) (S5PC1XX_GPIO_MP00_START + (_nr)) | ||
| 134 | #define S5PC1XX_MP01(_nr) (S5PC1XX_GPIO_MP01_START + (_nr)) | ||
| 135 | #define S5PC1XX_MP02(_nr) (S5PC1XX_GPIO_MP02_START + (_nr)) | ||
| 136 | #define S5PC1XX_MP03(_nr) (S5PC1XX_GPIO_MP03_START + (_nr)) | ||
| 137 | #define S5PC1XX_MP04(_nr) (S5PC1XX_GPIO_MP04_START + (_nr)) | ||
| 138 | |||
| 139 | /* the end of the S5PC1XX specific gpios */ | ||
| 140 | #define S5PC1XX_GPIO_END (S5PC1XX_MP04(S5PC1XX_GPIO_MP04_NR) + 1) | ||
| 141 | #define S3C_GPIO_END S5PC1XX_GPIO_END | ||
| 142 | |||
| 143 | /* define the number of gpios we need to the one after the MP04() range */ | ||
| 144 | #define ARCH_NR_GPIOS (S5PC1XX_MP04(S5PC1XX_GPIO_MP04_NR) + 1) | ||
| 145 | |||
| 146 | #include <asm-generic/gpio.h> | ||
diff --git a/arch/arm/mach-s5pc100/include/mach/hardware.h b/arch/arm/mach-s5pc100/include/mach/hardware.h new file mode 100644 index 000000000000..6b38618c2fd9 --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/hardware.h | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | /* linux/arch/arm/mach-s5pc100/include/mach/hardware.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC100 - Hardware support | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef __ASM_ARCH_HARDWARE_H | ||
| 10 | #define __ASM_ARCH_HARDWARE_H __FILE__ | ||
| 11 | |||
| 12 | /* currently nothing here, placeholder */ | ||
| 13 | |||
| 14 | #endif /* __ASM_ARCH_HARDWARE_H */ | ||
diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h new file mode 100644 index 000000000000..622720dba289 --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/irqs.h | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | /* linux/arch/arm/mach-s5pc100/include/mach/irqs.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC100 - IRQ definitions | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef __ASM_ARCH_IRQS_H | ||
| 10 | #define __ASM_ARCH_IRQS_H __FILE__ | ||
| 11 | |||
| 12 | #include <plat/irqs.h> | ||
| 13 | |||
| 14 | #endif /* __ASM_ARCH_IRQ_H */ | ||
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h new file mode 100644 index 000000000000..9e9f39130b2c --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/map.h | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | /* linux/arch/arm/mach-s5pc100/include/mach/map.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * Based on mach-s3c6400/include/mach/map.h | ||
| 7 | * | ||
| 8 | * S5PC1XX - Memory map definitions | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __ASM_ARCH_MAP_H | ||
| 16 | #define __ASM_ARCH_MAP_H __FILE__ | ||
| 17 | |||
| 18 | #include <plat/map-base.h> | ||
| 19 | |||
| 20 | |||
| 21 | /* Chip ID */ | ||
| 22 | #define S5PC100_PA_CHIPID (0xE0000000) | ||
| 23 | #define S5PC1XX_PA_CHIPID S5PC100_PA_CHIPID | ||
| 24 | #define S5PC1XX_VA_CHIPID S3C_VA_SYS | ||
| 25 | |||
| 26 | /* System */ | ||
| 27 | #define S5PC100_PA_SYS (0xE0100000) | ||
| 28 | #define S5PC100_PA_CLK (S5PC100_PA_SYS + 0x0) | ||
| 29 | #define S5PC100_PA_PWR (S5PC100_PA_SYS + 0x8000) | ||
| 30 | #define S5PC1XX_PA_CLK S5PC100_PA_CLK | ||
| 31 | #define S5PC1XX_PA_PWR S5PC100_PA_PWR | ||
| 32 | #define S5PC1XX_VA_CLK (S3C_VA_SYS + 0x10000) | ||
| 33 | #define S5PC1XX_VA_PWR (S3C_VA_SYS + 0x20000) | ||
| 34 | |||
| 35 | /* Interrupt */ | ||
| 36 | #define S5PC100_PA_VIC (0xE4000000) | ||
| 37 | #define S5PC100_VA_VIC S3C_VA_IRQ | ||
| 38 | #define S5PC100_PA_VIC_OFFSET 0x100000 | ||
| 39 | #define S5PC100_VA_VIC_OFFSET 0x10000 | ||
| 40 | #define S5PC1XX_PA_VIC(x) (S5PC100_PA_VIC + ((x) * S5PC100_PA_VIC_OFFSET)) | ||
| 41 | #define S5PC1XX_VA_VIC(x) (S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET)) | ||
| 42 | |||
| 43 | /* Timer */ | ||
| 44 | #define S5PC100_PA_TIMER (0xEA000000) | ||
| 45 | #define S5PC1XX_PA_TIMER S5PC100_PA_TIMER | ||
| 46 | #define S5PC1XX_VA_TIMER S3C_VA_TIMER | ||
| 47 | |||
| 48 | /* UART */ | ||
| 49 | #define S5PC100_PA_UART (0xEC000000) | ||
| 50 | #define S5PC1XX_PA_UART S5PC100_PA_UART | ||
| 51 | #define S5PC1XX_VA_UART S3C_VA_UART | ||
| 52 | |||
| 53 | /* IIC */ | ||
| 54 | #define S5PC100_PA_IIC (0xEC100000) | ||
| 55 | |||
| 56 | /* ETC */ | ||
| 57 | #define S5PC100_PA_SDRAM (0x20000000) | ||
| 58 | |||
| 59 | /* compatibility defines. */ | ||
| 60 | #define S3C_PA_UART S5PC100_PA_UART | ||
| 61 | #define S3C_PA_UART0 (S5PC100_PA_UART + 0x0) | ||
| 62 | #define S3C_PA_UART1 (S5PC100_PA_UART + 0x400) | ||
| 63 | #define S3C_PA_UART2 (S5PC100_PA_UART + 0x800) | ||
| 64 | #define S3C_PA_UART3 (S5PC100_PA_UART + 0xC00) | ||
| 65 | #define S3C_VA_UART0 (S3C_VA_UART + 0x0) | ||
| 66 | #define S3C_VA_UART1 (S3C_VA_UART + 0x400) | ||
| 67 | #define S3C_VA_UART2 (S3C_VA_UART + 0x800) | ||
| 68 | #define S3C_VA_UART3 (S3C_VA_UART + 0xC00) | ||
| 69 | #define S3C_UART_OFFSET 0x400 | ||
| 70 | #define S3C_VA_VIC0 (S3C_VA_IRQ + 0x0) | ||
| 71 | #define S3C_VA_VIC1 (S3C_VA_IRQ + 0x10000) | ||
| 72 | #define S3C_VA_VIC2 (S3C_VA_IRQ + 0x20000) | ||
| 73 | #define S3C_PA_IIC S5PC100_PA_IIC | ||
| 74 | |||
| 75 | #endif /* __ASM_ARCH_C100_MAP_H */ | ||
diff --git a/arch/arm/mach-s5pc100/include/mach/memory.h b/arch/arm/mach-s5pc100/include/mach/memory.h new file mode 100644 index 000000000000..4b60d18179f7 --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/memory.h | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* arch/arm/mach-s5pc100/include/mach/memory.h | ||
| 2 | * | ||
| 3 | * Copyright 2008 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * Based on mach-s3c6400/include/mach/memory.h | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef __ASM_ARCH_MEMORY_H | ||
| 14 | #define __ASM_ARCH_MEMORY_H | ||
| 15 | |||
| 16 | #define PHYS_OFFSET UL(0x20000000) | ||
| 17 | |||
| 18 | #endif | ||
diff --git a/arch/arm/mach-s5pc100/include/mach/pwm-clock.h b/arch/arm/mach-s5pc100/include/mach/pwm-clock.h new file mode 100644 index 000000000000..b34d2f7aae52 --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/pwm-clock.h | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | /* linux/arch/arm/mach-s5pc100/include/mach/pwm-clock.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC100 - pwm clock and timer support | ||
| 7 | * | ||
| 8 | * Based on mach-s3c6400/include/mach/pwm-clock.h | ||
| 9 | */ | ||
| 10 | |||
| 11 | /** | ||
| 12 | * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk | ||
| 13 | * @tcfg: The timer TCFG1 register bits shifted down to 0. | ||
| 14 | * | ||
| 15 | * Return true if the given configuration from TCFG1 is a TCLK instead | ||
| 16 | * any of the TDIV clocks. | ||
| 17 | */ | ||
| 18 | static inline int pwm_cfg_src_is_tclk(unsigned long tcfg) | ||
| 19 | { | ||
| 20 | return tcfg >= S3C64XX_TCFG1_MUX_TCLK; | ||
| 21 | } | ||
| 22 | |||
| 23 | /** | ||
| 24 | * tcfg_to_divisor() - convert tcfg1 setting to a divisor | ||
| 25 | * @tcfg1: The tcfg1 setting, shifted down. | ||
| 26 | * | ||
| 27 | * Get the divisor value for the given tcfg1 setting. We assume the | ||
| 28 | * caller has already checked to see if this is not a TCLK source. | ||
| 29 | */ | ||
| 30 | static inline unsigned long tcfg_to_divisor(unsigned long tcfg1) | ||
| 31 | { | ||
| 32 | return 1 << tcfg1; | ||
| 33 | } | ||
| 34 | |||
| 35 | /** | ||
| 36 | * pwm_tdiv_has_div1() - does the tdiv setting have a /1 | ||
| 37 | * | ||
| 38 | * Return true if we have a /1 in the tdiv setting. | ||
| 39 | */ | ||
| 40 | static inline unsigned int pwm_tdiv_has_div1(void) | ||
| 41 | { | ||
| 42 | return 1; | ||
| 43 | } | ||
| 44 | |||
| 45 | /** | ||
| 46 | * pwm_tdiv_div_bits() - calculate TCFG1 divisor value. | ||
| 47 | * @div: The divisor to calculate the bit information for. | ||
| 48 | * | ||
| 49 | * Turn a divisor into the necessary bit field for TCFG1. | ||
| 50 | */ | ||
| 51 | static inline unsigned long pwm_tdiv_div_bits(unsigned int div) | ||
| 52 | { | ||
| 53 | return ilog2(div); | ||
| 54 | } | ||
| 55 | |||
| 56 | #define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK | ||
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-irq.h b/arch/arm/mach-s5pc100/include/mach/regs-irq.h new file mode 100644 index 000000000000..751ac15438c8 --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/regs-irq.h | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | /* linux/arch/arm/mach-s5pc100/include/mach/regs-irq.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC1XX - IRQ register definitions | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef __ASM_ARCH_REGS_IRQ_H | ||
| 14 | #define __ASM_ARCH_REGS_IRQ_H __FILE__ | ||
| 15 | |||
| 16 | #include <mach/map.h> | ||
| 17 | #include <asm/hardware/vic.h> | ||
| 18 | |||
| 19 | /* interrupt controller */ | ||
| 20 | #define S5PC1XX_VIC0REG(x) ((x) + S5PC1XX_VA_VIC(0)) | ||
| 21 | #define S5PC1XX_VIC1REG(x) ((x) + S5PC1XX_VA_VIC(1)) | ||
| 22 | #define S5PC1XX_VIC2REG(x) ((x) + S5PC1XX_VA_VIC(2)) | ||
| 23 | |||
| 24 | #endif /* __ASM_ARCH_REGS_IRQ_H */ | ||
diff --git a/arch/arm/mach-s5pc100/include/mach/system.h b/arch/arm/mach-s5pc100/include/mach/system.h new file mode 100644 index 000000000000..e39014375470 --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/system.h | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | /* linux/arch/arm/mach-s5pc100/include/mach/system.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC1XX - system implementation | ||
| 7 | * | ||
| 8 | * Based on mach-s3c6400/include/mach/system.h | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef __ASM_ARCH_SYSTEM_H | ||
| 12 | #define __ASM_ARCH_SYSTEM_H __FILE__ | ||
| 13 | |||
| 14 | static void arch_idle(void) | ||
| 15 | { | ||
| 16 | /* nothing here yet */ | ||
| 17 | } | ||
| 18 | |||
| 19 | static void arch_reset(char mode, const char *cmd) | ||
| 20 | { | ||
| 21 | /* nothing here yet */ | ||
| 22 | } | ||
| 23 | |||
| 24 | #endif /* __ASM_ARCH_IRQ_H */ | ||
diff --git a/arch/arm/mach-s5pc100/include/mach/tick.h b/arch/arm/mach-s5pc100/include/mach/tick.h new file mode 100644 index 000000000000..d3de0f3591ae --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/tick.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* linux/arch/arm/mach-s5pc100/include/mach/tick.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S3C64XX - Timer tick support definitions | ||
| 7 | * | ||
| 8 | * Based on mach-s3c6400/include/mach/tick.h | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __ASM_ARCH_TICK_H | ||
| 16 | #define __ASM_ARCH_TICK_H __FILE__ | ||
| 17 | |||
| 18 | /* note, the timer interrutps turn up in 2 places, the vic and then | ||
| 19 | * the timer block. We take the VIC as the base at the moment. | ||
| 20 | */ | ||
| 21 | static inline u32 s3c24xx_ostimer_pending(void) | ||
| 22 | { | ||
| 23 | u32 pend = __raw_readl(S3C_VA_VIC0 + VIC_RAW_STATUS); | ||
| 24 | return pend & 1 << (IRQ_TIMER4 - S5PC1XX_IRQ_VIC0(0)); | ||
| 25 | } | ||
| 26 | |||
| 27 | #define TICK_MAX (0xffffffff) | ||
| 28 | |||
| 29 | #endif /* __ASM_ARCH_TICK_H */ | ||
diff --git a/arch/arm/mach-s5pc100/include/mach/uncompress.h b/arch/arm/mach-s5pc100/include/mach/uncompress.h new file mode 100644 index 000000000000..01ccf535e76c --- /dev/null +++ b/arch/arm/mach-s5pc100/include/mach/uncompress.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* arch/arm/mach-s5pc100/include/mach/uncompress.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC100 - uncompress code | ||
| 7 | * | ||
| 8 | * Based on mach-s3c6400/include/mach/uncompress.h | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __ASM_ARCH_UNCOMPRESS_H | ||
| 16 | #define __ASM_ARCH_UNCOMPRESS_H | ||
| 17 | |||
| 18 | #include <mach/map.h> | ||
| 19 | #include <plat/uncompress.h> | ||
| 20 | |||
| 21 | static void arch_detect_cpu(void) | ||
| 22 | { | ||
| 23 | /* we do not need to do any cpu detection here at the moment. */ | ||
| 24 | fifo_mask = S3C2440_UFSTAT_TXMASK; | ||
| 25 | fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT; | ||
| 26 | } | ||
| 27 | |||
| 28 | #endif /* __ASM_ARCH_UNCOMPRESS_H */ | ||
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c new file mode 100644 index 000000000000..214093cd7632 --- /dev/null +++ b/arch/arm/mach-s5pc100/mach-smdkc100.c | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | /* linux/arch/arm/mach-s5pc100/mach-smdkc100.c | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Author: Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/types.h> | ||
| 14 | #include <linux/interrupt.h> | ||
| 15 | #include <linux/list.h> | ||
| 16 | #include <linux/timer.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/serial_core.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/io.h> | ||
| 21 | #include <linux/gpio.h> | ||
| 22 | #include <linux/i2c.h> | ||
| 23 | #include <linux/fb.h> | ||
| 24 | #include <linux/delay.h> | ||
| 25 | |||
| 26 | #include <asm/mach/arch.h> | ||
| 27 | #include <asm/mach/map.h> | ||
| 28 | |||
| 29 | #include <mach/map.h> | ||
| 30 | |||
| 31 | #include <asm/irq.h> | ||
| 32 | #include <asm/mach-types.h> | ||
| 33 | |||
| 34 | #include <plat/regs-serial.h> | ||
| 35 | |||
| 36 | #include <plat/clock.h> | ||
| 37 | #include <plat/devs.h> | ||
| 38 | #include <plat/cpu.h> | ||
| 39 | #include <plat/s5pc100.h> | ||
| 40 | |||
| 41 | #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK) | ||
| 42 | #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) | ||
| 43 | #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) | ||
| 44 | |||
| 45 | static struct s3c2410_uartcfg smdkc100_uartcfgs[] __initdata = { | ||
| 46 | [0] = { | ||
| 47 | .hwport = 0, | ||
| 48 | .flags = 0, | ||
| 49 | .ucon = 0x3c5, | ||
| 50 | .ulcon = 0x03, | ||
| 51 | .ufcon = 0x51, | ||
| 52 | }, | ||
| 53 | [1] = { | ||
| 54 | .hwport = 1, | ||
| 55 | .flags = 0, | ||
| 56 | .ucon = 0x3c5, | ||
| 57 | .ulcon = 0x03, | ||
| 58 | .ufcon = 0x51, | ||
| 59 | }, | ||
| 60 | [2] = { | ||
| 61 | .hwport = 2, | ||
| 62 | .flags = 0, | ||
| 63 | .ucon = 0x3c5, | ||
| 64 | .ulcon = 0x03, | ||
| 65 | .ufcon = 0x51, | ||
| 66 | }, | ||
| 67 | [3] = { | ||
| 68 | .hwport = 3, | ||
| 69 | .flags = 0, | ||
| 70 | .ucon = 0x3c5, | ||
| 71 | .ulcon = 0x03, | ||
| 72 | .ufcon = 0x51, | ||
| 73 | }, | ||
| 74 | }; | ||
| 75 | |||
| 76 | static struct map_desc smdkc100_iodesc[] = {}; | ||
| 77 | |||
| 78 | static struct platform_device *smdkc100_devices[] __initdata = { | ||
| 79 | }; | ||
| 80 | |||
| 81 | static void __init smdkc100_map_io(void) | ||
| 82 | { | ||
| 83 | s5pc1xx_init_io(smdkc100_iodesc, ARRAY_SIZE(smdkc100_iodesc)); | ||
| 84 | s3c24xx_init_clocks(12000000); | ||
| 85 | s3c24xx_init_uarts(smdkc100_uartcfgs, ARRAY_SIZE(smdkc100_uartcfgs)); | ||
| 86 | } | ||
| 87 | |||
| 88 | static void __init smdkc100_machine_init(void) | ||
| 89 | { | ||
| 90 | platform_add_devices(smdkc100_devices, ARRAY_SIZE(smdkc100_devices)); | ||
| 91 | } | ||
| 92 | |||
| 93 | MACHINE_START(SMDKC100, "SMDKC100") | ||
| 94 | /* Maintainer: Byungho Min <bhmin@samsung.com> */ | ||
| 95 | .phys_io = S5PC1XX_PA_UART & 0xfff00000, | ||
| 96 | .io_pg_offst = (((u32)S5PC1XX_VA_UART) >> 18) & 0xfffc, | ||
| 97 | .boot_params = S5PC100_PA_SDRAM + 0x100, | ||
| 98 | |||
| 99 | .init_irq = s5pc100_init_irq, | ||
| 100 | .map_io = smdkc100_map_io, | ||
| 101 | .init_machine = smdkc100_machine_init, | ||
| 102 | .timer = &s3c24xx_timer, | ||
| 103 | MACHINE_END | ||
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c index 3138d3955c9e..585cc013639d 100644 --- a/arch/arm/mach-u300/mmc.c +++ b/arch/arm/mach-u300/mmc.c | |||
| @@ -156,6 +156,8 @@ int __devinit mmc_init(struct amba_device *adev) | |||
| 156 | mmci_card->mmc0_plat_data.ocr_mask = MMC_VDD_28_29; | 156 | mmci_card->mmc0_plat_data.ocr_mask = MMC_VDD_28_29; |
| 157 | mmci_card->mmc0_plat_data.translate_vdd = mmc_translate_vdd; | 157 | mmci_card->mmc0_plat_data.translate_vdd = mmc_translate_vdd; |
| 158 | mmci_card->mmc0_plat_data.status = mmc_status; | 158 | mmci_card->mmc0_plat_data.status = mmc_status; |
| 159 | mmci_card->mmc0_plat_data.gpio_wp = -1; | ||
| 160 | mmci_card->mmc0_plat_data.gpio_cd = -1; | ||
| 159 | 161 | ||
| 160 | mmcsd_device->platform_data = (void *) &mmci_card->mmc0_plat_data; | 162 | mmcsd_device->platform_data = (void *) &mmci_card->mmc0_plat_data; |
| 161 | 163 | ||
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 31093af7d052..975eae41ee66 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
| 27 | #include <linux/amba/bus.h> | 27 | #include <linux/amba/bus.h> |
| 28 | #include <linux/amba/clcd.h> | 28 | #include <linux/amba/clcd.h> |
| 29 | #include <linux/amba/pl061.h> | ||
| 29 | #include <linux/clocksource.h> | 30 | #include <linux/clocksource.h> |
| 30 | #include <linux/clockchips.h> | 31 | #include <linux/clockchips.h> |
| 31 | #include <linux/cnt32_to_63.h> | 32 | #include <linux/cnt32_to_63.h> |
| @@ -371,6 +372,8 @@ unsigned int mmc_status(struct device *dev) | |||
| 371 | static struct mmc_platform_data mmc0_plat_data = { | 372 | static struct mmc_platform_data mmc0_plat_data = { |
| 372 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | 373 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, |
| 373 | .status = mmc_status, | 374 | .status = mmc_status, |
| 375 | .gpio_wp = -1, | ||
| 376 | .gpio_cd = -1, | ||
| 374 | }; | 377 | }; |
| 375 | 378 | ||
| 376 | /* | 379 | /* |
| @@ -705,6 +708,16 @@ static struct clcd_board clcd_plat_data = { | |||
| 705 | .remove = versatile_clcd_remove, | 708 | .remove = versatile_clcd_remove, |
| 706 | }; | 709 | }; |
| 707 | 710 | ||
| 711 | static struct pl061_platform_data gpio0_plat_data = { | ||
| 712 | .gpio_base = 0, | ||
| 713 | .irq_base = IRQ_GPIO0_START, | ||
| 714 | }; | ||
| 715 | |||
| 716 | static struct pl061_platform_data gpio1_plat_data = { | ||
| 717 | .gpio_base = 8, | ||
| 718 | .irq_base = IRQ_GPIO1_START, | ||
| 719 | }; | ||
| 720 | |||
| 708 | #define AACI_IRQ { IRQ_AACI, NO_IRQ } | 721 | #define AACI_IRQ { IRQ_AACI, NO_IRQ } |
| 709 | #define AACI_DMA { 0x80, 0x81 } | 722 | #define AACI_DMA { 0x80, 0x81 } |
| 710 | #define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B } | 723 | #define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B } |
| @@ -767,8 +780,8 @@ AMBA_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data); | |||
| 767 | AMBA_DEVICE(dmac, "dev:30", DMAC, NULL); | 780 | AMBA_DEVICE(dmac, "dev:30", DMAC, NULL); |
| 768 | AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); | 781 | AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); |
| 769 | AMBA_DEVICE(wdog, "dev:e1", WATCHDOG, NULL); | 782 | AMBA_DEVICE(wdog, "dev:e1", WATCHDOG, NULL); |
| 770 | AMBA_DEVICE(gpio0, "dev:e4", GPIO0, NULL); | 783 | AMBA_DEVICE(gpio0, "dev:e4", GPIO0, &gpio0_plat_data); |
| 771 | AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); | 784 | AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data); |
| 772 | AMBA_DEVICE(rtc, "dev:e8", RTC, NULL); | 785 | AMBA_DEVICE(rtc, "dev:e8", RTC, NULL); |
| 773 | AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); | 786 | AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); |
| 774 | AMBA_DEVICE(uart0, "dev:f1", UART0, NULL); | 787 | AMBA_DEVICE(uart0, "dev:f1", UART0, NULL); |
diff --git a/arch/arm/mach-versatile/include/mach/gpio.h b/arch/arm/mach-versatile/include/mach/gpio.h new file mode 100644 index 000000000000..94ff27678a46 --- /dev/null +++ b/arch/arm/mach-versatile/include/mach/gpio.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #include <asm-generic/gpio.h> | ||
| 2 | |||
| 3 | #define gpio_get_value __gpio_get_value | ||
| 4 | #define gpio_set_value __gpio_set_value | ||
| 5 | #define gpio_cansleep __gpio_cansleep | ||
| 6 | #define gpio_to_irq __gpio_to_irq | ||
diff --git a/arch/arm/mach-versatile/include/mach/irqs.h b/arch/arm/mach-versatile/include/mach/irqs.h index 9bfdb30e1f3f..bf44c61bd1f6 100644 --- a/arch/arm/mach-versatile/include/mach/irqs.h +++ b/arch/arm/mach-versatile/include/mach/irqs.h | |||
| @@ -122,4 +122,13 @@ | |||
| 122 | #define IRQ_SIC_PCI3 (IRQ_SIC_START + SIC_INT_PCI3) | 122 | #define IRQ_SIC_PCI3 (IRQ_SIC_START + SIC_INT_PCI3) |
| 123 | #define IRQ_SIC_END 63 | 123 | #define IRQ_SIC_END 63 |
| 124 | 124 | ||
| 125 | #define NR_IRQS 64 | 125 | #define IRQ_GPIO0_START (IRQ_SIC_END + 1) |
| 126 | #define IRQ_GPIO0_END (IRQ_GPIO0_START + 31) | ||
| 127 | #define IRQ_GPIO1_START (IRQ_GPIO0_END + 1) | ||
| 128 | #define IRQ_GPIO1_END (IRQ_GPIO1_START + 31) | ||
| 129 | #define IRQ_GPIO2_START (IRQ_GPIO1_END + 1) | ||
| 130 | #define IRQ_GPIO2_END (IRQ_GPIO2_START + 31) | ||
| 131 | #define IRQ_GPIO3_START (IRQ_GPIO2_END + 1) | ||
| 132 | #define IRQ_GPIO3_END (IRQ_GPIO3_START + 31) | ||
| 133 | |||
| 134 | #define NR_IRQS (IRQ_GPIO3_END + 1) | ||
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c index aa051c0884f8..9af8d8154df5 100644 --- a/arch/arm/mach-versatile/versatile_pb.c +++ b/arch/arm/mach-versatile/versatile_pb.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
| 24 | #include <linux/sysdev.h> | 24 | #include <linux/sysdev.h> |
| 25 | #include <linux/amba/bus.h> | 25 | #include <linux/amba/bus.h> |
| 26 | #include <linux/amba/pl061.h> | ||
| 26 | #include <linux/io.h> | 27 | #include <linux/io.h> |
| 27 | 28 | ||
| 28 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
| @@ -43,6 +44,18 @@ | |||
| 43 | static struct mmc_platform_data mmc1_plat_data = { | 44 | static struct mmc_platform_data mmc1_plat_data = { |
| 44 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | 45 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, |
| 45 | .status = mmc_status, | 46 | .status = mmc_status, |
| 47 | .gpio_wp = -1, | ||
| 48 | .gpio_cd = -1, | ||
| 49 | }; | ||
| 50 | |||
| 51 | static struct pl061_platform_data gpio2_plat_data = { | ||
| 52 | .gpio_base = 16, | ||
| 53 | .irq_base = IRQ_GPIO2_START, | ||
| 54 | }; | ||
| 55 | |||
| 56 | static struct pl061_platform_data gpio3_plat_data = { | ||
| 57 | .gpio_base = 24, | ||
| 58 | .irq_base = IRQ_GPIO3_START, | ||
| 46 | }; | 59 | }; |
| 47 | 60 | ||
| 48 | #define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ } | 61 | #define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ } |
| @@ -70,8 +83,8 @@ AMBA_DEVICE(sci1, "fpga:0a", SCI1, NULL); | |||
| 70 | AMBA_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data); | 83 | AMBA_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data); |
| 71 | 84 | ||
| 72 | /* DevChip Primecells */ | 85 | /* DevChip Primecells */ |
| 73 | AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); | 86 | AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data); |
| 74 | AMBA_DEVICE(gpio3, "dev:e7", GPIO3, NULL); | 87 | AMBA_DEVICE(gpio3, "dev:e7", GPIO3, &gpio3_plat_data); |
| 75 | 88 | ||
| 76 | static struct amba_device *amba_devs[] __initdata = { | 89 | static struct amba_device *amba_devs[] __initdata = { |
| 77 | &uart3_device, | 90 | &uart3_device, |
diff --git a/arch/arm/mach-w90x900/Kconfig b/arch/arm/mach-w90x900/Kconfig index 8e4178fe5ec2..69bab32a8bc2 100644 --- a/arch/arm/mach-w90x900/Kconfig +++ b/arch/arm/mach-w90x900/Kconfig | |||
| @@ -5,6 +5,16 @@ config CPU_W90P910 | |||
| 5 | help | 5 | help |
| 6 | Support for W90P910 of Nuvoton W90X900 CPUs. | 6 | Support for W90P910 of Nuvoton W90X900 CPUs. |
| 7 | 7 | ||
| 8 | config CPU_NUC950 | ||
| 9 | bool | ||
| 10 | help | ||
| 11 | Support for NUCP950 of Nuvoton NUC900 CPUs. | ||
| 12 | |||
| 13 | config CPU_NUC960 | ||
| 14 | bool | ||
| 15 | help | ||
| 16 | Support for NUCP960 of Nuvoton NUC900 CPUs. | ||
| 17 | |||
| 8 | menu "W90P910 Machines" | 18 | menu "W90P910 Machines" |
| 9 | 19 | ||
| 10 | config MACH_W90P910EVB | 20 | config MACH_W90P910EVB |
| @@ -16,4 +26,24 @@ config MACH_W90P910EVB | |||
| 16 | 26 | ||
| 17 | endmenu | 27 | endmenu |
| 18 | 28 | ||
| 29 | menu "NUC950 Machines" | ||
| 30 | |||
| 31 | config MACH_W90P950EVB | ||
| 32 | bool "Nuvoton NUC950 Evaluation Board" | ||
| 33 | select CPU_NUC950 | ||
| 34 | help | ||
| 35 | Say Y here if you are using the Nuvoton NUC950EVB | ||
| 36 | |||
| 37 | endmenu | ||
| 38 | |||
| 39 | menu "NUC960 Machines" | ||
| 40 | |||
| 41 | config MACH_W90N960EVB | ||
| 42 | bool "Nuvoton NUC960 Evaluation Board" | ||
| 43 | select CPU_NUC960 | ||
| 44 | help | ||
| 45 | Say Y here if you are using the Nuvoton NUC960EVB | ||
| 46 | |||
| 47 | endmenu | ||
| 48 | |||
| 19 | endif | 49 | endif |
diff --git a/arch/arm/mach-w90x900/Makefile b/arch/arm/mach-w90x900/Makefile index d50c94f4dbdf..828c0326441e 100644 --- a/arch/arm/mach-w90x900/Makefile +++ b/arch/arm/mach-w90x900/Makefile | |||
| @@ -4,12 +4,16 @@ | |||
| 4 | 4 | ||
| 5 | # Object file lists. | 5 | # Object file lists. |
| 6 | 6 | ||
| 7 | obj-y := irq.o time.o mfp-w90p910.o gpio.o clock.o | 7 | obj-y := irq.o time.o mfp.o gpio.o clock.o |
| 8 | 8 | obj-y += clksel.o dev.o cpu.o | |
| 9 | # W90X900 CPU support files | 9 | # W90X900 CPU support files |
| 10 | 10 | ||
| 11 | obj-$(CONFIG_CPU_W90P910) += w90p910.o | 11 | obj-$(CONFIG_CPU_W90P910) += nuc910.o |
| 12 | obj-$(CONFIG_CPU_NUC950) += nuc950.o | ||
| 13 | obj-$(CONFIG_CPU_NUC960) += nuc960.o | ||
| 12 | 14 | ||
| 13 | # machine support | 15 | # machine support |
| 14 | 16 | ||
| 15 | obj-$(CONFIG_MACH_W90P910EVB) += mach-w90p910evb.o | 17 | obj-$(CONFIG_MACH_W90P910EVB) += mach-nuc910evb.o |
| 18 | obj-$(CONFIG_MACH_W90P950EVB) += mach-nuc950evb.o | ||
| 19 | obj-$(CONFIG_MACH_W90N960EVB) += mach-nuc960evb.o | ||
diff --git a/arch/arm/mach-w90x900/clksel.c b/arch/arm/mach-w90x900/clksel.c new file mode 100644 index 000000000000..3de4a5211c3b --- /dev/null +++ b/arch/arm/mach-w90x900/clksel.c | |||
| @@ -0,0 +1,91 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-w90x900/clksel.c | ||
| 3 | * | ||
| 4 | * Copyright (c) 2008 Nuvoton technology corporation | ||
| 5 | * | ||
| 6 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation;version 2 of the License. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/list.h> | ||
| 17 | #include <linux/errno.h> | ||
| 18 | #include <linux/err.h> | ||
| 19 | #include <linux/string.h> | ||
| 20 | #include <linux/clk.h> | ||
| 21 | #include <linux/mutex.h> | ||
| 22 | #include <linux/io.h> | ||
| 23 | |||
| 24 | #include <mach/hardware.h> | ||
| 25 | #include <mach/regs-clock.h> | ||
| 26 | |||
| 27 | #define PLL0 0x00 | ||
| 28 | #define PLL1 0x01 | ||
| 29 | #define OTHER 0x02 | ||
| 30 | #define EXT 0x03 | ||
| 31 | #define MSOFFSET 0x0C | ||
| 32 | #define ATAOFFSET 0x0a | ||
| 33 | #define LCDOFFSET 0x06 | ||
| 34 | #define AUDOFFSET 0x04 | ||
| 35 | #define CPUOFFSET 0x00 | ||
| 36 | |||
| 37 | static DEFINE_MUTEX(clksel_sem); | ||
| 38 | |||
| 39 | static void clock_source_select(const char *dev_id, unsigned int clkval) | ||
| 40 | { | ||
| 41 | unsigned int clksel, offset; | ||
| 42 | |||
| 43 | clksel = __raw_readl(REG_CLKSEL); | ||
| 44 | |||
| 45 | if (strcmp(dev_id, "nuc900-ms") == 0) | ||
| 46 | offset = MSOFFSET; | ||
| 47 | else if (strcmp(dev_id, "nuc900-atapi") == 0) | ||
| 48 | offset = ATAOFFSET; | ||
| 49 | else if (strcmp(dev_id, "nuc900-lcd") == 0) | ||
| 50 | offset = LCDOFFSET; | ||
| 51 | else if (strcmp(dev_id, "nuc900-audio") == 0) | ||
| 52 | offset = AUDOFFSET; | ||
| 53 | else | ||
| 54 | offset = CPUOFFSET; | ||
| 55 | |||
| 56 | clksel &= ~(0x03 << offset); | ||
| 57 | clksel |= (clkval << offset); | ||
| 58 | |||
| 59 | __raw_writel(clksel, REG_CLKSEL); | ||
| 60 | } | ||
| 61 | |||
| 62 | void nuc900_clock_source(struct device *dev, unsigned char *src) | ||
| 63 | { | ||
| 64 | unsigned int clkval; | ||
| 65 | const char *dev_id; | ||
| 66 | |||
| 67 | BUG_ON(!src); | ||
| 68 | clkval = 0; | ||
| 69 | |||
| 70 | mutex_lock(&clksel_sem); | ||
| 71 | |||
| 72 | if (dev) | ||
| 73 | dev_id = dev_name(dev); | ||
| 74 | else | ||
| 75 | dev_id = "cpufreq"; | ||
| 76 | |||
| 77 | if (strcmp(src, "pll0") == 0) | ||
| 78 | clkval = PLL0; | ||
| 79 | else if (strcmp(src, "pll1") == 0) | ||
| 80 | clkval = PLL1; | ||
| 81 | else if (strcmp(src, "ext") == 0) | ||
| 82 | clkval = EXT; | ||
| 83 | else if (strcmp(src, "oth") == 0) | ||
| 84 | clkval = OTHER; | ||
| 85 | |||
| 86 | clock_source_select(dev_id, clkval); | ||
| 87 | |||
| 88 | mutex_unlock(&clksel_sem); | ||
| 89 | } | ||
| 90 | EXPORT_SYMBOL(nuc900_clock_source); | ||
| 91 | |||
diff --git a/arch/arm/mach-w90x900/clock.c b/arch/arm/mach-w90x900/clock.c index f420613cd395..b785994bab0a 100644 --- a/arch/arm/mach-w90x900/clock.c +++ b/arch/arm/mach-w90x900/clock.c | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | 25 | ||
| 26 | #include "clock.h" | 26 | #include "clock.h" |
| 27 | 27 | ||
| 28 | #define SUBCLK 0x24 | ||
| 29 | |||
| 28 | static DEFINE_SPINLOCK(clocks_lock); | 30 | static DEFINE_SPINLOCK(clocks_lock); |
| 29 | 31 | ||
| 30 | int clk_enable(struct clk *clk) | 32 | int clk_enable(struct clk *clk) |
| @@ -53,7 +55,13 @@ void clk_disable(struct clk *clk) | |||
| 53 | } | 55 | } |
| 54 | EXPORT_SYMBOL(clk_disable); | 56 | EXPORT_SYMBOL(clk_disable); |
| 55 | 57 | ||
| 56 | void w90x900_clk_enable(struct clk *clk, int enable) | 58 | unsigned long clk_get_rate(struct clk *clk) |
| 59 | { | ||
| 60 | return 15000000; | ||
| 61 | } | ||
| 62 | EXPORT_SYMBOL(clk_get_rate); | ||
| 63 | |||
| 64 | void nuc900_clk_enable(struct clk *clk, int enable) | ||
| 57 | { | 65 | { |
| 58 | unsigned int clocks = clk->cken; | 66 | unsigned int clocks = clk->cken; |
| 59 | unsigned long clken; | 67 | unsigned long clken; |
| @@ -68,6 +76,22 @@ void w90x900_clk_enable(struct clk *clk, int enable) | |||
| 68 | __raw_writel(clken, W90X900_VA_CLKPWR); | 76 | __raw_writel(clken, W90X900_VA_CLKPWR); |
| 69 | } | 77 | } |
| 70 | 78 | ||
| 79 | void nuc900_subclk_enable(struct clk *clk, int enable) | ||
| 80 | { | ||
| 81 | unsigned int clocks = clk->cken; | ||
| 82 | unsigned long clken; | ||
| 83 | |||
| 84 | clken = __raw_readl(W90X900_VA_CLKPWR + SUBCLK); | ||
| 85 | |||
| 86 | if (enable) | ||
| 87 | clken |= clocks; | ||
| 88 | else | ||
| 89 | clken &= ~clocks; | ||
| 90 | |||
| 91 | __raw_writel(clken, W90X900_VA_CLKPWR + SUBCLK); | ||
| 92 | } | ||
| 93 | |||
| 94 | |||
| 71 | void clks_register(struct clk_lookup *clks, size_t num) | 95 | void clks_register(struct clk_lookup *clks, size_t num) |
| 72 | { | 96 | { |
| 73 | int i; | 97 | int i; |
diff --git a/arch/arm/mach-w90x900/clock.h b/arch/arm/mach-w90x900/clock.h index 4f27bda76d56..f5816a06eed6 100644 --- a/arch/arm/mach-w90x900/clock.h +++ b/arch/arm/mach-w90x900/clock.h | |||
| @@ -12,7 +12,8 @@ | |||
| 12 | 12 | ||
| 13 | #include <asm/clkdev.h> | 13 | #include <asm/clkdev.h> |
| 14 | 14 | ||
| 15 | void w90x900_clk_enable(struct clk *clk, int enable); | 15 | void nuc900_clk_enable(struct clk *clk, int enable); |
| 16 | void nuc900_subclk_enable(struct clk *clk, int enable); | ||
| 16 | void clks_register(struct clk_lookup *clks, size_t num); | 17 | void clks_register(struct clk_lookup *clks, size_t num); |
| 17 | 18 | ||
| 18 | struct clk { | 19 | struct clk { |
| @@ -23,10 +24,17 @@ struct clk { | |||
| 23 | 24 | ||
| 24 | #define DEFINE_CLK(_name, _ctrlbit) \ | 25 | #define DEFINE_CLK(_name, _ctrlbit) \ |
| 25 | struct clk clk_##_name = { \ | 26 | struct clk clk_##_name = { \ |
| 26 | .enable = w90x900_clk_enable, \ | 27 | .enable = nuc900_clk_enable, \ |
| 27 | .cken = (1 << _ctrlbit), \ | 28 | .cken = (1 << _ctrlbit), \ |
| 28 | } | 29 | } |
| 29 | 30 | ||
| 31 | #define DEFINE_SUBCLK(_name, _ctrlbit) \ | ||
| 32 | struct clk clk_##_name = { \ | ||
| 33 | .enable = nuc900_subclk_enable, \ | ||
| 34 | .cken = (1 << _ctrlbit), \ | ||
| 35 | } | ||
| 36 | |||
| 37 | |||
| 30 | #define DEF_CLKLOOK(_clk, _devname, _conname) \ | 38 | #define DEF_CLKLOOK(_clk, _devname, _conname) \ |
| 31 | { \ | 39 | { \ |
| 32 | .clk = _clk, \ | 40 | .clk = _clk, \ |
diff --git a/arch/arm/mach-w90x900/cpu.c b/arch/arm/mach-w90x900/cpu.c new file mode 100644 index 000000000000..921cef991bf0 --- /dev/null +++ b/arch/arm/mach-w90x900/cpu.c | |||
| @@ -0,0 +1,212 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-w90x900/cpu.c | ||
| 3 | * | ||
| 4 | * Copyright (c) 2009 Nuvoton corporation. | ||
| 5 | * | ||
| 6 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 7 | * | ||
| 8 | * NUC900 series cpu common support | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation;version 2 of the License. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/types.h> | ||
| 18 | #include <linux/interrupt.h> | ||
| 19 | #include <linux/list.h> | ||
| 20 | #include <linux/timer.h> | ||
| 21 | #include <linux/init.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/io.h> | ||
| 24 | #include <linux/serial_8250.h> | ||
| 25 | #include <linux/delay.h> | ||
| 26 | |||
| 27 | #include <asm/mach/arch.h> | ||
| 28 | #include <asm/mach/map.h> | ||
| 29 | #include <asm/mach/irq.h> | ||
| 30 | #include <asm/irq.h> | ||
| 31 | |||
| 32 | #include <mach/hardware.h> | ||
| 33 | #include <mach/regs-serial.h> | ||
| 34 | #include <mach/regs-clock.h> | ||
| 35 | #include <mach/regs-ebi.h> | ||
| 36 | |||
| 37 | #include "cpu.h" | ||
| 38 | #include "clock.h" | ||
| 39 | |||
| 40 | /* Initial IO mappings */ | ||
| 41 | |||
| 42 | static struct map_desc nuc900_iodesc[] __initdata = { | ||
| 43 | IODESC_ENT(IRQ), | ||
| 44 | IODESC_ENT(GCR), | ||
| 45 | IODESC_ENT(UART), | ||
| 46 | IODESC_ENT(TIMER), | ||
| 47 | IODESC_ENT(EBI), | ||
| 48 | }; | ||
| 49 | |||
| 50 | /* Initial clock declarations. */ | ||
| 51 | static DEFINE_CLK(lcd, 0); | ||
| 52 | static DEFINE_CLK(audio, 1); | ||
| 53 | static DEFINE_CLK(fmi, 4); | ||
| 54 | static DEFINE_SUBCLK(ms, 0); | ||
| 55 | static DEFINE_SUBCLK(sd, 1); | ||
| 56 | static DEFINE_CLK(dmac, 5); | ||
| 57 | static DEFINE_CLK(atapi, 6); | ||
| 58 | static DEFINE_CLK(emc, 7); | ||
| 59 | static DEFINE_SUBCLK(rmii, 2); | ||
| 60 | static DEFINE_CLK(usbd, 8); | ||
| 61 | static DEFINE_CLK(usbh, 9); | ||
| 62 | static DEFINE_CLK(g2d, 10);; | ||
| 63 | static DEFINE_CLK(pwm, 18); | ||
| 64 | static DEFINE_CLK(ps2, 24); | ||
| 65 | static DEFINE_CLK(kpi, 25); | ||
| 66 | static DEFINE_CLK(wdt, 26); | ||
| 67 | static DEFINE_CLK(gdma, 27); | ||
| 68 | static DEFINE_CLK(adc, 28); | ||
| 69 | static DEFINE_CLK(usi, 29); | ||
| 70 | static DEFINE_CLK(ext, 0); | ||
| 71 | |||
| 72 | static struct clk_lookup nuc900_clkregs[] = { | ||
| 73 | DEF_CLKLOOK(&clk_lcd, "nuc900-lcd", NULL), | ||
| 74 | DEF_CLKLOOK(&clk_audio, "nuc900-audio", NULL), | ||
| 75 | DEF_CLKLOOK(&clk_fmi, "nuc900-fmi", NULL), | ||
| 76 | DEF_CLKLOOK(&clk_ms, "nuc900-fmi", "MS"), | ||
| 77 | DEF_CLKLOOK(&clk_sd, "nuc900-fmi", "SD"), | ||
| 78 | DEF_CLKLOOK(&clk_dmac, "nuc900-dmac", NULL), | ||
| 79 | DEF_CLKLOOK(&clk_atapi, "nuc900-atapi", NULL), | ||
| 80 | DEF_CLKLOOK(&clk_emc, "nuc900-emc", NULL), | ||
| 81 | DEF_CLKLOOK(&clk_rmii, "nuc900-emc", "RMII"), | ||
| 82 | DEF_CLKLOOK(&clk_usbd, "nuc900-usbd", NULL), | ||
| 83 | DEF_CLKLOOK(&clk_usbh, "nuc900-usbh", NULL), | ||
| 84 | DEF_CLKLOOK(&clk_g2d, "nuc900-g2d", NULL), | ||
| 85 | DEF_CLKLOOK(&clk_pwm, "nuc900-pwm", NULL), | ||
| 86 | DEF_CLKLOOK(&clk_ps2, "nuc900-ps2", NULL), | ||
| 87 | DEF_CLKLOOK(&clk_kpi, "nuc900-kpi", NULL), | ||
| 88 | DEF_CLKLOOK(&clk_wdt, "nuc900-wdt", NULL), | ||
| 89 | DEF_CLKLOOK(&clk_gdma, "nuc900-gdma", NULL), | ||
| 90 | DEF_CLKLOOK(&clk_adc, "nuc900-adc", NULL), | ||
| 91 | DEF_CLKLOOK(&clk_usi, "nuc900-spi", NULL), | ||
| 92 | DEF_CLKLOOK(&clk_ext, NULL, "ext"), | ||
| 93 | }; | ||
| 94 | |||
| 95 | /* Initial serial platform data */ | ||
| 96 | |||
| 97 | struct plat_serial8250_port nuc900_uart_data[] = { | ||
| 98 | NUC900_8250PORT(UART0), | ||
| 99 | }; | ||
| 100 | |||
| 101 | struct platform_device nuc900_serial_device = { | ||
| 102 | .name = "serial8250", | ||
| 103 | .id = PLAT8250_DEV_PLATFORM, | ||
| 104 | .dev = { | ||
| 105 | .platform_data = nuc900_uart_data, | ||
| 106 | }, | ||
| 107 | }; | ||
| 108 | |||
| 109 | /*Set NUC900 series cpu frequence*/ | ||
| 110 | static int __init nuc900_set_clkval(unsigned int cpufreq) | ||
| 111 | { | ||
| 112 | unsigned int pllclk, ahbclk, apbclk, val; | ||
| 113 | |||
| 114 | pllclk = 0; | ||
| 115 | ahbclk = 0; | ||
| 116 | apbclk = 0; | ||
| 117 | |||
| 118 | switch (cpufreq) { | ||
| 119 | case 66: | ||
| 120 | pllclk = PLL_66MHZ; | ||
| 121 | ahbclk = AHB_CPUCLK_1_1; | ||
| 122 | apbclk = APB_AHB_1_2; | ||
| 123 | break; | ||
| 124 | |||
| 125 | case 100: | ||
| 126 | pllclk = PLL_100MHZ; | ||
| 127 | ahbclk = AHB_CPUCLK_1_1; | ||
| 128 | apbclk = APB_AHB_1_2; | ||
| 129 | break; | ||
| 130 | |||
| 131 | case 120: | ||
| 132 | pllclk = PLL_120MHZ; | ||
| 133 | ahbclk = AHB_CPUCLK_1_2; | ||
| 134 | apbclk = APB_AHB_1_2; | ||
| 135 | break; | ||
| 136 | |||
| 137 | case 166: | ||
| 138 | pllclk = PLL_166MHZ; | ||
| 139 | ahbclk = AHB_CPUCLK_1_2; | ||
| 140 | apbclk = APB_AHB_1_2; | ||
| 141 | break; | ||
| 142 | |||
| 143 | case 200: | ||
| 144 | pllclk = PLL_200MHZ; | ||
| 145 | ahbclk = AHB_CPUCLK_1_2; | ||
| 146 | apbclk = APB_AHB_1_2; | ||
| 147 | break; | ||
| 148 | } | ||
| 149 | |||
| 150 | __raw_writel(pllclk, REG_PLLCON0); | ||
| 151 | |||
| 152 | val = __raw_readl(REG_CLKDIV); | ||
| 153 | val &= ~(0x03 << 24 | 0x03 << 26); | ||
| 154 | val |= (ahbclk << 24 | apbclk << 26); | ||
| 155 | __raw_writel(val, REG_CLKDIV); | ||
| 156 | |||
| 157 | return 0; | ||
| 158 | } | ||
| 159 | static int __init nuc900_set_cpufreq(char *str) | ||
| 160 | { | ||
| 161 | unsigned long cpufreq, val; | ||
| 162 | |||
| 163 | if (!*str) | ||
| 164 | return 0; | ||
| 165 | |||
| 166 | strict_strtoul(str, 0, &cpufreq); | ||
| 167 | |||
| 168 | nuc900_clock_source(NULL, "ext"); | ||
| 169 | |||
| 170 | nuc900_set_clkval(cpufreq); | ||
| 171 | |||
| 172 | mdelay(1); | ||
| 173 | |||
| 174 | val = __raw_readl(REG_CKSKEW); | ||
| 175 | val &= ~0xff; | ||
| 176 | val |= DEFAULTSKEW; | ||
| 177 | __raw_writel(val, REG_CKSKEW); | ||
| 178 | |||
| 179 | nuc900_clock_source(NULL, "pll0"); | ||
| 180 | |||
| 181 | return 1; | ||
| 182 | } | ||
| 183 | |||
| 184 | __setup("cpufreq=", nuc900_set_cpufreq); | ||
| 185 | |||
| 186 | /*Init NUC900 evb io*/ | ||
| 187 | |||
| 188 | void __init nuc900_map_io(struct map_desc *mach_desc, int mach_size) | ||
| 189 | { | ||
| 190 | unsigned long idcode = 0x0; | ||
| 191 | |||
| 192 | iotable_init(mach_desc, mach_size); | ||
| 193 | iotable_init(nuc900_iodesc, ARRAY_SIZE(nuc900_iodesc)); | ||
| 194 | |||
| 195 | idcode = __raw_readl(NUC900PDID); | ||
| 196 | if (idcode == NUC910_CPUID) | ||
| 197 | printk(KERN_INFO "CPU type 0x%08lx is NUC910\n", idcode); | ||
| 198 | else if (idcode == NUC920_CPUID) | ||
| 199 | printk(KERN_INFO "CPU type 0x%08lx is NUC920\n", idcode); | ||
| 200 | else if (idcode == NUC950_CPUID) | ||
| 201 | printk(KERN_INFO "CPU type 0x%08lx is NUC950\n", idcode); | ||
| 202 | else if (idcode == NUC960_CPUID) | ||
| 203 | printk(KERN_INFO "CPU type 0x%08lx is NUC960\n", idcode); | ||
| 204 | } | ||
| 205 | |||
| 206 | /*Init NUC900 clock*/ | ||
| 207 | |||
| 208 | void __init nuc900_init_clocks(void) | ||
| 209 | { | ||
| 210 | clks_register(nuc900_clkregs, ARRAY_SIZE(nuc900_clkregs)); | ||
| 211 | } | ||
| 212 | |||
diff --git a/arch/arm/mach-w90x900/cpu.h b/arch/arm/mach-w90x900/cpu.h index 57b5dbabeb41..4d58ba164e25 100644 --- a/arch/arm/mach-w90x900/cpu.h +++ b/arch/arm/mach-w90x900/cpu.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * Copyright (c) 2008 Nuvoton technology corporation | 6 | * Copyright (c) 2008 Nuvoton technology corporation |
| 7 | * All rights reserved. | 7 | * All rights reserved. |
| 8 | * | 8 | * |
| 9 | * Header file for W90X900 CPU support | 9 | * Header file for NUC900 CPU support |
| 10 | * | 10 | * |
| 11 | * Wan ZongShun <mcuos.com@gmail.com> | 11 | * Wan ZongShun <mcuos.com@gmail.com> |
| 12 | * | 12 | * |
| @@ -24,29 +24,7 @@ | |||
| 24 | .type = MT_DEVICE, \ | 24 | .type = MT_DEVICE, \ |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | /*Cpu identifier register*/ | 27 | #define NUC900_8250PORT(name) \ |
| 28 | |||
| 29 | #define W90X900PDID W90X900_VA_GCR | ||
| 30 | #define W90P910_CPUID 0x02900910 | ||
| 31 | #define W90P920_CPUID 0x02900920 | ||
| 32 | #define W90P950_CPUID 0x02900950 | ||
| 33 | #define W90N960_CPUID 0x02900960 | ||
| 34 | |||
| 35 | struct w90x900_uartcfg; | ||
| 36 | struct map_desc; | ||
| 37 | struct sys_timer; | ||
| 38 | |||
| 39 | /* core initialisation functions */ | ||
| 40 | |||
| 41 | extern void w90x900_init_irq(void); | ||
| 42 | extern void w90p910_init_io(struct map_desc *mach_desc, int size); | ||
| 43 | extern void w90p910_init_uarts(struct w90x900_uartcfg *cfg, int no); | ||
| 44 | extern void w90p910_init_clocks(void); | ||
| 45 | extern void w90p910_map_io(struct map_desc *mach_desc, int size); | ||
| 46 | extern struct platform_device w90p910_serial_device; | ||
| 47 | extern struct sys_timer w90x900_timer; | ||
| 48 | |||
| 49 | #define W90X900_8250PORT(name) \ | ||
| 50 | { \ | 28 | { \ |
| 51 | .membase = name##_BA, \ | 29 | .membase = name##_BA, \ |
| 52 | .mapbase = name##_PA, \ | 30 | .mapbase = name##_PA, \ |
| @@ -56,3 +34,26 @@ extern struct sys_timer w90x900_timer; | |||
| 56 | .iotype = UPIO_MEM, \ | 34 | .iotype = UPIO_MEM, \ |
| 57 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ | 35 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \ |
| 58 | } | 36 | } |
| 37 | |||
| 38 | /*Cpu identifier register*/ | ||
| 39 | |||
| 40 | #define NUC900PDID W90X900_VA_GCR | ||
| 41 | #define NUC910_CPUID 0x02900910 | ||
| 42 | #define NUC920_CPUID 0x02900920 | ||
| 43 | #define NUC950_CPUID 0x02900950 | ||
| 44 | #define NUC960_CPUID 0x02900960 | ||
| 45 | |||
| 46 | /* extern file from cpu.c */ | ||
| 47 | |||
| 48 | extern void nuc900_clock_source(struct device *dev, unsigned char *src); | ||
| 49 | extern void nuc900_init_clocks(void); | ||
| 50 | extern void nuc900_map_io(struct map_desc *mach_desc, int mach_size); | ||
| 51 | extern void nuc900_board_init(struct platform_device **device, int size); | ||
| 52 | |||
| 53 | /* for either public between 910 and 920, or between 920 and 950 */ | ||
| 54 | |||
| 55 | extern struct platform_device nuc900_serial_device; | ||
| 56 | extern struct platform_device nuc900_device_fmi; | ||
| 57 | extern struct platform_device nuc900_device_kpi; | ||
| 58 | extern struct platform_device nuc900_device_rtc; | ||
| 59 | extern struct platform_device nuc900_device_ts; | ||
diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c new file mode 100644 index 000000000000..2a6f98de48d2 --- /dev/null +++ b/arch/arm/mach-w90x900/dev.c | |||
| @@ -0,0 +1,389 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-w90x900/dev.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 Nuvoton corporation. | ||
| 5 | * | ||
| 6 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU General Public License as | ||
| 10 | * published by the Free Software Foundation;version 2 of the License. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/types.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/list.h> | ||
| 18 | #include <linux/timer.h> | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | |||
| 22 | #include <linux/mtd/physmap.h> | ||
| 23 | #include <linux/mtd/mtd.h> | ||
| 24 | #include <linux/mtd/partitions.h> | ||
| 25 | |||
| 26 | #include <linux/spi/spi.h> | ||
| 27 | #include <linux/spi/flash.h> | ||
| 28 | |||
| 29 | #include <asm/mach/arch.h> | ||
| 30 | #include <asm/mach/map.h> | ||
| 31 | #include <asm/mach/irq.h> | ||
| 32 | #include <asm/mach-types.h> | ||
| 33 | |||
| 34 | #include <mach/regs-serial.h> | ||
| 35 | #include <mach/map.h> | ||
| 36 | |||
| 37 | #include "cpu.h" | ||
| 38 | |||
| 39 | /*NUC900 evb norflash driver data */ | ||
| 40 | |||
| 41 | #define NUC900_FLASH_BASE 0xA0000000 | ||
| 42 | #define NUC900_FLASH_SIZE 0x400000 | ||
| 43 | #define SPIOFFSET 0x200 | ||
| 44 | #define SPIOREG_SIZE 0x100 | ||
| 45 | |||
| 46 | static struct mtd_partition nuc900_flash_partitions[] = { | ||
| 47 | { | ||
| 48 | .name = "NOR Partition 1 for kernel (960K)", | ||
| 49 | .size = 0xF0000, | ||
| 50 | .offset = 0x10000, | ||
| 51 | }, | ||
| 52 | { | ||
| 53 | .name = "NOR Partition 2 for image (1M)", | ||
| 54 | .size = 0x100000, | ||
| 55 | .offset = 0x100000, | ||
| 56 | }, | ||
| 57 | { | ||
| 58 | .name = "NOR Partition 3 for user (2M)", | ||
| 59 | .size = 0x200000, | ||
| 60 | .offset = 0x00200000, | ||
| 61 | } | ||
| 62 | }; | ||
| 63 | |||
| 64 | static struct physmap_flash_data nuc900_flash_data = { | ||
| 65 | .width = 2, | ||
| 66 | .parts = nuc900_flash_partitions, | ||
| 67 | .nr_parts = ARRAY_SIZE(nuc900_flash_partitions), | ||
| 68 | }; | ||
| 69 | |||
| 70 | static struct resource nuc900_flash_resources[] = { | ||
| 71 | { | ||
| 72 | .start = NUC900_FLASH_BASE, | ||
| 73 | .end = NUC900_FLASH_BASE + NUC900_FLASH_SIZE - 1, | ||
| 74 | .flags = IORESOURCE_MEM, | ||
| 75 | } | ||
| 76 | }; | ||
| 77 | |||
| 78 | static struct platform_device nuc900_flash_device = { | ||
| 79 | .name = "physmap-flash", | ||
| 80 | .id = 0, | ||
| 81 | .dev = { | ||
| 82 | .platform_data = &nuc900_flash_data, | ||
| 83 | }, | ||
| 84 | .resource = nuc900_flash_resources, | ||
| 85 | .num_resources = ARRAY_SIZE(nuc900_flash_resources), | ||
| 86 | }; | ||
| 87 | |||
| 88 | /* USB EHCI Host Controller */ | ||
| 89 | |||
| 90 | static struct resource nuc900_usb_ehci_resource[] = { | ||
| 91 | [0] = { | ||
| 92 | .start = W90X900_PA_USBEHCIHOST, | ||
| 93 | .end = W90X900_PA_USBEHCIHOST + W90X900_SZ_USBEHCIHOST - 1, | ||
| 94 | .flags = IORESOURCE_MEM, | ||
| 95 | }, | ||
| 96 | [1] = { | ||
| 97 | .start = IRQ_USBH, | ||
| 98 | .end = IRQ_USBH, | ||
| 99 | .flags = IORESOURCE_IRQ, | ||
| 100 | } | ||
| 101 | }; | ||
| 102 | |||
| 103 | static u64 nuc900_device_usb_ehci_dmamask = 0xffffffffUL; | ||
| 104 | |||
| 105 | static struct platform_device nuc900_device_usb_ehci = { | ||
| 106 | .name = "nuc900-ehci", | ||
| 107 | .id = -1, | ||
| 108 | .num_resources = ARRAY_SIZE(nuc900_usb_ehci_resource), | ||
| 109 | .resource = nuc900_usb_ehci_resource, | ||
| 110 | .dev = { | ||
| 111 | .dma_mask = &nuc900_device_usb_ehci_dmamask, | ||
| 112 | .coherent_dma_mask = 0xffffffffUL | ||
| 113 | } | ||
| 114 | }; | ||
| 115 | |||
| 116 | /* USB OHCI Host Controller */ | ||
| 117 | |||
| 118 | static struct resource nuc900_usb_ohci_resource[] = { | ||
| 119 | [0] = { | ||
| 120 | .start = W90X900_PA_USBOHCIHOST, | ||
| 121 | .end = W90X900_PA_USBOHCIHOST + W90X900_SZ_USBOHCIHOST - 1, | ||
| 122 | .flags = IORESOURCE_MEM, | ||
| 123 | }, | ||
| 124 | [1] = { | ||
| 125 | .start = IRQ_USBH, | ||
| 126 | .end = IRQ_USBH, | ||
| 127 | .flags = IORESOURCE_IRQ, | ||
| 128 | } | ||
| 129 | }; | ||
| 130 | |||
| 131 | static u64 nuc900_device_usb_ohci_dmamask = 0xffffffffUL; | ||
| 132 | static struct platform_device nuc900_device_usb_ohci = { | ||
| 133 | .name = "nuc900-ohci", | ||
| 134 | .id = -1, | ||
| 135 | .num_resources = ARRAY_SIZE(nuc900_usb_ohci_resource), | ||
| 136 | .resource = nuc900_usb_ohci_resource, | ||
| 137 | .dev = { | ||
| 138 | .dma_mask = &nuc900_device_usb_ohci_dmamask, | ||
| 139 | .coherent_dma_mask = 0xffffffffUL | ||
| 140 | } | ||
| 141 | }; | ||
| 142 | |||
| 143 | /* USB Device (Gadget)*/ | ||
| 144 | |||
| 145 | static struct resource nuc900_usbgadget_resource[] = { | ||
| 146 | [0] = { | ||
| 147 | .start = W90X900_PA_USBDEV, | ||
| 148 | .end = W90X900_PA_USBDEV + W90X900_SZ_USBDEV - 1, | ||
| 149 | .flags = IORESOURCE_MEM, | ||
| 150 | }, | ||
| 151 | [1] = { | ||
| 152 | .start = IRQ_USBD, | ||
| 153 | .end = IRQ_USBD, | ||
| 154 | .flags = IORESOURCE_IRQ, | ||
| 155 | } | ||
| 156 | }; | ||
| 157 | |||
| 158 | static struct platform_device nuc900_device_usbgadget = { | ||
| 159 | .name = "nuc900-usbgadget", | ||
| 160 | .id = -1, | ||
| 161 | .num_resources = ARRAY_SIZE(nuc900_usbgadget_resource), | ||
| 162 | .resource = nuc900_usbgadget_resource, | ||
| 163 | }; | ||
| 164 | |||
| 165 | /* MAC device */ | ||
| 166 | |||
| 167 | static struct resource nuc900_emc_resource[] = { | ||
| 168 | [0] = { | ||
| 169 | .start = W90X900_PA_EMC, | ||
| 170 | .end = W90X900_PA_EMC + W90X900_SZ_EMC - 1, | ||
| 171 | .flags = IORESOURCE_MEM, | ||
| 172 | }, | ||
| 173 | [1] = { | ||
| 174 | .start = IRQ_EMCTX, | ||
| 175 | .end = IRQ_EMCTX, | ||
| 176 | .flags = IORESOURCE_IRQ, | ||
| 177 | }, | ||
| 178 | [2] = { | ||
| 179 | .start = IRQ_EMCRX, | ||
| 180 | .end = IRQ_EMCRX, | ||
| 181 | .flags = IORESOURCE_IRQ, | ||
| 182 | } | ||
| 183 | }; | ||
| 184 | |||
| 185 | static u64 nuc900_device_emc_dmamask = 0xffffffffUL; | ||
| 186 | static struct platform_device nuc900_device_emc = { | ||
| 187 | .name = "nuc900-emc", | ||
| 188 | .id = -1, | ||
| 189 | .num_resources = ARRAY_SIZE(nuc900_emc_resource), | ||
| 190 | .resource = nuc900_emc_resource, | ||
| 191 | .dev = { | ||
| 192 | .dma_mask = &nuc900_device_emc_dmamask, | ||
| 193 | .coherent_dma_mask = 0xffffffffUL | ||
| 194 | } | ||
| 195 | }; | ||
| 196 | |||
| 197 | /* SPI device */ | ||
| 198 | |||
| 199 | static struct resource nuc900_spi_resource[] = { | ||
| 200 | [0] = { | ||
| 201 | .start = W90X900_PA_I2C + SPIOFFSET, | ||
| 202 | .end = W90X900_PA_I2C + SPIOFFSET + SPIOREG_SIZE - 1, | ||
| 203 | .flags = IORESOURCE_MEM, | ||
| 204 | }, | ||
| 205 | [1] = { | ||
| 206 | .start = IRQ_SSP, | ||
| 207 | .end = IRQ_SSP, | ||
| 208 | .flags = IORESOURCE_IRQ, | ||
| 209 | } | ||
| 210 | }; | ||
| 211 | |||
| 212 | static struct platform_device nuc900_device_spi = { | ||
| 213 | .name = "nuc900-spi", | ||
| 214 | .id = -1, | ||
| 215 | .num_resources = ARRAY_SIZE(nuc900_spi_resource), | ||
| 216 | .resource = nuc900_spi_resource, | ||
| 217 | }; | ||
| 218 | |||
| 219 | /* spi device, spi flash info */ | ||
| 220 | |||
| 221 | static struct mtd_partition nuc900_spi_flash_partitions[] = { | ||
| 222 | { | ||
| 223 | .name = "bootloader(spi)", | ||
| 224 | .size = 0x0100000, | ||
| 225 | .offset = 0, | ||
| 226 | }, | ||
| 227 | }; | ||
| 228 | |||
| 229 | static struct flash_platform_data nuc900_spi_flash_data = { | ||
| 230 | .name = "m25p80", | ||
| 231 | .parts = nuc900_spi_flash_partitions, | ||
| 232 | .nr_parts = ARRAY_SIZE(nuc900_spi_flash_partitions), | ||
| 233 | .type = "w25x16", | ||
| 234 | }; | ||
| 235 | |||
| 236 | static struct spi_board_info nuc900_spi_board_info[] __initdata = { | ||
| 237 | { | ||
| 238 | .modalias = "m25p80", | ||
| 239 | .max_speed_hz = 20000000, | ||
| 240 | .bus_num = 0, | ||
| 241 | .chip_select = 1, | ||
| 242 | .platform_data = &nuc900_spi_flash_data, | ||
| 243 | .mode = SPI_MODE_0, | ||
| 244 | }, | ||
| 245 | }; | ||
| 246 | |||
| 247 | /* WDT Device */ | ||
| 248 | |||
| 249 | static struct resource nuc900_wdt_resource[] = { | ||
| 250 | [0] = { | ||
| 251 | .start = W90X900_PA_TIMER, | ||
| 252 | .end = W90X900_PA_TIMER + W90X900_SZ_TIMER - 1, | ||
| 253 | .flags = IORESOURCE_MEM, | ||
| 254 | }, | ||
| 255 | [1] = { | ||
| 256 | .start = IRQ_WDT, | ||
| 257 | .end = IRQ_WDT, | ||
| 258 | .flags = IORESOURCE_IRQ, | ||
| 259 | } | ||
| 260 | }; | ||
| 261 | |||
| 262 | static struct platform_device nuc900_device_wdt = { | ||
| 263 | .name = "nuc900-wdt", | ||
| 264 | .id = -1, | ||
| 265 | .num_resources = ARRAY_SIZE(nuc900_wdt_resource), | ||
| 266 | .resource = nuc900_wdt_resource, | ||
| 267 | }; | ||
| 268 | |||
| 269 | /* | ||
| 270 | * public device definition between 910 and 920, or 910 | ||
| 271 | * and 950 or 950 and 960...,their dev platform register | ||
| 272 | * should be in specific file such as nuc950, nuc960 c | ||
| 273 | * files rather than the public dev.c file here. so the | ||
| 274 | * corresponding platform_device definition should not be | ||
| 275 | * static. | ||
| 276 | */ | ||
| 277 | |||
| 278 | /* RTC controller*/ | ||
| 279 | |||
| 280 | static struct resource nuc900_rtc_resource[] = { | ||
| 281 | [0] = { | ||
| 282 | .start = W90X900_PA_RTC, | ||
| 283 | .end = W90X900_PA_RTC + 0xff, | ||
| 284 | .flags = IORESOURCE_MEM, | ||
| 285 | }, | ||
| 286 | [1] = { | ||
| 287 | .start = IRQ_RTC, | ||
| 288 | .end = IRQ_RTC, | ||
| 289 | .flags = IORESOURCE_IRQ, | ||
| 290 | }, | ||
| 291 | }; | ||
| 292 | |||
| 293 | struct platform_device nuc900_device_rtc = { | ||
| 294 | .name = "nuc900-rtc", | ||
| 295 | .id = -1, | ||
| 296 | .num_resources = ARRAY_SIZE(nuc900_rtc_resource), | ||
| 297 | .resource = nuc900_rtc_resource, | ||
| 298 | }; | ||
| 299 | |||
| 300 | /*TouchScreen controller*/ | ||
| 301 | |||
| 302 | static struct resource nuc900_ts_resource[] = { | ||
| 303 | [0] = { | ||
| 304 | .start = W90X900_PA_ADC, | ||
| 305 | .end = W90X900_PA_ADC + W90X900_SZ_ADC-1, | ||
| 306 | .flags = IORESOURCE_MEM, | ||
| 307 | }, | ||
| 308 | [1] = { | ||
| 309 | .start = IRQ_ADC, | ||
| 310 | .end = IRQ_ADC, | ||
| 311 | .flags = IORESOURCE_IRQ, | ||
| 312 | }, | ||
| 313 | }; | ||
| 314 | |||
| 315 | struct platform_device nuc900_device_ts = { | ||
| 316 | .name = "nuc900-ts", | ||
| 317 | .id = -1, | ||
| 318 | .resource = nuc900_ts_resource, | ||
| 319 | .num_resources = ARRAY_SIZE(nuc900_ts_resource), | ||
| 320 | }; | ||
| 321 | |||
| 322 | /* FMI Device */ | ||
| 323 | |||
| 324 | static struct resource nuc900_fmi_resource[] = { | ||
| 325 | [0] = { | ||
| 326 | .start = W90X900_PA_FMI, | ||
| 327 | .end = W90X900_PA_FMI + W90X900_SZ_FMI - 1, | ||
| 328 | .flags = IORESOURCE_MEM, | ||
| 329 | }, | ||
| 330 | [1] = { | ||
| 331 | .start = IRQ_FMI, | ||
| 332 | .end = IRQ_FMI, | ||
| 333 | .flags = IORESOURCE_IRQ, | ||
| 334 | } | ||
| 335 | }; | ||
| 336 | |||
| 337 | struct platform_device nuc900_device_fmi = { | ||
| 338 | .name = "nuc900-fmi", | ||
| 339 | .id = -1, | ||
| 340 | .num_resources = ARRAY_SIZE(nuc900_fmi_resource), | ||
| 341 | .resource = nuc900_fmi_resource, | ||
| 342 | }; | ||
| 343 | |||
| 344 | /* KPI controller*/ | ||
| 345 | |||
| 346 | static struct resource nuc900_kpi_resource[] = { | ||
| 347 | [0] = { | ||
| 348 | .start = W90X900_PA_KPI, | ||
| 349 | .end = W90X900_PA_KPI + W90X900_SZ_KPI - 1, | ||
| 350 | .flags = IORESOURCE_MEM, | ||
| 351 | }, | ||
| 352 | [1] = { | ||
| 353 | .start = IRQ_KPI, | ||
| 354 | .end = IRQ_KPI, | ||
| 355 | .flags = IORESOURCE_IRQ, | ||
| 356 | } | ||
| 357 | |||
| 358 | }; | ||
| 359 | |||
| 360 | struct platform_device nuc900_device_kpi = { | ||
| 361 | .name = "nuc900-kpi", | ||
| 362 | .id = -1, | ||
| 363 | .num_resources = ARRAY_SIZE(nuc900_kpi_resource), | ||
| 364 | .resource = nuc900_kpi_resource, | ||
| 365 | }; | ||
| 366 | |||
| 367 | /*Here should be your evb resourse,such as LCD*/ | ||
| 368 | |||
| 369 | static struct platform_device *nuc900_public_dev[] __initdata = { | ||
| 370 | &nuc900_serial_device, | ||
| 371 | &nuc900_flash_device, | ||
| 372 | &nuc900_device_usb_ehci, | ||
| 373 | &nuc900_device_usb_ohci, | ||
| 374 | &nuc900_device_usbgadget, | ||
| 375 | &nuc900_device_emc, | ||
| 376 | &nuc900_device_spi, | ||
| 377 | &nuc900_device_wdt, | ||
| 378 | }; | ||
| 379 | |||
| 380 | /* Provide adding specific CPU platform devices API */ | ||
| 381 | |||
| 382 | void __init nuc900_board_init(struct platform_device **device, int size) | ||
| 383 | { | ||
| 384 | platform_add_devices(device, size); | ||
| 385 | platform_add_devices(nuc900_public_dev, ARRAY_SIZE(nuc900_public_dev)); | ||
| 386 | spi_register_board_info(nuc900_spi_board_info, | ||
| 387 | ARRAY_SIZE(nuc900_spi_board_info)); | ||
| 388 | } | ||
| 389 | |||
diff --git a/arch/arm/mach-w90x900/gpio.c b/arch/arm/mach-w90x900/gpio.c index c72e0dfa1825..ba05aec7ea4b 100644 --- a/arch/arm/mach-w90x900/gpio.c +++ b/arch/arm/mach-w90x900/gpio.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/arch/arm/mach-w90p910/gpio.c | 2 | * linux/arch/arm/mach-w90x900/gpio.c |
| 3 | * | 3 | * |
| 4 | * Generic w90p910 GPIO handling | 4 | * Generic nuc900 GPIO handling |
| 5 | * | 5 | * |
| 6 | * Wan ZongShun <mcuos.com@gmail.com> | 6 | * Wan ZongShun <mcuos.com@gmail.com> |
| 7 | * | 7 | * |
| @@ -30,31 +30,31 @@ | |||
| 30 | #define GPIO_IN (0x0C) | 30 | #define GPIO_IN (0x0C) |
| 31 | #define GROUPINERV (0x10) | 31 | #define GROUPINERV (0x10) |
| 32 | #define GPIO_GPIO(Nb) (0x00000001 << (Nb)) | 32 | #define GPIO_GPIO(Nb) (0x00000001 << (Nb)) |
| 33 | #define to_w90p910_gpio_chip(c) container_of(c, struct w90p910_gpio_chip, chip) | 33 | #define to_nuc900_gpio_chip(c) container_of(c, struct nuc900_gpio_chip, chip) |
| 34 | 34 | ||
| 35 | #define W90P910_GPIO_CHIP(name, base_gpio, nr_gpio) \ | 35 | #define NUC900_GPIO_CHIP(name, base_gpio, nr_gpio) \ |
| 36 | { \ | 36 | { \ |
| 37 | .chip = { \ | 37 | .chip = { \ |
| 38 | .label = name, \ | 38 | .label = name, \ |
| 39 | .direction_input = w90p910_dir_input, \ | 39 | .direction_input = nuc900_dir_input, \ |
| 40 | .direction_output = w90p910_dir_output, \ | 40 | .direction_output = nuc900_dir_output, \ |
| 41 | .get = w90p910_gpio_get, \ | 41 | .get = nuc900_gpio_get, \ |
| 42 | .set = w90p910_gpio_set, \ | 42 | .set = nuc900_gpio_set, \ |
| 43 | .base = base_gpio, \ | 43 | .base = base_gpio, \ |
| 44 | .ngpio = nr_gpio, \ | 44 | .ngpio = nr_gpio, \ |
| 45 | } \ | 45 | } \ |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | struct w90p910_gpio_chip { | 48 | struct nuc900_gpio_chip { |
| 49 | struct gpio_chip chip; | 49 | struct gpio_chip chip; |
| 50 | void __iomem *regbase; /* Base of group register*/ | 50 | void __iomem *regbase; /* Base of group register*/ |
| 51 | spinlock_t gpio_lock; | 51 | spinlock_t gpio_lock; |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | static int w90p910_gpio_get(struct gpio_chip *chip, unsigned offset) | 54 | static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset) |
| 55 | { | 55 | { |
| 56 | struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip); | 56 | struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip); |
| 57 | void __iomem *pio = w90p910_gpio->regbase + GPIO_IN; | 57 | void __iomem *pio = nuc900_gpio->regbase + GPIO_IN; |
| 58 | unsigned int regval; | 58 | unsigned int regval; |
| 59 | 59 | ||
| 60 | regval = __raw_readl(pio); | 60 | regval = __raw_readl(pio); |
| @@ -63,14 +63,14 @@ static int w90p910_gpio_get(struct gpio_chip *chip, unsigned offset) | |||
| 63 | return (regval != 0); | 63 | return (regval != 0); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | static void w90p910_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | 66 | static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val) |
| 67 | { | 67 | { |
| 68 | struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip); | 68 | struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip); |
| 69 | void __iomem *pio = w90p910_gpio->regbase + GPIO_OUT; | 69 | void __iomem *pio = nuc900_gpio->regbase + GPIO_OUT; |
| 70 | unsigned int regval; | 70 | unsigned int regval; |
| 71 | unsigned long flags; | 71 | unsigned long flags; |
| 72 | 72 | ||
| 73 | spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags); | 73 | spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags); |
| 74 | 74 | ||
| 75 | regval = __raw_readl(pio); | 75 | regval = __raw_readl(pio); |
| 76 | 76 | ||
| @@ -81,36 +81,36 @@ static void w90p910_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | |||
| 81 | 81 | ||
| 82 | __raw_writel(regval, pio); | 82 | __raw_writel(regval, pio); |
| 83 | 83 | ||
| 84 | spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags); | 84 | spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | static int w90p910_dir_input(struct gpio_chip *chip, unsigned offset) | 87 | static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset) |
| 88 | { | 88 | { |
| 89 | struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip); | 89 | struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip); |
| 90 | void __iomem *pio = w90p910_gpio->regbase + GPIO_DIR; | 90 | void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR; |
| 91 | unsigned int regval; | 91 | unsigned int regval; |
| 92 | unsigned long flags; | 92 | unsigned long flags; |
| 93 | 93 | ||
| 94 | spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags); | 94 | spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags); |
| 95 | 95 | ||
| 96 | regval = __raw_readl(pio); | 96 | regval = __raw_readl(pio); |
| 97 | regval &= ~GPIO_GPIO(offset); | 97 | regval &= ~GPIO_GPIO(offset); |
| 98 | __raw_writel(regval, pio); | 98 | __raw_writel(regval, pio); |
| 99 | 99 | ||
| 100 | spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags); | 100 | spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags); |
| 101 | 101 | ||
| 102 | return 0; | 102 | return 0; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | static int w90p910_dir_output(struct gpio_chip *chip, unsigned offset, int val) | 105 | static int nuc900_dir_output(struct gpio_chip *chip, unsigned offset, int val) |
| 106 | { | 106 | { |
| 107 | struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip); | 107 | struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip); |
| 108 | void __iomem *outreg = w90p910_gpio->regbase + GPIO_OUT; | 108 | void __iomem *outreg = nuc900_gpio->regbase + GPIO_OUT; |
| 109 | void __iomem *pio = w90p910_gpio->regbase + GPIO_DIR; | 109 | void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR; |
| 110 | unsigned int regval; | 110 | unsigned int regval; |
| 111 | unsigned long flags; | 111 | unsigned long flags; |
| 112 | 112 | ||
| 113 | spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags); | 113 | spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags); |
| 114 | 114 | ||
| 115 | regval = __raw_readl(pio); | 115 | regval = __raw_readl(pio); |
| 116 | regval |= GPIO_GPIO(offset); | 116 | regval |= GPIO_GPIO(offset); |
| @@ -125,28 +125,28 @@ static int w90p910_dir_output(struct gpio_chip *chip, unsigned offset, int val) | |||
| 125 | 125 | ||
| 126 | __raw_writel(regval, outreg); | 126 | __raw_writel(regval, outreg); |
| 127 | 127 | ||
| 128 | spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags); | 128 | spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags); |
| 129 | 129 | ||
| 130 | return 0; | 130 | return 0; |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | static struct w90p910_gpio_chip w90p910_gpio[] = { | 133 | static struct nuc900_gpio_chip nuc900_gpio[] = { |
| 134 | W90P910_GPIO_CHIP("GROUPC", 0, 16), | 134 | NUC900_GPIO_CHIP("GROUPC", 0, 16), |
| 135 | W90P910_GPIO_CHIP("GROUPD", 16, 10), | 135 | NUC900_GPIO_CHIP("GROUPD", 16, 10), |
| 136 | W90P910_GPIO_CHIP("GROUPE", 26, 14), | 136 | NUC900_GPIO_CHIP("GROUPE", 26, 14), |
| 137 | W90P910_GPIO_CHIP("GROUPF", 40, 10), | 137 | NUC900_GPIO_CHIP("GROUPF", 40, 10), |
| 138 | W90P910_GPIO_CHIP("GROUPG", 50, 17), | 138 | NUC900_GPIO_CHIP("GROUPG", 50, 17), |
| 139 | W90P910_GPIO_CHIP("GROUPH", 67, 8), | 139 | NUC900_GPIO_CHIP("GROUPH", 67, 8), |
| 140 | W90P910_GPIO_CHIP("GROUPI", 75, 17), | 140 | NUC900_GPIO_CHIP("GROUPI", 75, 17), |
| 141 | }; | 141 | }; |
| 142 | 142 | ||
| 143 | void __init w90p910_init_gpio(int nr_group) | 143 | void __init nuc900_init_gpio(int nr_group) |
| 144 | { | 144 | { |
| 145 | unsigned i; | 145 | unsigned i; |
| 146 | struct w90p910_gpio_chip *gpio_chip; | 146 | struct nuc900_gpio_chip *gpio_chip; |
| 147 | 147 | ||
| 148 | for (i = 0; i < nr_group; i++) { | 148 | for (i = 0; i < nr_group; i++) { |
| 149 | gpio_chip = &w90p910_gpio[i]; | 149 | gpio_chip = &nuc900_gpio[i]; |
| 150 | spin_lock_init(&gpio_chip->gpio_lock); | 150 | spin_lock_init(&gpio_chip->gpio_lock); |
| 151 | gpio_chip->regbase = GPIO_BASE + i * GROUPINERV; | 151 | gpio_chip->regbase = GPIO_BASE + i * GROUPINERV; |
| 152 | gpiochip_add(&gpio_chip->chip); | 152 | gpiochip_add(&gpio_chip->chip); |
diff --git a/arch/arm/mach-w90x900/include/mach/regs-clock.h b/arch/arm/mach-w90x900/include/mach/regs-clock.h index f10b6a8dc069..516d6b477b61 100644 --- a/arch/arm/mach-w90x900/include/mach/regs-clock.h +++ b/arch/arm/mach-w90x900/include/mach/regs-clock.h | |||
| @@ -28,4 +28,26 @@ | |||
| 28 | #define REG_CLKEN1 (CLK_BA + 0x24) | 28 | #define REG_CLKEN1 (CLK_BA + 0x24) |
| 29 | #define REG_CLKDIV1 (CLK_BA + 0x28) | 29 | #define REG_CLKDIV1 (CLK_BA + 0x28) |
| 30 | 30 | ||
| 31 | /* Define PLL freq setting */ | ||
| 32 | #define PLL_DISABLE 0x12B63 | ||
| 33 | #define PLL_66MHZ 0x2B63 | ||
| 34 | #define PLL_100MHZ 0x4F64 | ||
| 35 | #define PLL_120MHZ 0x4F63 | ||
| 36 | #define PLL_166MHZ 0x4124 | ||
| 37 | #define PLL_200MHZ 0x4F24 | ||
| 38 | |||
| 39 | /* Define AHB:CPUFREQ ratio */ | ||
| 40 | #define AHB_CPUCLK_1_1 0x00 | ||
| 41 | #define AHB_CPUCLK_1_2 0x01 | ||
| 42 | #define AHB_CPUCLK_1_4 0x02 | ||
| 43 | #define AHB_CPUCLK_1_8 0x03 | ||
| 44 | |||
| 45 | /* Define APB:AHB ratio */ | ||
| 46 | #define APB_AHB_1_2 0x01 | ||
| 47 | #define APB_AHB_1_4 0x02 | ||
| 48 | #define APB_AHB_1_8 0x03 | ||
| 49 | |||
| 50 | /* Define clock skew */ | ||
| 51 | #define DEFAULTSKEW 0x48 | ||
| 52 | |||
| 31 | #endif /* __ASM_ARCH_REGS_CLOCK_H */ | 53 | #endif /* __ASM_ARCH_REGS_CLOCK_H */ |
diff --git a/arch/arm/mach-w90x900/include/mach/regs-ebi.h b/arch/arm/mach-w90x900/include/mach/regs-ebi.h new file mode 100644 index 000000000000..b68455e7f88b --- /dev/null +++ b/arch/arm/mach-w90x900/include/mach/regs-ebi.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/mach-w90x900/include/mach/regs-ebi.h | ||
| 3 | * | ||
| 4 | * Copyright (c) 2009 Nuvoton technology corporation. | ||
| 5 | * | ||
| 6 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation;version 2 of the License. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | #ifndef __ASM_ARCH_REGS_EBI_H | ||
| 15 | #define __ASM_ARCH_REGS_EBI_H | ||
| 16 | |||
| 17 | /* EBI Control Registers */ | ||
| 18 | |||
| 19 | #define EBI_BA W90X900_VA_EBI | ||
| 20 | #define REG_EBICON (EBI_BA + 0x00) | ||
| 21 | #define REG_ROMCON (EBI_BA + 0x04) | ||
| 22 | #define REG_SDCONF0 (EBI_BA + 0x08) | ||
| 23 | #define REG_SDCONF1 (EBI_BA + 0x0C) | ||
| 24 | #define REG_SDTIME0 (EBI_BA + 0x10) | ||
| 25 | #define REG_SDTIME1 (EBI_BA + 0x14) | ||
| 26 | #define REG_EXT0CON (EBI_BA + 0x18) | ||
| 27 | #define REG_EXT1CON (EBI_BA + 0x1C) | ||
| 28 | #define REG_EXT2CON (EBI_BA + 0x20) | ||
| 29 | #define REG_EXT3CON (EBI_BA + 0x24) | ||
| 30 | #define REG_EXT4CON (EBI_BA + 0x28) | ||
| 31 | #define REG_CKSKEW (EBI_BA + 0x2C) | ||
| 32 | |||
| 33 | #endif /* __ASM_ARCH_REGS_EBI_H */ | ||
diff --git a/arch/arm/mach-w90x900/irq.c b/arch/arm/mach-w90x900/irq.c index 0b4fc194729c..0ce9d8e867eb 100644 --- a/arch/arm/mach-w90x900/irq.c +++ b/arch/arm/mach-w90x900/irq.c | |||
| @@ -10,8 +10,7 @@ | |||
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
| 13 | * the Free Software Foundation; either version 2 of the License, or | 13 | * the Free Software Foundation;version 2 of the License. |
| 14 | * (at your option) any later version. | ||
| 15 | * | 14 | * |
| 16 | */ | 15 | */ |
| 17 | 16 | ||
| @@ -29,9 +28,114 @@ | |||
| 29 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
| 30 | #include <mach/regs-irq.h> | 29 | #include <mach/regs-irq.h> |
| 31 | 30 | ||
| 32 | static void w90x900_irq_mask(unsigned int irq) | 31 | struct group_irq { |
| 32 | unsigned long gpen; | ||
| 33 | unsigned int enabled; | ||
| 34 | void (*enable)(struct group_irq *, int enable); | ||
| 35 | }; | ||
| 36 | |||
| 37 | static DEFINE_SPINLOCK(groupirq_lock); | ||
| 38 | |||
| 39 | #define DEFINE_GROUP(_name, _ctrlbit, _num) \ | ||
| 40 | struct group_irq group_##_name = { \ | ||
| 41 | .enable = nuc900_group_enable, \ | ||
| 42 | .gpen = ((1 << _num) - 1) << _ctrlbit, \ | ||
| 43 | } | ||
| 44 | |||
| 45 | static void nuc900_group_enable(struct group_irq *gpirq, int enable); | ||
| 46 | |||
| 47 | static DEFINE_GROUP(nirq0, 0, 4); | ||
| 48 | static DEFINE_GROUP(nirq1, 4, 4); | ||
| 49 | static DEFINE_GROUP(usbh, 8, 2); | ||
| 50 | static DEFINE_GROUP(ottimer, 16, 3); | ||
| 51 | static DEFINE_GROUP(gdma, 20, 2); | ||
| 52 | static DEFINE_GROUP(sc, 24, 2); | ||
| 53 | static DEFINE_GROUP(i2c, 26, 2); | ||
| 54 | static DEFINE_GROUP(ps2, 28, 2); | ||
| 55 | |||
| 56 | static int group_irq_enable(struct group_irq *group_irq) | ||
| 57 | { | ||
| 58 | unsigned long flags; | ||
| 59 | |||
| 60 | spin_lock_irqsave(&groupirq_lock, flags); | ||
| 61 | if (group_irq->enabled++ == 0) | ||
| 62 | (group_irq->enable)(group_irq, 1); | ||
| 63 | spin_unlock_irqrestore(&groupirq_lock, flags); | ||
| 64 | |||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 68 | static void group_irq_disable(struct group_irq *group_irq) | ||
| 33 | { | 69 | { |
| 70 | unsigned long flags; | ||
| 71 | |||
| 72 | WARN_ON(group_irq->enabled == 0); | ||
| 73 | |||
| 74 | spin_lock_irqsave(&groupirq_lock, flags); | ||
| 75 | if (--group_irq->enabled == 0) | ||
| 76 | (group_irq->enable)(group_irq, 0); | ||
| 77 | spin_unlock_irqrestore(&groupirq_lock, flags); | ||
| 78 | } | ||
| 79 | |||
| 80 | static void nuc900_group_enable(struct group_irq *gpirq, int enable) | ||
| 81 | { | ||
| 82 | unsigned int groupen = gpirq->gpen; | ||
| 83 | unsigned long regval; | ||
| 84 | |||
| 85 | regval = __raw_readl(REG_AIC_GEN); | ||
| 86 | |||
| 87 | if (enable) | ||
| 88 | regval |= groupen; | ||
| 89 | else | ||
| 90 | regval &= ~groupen; | ||
| 91 | |||
| 92 | __raw_writel(regval, REG_AIC_GEN); | ||
| 93 | } | ||
| 94 | |||
| 95 | static void nuc900_irq_mask(unsigned int irq) | ||
| 96 | { | ||
| 97 | struct group_irq *group_irq; | ||
| 98 | |||
| 99 | group_irq = NULL; | ||
| 100 | |||
| 34 | __raw_writel(1 << irq, REG_AIC_MDCR); | 101 | __raw_writel(1 << irq, REG_AIC_MDCR); |
| 102 | |||
| 103 | switch (irq) { | ||
| 104 | case IRQ_GROUP0: | ||
| 105 | group_irq = &group_nirq0; | ||
| 106 | break; | ||
| 107 | |||
| 108 | case IRQ_GROUP1: | ||
| 109 | group_irq = &group_nirq1; | ||
| 110 | break; | ||
| 111 | |||
| 112 | case IRQ_USBH: | ||
| 113 | group_irq = &group_usbh; | ||
| 114 | break; | ||
| 115 | |||
| 116 | case IRQ_T_INT_GROUP: | ||
| 117 | group_irq = &group_ottimer; | ||
| 118 | break; | ||
| 119 | |||
| 120 | case IRQ_GDMAGROUP: | ||
| 121 | group_irq = &group_gdma; | ||
| 122 | break; | ||
| 123 | |||
| 124 | case IRQ_SCGROUP: | ||
| 125 | group_irq = &group_sc; | ||
| 126 | break; | ||
| 127 | |||
| 128 | case IRQ_I2CGROUP: | ||
| 129 | group_irq = &group_i2c; | ||
| 130 | break; | ||
| 131 | |||
| 132 | case IRQ_P2SGROUP: | ||
| 133 | group_irq = &group_ps2; | ||
| 134 | break; | ||
| 135 | } | ||
| 136 | |||
| 137 | if (group_irq) | ||
| 138 | group_irq_disable(group_irq); | ||
| 35 | } | 139 | } |
| 36 | 140 | ||
| 37 | /* | 141 | /* |
| @@ -39,37 +143,71 @@ static void w90x900_irq_mask(unsigned int irq) | |||
| 39 | * to REG_AIC_EOSCR for ACK | 143 | * to REG_AIC_EOSCR for ACK |
| 40 | */ | 144 | */ |
| 41 | 145 | ||
| 42 | static void w90x900_irq_ack(unsigned int irq) | 146 | static void nuc900_irq_ack(unsigned int irq) |
| 43 | { | 147 | { |
| 44 | __raw_writel(0x01, REG_AIC_EOSCR); | 148 | __raw_writel(0x01, REG_AIC_EOSCR); |
| 45 | } | 149 | } |
| 46 | 150 | ||
| 47 | static void w90x900_irq_unmask(unsigned int irq) | 151 | static void nuc900_irq_unmask(unsigned int irq) |
| 48 | { | 152 | { |
| 49 | unsigned long mask; | 153 | struct group_irq *group_irq; |
| 154 | |||
| 155 | group_irq = NULL; | ||
| 50 | 156 | ||
| 51 | if (irq == IRQ_T_INT_GROUP) { | ||
| 52 | mask = __raw_readl(REG_AIC_GEN); | ||
| 53 | __raw_writel(TIME_GROUP_IRQ | mask, REG_AIC_GEN); | ||
| 54 | __raw_writel(1 << IRQ_T_INT_GROUP, REG_AIC_MECR); | ||
| 55 | } | ||
| 56 | __raw_writel(1 << irq, REG_AIC_MECR); | 157 | __raw_writel(1 << irq, REG_AIC_MECR); |
| 158 | |||
| 159 | switch (irq) { | ||
| 160 | case IRQ_GROUP0: | ||
| 161 | group_irq = &group_nirq0; | ||
| 162 | break; | ||
| 163 | |||
| 164 | case IRQ_GROUP1: | ||
| 165 | group_irq = &group_nirq1; | ||
| 166 | break; | ||
| 167 | |||
| 168 | case IRQ_USBH: | ||
| 169 | group_irq = &group_usbh; | ||
| 170 | break; | ||
| 171 | |||
| 172 | case IRQ_T_INT_GROUP: | ||
| 173 | group_irq = &group_ottimer; | ||
| 174 | break; | ||
| 175 | |||
| 176 | case IRQ_GDMAGROUP: | ||
| 177 | group_irq = &group_gdma; | ||
| 178 | break; | ||
| 179 | |||
| 180 | case IRQ_SCGROUP: | ||
| 181 | group_irq = &group_sc; | ||
| 182 | break; | ||
| 183 | |||
| 184 | case IRQ_I2CGROUP: | ||
| 185 | group_irq = &group_i2c; | ||
| 186 | break; | ||
| 187 | |||
| 188 | case IRQ_P2SGROUP: | ||
| 189 | group_irq = &group_ps2; | ||
| 190 | break; | ||
| 191 | } | ||
| 192 | |||
| 193 | if (group_irq) | ||
| 194 | group_irq_enable(group_irq); | ||
| 57 | } | 195 | } |
| 58 | 196 | ||
| 59 | static struct irq_chip w90x900_irq_chip = { | 197 | static struct irq_chip nuc900_irq_chip = { |
| 60 | .ack = w90x900_irq_ack, | 198 | .ack = nuc900_irq_ack, |
| 61 | .mask = w90x900_irq_mask, | 199 | .mask = nuc900_irq_mask, |
| 62 | .unmask = w90x900_irq_unmask, | 200 | .unmask = nuc900_irq_unmask, |
| 63 | }; | 201 | }; |
| 64 | 202 | ||
| 65 | void __init w90x900_init_irq(void) | 203 | void __init nuc900_init_irq(void) |
| 66 | { | 204 | { |
| 67 | int irqno; | 205 | int irqno; |
| 68 | 206 | ||
| 69 | __raw_writel(0xFFFFFFFE, REG_AIC_MDCR); | 207 | __raw_writel(0xFFFFFFFE, REG_AIC_MDCR); |
| 70 | 208 | ||
| 71 | for (irqno = IRQ_WDT; irqno <= IRQ_ADC; irqno++) { | 209 | for (irqno = IRQ_WDT; irqno <= IRQ_ADC; irqno++) { |
| 72 | set_irq_chip(irqno, &w90x900_irq_chip); | 210 | set_irq_chip(irqno, &nuc900_irq_chip); |
| 73 | set_irq_handler(irqno, handle_level_irq); | 211 | set_irq_handler(irqno, handle_level_irq); |
| 74 | set_irq_flags(irqno, IRQF_VALID); | 212 | set_irq_flags(irqno, IRQF_VALID); |
| 75 | } | 213 | } |
diff --git a/arch/arm/mach-w90x900/mach-nuc910evb.c b/arch/arm/mach-w90x900/mach-nuc910evb.c new file mode 100644 index 000000000000..ec05bda946f3 --- /dev/null +++ b/arch/arm/mach-w90x900/mach-nuc910evb.c | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-w90x900/mach-nuc910evb.c | ||
| 3 | * | ||
| 4 | * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche | ||
| 5 | * | ||
| 6 | * Copyright (C) 2008 Nuvoton technology corporation. | ||
| 7 | * | ||
| 8 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation;version 2 of the License. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <asm/mach/arch.h> | ||
| 18 | #include <asm/mach/map.h> | ||
| 19 | #include <asm/mach-types.h> | ||
| 20 | #include <mach/map.h> | ||
| 21 | |||
| 22 | #include "nuc910.h" | ||
| 23 | |||
| 24 | static void __init nuc910evb_map_io(void) | ||
| 25 | { | ||
| 26 | nuc910_map_io(); | ||
| 27 | nuc910_init_clocks(); | ||
| 28 | } | ||
| 29 | |||
| 30 | static void __init nuc910evb_init(void) | ||
| 31 | { | ||
| 32 | nuc910_board_init(); | ||
| 33 | } | ||
| 34 | |||
| 35 | MACHINE_START(W90P910EVB, "W90P910EVB") | ||
| 36 | /* Maintainer: Wan ZongShun */ | ||
| 37 | .phys_io = W90X900_PA_UART, | ||
| 38 | .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc, | ||
| 39 | .boot_params = 0, | ||
| 40 | .map_io = nuc910evb_map_io, | ||
| 41 | .init_irq = nuc900_init_irq, | ||
| 42 | .init_machine = nuc910evb_init, | ||
| 43 | .timer = &nuc900_timer, | ||
| 44 | MACHINE_END | ||
diff --git a/arch/arm/mach-w90x900/mach-nuc950evb.c b/arch/arm/mach-w90x900/mach-nuc950evb.c new file mode 100644 index 000000000000..cef903bcccd1 --- /dev/null +++ b/arch/arm/mach-w90x900/mach-nuc950evb.c | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-w90x900/mach-nuc950evb.c | ||
| 3 | * | ||
| 4 | * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche | ||
| 5 | * | ||
| 6 | * Copyright (C) 2008 Nuvoton technology corporation. | ||
| 7 | * | ||
| 8 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation;version 2 of the License. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <asm/mach/arch.h> | ||
| 18 | #include <asm/mach/map.h> | ||
| 19 | #include <asm/mach-types.h> | ||
| 20 | #include <mach/map.h> | ||
| 21 | |||
| 22 | #include "nuc950.h" | ||
| 23 | |||
| 24 | static void __init nuc950evb_map_io(void) | ||
| 25 | { | ||
| 26 | nuc950_map_io(); | ||
| 27 | nuc950_init_clocks(); | ||
| 28 | } | ||
| 29 | |||
| 30 | static void __init nuc950evb_init(void) | ||
| 31 | { | ||
| 32 | nuc950_board_init(); | ||
| 33 | } | ||
| 34 | |||
| 35 | MACHINE_START(W90P950EVB, "W90P950EVB") | ||
| 36 | /* Maintainer: Wan ZongShun */ | ||
| 37 | .phys_io = W90X900_PA_UART, | ||
| 38 | .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc, | ||
| 39 | .boot_params = 0, | ||
| 40 | .map_io = nuc950evb_map_io, | ||
| 41 | .init_irq = nuc900_init_irq, | ||
| 42 | .init_machine = nuc950evb_init, | ||
| 43 | .timer = &nuc900_timer, | ||
| 44 | MACHINE_END | ||
diff --git a/arch/arm/mach-w90x900/mach-nuc960evb.c b/arch/arm/mach-w90x900/mach-nuc960evb.c new file mode 100644 index 000000000000..e3a46f19f2bc --- /dev/null +++ b/arch/arm/mach-w90x900/mach-nuc960evb.c | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-w90x900/mach-nuc960evb.c | ||
| 3 | * | ||
| 4 | * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche | ||
| 5 | * | ||
| 6 | * Copyright (C) 2008 Nuvoton technology corporation. | ||
| 7 | * | ||
| 8 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation;version 2 of the License. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <asm/mach/arch.h> | ||
| 18 | #include <asm/mach/map.h> | ||
| 19 | #include <asm/mach-types.h> | ||
| 20 | #include <mach/map.h> | ||
| 21 | |||
| 22 | #include "nuc960.h" | ||
| 23 | |||
| 24 | static void __init nuc960evb_map_io(void) | ||
| 25 | { | ||
| 26 | nuc960_map_io(); | ||
| 27 | nuc960_init_clocks(); | ||
| 28 | } | ||
| 29 | |||
| 30 | static void __init nuc960evb_init(void) | ||
| 31 | { | ||
| 32 | nuc960_board_init(); | ||
| 33 | } | ||
| 34 | |||
| 35 | MACHINE_START(W90N960EVB, "W90N960EVB") | ||
| 36 | /* Maintainer: Wan ZongShun */ | ||
| 37 | .phys_io = W90X900_PA_UART, | ||
| 38 | .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc, | ||
| 39 | .boot_params = 0, | ||
| 40 | .map_io = nuc960evb_map_io, | ||
| 41 | .init_irq = nuc900_init_irq, | ||
| 42 | .init_machine = nuc960evb_init, | ||
| 43 | .timer = &nuc900_timer, | ||
| 44 | MACHINE_END | ||
diff --git a/arch/arm/mach-w90x900/mach-w90p910evb.c b/arch/arm/mach-w90x900/mach-w90p910evb.c deleted file mode 100644 index 7a62bd348e80..000000000000 --- a/arch/arm/mach-w90x900/mach-w90p910evb.c +++ /dev/null | |||
| @@ -1,267 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-w90x900/mach-w90p910evb.c | ||
| 3 | * | ||
| 4 | * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche | ||
| 5 | * | ||
| 6 | * Copyright (C) 2008 Nuvoton technology corporation. | ||
| 7 | * | ||
| 8 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation;version 2 of the License. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/types.h> | ||
| 18 | #include <linux/interrupt.h> | ||
| 19 | #include <linux/list.h> | ||
| 20 | #include <linux/timer.h> | ||
| 21 | #include <linux/init.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/mtd/physmap.h> | ||
| 24 | |||
| 25 | #include <asm/mach/arch.h> | ||
| 26 | #include <asm/mach/map.h> | ||
| 27 | #include <asm/mach/irq.h> | ||
| 28 | #include <asm/mach-types.h> | ||
| 29 | |||
| 30 | #include <mach/regs-serial.h> | ||
| 31 | #include <mach/map.h> | ||
| 32 | |||
| 33 | #include "cpu.h" | ||
| 34 | /*w90p910 evb norflash driver data */ | ||
| 35 | |||
| 36 | #define W90P910_FLASH_BASE 0xA0000000 | ||
| 37 | #define W90P910_FLASH_SIZE 0x400000 | ||
| 38 | |||
| 39 | static struct mtd_partition w90p910_flash_partitions[] = { | ||
| 40 | { | ||
| 41 | .name = "NOR Partition 1 for kernel (960K)", | ||
| 42 | .size = 0xF0000, | ||
| 43 | .offset = 0x10000, | ||
| 44 | }, | ||
| 45 | { | ||
| 46 | .name = "NOR Partition 2 for image (1M)", | ||
| 47 | .size = 0x100000, | ||
| 48 | .offset = 0x100000, | ||
| 49 | }, | ||
| 50 | { | ||
| 51 | .name = "NOR Partition 3 for user (2M)", | ||
| 52 | .size = 0x200000, | ||
| 53 | .offset = 0x00200000, | ||
| 54 | } | ||
| 55 | }; | ||
| 56 | |||
| 57 | static struct physmap_flash_data w90p910_flash_data = { | ||
| 58 | .width = 2, | ||
| 59 | .parts = w90p910_flash_partitions, | ||
| 60 | .nr_parts = ARRAY_SIZE(w90p910_flash_partitions), | ||
| 61 | }; | ||
| 62 | |||
| 63 | static struct resource w90p910_flash_resources[] = { | ||
| 64 | { | ||
| 65 | .start = W90P910_FLASH_BASE, | ||
| 66 | .end = W90P910_FLASH_BASE + W90P910_FLASH_SIZE - 1, | ||
| 67 | .flags = IORESOURCE_MEM, | ||
| 68 | } | ||
| 69 | }; | ||
| 70 | |||
| 71 | static struct platform_device w90p910_flash_device = { | ||
| 72 | .name = "physmap-flash", | ||
| 73 | .id = 0, | ||
| 74 | .dev = { | ||
| 75 | .platform_data = &w90p910_flash_data, | ||
| 76 | }, | ||
| 77 | .resource = w90p910_flash_resources, | ||
| 78 | .num_resources = ARRAY_SIZE(w90p910_flash_resources), | ||
| 79 | }; | ||
| 80 | |||
| 81 | /* USB EHCI Host Controller */ | ||
| 82 | |||
| 83 | static struct resource w90x900_usb_ehci_resource[] = { | ||
| 84 | [0] = { | ||
| 85 | .start = W90X900_PA_USBEHCIHOST, | ||
| 86 | .end = W90X900_PA_USBEHCIHOST + W90X900_SZ_USBEHCIHOST - 1, | ||
| 87 | .flags = IORESOURCE_MEM, | ||
| 88 | }, | ||
| 89 | [1] = { | ||
| 90 | .start = IRQ_USBH, | ||
| 91 | .end = IRQ_USBH, | ||
| 92 | .flags = IORESOURCE_IRQ, | ||
| 93 | } | ||
| 94 | }; | ||
| 95 | |||
| 96 | static u64 w90x900_device_usb_ehci_dmamask = 0xffffffffUL; | ||
| 97 | |||
| 98 | struct platform_device w90x900_device_usb_ehci = { | ||
| 99 | .name = "w90x900-ehci", | ||
| 100 | .id = -1, | ||
| 101 | .num_resources = ARRAY_SIZE(w90x900_usb_ehci_resource), | ||
| 102 | .resource = w90x900_usb_ehci_resource, | ||
| 103 | .dev = { | ||
| 104 | .dma_mask = &w90x900_device_usb_ehci_dmamask, | ||
| 105 | .coherent_dma_mask = 0xffffffffUL | ||
| 106 | } | ||
| 107 | }; | ||
| 108 | EXPORT_SYMBOL(w90x900_device_usb_ehci); | ||
| 109 | |||
| 110 | /* USB OHCI Host Controller */ | ||
| 111 | |||
| 112 | static struct resource w90x900_usb_ohci_resource[] = { | ||
| 113 | [0] = { | ||
| 114 | .start = W90X900_PA_USBOHCIHOST, | ||
| 115 | .end = W90X900_PA_USBOHCIHOST + W90X900_SZ_USBOHCIHOST - 1, | ||
| 116 | .flags = IORESOURCE_MEM, | ||
| 117 | }, | ||
| 118 | [1] = { | ||
| 119 | .start = IRQ_USBH, | ||
| 120 | .end = IRQ_USBH, | ||
| 121 | .flags = IORESOURCE_IRQ, | ||
| 122 | } | ||
| 123 | }; | ||
| 124 | |||
| 125 | static u64 w90x900_device_usb_ohci_dmamask = 0xffffffffUL; | ||
| 126 | struct platform_device w90x900_device_usb_ohci = { | ||
| 127 | .name = "w90x900-ohci", | ||
| 128 | .id = -1, | ||
| 129 | .num_resources = ARRAY_SIZE(w90x900_usb_ohci_resource), | ||
| 130 | .resource = w90x900_usb_ohci_resource, | ||
| 131 | .dev = { | ||
| 132 | .dma_mask = &w90x900_device_usb_ohci_dmamask, | ||
| 133 | .coherent_dma_mask = 0xffffffffUL | ||
| 134 | } | ||
| 135 | }; | ||
| 136 | EXPORT_SYMBOL(w90x900_device_usb_ohci); | ||
| 137 | |||
| 138 | /*TouchScreen controller*/ | ||
| 139 | |||
| 140 | static struct resource w90x900_ts_resource[] = { | ||
| 141 | [0] = { | ||
| 142 | .start = W90X900_PA_ADC, | ||
| 143 | .end = W90X900_PA_ADC + W90X900_SZ_ADC-1, | ||
| 144 | .flags = IORESOURCE_MEM, | ||
| 145 | }, | ||
| 146 | [1] = { | ||
| 147 | .start = IRQ_ADC, | ||
| 148 | .end = IRQ_ADC, | ||
| 149 | .flags = IORESOURCE_IRQ, | ||
| 150 | }, | ||
| 151 | }; | ||
| 152 | |||
| 153 | struct platform_device w90x900_device_ts = { | ||
| 154 | .name = "w90x900-ts", | ||
| 155 | .id = -1, | ||
| 156 | .resource = w90x900_ts_resource, | ||
| 157 | .num_resources = ARRAY_SIZE(w90x900_ts_resource), | ||
| 158 | }; | ||
| 159 | EXPORT_SYMBOL(w90x900_device_ts); | ||
| 160 | |||
| 161 | /* RTC controller*/ | ||
| 162 | |||
| 163 | static struct resource w90x900_rtc_resource[] = { | ||
| 164 | [0] = { | ||
| 165 | .start = W90X900_PA_RTC, | ||
| 166 | .end = W90X900_PA_RTC + 0xff, | ||
| 167 | .flags = IORESOURCE_MEM, | ||
| 168 | }, | ||
| 169 | [1] = { | ||
| 170 | .start = IRQ_RTC, | ||
| 171 | .end = IRQ_RTC, | ||
| 172 | .flags = IORESOURCE_IRQ, | ||
| 173 | }, | ||
| 174 | }; | ||
| 175 | |||
| 176 | struct platform_device w90x900_device_rtc = { | ||
| 177 | .name = "w90x900-rtc", | ||
| 178 | .id = -1, | ||
| 179 | .num_resources = ARRAY_SIZE(w90x900_rtc_resource), | ||
| 180 | .resource = w90x900_rtc_resource, | ||
| 181 | }; | ||
| 182 | EXPORT_SYMBOL(w90x900_device_rtc); | ||
| 183 | |||
| 184 | /* KPI controller*/ | ||
| 185 | |||
| 186 | static struct resource w90x900_kpi_resource[] = { | ||
| 187 | [0] = { | ||
| 188 | .start = W90X900_PA_KPI, | ||
| 189 | .end = W90X900_PA_KPI + W90X900_SZ_KPI - 1, | ||
| 190 | .flags = IORESOURCE_MEM, | ||
| 191 | }, | ||
| 192 | [1] = { | ||
| 193 | .start = IRQ_KPI, | ||
| 194 | .end = IRQ_KPI, | ||
| 195 | .flags = IORESOURCE_IRQ, | ||
| 196 | } | ||
| 197 | |||
| 198 | }; | ||
| 199 | |||
| 200 | struct platform_device w90x900_device_kpi = { | ||
| 201 | .name = "w90x900-kpi", | ||
| 202 | .id = -1, | ||
| 203 | .num_resources = ARRAY_SIZE(w90x900_kpi_resource), | ||
| 204 | .resource = w90x900_kpi_resource, | ||
| 205 | }; | ||
| 206 | EXPORT_SYMBOL(w90x900_device_kpi); | ||
| 207 | |||
| 208 | /* USB Device (Gadget)*/ | ||
| 209 | |||
| 210 | static struct resource w90x900_usbgadget_resource[] = { | ||
| 211 | [0] = { | ||
| 212 | .start = W90X900_PA_USBDEV, | ||
| 213 | .end = W90X900_PA_USBDEV + W90X900_SZ_USBDEV - 1, | ||
| 214 | .flags = IORESOURCE_MEM, | ||
| 215 | }, | ||
| 216 | [1] = { | ||
| 217 | .start = IRQ_USBD, | ||
| 218 | .end = IRQ_USBD, | ||
| 219 | .flags = IORESOURCE_IRQ, | ||
| 220 | } | ||
| 221 | }; | ||
| 222 | |||
| 223 | struct platform_device w90x900_device_usbgadget = { | ||
| 224 | .name = "w90x900-usbgadget", | ||
| 225 | .id = -1, | ||
| 226 | .num_resources = ARRAY_SIZE(w90x900_usbgadget_resource), | ||
| 227 | .resource = w90x900_usbgadget_resource, | ||
| 228 | }; | ||
| 229 | EXPORT_SYMBOL(w90x900_device_usbgadget); | ||
| 230 | |||
| 231 | static struct map_desc w90p910_iodesc[] __initdata = { | ||
| 232 | }; | ||
| 233 | |||
| 234 | /*Here should be your evb resourse,such as LCD*/ | ||
| 235 | |||
| 236 | static struct platform_device *w90p910evb_dev[] __initdata = { | ||
| 237 | &w90p910_serial_device, | ||
| 238 | &w90p910_flash_device, | ||
| 239 | &w90x900_device_usb_ehci, | ||
| 240 | &w90x900_device_usb_ohci, | ||
| 241 | &w90x900_device_ts, | ||
| 242 | &w90x900_device_rtc, | ||
| 243 | &w90x900_device_kpi, | ||
| 244 | &w90x900_device_usbgadget, | ||
| 245 | }; | ||
| 246 | |||
| 247 | static void __init w90p910evb_map_io(void) | ||
| 248 | { | ||
| 249 | w90p910_map_io(w90p910_iodesc, ARRAY_SIZE(w90p910_iodesc)); | ||
| 250 | w90p910_init_clocks(); | ||
| 251 | } | ||
| 252 | |||
| 253 | static void __init w90p910evb_init(void) | ||
| 254 | { | ||
| 255 | platform_add_devices(w90p910evb_dev, ARRAY_SIZE(w90p910evb_dev)); | ||
| 256 | } | ||
| 257 | |||
| 258 | MACHINE_START(W90P910EVB, "W90P910EVB") | ||
| 259 | /* Maintainer: Wan ZongShun */ | ||
| 260 | .phys_io = W90X900_PA_UART, | ||
| 261 | .io_pg_offst = (((u32)W90X900_VA_UART) >> 18) & 0xfffc, | ||
| 262 | .boot_params = 0, | ||
| 263 | .map_io = w90p910evb_map_io, | ||
| 264 | .init_irq = w90x900_init_irq, | ||
| 265 | .init_machine = w90p910evb_init, | ||
| 266 | .timer = &w90x900_timer, | ||
| 267 | MACHINE_END | ||
diff --git a/arch/arm/mach-w90x900/mfp-w90p910.c b/arch/arm/mach-w90x900/mfp-w90p910.c deleted file mode 100644 index a3520fefb5e7..000000000000 --- a/arch/arm/mach-w90x900/mfp-w90p910.c +++ /dev/null | |||
| @@ -1,116 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-w90x900/mfp-w90p910.c | ||
| 3 | * | ||
| 4 | * Copyright (c) 2008 Nuvoton technology corporation | ||
| 5 | * | ||
| 6 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation;version 2 of the License. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/list.h> | ||
| 17 | #include <linux/errno.h> | ||
| 18 | #include <linux/err.h> | ||
| 19 | #include <linux/string.h> | ||
| 20 | #include <linux/clk.h> | ||
| 21 | #include <linux/mutex.h> | ||
| 22 | #include <linux/io.h> | ||
| 23 | |||
| 24 | #include <mach/hardware.h> | ||
| 25 | |||
| 26 | #define REG_MFSEL (W90X900_VA_GCR + 0xC) | ||
| 27 | |||
| 28 | #define GPSELF (0x01 << 1) | ||
| 29 | |||
| 30 | #define GPSELC (0x03 << 2) | ||
| 31 | #define ENKPI (0x02 << 2) | ||
| 32 | #define ENNAND (0x01 << 2) | ||
| 33 | |||
| 34 | #define GPSELEI0 (0x01 << 26) | ||
| 35 | #define GPSELEI1 (0x01 << 27) | ||
| 36 | |||
| 37 | static DECLARE_MUTEX(mfp_sem); | ||
| 38 | |||
| 39 | void mfp_set_groupf(struct device *dev) | ||
| 40 | { | ||
| 41 | unsigned long mfpen; | ||
| 42 | const char *dev_id; | ||
| 43 | |||
| 44 | BUG_ON(!dev); | ||
| 45 | |||
| 46 | down(&mfp_sem); | ||
| 47 | |||
| 48 | dev_id = dev_name(dev); | ||
| 49 | |||
| 50 | mfpen = __raw_readl(REG_MFSEL); | ||
| 51 | |||
| 52 | if (strcmp(dev_id, "w90p910-emc") == 0) | ||
| 53 | mfpen |= GPSELF;/*enable mac*/ | ||
| 54 | else | ||
| 55 | mfpen &= ~GPSELF;/*GPIOF[9:0]*/ | ||
| 56 | |||
| 57 | __raw_writel(mfpen, REG_MFSEL); | ||
| 58 | |||
| 59 | up(&mfp_sem); | ||
| 60 | } | ||
| 61 | EXPORT_SYMBOL(mfp_set_groupf); | ||
| 62 | |||
| 63 | void mfp_set_groupc(struct device *dev) | ||
| 64 | { | ||
| 65 | unsigned long mfpen; | ||
| 66 | const char *dev_id; | ||
| 67 | |||
| 68 | BUG_ON(!dev); | ||
| 69 | |||
| 70 | down(&mfp_sem); | ||
| 71 | |||
| 72 | dev_id = dev_name(dev); | ||
| 73 | |||
| 74 | mfpen = __raw_readl(REG_MFSEL); | ||
| 75 | |||
| 76 | if (strcmp(dev_id, "w90p910-lcd") == 0) | ||
| 77 | mfpen |= GPSELC;/*enable lcd*/ | ||
| 78 | else if (strcmp(dev_id, "w90p910-kpi") == 0) { | ||
| 79 | mfpen &= (~GPSELC);/*enable kpi*/ | ||
| 80 | mfpen |= ENKPI; | ||
| 81 | } else if (strcmp(dev_id, "w90p910-nand") == 0) { | ||
| 82 | mfpen &= (~GPSELC);/*enable nand*/ | ||
| 83 | mfpen |= ENNAND; | ||
| 84 | } else | ||
| 85 | mfpen &= (~GPSELC);/*GPIOC[14:0]*/ | ||
| 86 | |||
| 87 | __raw_writel(mfpen, REG_MFSEL); | ||
| 88 | |||
| 89 | up(&mfp_sem); | ||
| 90 | } | ||
| 91 | EXPORT_SYMBOL(mfp_set_groupc); | ||
| 92 | |||
| 93 | void mfp_set_groupi(struct device *dev, int gpio) | ||
| 94 | { | ||
| 95 | unsigned long mfpen; | ||
| 96 | const char *dev_id; | ||
| 97 | |||
| 98 | BUG_ON(!dev); | ||
| 99 | |||
| 100 | down(&mfp_sem); | ||
| 101 | |||
| 102 | dev_id = dev_name(dev); | ||
| 103 | |||
| 104 | mfpen = __raw_readl(REG_MFSEL); | ||
| 105 | |||
| 106 | if (strcmp(dev_id, "w90p910-wdog") == 0) | ||
| 107 | mfpen |= GPSELEI1;/*enable wdog*/ | ||
| 108 | else if (strcmp(dev_id, "w90p910-atapi") == 0) | ||
| 109 | mfpen |= GPSELEI0;/*enable atapi*/ | ||
| 110 | |||
| 111 | __raw_writel(mfpen, REG_MFSEL); | ||
| 112 | |||
| 113 | up(&mfp_sem); | ||
| 114 | } | ||
| 115 | EXPORT_SYMBOL(mfp_set_groupi); | ||
| 116 | |||
diff --git a/arch/arm/mach-w90x900/mfp.c b/arch/arm/mach-w90x900/mfp.c new file mode 100644 index 000000000000..a47dc9a708ee --- /dev/null +++ b/arch/arm/mach-w90x900/mfp.c | |||
| @@ -0,0 +1,158 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-w90x900/mfp.c | ||
| 3 | * | ||
| 4 | * Copyright (c) 2008 Nuvoton technology corporation | ||
| 5 | * | ||
| 6 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation;version 2 of the License. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/device.h> | ||
| 16 | #include <linux/list.h> | ||
| 17 | #include <linux/errno.h> | ||
| 18 | #include <linux/err.h> | ||
| 19 | #include <linux/string.h> | ||
| 20 | #include <linux/clk.h> | ||
| 21 | #include <linux/mutex.h> | ||
| 22 | #include <linux/io.h> | ||
| 23 | |||
| 24 | #include <mach/hardware.h> | ||
| 25 | |||
| 26 | #define REG_MFSEL (W90X900_VA_GCR + 0xC) | ||
| 27 | |||
| 28 | #define GPSELF (0x01 << 1) | ||
| 29 | |||
| 30 | #define GPSELC (0x03 << 2) | ||
| 31 | #define ENKPI (0x02 << 2) | ||
| 32 | #define ENNAND (0x01 << 2) | ||
| 33 | |||
| 34 | #define GPSELEI0 (0x01 << 26) | ||
| 35 | #define GPSELEI1 (0x01 << 27) | ||
| 36 | |||
| 37 | #define GPIOG0TO1 (0x03 << 14) | ||
| 38 | #define GPIOG2TO3 (0x03 << 16) | ||
| 39 | #define ENSPI (0x0a << 14) | ||
| 40 | #define ENI2C0 (0x01 << 14) | ||
| 41 | #define ENI2C1 (0x01 << 16) | ||
| 42 | |||
| 43 | static DEFINE_MUTEX(mfp_mutex); | ||
| 44 | |||
| 45 | void mfp_set_groupf(struct device *dev) | ||
| 46 | { | ||
| 47 | unsigned long mfpen; | ||
| 48 | const char *dev_id; | ||
| 49 | |||
| 50 | BUG_ON(!dev); | ||
| 51 | |||
| 52 | mutex_lock(&mfp_mutex); | ||
| 53 | |||
| 54 | dev_id = dev_name(dev); | ||
| 55 | |||
| 56 | mfpen = __raw_readl(REG_MFSEL); | ||
| 57 | |||
| 58 | if (strcmp(dev_id, "nuc900-emc") == 0) | ||
| 59 | mfpen |= GPSELF;/*enable mac*/ | ||
| 60 | else | ||
| 61 | mfpen &= ~GPSELF;/*GPIOF[9:0]*/ | ||
| 62 | |||
| 63 | __raw_writel(mfpen, REG_MFSEL); | ||
| 64 | |||
| 65 | mutex_unlock(&mfp_mutex); | ||
| 66 | } | ||
| 67 | EXPORT_SYMBOL(mfp_set_groupf); | ||
| 68 | |||
| 69 | void mfp_set_groupc(struct device *dev) | ||
| 70 | { | ||
| 71 | unsigned long mfpen; | ||
| 72 | const char *dev_id; | ||
| 73 | |||
| 74 | BUG_ON(!dev); | ||
| 75 | |||
| 76 | mutex_lock(&mfp_mutex); | ||
| 77 | |||
| 78 | dev_id = dev_name(dev); | ||
| 79 | |||
| 80 | mfpen = __raw_readl(REG_MFSEL); | ||
| 81 | |||
| 82 | if (strcmp(dev_id, "nuc900-lcd") == 0) | ||
| 83 | mfpen |= GPSELC;/*enable lcd*/ | ||
| 84 | else if (strcmp(dev_id, "nuc900-kpi") == 0) { | ||
| 85 | mfpen &= (~GPSELC);/*enable kpi*/ | ||
| 86 | mfpen |= ENKPI; | ||
| 87 | } else if (strcmp(dev_id, "nuc900-nand") == 0) { | ||
| 88 | mfpen &= (~GPSELC);/*enable nand*/ | ||
| 89 | mfpen |= ENNAND; | ||
| 90 | } else | ||
| 91 | mfpen &= (~GPSELC);/*GPIOC[14:0]*/ | ||
| 92 | |||
| 93 | __raw_writel(mfpen, REG_MFSEL); | ||
| 94 | |||
| 95 | mutex_unlock(&mfp_mutex); | ||
| 96 | } | ||
| 97 | EXPORT_SYMBOL(mfp_set_groupc); | ||
| 98 | |||
| 99 | void mfp_set_groupi(struct device *dev) | ||
| 100 | { | ||
| 101 | unsigned long mfpen; | ||
| 102 | const char *dev_id; | ||
| 103 | |||
| 104 | BUG_ON(!dev); | ||
| 105 | |||
| 106 | mutex_lock(&mfp_mutex); | ||
| 107 | |||
| 108 | dev_id = dev_name(dev); | ||
| 109 | |||
| 110 | mfpen = __raw_readl(REG_MFSEL); | ||
| 111 | |||
| 112 | mfpen &= ~GPSELEI1;/*default gpio16*/ | ||
| 113 | |||
| 114 | if (strcmp(dev_id, "nuc900-wdog") == 0) | ||
| 115 | mfpen |= GPSELEI1;/*enable wdog*/ | ||
| 116 | else if (strcmp(dev_id, "nuc900-atapi") == 0) | ||
| 117 | mfpen |= GPSELEI0;/*enable atapi*/ | ||
| 118 | else if (strcmp(dev_id, "nuc900-keypad") == 0) | ||
| 119 | mfpen &= ~GPSELEI0;/*enable keypad*/ | ||
| 120 | |||
| 121 | __raw_writel(mfpen, REG_MFSEL); | ||
| 122 | |||
| 123 | mutex_unlock(&mfp_mutex); | ||
| 124 | } | ||
| 125 | EXPORT_SYMBOL(mfp_set_groupi); | ||
| 126 | |||
| 127 | void mfp_set_groupg(struct device *dev) | ||
| 128 | { | ||
| 129 | unsigned long mfpen; | ||
| 130 | const char *dev_id; | ||
| 131 | |||
| 132 | BUG_ON(!dev); | ||
| 133 | |||
| 134 | mutex_lock(&mfp_mutex); | ||
| 135 | |||
| 136 | dev_id = dev_name(dev); | ||
| 137 | |||
| 138 | mfpen = __raw_readl(REG_MFSEL); | ||
| 139 | |||
| 140 | if (strcmp(dev_id, "nuc900-spi") == 0) { | ||
| 141 | mfpen &= ~(GPIOG0TO1 | GPIOG2TO3); | ||
| 142 | mfpen |= ENSPI;/*enable spi*/ | ||
| 143 | } else if (strcmp(dev_id, "nuc900-i2c0") == 0) { | ||
| 144 | mfpen &= ~(GPIOG0TO1); | ||
| 145 | mfpen |= ENI2C0;/*enable i2c0*/ | ||
| 146 | } else if (strcmp(dev_id, "nuc900-i2c1") == 0) { | ||
| 147 | mfpen &= ~(GPIOG2TO3); | ||
| 148 | mfpen |= ENI2C1;/*enable i2c1*/ | ||
| 149 | } else { | ||
| 150 | mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);/*GPIOG[3:0]*/ | ||
| 151 | } | ||
| 152 | |||
| 153 | __raw_writel(mfpen, REG_MFSEL); | ||
| 154 | |||
| 155 | mutex_unlock(&mfp_mutex); | ||
| 156 | } | ||
| 157 | EXPORT_SYMBOL(mfp_set_groupg); | ||
| 158 | |||
diff --git a/arch/arm/mach-w90x900/nuc910.c b/arch/arm/mach-w90x900/nuc910.c new file mode 100644 index 000000000000..656f03b3b629 --- /dev/null +++ b/arch/arm/mach-w90x900/nuc910.c | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-w90x900/nuc910.c | ||
| 3 | * | ||
| 4 | * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks | ||
| 5 | * | ||
| 6 | * Copyright (c) 2009 Nuvoton corporation. | ||
| 7 | * | ||
| 8 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 9 | * | ||
| 10 | * NUC910 cpu support | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify | ||
| 13 | * it under the terms of the GNU General Public License as published by | ||
| 14 | * the Free Software Foundation;version 2 of the License. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/platform_device.h> | ||
| 19 | #include <asm/mach/map.h> | ||
| 20 | #include <mach/hardware.h> | ||
| 21 | #include "cpu.h" | ||
| 22 | #include "clock.h" | ||
| 23 | |||
| 24 | /* define specific CPU platform device */ | ||
| 25 | |||
| 26 | static struct platform_device *nuc910_dev[] __initdata = { | ||
| 27 | &nuc900_device_ts, | ||
| 28 | &nuc900_device_rtc, | ||
| 29 | }; | ||
| 30 | |||
| 31 | /* define specific CPU platform io map */ | ||
| 32 | |||
| 33 | static struct map_desc nuc910evb_iodesc[] __initdata = { | ||
| 34 | IODESC_ENT(USBEHCIHOST), | ||
| 35 | IODESC_ENT(USBOHCIHOST), | ||
| 36 | IODESC_ENT(KPI), | ||
| 37 | IODESC_ENT(USBDEV), | ||
| 38 | IODESC_ENT(ADC), | ||
| 39 | }; | ||
| 40 | |||
| 41 | /*Init NUC910 evb io*/ | ||
| 42 | |||
| 43 | void __init nuc910_map_io(void) | ||
| 44 | { | ||
| 45 | nuc900_map_io(nuc910evb_iodesc, ARRAY_SIZE(nuc910evb_iodesc)); | ||
| 46 | } | ||
| 47 | |||
| 48 | /*Init NUC910 clock*/ | ||
| 49 | |||
| 50 | void __init nuc910_init_clocks(void) | ||
| 51 | { | ||
| 52 | nuc900_init_clocks(); | ||
| 53 | } | ||
| 54 | |||
| 55 | /*Init NUC910 board info*/ | ||
| 56 | |||
| 57 | void __init nuc910_board_init(void) | ||
| 58 | { | ||
| 59 | nuc900_board_init(nuc910_dev, ARRAY_SIZE(nuc910_dev)); | ||
| 60 | } | ||
diff --git a/arch/arm/mach-w90x900/nuc910.h b/arch/arm/mach-w90x900/nuc910.h new file mode 100644 index 000000000000..83e9ba5fc26c --- /dev/null +++ b/arch/arm/mach-w90x900/nuc910.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/mach-w90x900/nuc910.h | ||
| 3 | * | ||
| 4 | * Copyright (c) 2008 Nuvoton corporation | ||
| 5 | * | ||
| 6 | * Header file for NUC900 CPU support | ||
| 7 | * | ||
| 8 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | struct map_desc; | ||
| 17 | struct sys_timer; | ||
| 18 | |||
| 19 | /* core initialisation functions */ | ||
| 20 | |||
| 21 | extern void nuc900_init_irq(void); | ||
| 22 | extern struct sys_timer nuc900_timer; | ||
| 23 | |||
| 24 | /* extern file from nuc910.c */ | ||
| 25 | |||
| 26 | extern void nuc910_board_init(void); | ||
| 27 | extern void nuc910_init_clocks(void); | ||
| 28 | extern void nuc910_map_io(void); | ||
diff --git a/arch/arm/mach-w90x900/nuc950.c b/arch/arm/mach-w90x900/nuc950.c new file mode 100644 index 000000000000..149508116d18 --- /dev/null +++ b/arch/arm/mach-w90x900/nuc950.c | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-w90x900/nuc950.c | ||
| 3 | * | ||
| 4 | * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks | ||
| 5 | * | ||
| 6 | * Copyright (c) 2008 Nuvoton technology corporation. | ||
| 7 | * | ||
| 8 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 9 | * | ||
| 10 | * NUC950 cpu support | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify | ||
| 13 | * it under the terms of the GNU General Public License as published by | ||
| 14 | * the Free Software Foundation;version 2 of the License. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/platform_device.h> | ||
| 19 | #include <asm/mach/map.h> | ||
| 20 | #include <mach/hardware.h> | ||
| 21 | #include "cpu.h" | ||
| 22 | |||
| 23 | /* define specific CPU platform device */ | ||
| 24 | |||
| 25 | static struct platform_device *nuc950_dev[] __initdata = { | ||
| 26 | &nuc900_device_kpi, | ||
| 27 | &nuc900_device_fmi, | ||
| 28 | }; | ||
| 29 | |||
| 30 | /* define specific CPU platform io map */ | ||
| 31 | |||
| 32 | static struct map_desc nuc950evb_iodesc[] __initdata = { | ||
| 33 | }; | ||
| 34 | |||
| 35 | /*Init NUC950 evb io*/ | ||
| 36 | |||
| 37 | void __init nuc950_map_io(void) | ||
| 38 | { | ||
| 39 | nuc900_map_io(nuc950evb_iodesc, ARRAY_SIZE(nuc950evb_iodesc)); | ||
| 40 | } | ||
| 41 | |||
| 42 | /*Init NUC950 clock*/ | ||
| 43 | |||
| 44 | void __init nuc950_init_clocks(void) | ||
| 45 | { | ||
| 46 | nuc900_init_clocks(); | ||
| 47 | } | ||
| 48 | |||
| 49 | /*Init NUC950 board info*/ | ||
| 50 | |||
| 51 | void __init nuc950_board_init(void) | ||
| 52 | { | ||
| 53 | nuc900_board_init(nuc950_dev, ARRAY_SIZE(nuc950_dev)); | ||
| 54 | } | ||
diff --git a/arch/arm/mach-w90x900/nuc950.h b/arch/arm/mach-w90x900/nuc950.h new file mode 100644 index 000000000000..98a1148bc5ae --- /dev/null +++ b/arch/arm/mach-w90x900/nuc950.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/mach-w90x900/nuc950.h | ||
| 3 | * | ||
| 4 | * Copyright (c) 2008 Nuvoton corporation | ||
| 5 | * | ||
| 6 | * Header file for NUC900 CPU support | ||
| 7 | * | ||
| 8 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | struct map_desc; | ||
| 17 | struct sys_timer; | ||
| 18 | |||
| 19 | /* core initialisation functions */ | ||
| 20 | |||
| 21 | extern void nuc900_init_irq(void); | ||
| 22 | extern struct sys_timer nuc900_timer; | ||
| 23 | |||
| 24 | /* extern file from nuc950.c */ | ||
| 25 | |||
| 26 | extern void nuc950_board_init(void); | ||
| 27 | extern void nuc950_init_clocks(void); | ||
| 28 | extern void nuc950_map_io(void); | ||
diff --git a/arch/arm/mach-w90x900/nuc960.c b/arch/arm/mach-w90x900/nuc960.c new file mode 100644 index 000000000000..8851a3a27ce2 --- /dev/null +++ b/arch/arm/mach-w90x900/nuc960.c | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-w90x900/nuc960.c | ||
| 3 | * | ||
| 4 | * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks | ||
| 5 | * | ||
| 6 | * Copyright (c) 2008 Nuvoton technology corporation. | ||
| 7 | * | ||
| 8 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 9 | * | ||
| 10 | * NUC960 cpu support | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify | ||
| 13 | * it under the terms of the GNU General Public License as published by | ||
| 14 | * the Free Software Foundation;version 2 of the License. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/platform_device.h> | ||
| 19 | #include <asm/mach/map.h> | ||
| 20 | #include <mach/hardware.h> | ||
| 21 | #include "cpu.h" | ||
| 22 | |||
| 23 | /* define specific CPU platform device */ | ||
| 24 | |||
| 25 | static struct platform_device *nuc960_dev[] __initdata = { | ||
| 26 | &nuc900_device_kpi, | ||
| 27 | &nuc900_device_fmi, | ||
| 28 | }; | ||
| 29 | |||
| 30 | /* define specific CPU platform io map */ | ||
| 31 | |||
| 32 | static struct map_desc nuc960evb_iodesc[] __initdata = { | ||
| 33 | }; | ||
| 34 | |||
| 35 | /*Init NUC960 evb io*/ | ||
| 36 | |||
| 37 | void __init nuc960_map_io(void) | ||
| 38 | { | ||
| 39 | nuc900_map_io(nuc960evb_iodesc, ARRAY_SIZE(nuc960evb_iodesc)); | ||
| 40 | } | ||
| 41 | |||
| 42 | /*Init NUC960 clock*/ | ||
| 43 | |||
| 44 | void __init nuc960_init_clocks(void) | ||
| 45 | { | ||
| 46 | nuc900_init_clocks(); | ||
| 47 | } | ||
| 48 | |||
| 49 | /*Init NUC960 board info*/ | ||
| 50 | |||
| 51 | void __init nuc960_board_init(void) | ||
| 52 | { | ||
| 53 | nuc900_board_init(nuc960_dev, ARRAY_SIZE(nuc960_dev)); | ||
| 54 | } | ||
diff --git a/arch/arm/mach-w90x900/nuc960.h b/arch/arm/mach-w90x900/nuc960.h new file mode 100644 index 000000000000..f0c07cbe3a82 --- /dev/null +++ b/arch/arm/mach-w90x900/nuc960.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/mach-w90x900/nuc960.h | ||
| 3 | * | ||
| 4 | * Copyright (c) 2008 Nuvoton corporation | ||
| 5 | * | ||
| 6 | * Header file for NUC900 CPU support | ||
| 7 | * | ||
| 8 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | struct map_desc; | ||
| 17 | struct sys_timer; | ||
| 18 | |||
| 19 | /* core initialisation functions */ | ||
| 20 | |||
| 21 | extern void nuc900_init_irq(void); | ||
| 22 | extern struct sys_timer nuc900_timer; | ||
| 23 | |||
| 24 | /* extern file from nuc960.c */ | ||
| 25 | |||
| 26 | extern void nuc960_board_init(void); | ||
| 27 | extern void nuc960_init_clocks(void); | ||
| 28 | extern void nuc960_map_io(void); | ||
diff --git a/arch/arm/mach-w90x900/time.c b/arch/arm/mach-w90x900/time.c index bcc838f6b393..4128af870b41 100644 --- a/arch/arm/mach-w90x900/time.c +++ b/arch/arm/mach-w90x900/time.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Based on linux/arch/arm/plat-s3c24xx/time.c by Ben Dooks | 4 | * Based on linux/arch/arm/plat-s3c24xx/time.c by Ben Dooks |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2008 Nuvoton technology corporation | 6 | * Copyright (c) 2009 Nuvoton technology corporation |
| 7 | * All rights reserved. | 7 | * All rights reserved. |
| 8 | * | 8 | * |
| 9 | * Wan ZongShun <mcuos.com@gmail.com> | 9 | * Wan ZongShun <mcuos.com@gmail.com> |
| @@ -23,6 +23,8 @@ | |||
| 23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
| 24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
| 25 | #include <linux/leds.h> | 25 | #include <linux/leds.h> |
| 26 | #include <linux/clocksource.h> | ||
| 27 | #include <linux/clockchips.h> | ||
| 26 | 28 | ||
| 27 | #include <asm/mach-types.h> | 29 | #include <asm/mach-types.h> |
| 28 | #include <asm/mach/irq.h> | 30 | #include <asm/mach/irq.h> |
| @@ -31,49 +33,150 @@ | |||
| 31 | #include <mach/map.h> | 33 | #include <mach/map.h> |
| 32 | #include <mach/regs-timer.h> | 34 | #include <mach/regs-timer.h> |
| 33 | 35 | ||
| 34 | static unsigned long w90x900_gettimeoffset(void) | 36 | #define RESETINT 0x1f |
| 37 | #define PERIOD (0x01 << 27) | ||
| 38 | #define ONESHOT (0x00 << 27) | ||
| 39 | #define COUNTEN (0x01 << 30) | ||
| 40 | #define INTEN (0x01 << 29) | ||
| 41 | |||
| 42 | #define TICKS_PER_SEC 100 | ||
| 43 | #define PRESCALE 0x63 /* Divider = prescale + 1 */ | ||
| 44 | |||
| 45 | unsigned int timer0_load; | ||
| 46 | |||
| 47 | static void nuc900_clockevent_setmode(enum clock_event_mode mode, | ||
| 48 | struct clock_event_device *clk) | ||
| 35 | { | 49 | { |
| 50 | unsigned int val; | ||
| 51 | |||
| 52 | val = __raw_readl(REG_TCSR0); | ||
| 53 | val &= ~(0x03 << 27); | ||
| 54 | |||
| 55 | switch (mode) { | ||
| 56 | case CLOCK_EVT_MODE_PERIODIC: | ||
| 57 | __raw_writel(timer0_load, REG_TICR0); | ||
| 58 | val |= (PERIOD | COUNTEN | INTEN | PRESCALE); | ||
| 59 | break; | ||
| 60 | |||
| 61 | case CLOCK_EVT_MODE_ONESHOT: | ||
| 62 | val |= (ONESHOT | COUNTEN | INTEN | PRESCALE); | ||
| 63 | break; | ||
| 64 | |||
| 65 | case CLOCK_EVT_MODE_UNUSED: | ||
| 66 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
| 67 | case CLOCK_EVT_MODE_RESUME: | ||
| 68 | break; | ||
| 69 | } | ||
| 70 | |||
| 71 | __raw_writel(val, REG_TCSR0); | ||
| 72 | } | ||
| 73 | |||
| 74 | static int nuc900_clockevent_setnextevent(unsigned long evt, | ||
| 75 | struct clock_event_device *clk) | ||
| 76 | { | ||
| 77 | unsigned int val; | ||
| 78 | |||
| 79 | __raw_writel(evt, REG_TICR0); | ||
| 80 | |||
| 81 | val = __raw_readl(REG_TCSR0); | ||
| 82 | val |= (COUNTEN | INTEN | PRESCALE); | ||
| 83 | __raw_writel(val, REG_TCSR0); | ||
| 84 | |||
| 36 | return 0; | 85 | return 0; |
| 37 | } | 86 | } |
| 38 | 87 | ||
| 88 | static struct clock_event_device nuc900_clockevent_device = { | ||
| 89 | .name = "nuc900-timer0", | ||
| 90 | .shift = 32, | ||
| 91 | .features = CLOCK_EVT_MODE_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
| 92 | .set_mode = nuc900_clockevent_setmode, | ||
| 93 | .set_next_event = nuc900_clockevent_setnextevent, | ||
| 94 | .rating = 300, | ||
| 95 | }; | ||
| 96 | |||
| 39 | /*IRQ handler for the timer*/ | 97 | /*IRQ handler for the timer*/ |
| 40 | 98 | ||
| 41 | static irqreturn_t | 99 | static irqreturn_t nuc900_timer0_interrupt(int irq, void *dev_id) |
| 42 | w90x900_timer_interrupt(int irq, void *dev_id) | ||
| 43 | { | 100 | { |
| 44 | timer_tick(); | 101 | struct clock_event_device *evt = &nuc900_clockevent_device; |
| 102 | |||
| 45 | __raw_writel(0x01, REG_TISR); /* clear TIF0 */ | 103 | __raw_writel(0x01, REG_TISR); /* clear TIF0 */ |
| 104 | |||
| 105 | evt->event_handler(evt); | ||
| 46 | return IRQ_HANDLED; | 106 | return IRQ_HANDLED; |
| 47 | } | 107 | } |
| 48 | 108 | ||
| 49 | static struct irqaction w90x900_timer_irq = { | 109 | static struct irqaction nuc900_timer0_irq = { |
| 50 | .name = "w90x900 Timer Tick", | 110 | .name = "nuc900-timer0", |
| 51 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | 111 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, |
| 52 | .handler = w90x900_timer_interrupt, | 112 | .handler = nuc900_timer0_interrupt, |
| 53 | }; | 113 | }; |
| 54 | 114 | ||
| 55 | /*Set up timer reg.*/ | 115 | static void __init nuc900_clockevents_init(unsigned int rate) |
| 116 | { | ||
| 117 | nuc900_clockevent_device.mult = div_sc(rate, NSEC_PER_SEC, | ||
| 118 | nuc900_clockevent_device.shift); | ||
| 119 | nuc900_clockevent_device.max_delta_ns = clockevent_delta2ns(0xffffffff, | ||
| 120 | &nuc900_clockevent_device); | ||
| 121 | nuc900_clockevent_device.min_delta_ns = clockevent_delta2ns(0xf, | ||
| 122 | &nuc900_clockevent_device); | ||
| 123 | nuc900_clockevent_device.cpumask = cpumask_of(0); | ||
| 56 | 124 | ||
| 57 | static void w90x900_timer_setup(void) | 125 | clockevents_register_device(&nuc900_clockevent_device); |
| 126 | } | ||
| 127 | |||
| 128 | static cycle_t nuc900_get_cycles(struct clocksource *cs) | ||
| 58 | { | 129 | { |
| 59 | __raw_writel(0, REG_TCSR0); | 130 | return ~__raw_readl(REG_TDR1); |
| 60 | __raw_writel(0, REG_TCSR1); | ||
| 61 | __raw_writel(0, REG_TCSR2); | ||
| 62 | __raw_writel(0, REG_TCSR3); | ||
| 63 | __raw_writel(0, REG_TCSR4); | ||
| 64 | __raw_writel(0x1F, REG_TISR); | ||
| 65 | __raw_writel(15000000/(100 * 100), REG_TICR0); | ||
| 66 | __raw_writel(0x68000063, REG_TCSR0); | ||
| 67 | } | 131 | } |
| 68 | 132 | ||
| 69 | static void __init w90x900_timer_init(void) | 133 | static struct clocksource clocksource_nuc900 = { |
| 134 | .name = "nuc900-timer1", | ||
| 135 | .rating = 200, | ||
| 136 | .read = nuc900_get_cycles, | ||
| 137 | .mask = CLOCKSOURCE_MASK(32), | ||
| 138 | .shift = 20, | ||
| 139 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
| 140 | }; | ||
| 141 | |||
| 142 | static void __init nuc900_clocksource_init(unsigned int rate) | ||
| 70 | { | 143 | { |
| 71 | w90x900_timer_setup(); | 144 | unsigned int val; |
| 72 | setup_irq(IRQ_TIMER0, &w90x900_timer_irq); | 145 | |
| 146 | __raw_writel(0xffffffff, REG_TICR1); | ||
| 147 | |||
| 148 | val = __raw_readl(REG_TCSR1); | ||
| 149 | val |= (COUNTEN | PERIOD); | ||
| 150 | __raw_writel(val, REG_TCSR1); | ||
| 151 | |||
| 152 | clocksource_nuc900.mult = | ||
| 153 | clocksource_khz2mult((rate / 1000), clocksource_nuc900.shift); | ||
| 154 | clocksource_register(&clocksource_nuc900); | ||
| 155 | } | ||
| 156 | |||
| 157 | static void __init nuc900_timer_init(void) | ||
| 158 | { | ||
| 159 | struct clk *ck_ext = clk_get(NULL, "ext"); | ||
| 160 | unsigned int rate; | ||
| 161 | |||
| 162 | BUG_ON(IS_ERR(ck_ext)); | ||
| 163 | |||
| 164 | rate = clk_get_rate(ck_ext); | ||
| 165 | clk_put(ck_ext); | ||
| 166 | rate = rate / (PRESCALE + 0x01); | ||
| 167 | |||
| 168 | /* set a known state */ | ||
| 169 | __raw_writel(0x00, REG_TCSR0); | ||
| 170 | __raw_writel(0x00, REG_TCSR1); | ||
| 171 | __raw_writel(RESETINT, REG_TISR); | ||
| 172 | timer0_load = (rate / TICKS_PER_SEC); | ||
| 173 | |||
| 174 | setup_irq(IRQ_TIMER0, &nuc900_timer0_irq); | ||
| 175 | |||
| 176 | nuc900_clocksource_init(rate); | ||
| 177 | nuc900_clockevents_init(rate); | ||
| 73 | } | 178 | } |
| 74 | 179 | ||
| 75 | struct sys_timer w90x900_timer = { | 180 | struct sys_timer nuc900_timer = { |
| 76 | .init = w90x900_timer_init, | 181 | .init = nuc900_timer_init, |
| 77 | .offset = w90x900_gettimeoffset, | ||
| 78 | .resume = w90x900_timer_setup | ||
| 79 | }; | 182 | }; |
diff --git a/arch/arm/mach-w90x900/w90p910.c b/arch/arm/mach-w90x900/w90p910.c deleted file mode 100644 index 1c97e4930b7a..000000000000 --- a/arch/arm/mach-w90x900/w90p910.c +++ /dev/null | |||
| @@ -1,136 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-w90x900/w90p910.c | ||
| 3 | * | ||
| 4 | * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks | ||
| 5 | * | ||
| 6 | * Copyright (c) 2008 Nuvoton technology corporation. | ||
| 7 | * | ||
| 8 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 9 | * | ||
| 10 | * W90P910 cpu support | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify | ||
| 13 | * it under the terms of the GNU General Public License as published by | ||
| 14 | * the Free Software Foundation;version 2 of the License. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/types.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/list.h> | ||
| 22 | #include <linux/timer.h> | ||
| 23 | #include <linux/init.h> | ||
| 24 | #include <linux/platform_device.h> | ||
| 25 | #include <linux/io.h> | ||
| 26 | #include <linux/serial_8250.h> | ||
| 27 | |||
| 28 | #include <asm/mach/arch.h> | ||
| 29 | #include <asm/mach/map.h> | ||
| 30 | #include <asm/mach/irq.h> | ||
| 31 | #include <asm/irq.h> | ||
| 32 | |||
| 33 | #include <mach/hardware.h> | ||
| 34 | #include <mach/regs-serial.h> | ||
| 35 | |||
| 36 | #include "cpu.h" | ||
| 37 | #include "clock.h" | ||
| 38 | |||
| 39 | /* Initial IO mappings */ | ||
| 40 | |||
| 41 | static struct map_desc w90p910_iodesc[] __initdata = { | ||
| 42 | IODESC_ENT(IRQ), | ||
| 43 | IODESC_ENT(GCR), | ||
| 44 | IODESC_ENT(UART), | ||
| 45 | IODESC_ENT(TIMER), | ||
| 46 | IODESC_ENT(EBI), | ||
| 47 | IODESC_ENT(USBEHCIHOST), | ||
| 48 | IODESC_ENT(USBOHCIHOST), | ||
| 49 | IODESC_ENT(ADC), | ||
| 50 | IODESC_ENT(RTC), | ||
| 51 | IODESC_ENT(KPI), | ||
| 52 | IODESC_ENT(USBDEV), | ||
| 53 | /*IODESC_ENT(LCD),*/ | ||
| 54 | }; | ||
| 55 | |||
| 56 | /* Initial clock declarations. */ | ||
| 57 | static DEFINE_CLK(lcd, 0); | ||
| 58 | static DEFINE_CLK(audio, 1); | ||
| 59 | static DEFINE_CLK(fmi, 4); | ||
| 60 | static DEFINE_CLK(dmac, 5); | ||
| 61 | static DEFINE_CLK(atapi, 6); | ||
| 62 | static DEFINE_CLK(emc, 7); | ||
| 63 | static DEFINE_CLK(usbd, 8); | ||
| 64 | static DEFINE_CLK(usbh, 9); | ||
| 65 | static DEFINE_CLK(g2d, 10);; | ||
| 66 | static DEFINE_CLK(pwm, 18); | ||
| 67 | static DEFINE_CLK(ps2, 24); | ||
| 68 | static DEFINE_CLK(kpi, 25); | ||
| 69 | static DEFINE_CLK(wdt, 26); | ||
| 70 | static DEFINE_CLK(gdma, 27); | ||
| 71 | static DEFINE_CLK(adc, 28); | ||
| 72 | static DEFINE_CLK(usi, 29); | ||
| 73 | |||
| 74 | static struct clk_lookup w90p910_clkregs[] = { | ||
| 75 | DEF_CLKLOOK(&clk_lcd, "w90p910-lcd", NULL), | ||
| 76 | DEF_CLKLOOK(&clk_audio, "w90p910-audio", NULL), | ||
| 77 | DEF_CLKLOOK(&clk_fmi, "w90p910-fmi", NULL), | ||
| 78 | DEF_CLKLOOK(&clk_dmac, "w90p910-dmac", NULL), | ||
| 79 | DEF_CLKLOOK(&clk_atapi, "w90p910-atapi", NULL), | ||
| 80 | DEF_CLKLOOK(&clk_emc, "w90p910-emc", NULL), | ||
| 81 | DEF_CLKLOOK(&clk_usbd, "w90p910-usbd", NULL), | ||
| 82 | DEF_CLKLOOK(&clk_usbh, "w90p910-usbh", NULL), | ||
| 83 | DEF_CLKLOOK(&clk_g2d, "w90p910-g2d", NULL), | ||
| 84 | DEF_CLKLOOK(&clk_pwm, "w90p910-pwm", NULL), | ||
| 85 | DEF_CLKLOOK(&clk_ps2, "w90p910-ps2", NULL), | ||
| 86 | DEF_CLKLOOK(&clk_kpi, "w90p910-kpi", NULL), | ||
| 87 | DEF_CLKLOOK(&clk_wdt, "w90p910-wdt", NULL), | ||
| 88 | DEF_CLKLOOK(&clk_gdma, "w90p910-gdma", NULL), | ||
| 89 | DEF_CLKLOOK(&clk_adc, "w90p910-adc", NULL), | ||
| 90 | DEF_CLKLOOK(&clk_usi, "w90p910-usi", NULL), | ||
| 91 | }; | ||
| 92 | |||
| 93 | /* Initial serial platform data */ | ||
| 94 | |||
| 95 | struct plat_serial8250_port w90p910_uart_data[] = { | ||
| 96 | W90X900_8250PORT(UART0), | ||
| 97 | }; | ||
| 98 | |||
| 99 | struct platform_device w90p910_serial_device = { | ||
| 100 | .name = "serial8250", | ||
| 101 | .id = PLAT8250_DEV_PLATFORM, | ||
| 102 | .dev = { | ||
| 103 | .platform_data = w90p910_uart_data, | ||
| 104 | }, | ||
| 105 | }; | ||
| 106 | |||
| 107 | /*Init W90P910 evb io*/ | ||
| 108 | |||
| 109 | void __init w90p910_map_io(struct map_desc *mach_desc, int mach_size) | ||
| 110 | { | ||
| 111 | unsigned long idcode = 0x0; | ||
| 112 | |||
| 113 | iotable_init(w90p910_iodesc, ARRAY_SIZE(w90p910_iodesc)); | ||
| 114 | |||
| 115 | idcode = __raw_readl(W90X900PDID); | ||
| 116 | if (idcode != W90P910_CPUID) | ||
| 117 | printk(KERN_ERR "CPU type 0x%08lx is not W90P910\n", idcode); | ||
| 118 | } | ||
| 119 | |||
| 120 | /*Init W90P910 clock*/ | ||
| 121 | |||
| 122 | void __init w90p910_init_clocks(void) | ||
| 123 | { | ||
| 124 | clks_register(w90p910_clkregs, ARRAY_SIZE(w90p910_clkregs)); | ||
| 125 | } | ||
| 126 | |||
| 127 | static int __init w90p910_init_cpu(void) | ||
| 128 | { | ||
| 129 | return 0; | ||
| 130 | } | ||
| 131 | |||
| 132 | static int __init w90x900_arch_init(void) | ||
| 133 | { | ||
| 134 | return w90p910_init_cpu(); | ||
| 135 | } | ||
| 136 | arch_initcall(w90x900_arch_init); | ||
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 83c025e72ceb..5fe595aeba69 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
| @@ -758,7 +758,7 @@ config CACHE_FEROCEON_L2_WRITETHROUGH | |||
| 758 | config CACHE_L2X0 | 758 | config CACHE_L2X0 |
| 759 | bool "Enable the L2x0 outer cache controller" | 759 | bool "Enable the L2x0 outer cache controller" |
| 760 | depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ | 760 | depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ |
| 761 | REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX | 761 | REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK |
| 762 | default y | 762 | default y |
| 763 | select OUTER_CACHE | 763 | select OUTER_CACHE |
| 764 | help | 764 | help |
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 03cd27d917b9..b270d6228fe2 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c | |||
| @@ -159,7 +159,9 @@ union offset_union { | |||
| 159 | 159 | ||
| 160 | #define __get8_unaligned_check(ins,val,addr,err) \ | 160 | #define __get8_unaligned_check(ins,val,addr,err) \ |
| 161 | __asm__( \ | 161 | __asm__( \ |
| 162 | "1: "ins" %1, [%2], #1\n" \ | 162 | ARM( "1: "ins" %1, [%2], #1\n" ) \ |
| 163 | THUMB( "1: "ins" %1, [%2]\n" ) \ | ||
| 164 | THUMB( " add %2, %2, #1\n" ) \ | ||
| 163 | "2:\n" \ | 165 | "2:\n" \ |
| 164 | " .section .fixup,\"ax\"\n" \ | 166 | " .section .fixup,\"ax\"\n" \ |
| 165 | " .align 2\n" \ | 167 | " .align 2\n" \ |
| @@ -215,7 +217,9 @@ union offset_union { | |||
| 215 | do { \ | 217 | do { \ |
| 216 | unsigned int err = 0, v = val, a = addr; \ | 218 | unsigned int err = 0, v = val, a = addr; \ |
| 217 | __asm__( FIRST_BYTE_16 \ | 219 | __asm__( FIRST_BYTE_16 \ |
| 218 | "1: "ins" %1, [%2], #1\n" \ | 220 | ARM( "1: "ins" %1, [%2], #1\n" ) \ |
| 221 | THUMB( "1: "ins" %1, [%2]\n" ) \ | ||
| 222 | THUMB( " add %2, %2, #1\n" ) \ | ||
| 219 | " mov %1, %1, "NEXT_BYTE"\n" \ | 223 | " mov %1, %1, "NEXT_BYTE"\n" \ |
| 220 | "2: "ins" %1, [%2]\n" \ | 224 | "2: "ins" %1, [%2]\n" \ |
| 221 | "3:\n" \ | 225 | "3:\n" \ |
| @@ -245,11 +249,17 @@ union offset_union { | |||
| 245 | do { \ | 249 | do { \ |
| 246 | unsigned int err = 0, v = val, a = addr; \ | 250 | unsigned int err = 0, v = val, a = addr; \ |
| 247 | __asm__( FIRST_BYTE_32 \ | 251 | __asm__( FIRST_BYTE_32 \ |
| 248 | "1: "ins" %1, [%2], #1\n" \ | 252 | ARM( "1: "ins" %1, [%2], #1\n" ) \ |
| 253 | THUMB( "1: "ins" %1, [%2]\n" ) \ | ||
| 254 | THUMB( " add %2, %2, #1\n" ) \ | ||
| 249 | " mov %1, %1, "NEXT_BYTE"\n" \ | 255 | " mov %1, %1, "NEXT_BYTE"\n" \ |
| 250 | "2: "ins" %1, [%2], #1\n" \ | 256 | ARM( "2: "ins" %1, [%2], #1\n" ) \ |
| 257 | THUMB( "2: "ins" %1, [%2]\n" ) \ | ||
| 258 | THUMB( " add %2, %2, #1\n" ) \ | ||
| 251 | " mov %1, %1, "NEXT_BYTE"\n" \ | 259 | " mov %1, %1, "NEXT_BYTE"\n" \ |
| 252 | "3: "ins" %1, [%2], #1\n" \ | 260 | ARM( "3: "ins" %1, [%2], #1\n" ) \ |
| 261 | THUMB( "3: "ins" %1, [%2]\n" ) \ | ||
| 262 | THUMB( " add %2, %2, #1\n" ) \ | ||
| 253 | " mov %1, %1, "NEXT_BYTE"\n" \ | 263 | " mov %1, %1, "NEXT_BYTE"\n" \ |
| 254 | "4: "ins" %1, [%2]\n" \ | 264 | "4: "ins" %1, [%2]\n" \ |
| 255 | "5:\n" \ | 265 | "5:\n" \ |
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index be93ff02a98d..bda0ec31a4e2 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | * | 21 | * |
| 22 | * Flush the whole D-cache. | 22 | * Flush the whole D-cache. |
| 23 | * | 23 | * |
| 24 | * Corrupted registers: r0-r5, r7, r9-r11 | 24 | * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode) |
| 25 | * | 25 | * |
| 26 | * - mm - mm_struct describing address space | 26 | * - mm - mm_struct describing address space |
| 27 | */ | 27 | */ |
| @@ -51,8 +51,12 @@ loop1: | |||
| 51 | loop2: | 51 | loop2: |
| 52 | mov r9, r4 @ create working copy of max way size | 52 | mov r9, r4 @ create working copy of max way size |
| 53 | loop3: | 53 | loop3: |
| 54 | orr r11, r10, r9, lsl r5 @ factor way and cache number into r11 | 54 | ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11 |
| 55 | orr r11, r11, r7, lsl r2 @ factor index number into r11 | 55 | THUMB( lsl r6, r9, r5 ) |
| 56 | THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11 | ||
| 57 | ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11 | ||
| 58 | THUMB( lsl r6, r7, r2 ) | ||
| 59 | THUMB( orr r11, r11, r6 ) @ factor index number into r11 | ||
| 56 | mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way | 60 | mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way |
| 57 | subs r9, r9, #1 @ decrement the way | 61 | subs r9, r9, #1 @ decrement the way |
| 58 | bge loop3 | 62 | bge loop3 |
| @@ -82,11 +86,13 @@ ENDPROC(v7_flush_dcache_all) | |||
| 82 | * | 86 | * |
| 83 | */ | 87 | */ |
| 84 | ENTRY(v7_flush_kern_cache_all) | 88 | ENTRY(v7_flush_kern_cache_all) |
| 85 | stmfd sp!, {r4-r5, r7, r9-r11, lr} | 89 | ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} ) |
| 90 | THUMB( stmfd sp!, {r4-r7, r9-r11, lr} ) | ||
| 86 | bl v7_flush_dcache_all | 91 | bl v7_flush_dcache_all |
| 87 | mov r0, #0 | 92 | mov r0, #0 |
| 88 | mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate | 93 | mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate |
| 89 | ldmfd sp!, {r4-r5, r7, r9-r11, lr} | 94 | ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} ) |
| 95 | THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} ) | ||
| 90 | mov pc, lr | 96 | mov pc, lr |
| 91 | ENDPROC(v7_flush_kern_cache_all) | 97 | ENDPROC(v7_flush_kern_cache_all) |
| 92 | 98 | ||
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 510c179b0ac8..b30925fcbcdc 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
| @@ -36,7 +36,34 @@ | |||
| 36 | #define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT) | 36 | #define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT) |
| 37 | #define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT) | 37 | #define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT) |
| 38 | 38 | ||
| 39 | static u64 get_coherent_dma_mask(struct device *dev) | ||
| 40 | { | ||
| 41 | u64 mask = ISA_DMA_THRESHOLD; | ||
| 42 | |||
| 43 | if (dev) { | ||
| 44 | mask = dev->coherent_dma_mask; | ||
| 45 | |||
| 46 | /* | ||
| 47 | * Sanity check the DMA mask - it must be non-zero, and | ||
| 48 | * must be able to be satisfied by a DMA allocation. | ||
| 49 | */ | ||
| 50 | if (mask == 0) { | ||
| 51 | dev_warn(dev, "coherent DMA mask is unset\n"); | ||
| 52 | return 0; | ||
| 53 | } | ||
| 54 | |||
| 55 | if ((~mask) & ISA_DMA_THRESHOLD) { | ||
| 56 | dev_warn(dev, "coherent DMA mask %#llx is smaller " | ||
| 57 | "than system GFP_DMA mask %#llx\n", | ||
| 58 | mask, (unsigned long long)ISA_DMA_THRESHOLD); | ||
| 59 | return 0; | ||
| 60 | } | ||
| 61 | } | ||
| 39 | 62 | ||
| 63 | return mask; | ||
| 64 | } | ||
| 65 | |||
| 66 | #ifdef CONFIG_MMU | ||
| 40 | /* | 67 | /* |
| 41 | * These are the page tables (2MB each) covering uncached, DMA consistent allocations | 68 | * These are the page tables (2MB each) covering uncached, DMA consistent allocations |
| 42 | */ | 69 | */ |
| @@ -152,7 +179,8 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, | |||
| 152 | struct page *page; | 179 | struct page *page; |
| 153 | struct arm_vm_region *c; | 180 | struct arm_vm_region *c; |
| 154 | unsigned long order; | 181 | unsigned long order; |
| 155 | u64 mask = ISA_DMA_THRESHOLD, limit; | 182 | u64 mask = get_coherent_dma_mask(dev); |
| 183 | u64 limit; | ||
| 156 | 184 | ||
| 157 | if (!consistent_pte[0]) { | 185 | if (!consistent_pte[0]) { |
| 158 | printk(KERN_ERR "%s: not initialised\n", __func__); | 186 | printk(KERN_ERR "%s: not initialised\n", __func__); |
| @@ -160,25 +188,8 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, | |||
| 160 | return NULL; | 188 | return NULL; |
| 161 | } | 189 | } |
| 162 | 190 | ||
| 163 | if (dev) { | 191 | if (!mask) |
| 164 | mask = dev->coherent_dma_mask; | 192 | goto no_page; |
| 165 | |||
| 166 | /* | ||
| 167 | * Sanity check the DMA mask - it must be non-zero, and | ||
| 168 | * must be able to be satisfied by a DMA allocation. | ||
| 169 | */ | ||
| 170 | if (mask == 0) { | ||
| 171 | dev_warn(dev, "coherent DMA mask is unset\n"); | ||
| 172 | goto no_page; | ||
| 173 | } | ||
| 174 | |||
| 175 | if ((~mask) & ISA_DMA_THRESHOLD) { | ||
| 176 | dev_warn(dev, "coherent DMA mask %#llx is smaller " | ||
| 177 | "than system GFP_DMA mask %#llx\n", | ||
| 178 | mask, (unsigned long long)ISA_DMA_THRESHOLD); | ||
| 179 | goto no_page; | ||
| 180 | } | ||
| 181 | } | ||
| 182 | 193 | ||
| 183 | /* | 194 | /* |
| 184 | * Sanity check the allocation size. | 195 | * Sanity check the allocation size. |
| @@ -267,6 +278,31 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, | |||
| 267 | *handle = ~0; | 278 | *handle = ~0; |
| 268 | return NULL; | 279 | return NULL; |
| 269 | } | 280 | } |
| 281 | #else /* !CONFIG_MMU */ | ||
| 282 | static void * | ||
| 283 | __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, | ||
| 284 | pgprot_t prot) | ||
| 285 | { | ||
| 286 | void *virt; | ||
| 287 | u64 mask = get_coherent_dma_mask(dev); | ||
| 288 | |||
| 289 | if (!mask) | ||
| 290 | goto error; | ||
| 291 | |||
| 292 | if (mask != 0xffffffff) | ||
| 293 | gfp |= GFP_DMA; | ||
| 294 | virt = kmalloc(size, gfp); | ||
| 295 | if (!virt) | ||
| 296 | goto error; | ||
| 297 | |||
| 298 | *handle = virt_to_dma(dev, virt); | ||
| 299 | return virt; | ||
| 300 | |||
| 301 | error: | ||
| 302 | *handle = ~0; | ||
| 303 | return NULL; | ||
| 304 | } | ||
| 305 | #endif /* CONFIG_MMU */ | ||
| 270 | 306 | ||
| 271 | /* | 307 | /* |
| 272 | * Allocate DMA-coherent memory space and return both the kernel remapped | 308 | * Allocate DMA-coherent memory space and return both the kernel remapped |
| @@ -311,9 +347,10 @@ EXPORT_SYMBOL(dma_alloc_writecombine); | |||
| 311 | static int dma_mmap(struct device *dev, struct vm_area_struct *vma, | 347 | static int dma_mmap(struct device *dev, struct vm_area_struct *vma, |
| 312 | void *cpu_addr, dma_addr_t dma_addr, size_t size) | 348 | void *cpu_addr, dma_addr_t dma_addr, size_t size) |
| 313 | { | 349 | { |
| 350 | int ret = -ENXIO; | ||
| 351 | #ifdef CONFIG_MMU | ||
| 314 | unsigned long flags, user_size, kern_size; | 352 | unsigned long flags, user_size, kern_size; |
| 315 | struct arm_vm_region *c; | 353 | struct arm_vm_region *c; |
| 316 | int ret = -ENXIO; | ||
| 317 | 354 | ||
| 318 | user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | 355 | user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; |
| 319 | 356 | ||
| @@ -334,6 +371,7 @@ static int dma_mmap(struct device *dev, struct vm_area_struct *vma, | |||
| 334 | vma->vm_page_prot); | 371 | vma->vm_page_prot); |
| 335 | } | 372 | } |
| 336 | } | 373 | } |
| 374 | #endif /* CONFIG_MMU */ | ||
| 337 | 375 | ||
| 338 | return ret; | 376 | return ret; |
| 339 | } | 377 | } |
| @@ -358,6 +396,7 @@ EXPORT_SYMBOL(dma_mmap_writecombine); | |||
| 358 | * free a page as defined by the above mapping. | 396 | * free a page as defined by the above mapping. |
| 359 | * Must not be called with IRQs disabled. | 397 | * Must not be called with IRQs disabled. |
| 360 | */ | 398 | */ |
| 399 | #ifdef CONFIG_MMU | ||
| 361 | void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle) | 400 | void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle) |
| 362 | { | 401 | { |
| 363 | struct arm_vm_region *c; | 402 | struct arm_vm_region *c; |
| @@ -444,6 +483,14 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr | |||
| 444 | __func__, cpu_addr); | 483 | __func__, cpu_addr); |
| 445 | dump_stack(); | 484 | dump_stack(); |
| 446 | } | 485 | } |
| 486 | #else /* !CONFIG_MMU */ | ||
| 487 | void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle) | ||
| 488 | { | ||
| 489 | if (dma_release_from_coherent(dev, get_order(size), cpu_addr)) | ||
| 490 | return; | ||
| 491 | kfree(cpu_addr); | ||
| 492 | } | ||
| 493 | #endif /* CONFIG_MMU */ | ||
| 447 | EXPORT_SYMBOL(dma_free_coherent); | 494 | EXPORT_SYMBOL(dma_free_coherent); |
| 448 | 495 | ||
| 449 | /* | 496 | /* |
| @@ -451,10 +498,12 @@ EXPORT_SYMBOL(dma_free_coherent); | |||
| 451 | */ | 498 | */ |
| 452 | static int __init consistent_init(void) | 499 | static int __init consistent_init(void) |
| 453 | { | 500 | { |
| 501 | int ret = 0; | ||
| 502 | #ifdef CONFIG_MMU | ||
| 454 | pgd_t *pgd; | 503 | pgd_t *pgd; |
| 455 | pmd_t *pmd; | 504 | pmd_t *pmd; |
| 456 | pte_t *pte; | 505 | pte_t *pte; |
| 457 | int ret = 0, i = 0; | 506 | int i = 0; |
| 458 | u32 base = CONSISTENT_BASE; | 507 | u32 base = CONSISTENT_BASE; |
| 459 | 508 | ||
| 460 | do { | 509 | do { |
| @@ -477,6 +526,7 @@ static int __init consistent_init(void) | |||
| 477 | consistent_pte[i++] = pte; | 526 | consistent_pte[i++] = pte; |
| 478 | base += (1 << PGDIR_SHIFT); | 527 | base += (1 << PGDIR_SHIFT); |
| 479 | } while (base < CONSISTENT_END); | 528 | } while (base < CONSISTENT_END); |
| 529 | #endif /* !CONFIG_MMU */ | ||
| 480 | 530 | ||
| 481 | return ret; | 531 | return ret; |
| 482 | } | 532 | } |
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 6fdcbb709827..cc8829d7e116 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c | |||
| @@ -16,6 +16,8 @@ | |||
| 16 | #include <linux/kprobes.h> | 16 | #include <linux/kprobes.h> |
| 17 | #include <linux/uaccess.h> | 17 | #include <linux/uaccess.h> |
| 18 | #include <linux/page-flags.h> | 18 | #include <linux/page-flags.h> |
| 19 | #include <linux/sched.h> | ||
| 20 | #include <linux/highmem.h> | ||
| 19 | 21 | ||
| 20 | #include <asm/system.h> | 22 | #include <asm/system.h> |
| 21 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
| @@ -23,6 +25,7 @@ | |||
| 23 | 25 | ||
| 24 | #include "fault.h" | 26 | #include "fault.h" |
| 25 | 27 | ||
| 28 | #ifdef CONFIG_MMU | ||
| 26 | 29 | ||
| 27 | #ifdef CONFIG_KPROBES | 30 | #ifdef CONFIG_KPROBES |
| 28 | static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr) | 31 | static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr) |
| @@ -97,6 +100,10 @@ void show_pte(struct mm_struct *mm, unsigned long addr) | |||
| 97 | 100 | ||
| 98 | printk("\n"); | 101 | printk("\n"); |
| 99 | } | 102 | } |
| 103 | #else /* CONFIG_MMU */ | ||
| 104 | void show_pte(struct mm_struct *mm, unsigned long addr) | ||
| 105 | { } | ||
| 106 | #endif /* CONFIG_MMU */ | ||
| 100 | 107 | ||
| 101 | /* | 108 | /* |
| 102 | * Oops. The kernel tried to access some page that wasn't present. | 109 | * Oops. The kernel tried to access some page that wasn't present. |
| @@ -171,6 +178,7 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
| 171 | __do_kernel_fault(mm, addr, fsr, regs); | 178 | __do_kernel_fault(mm, addr, fsr, regs); |
| 172 | } | 179 | } |
| 173 | 180 | ||
| 181 | #ifdef CONFIG_MMU | ||
| 174 | #define VM_FAULT_BADMAP 0x010000 | 182 | #define VM_FAULT_BADMAP 0x010000 |
| 175 | #define VM_FAULT_BADACCESS 0x020000 | 183 | #define VM_FAULT_BADACCESS 0x020000 |
| 176 | 184 | ||
| @@ -322,6 +330,13 @@ no_context: | |||
| 322 | __do_kernel_fault(mm, addr, fsr, regs); | 330 | __do_kernel_fault(mm, addr, fsr, regs); |
| 323 | return 0; | 331 | return 0; |
| 324 | } | 332 | } |
| 333 | #else /* CONFIG_MMU */ | ||
| 334 | static int | ||
| 335 | do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | ||
| 336 | { | ||
| 337 | return 0; | ||
| 338 | } | ||
| 339 | #endif /* CONFIG_MMU */ | ||
| 325 | 340 | ||
| 326 | /* | 341 | /* |
| 327 | * First Level Translation Fault Handler | 342 | * First Level Translation Fault Handler |
| @@ -340,6 +355,7 @@ no_context: | |||
| 340 | * interrupt or a critical region, and should only copy the information | 355 | * interrupt or a critical region, and should only copy the information |
| 341 | * from the master page table, nothing more. | 356 | * from the master page table, nothing more. |
| 342 | */ | 357 | */ |
| 358 | #ifdef CONFIG_MMU | ||
| 343 | static int __kprobes | 359 | static int __kprobes |
| 344 | do_translation_fault(unsigned long addr, unsigned int fsr, | 360 | do_translation_fault(unsigned long addr, unsigned int fsr, |
| 345 | struct pt_regs *regs) | 361 | struct pt_regs *regs) |
| @@ -378,6 +394,14 @@ bad_area: | |||
| 378 | do_bad_area(addr, fsr, regs); | 394 | do_bad_area(addr, fsr, regs); |
| 379 | return 0; | 395 | return 0; |
| 380 | } | 396 | } |
| 397 | #else /* CONFIG_MMU */ | ||
| 398 | static int | ||
| 399 | do_translation_fault(unsigned long addr, unsigned int fsr, | ||
| 400 | struct pt_regs *regs) | ||
| 401 | { | ||
| 402 | return 0; | ||
| 403 | } | ||
| 404 | #endif /* CONFIG_MMU */ | ||
| 381 | 405 | ||
| 382 | /* | 406 | /* |
| 383 | * Some section permission faults need to be handled gracefully. | 407 | * Some section permission faults need to be handled gracefully. |
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index c07222eb5ce0..575f3ad722e7 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c | |||
| @@ -144,7 +144,14 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page) | |||
| 144 | * page. This ensures that data in the physical page is mutually | 144 | * page. This ensures that data in the physical page is mutually |
| 145 | * coherent with the kernels mapping. | 145 | * coherent with the kernels mapping. |
| 146 | */ | 146 | */ |
| 147 | __cpuc_flush_dcache_page(page_address(page)); | 147 | #ifdef CONFIG_HIGHMEM |
| 148 | /* | ||
| 149 | * kmap_atomic() doesn't set the page virtual address, and | ||
| 150 | * kunmap_atomic() takes care of cache flushing already. | ||
| 151 | */ | ||
| 152 | if (page_address(page)) | ||
| 153 | #endif | ||
| 154 | __cpuc_flush_dcache_page(page_address(page)); | ||
| 148 | 155 | ||
| 149 | /* | 156 | /* |
| 150 | * If this is a page cache page, and we have an aliasing VIPT cache, | 157 | * If this is a page cache page, and we have an aliasing VIPT cache, |
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index a34954d9df7d..73cae57fa707 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c | |||
| @@ -40,11 +40,16 @@ void *kmap_atomic(struct page *page, enum km_type type) | |||
| 40 | { | 40 | { |
| 41 | unsigned int idx; | 41 | unsigned int idx; |
| 42 | unsigned long vaddr; | 42 | unsigned long vaddr; |
| 43 | void *kmap; | ||
| 43 | 44 | ||
| 44 | pagefault_disable(); | 45 | pagefault_disable(); |
| 45 | if (!PageHighMem(page)) | 46 | if (!PageHighMem(page)) |
| 46 | return page_address(page); | 47 | return page_address(page); |
| 47 | 48 | ||
| 49 | kmap = kmap_high_get(page); | ||
| 50 | if (kmap) | ||
| 51 | return kmap; | ||
| 52 | |||
| 48 | idx = type + KM_TYPE_NR * smp_processor_id(); | 53 | idx = type + KM_TYPE_NR * smp_processor_id(); |
| 49 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 54 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
| 50 | #ifdef CONFIG_DEBUG_HIGHMEM | 55 | #ifdef CONFIG_DEBUG_HIGHMEM |
| @@ -80,6 +85,9 @@ void kunmap_atomic(void *kvaddr, enum km_type type) | |||
| 80 | #else | 85 | #else |
| 81 | (void) idx; /* to kill a warning */ | 86 | (void) idx; /* to kill a warning */ |
| 82 | #endif | 87 | #endif |
| 88 | } else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) { | ||
| 89 | /* this address was obtained through kmap_high_get() */ | ||
| 90 | kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)])); | ||
| 83 | } | 91 | } |
| 84 | pagefault_enable(); | 92 | pagefault_enable(); |
| 85 | } | 93 | } |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 3a7279c1ce5e..ea36186f32c3 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/mman.h> | 15 | #include <linux/mman.h> |
| 16 | #include <linux/nodemask.h> | 16 | #include <linux/nodemask.h> |
| 17 | #include <linux/initrd.h> | 17 | #include <linux/initrd.h> |
| 18 | #include <linux/sort.h> | ||
| 18 | #include <linux/highmem.h> | 19 | #include <linux/highmem.h> |
| 19 | 20 | ||
| 20 | #include <asm/mach-types.h> | 21 | #include <asm/mach-types.h> |
| @@ -349,12 +350,43 @@ static void __init bootmem_free_node(int node, struct meminfo *mi) | |||
| 349 | free_area_init_node(node, zone_size, min, zhole_size); | 350 | free_area_init_node(node, zone_size, min, zhole_size); |
| 350 | } | 351 | } |
| 351 | 352 | ||
| 353 | #ifndef CONFIG_SPARSEMEM | ||
| 354 | int pfn_valid(unsigned long pfn) | ||
| 355 | { | ||
| 356 | struct meminfo *mi = &meminfo; | ||
| 357 | unsigned int left = 0, right = mi->nr_banks; | ||
| 358 | |||
| 359 | do { | ||
| 360 | unsigned int mid = (right + left) / 2; | ||
| 361 | struct membank *bank = &mi->bank[mid]; | ||
| 362 | |||
| 363 | if (pfn < bank_pfn_start(bank)) | ||
| 364 | right = mid; | ||
| 365 | else if (pfn >= bank_pfn_end(bank)) | ||
| 366 | left = mid + 1; | ||
| 367 | else | ||
| 368 | return 1; | ||
| 369 | } while (left < right); | ||
| 370 | return 0; | ||
| 371 | } | ||
| 372 | EXPORT_SYMBOL(pfn_valid); | ||
| 373 | #endif | ||
| 374 | |||
| 375 | static int __init meminfo_cmp(const void *_a, const void *_b) | ||
| 376 | { | ||
| 377 | const struct membank *a = _a, *b = _b; | ||
| 378 | long cmp = bank_pfn_start(a) - bank_pfn_start(b); | ||
| 379 | return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; | ||
| 380 | } | ||
| 381 | |||
| 352 | void __init bootmem_init(void) | 382 | void __init bootmem_init(void) |
| 353 | { | 383 | { |
| 354 | struct meminfo *mi = &meminfo; | 384 | struct meminfo *mi = &meminfo; |
| 355 | unsigned long min, max_low, max_high; | 385 | unsigned long min, max_low, max_high; |
| 356 | int node, initrd_node; | 386 | int node, initrd_node; |
| 357 | 387 | ||
| 388 | sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL); | ||
| 389 | |||
| 358 | /* | 390 | /* |
| 359 | * Locate which node contains the ramdisk image, if any. | 391 | * Locate which node contains the ramdisk image, if any. |
| 360 | */ | 392 | */ |
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index ad7bacc693b2..900811cc9130 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <asm/cacheflush.h> | 12 | #include <asm/cacheflush.h> |
| 13 | #include <asm/sections.h> | 13 | #include <asm/sections.h> |
| 14 | #include <asm/page.h> | 14 | #include <asm/page.h> |
| 15 | #include <asm/setup.h> | ||
| 15 | #include <asm/mach/arch.h> | 16 | #include <asm/mach/arch.h> |
| 16 | 17 | ||
| 17 | #include "mm.h" | 18 | #include "mm.h" |
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 54b1f721dec8..7d63beaf9745 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S | |||
| @@ -77,19 +77,15 @@ | |||
| 77 | * Sanity check the PTE configuration for the code below - which makes | 77 | * Sanity check the PTE configuration for the code below - which makes |
| 78 | * certain assumptions about how these bits are layed out. | 78 | * certain assumptions about how these bits are layed out. |
| 79 | */ | 79 | */ |
| 80 | #ifdef CONFIG_MMU | ||
| 80 | #if L_PTE_SHARED != PTE_EXT_SHARED | 81 | #if L_PTE_SHARED != PTE_EXT_SHARED |
| 81 | #error PTE shared bit mismatch | 82 | #error PTE shared bit mismatch |
| 82 | #endif | 83 | #endif |
| 83 | #if L_PTE_BUFFERABLE != PTE_BUFFERABLE | ||
| 84 | #error PTE bufferable bit mismatch | ||
| 85 | #endif | ||
| 86 | #if L_PTE_CACHEABLE != PTE_CACHEABLE | ||
| 87 | #error PTE cacheable bit mismatch | ||
| 88 | #endif | ||
| 89 | #if (L_PTE_EXEC+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\ | 84 | #if (L_PTE_EXEC+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\ |
| 90 | L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED | 85 | L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED |
| 91 | #error Invalid Linux PTE bit settings | 86 | #error Invalid Linux PTE bit settings |
| 92 | #endif | 87 | #endif |
| 88 | #endif /* CONFIG_MMU */ | ||
| 93 | 89 | ||
| 94 | /* | 90 | /* |
| 95 | * The ARMv6 and ARMv7 set_pte_ext translation function. | 91 | * The ARMv6 and ARMv7 set_pte_ext translation function. |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 180a08d03a03..f3fa1c32fe92 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
| @@ -127,7 +127,9 @@ ENDPROC(cpu_v7_switch_mm) | |||
| 127 | */ | 127 | */ |
| 128 | ENTRY(cpu_v7_set_pte_ext) | 128 | ENTRY(cpu_v7_set_pte_ext) |
| 129 | #ifdef CONFIG_MMU | 129 | #ifdef CONFIG_MMU |
| 130 | str r1, [r0], #-2048 @ linux version | 130 | ARM( str r1, [r0], #-2048 ) @ linux version |
| 131 | THUMB( str r1, [r0] ) @ linux version | ||
| 132 | THUMB( sub r0, r0, #2048 ) | ||
| 131 | 133 | ||
| 132 | bic r3, r1, #0x000003f0 | 134 | bic r3, r1, #0x000003f0 |
| 133 | bic r3, r3, #PTE_TYPE_MASK | 135 | bic r3, r3, #PTE_TYPE_MASK |
| @@ -232,7 +234,6 @@ __v7_setup: | |||
| 232 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 | 234 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 |
| 233 | mov r10, #0x1f @ domains 0, 1 = manager | 235 | mov r10, #0x1f @ domains 0, 1 = manager |
| 234 | mcr p15, 0, r10, c3, c0, 0 @ load domain access register | 236 | mcr p15, 0, r10, c3, c0, 0 @ load domain access register |
| 235 | #endif | ||
| 236 | /* | 237 | /* |
| 237 | * Memory region attributes with SCTLR.TRE=1 | 238 | * Memory region attributes with SCTLR.TRE=1 |
| 238 | * | 239 | * |
| @@ -265,6 +266,7 @@ __v7_setup: | |||
| 265 | ldr r6, =0x40e040e0 @ NMRR | 266 | ldr r6, =0x40e040e0 @ NMRR |
| 266 | mcr p15, 0, r5, c10, c2, 0 @ write PRRR | 267 | mcr p15, 0, r5, c10, c2, 0 @ write PRRR |
| 267 | mcr p15, 0, r6, c10, c2, 1 @ write NMRR | 268 | mcr p15, 0, r6, c10, c2, 1 @ write NMRR |
| 269 | #endif | ||
| 268 | adr r5, v7_crval | 270 | adr r5, v7_crval |
| 269 | ldmia r5, {r5, r6} | 271 | ldmia r5, {r5, r6} |
| 270 | #ifdef CONFIG_CPU_ENDIAN_BE8 | 272 | #ifdef CONFIG_CPU_ENDIAN_BE8 |
| @@ -273,6 +275,7 @@ __v7_setup: | |||
| 273 | mrc p15, 0, r0, c1, c0, 0 @ read control register | 275 | mrc p15, 0, r0, c1, c0, 0 @ read control register |
| 274 | bic r0, r0, r5 @ clear bits them | 276 | bic r0, r0, r5 @ clear bits them |
| 275 | orr r0, r0, r6 @ set them | 277 | orr r0, r0, r6 @ set them |
| 278 | THUMB( orr r0, r0, #1 << 30 ) @ Thumb exceptions | ||
| 276 | mov pc, lr @ return to head.S:__ret | 279 | mov pc, lr @ return to head.S:__ret |
| 277 | ENDPROC(__v7_setup) | 280 | ENDPROC(__v7_setup) |
| 278 | 281 | ||
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index 8986b7412235..ca5c7c226341 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig | |||
| @@ -9,6 +9,7 @@ choice | |||
| 9 | config ARCH_MX1 | 9 | config ARCH_MX1 |
| 10 | bool "MX1-based" | 10 | bool "MX1-based" |
| 11 | select CPU_ARM920T | 11 | select CPU_ARM920T |
| 12 | select COMMON_CLKDEV | ||
| 12 | help | 13 | help |
| 13 | This enables support for systems based on the Freescale i.MX1 family | 14 | This enables support for systems based on the Freescale i.MX1 family |
| 14 | 15 | ||
| @@ -19,6 +20,13 @@ config ARCH_MX2 | |||
| 19 | help | 20 | help |
| 20 | This enables support for systems based on the Freescale i.MX2 family | 21 | This enables support for systems based on the Freescale i.MX2 family |
| 21 | 22 | ||
| 23 | config ARCH_MX25 | ||
| 24 | bool "MX25-based" | ||
| 25 | select CPU_ARM926T | ||
| 26 | select COMMON_CLKDEV | ||
| 27 | help | ||
| 28 | This enables support for systems based on the Freescale i.MX25 family | ||
| 29 | |||
| 22 | config ARCH_MX3 | 30 | config ARCH_MX3 |
| 23 | bool "MX3-based" | 31 | bool "MX3-based" |
| 24 | select CPU_V6 | 32 | select CPU_V6 |
| @@ -26,11 +34,20 @@ config ARCH_MX3 | |||
| 26 | help | 34 | help |
| 27 | This enables support for systems based on the Freescale i.MX3 family | 35 | This enables support for systems based on the Freescale i.MX3 family |
| 28 | 36 | ||
| 37 | config ARCH_MXC91231 | ||
| 38 | bool "MXC91231-based" | ||
| 39 | select CPU_V6 | ||
| 40 | select COMMON_CLKDEV | ||
| 41 | help | ||
| 42 | This enables support for systems based on the Freescale MXC91231 family | ||
| 43 | |||
| 29 | endchoice | 44 | endchoice |
| 30 | 45 | ||
| 31 | source "arch/arm/mach-mx1/Kconfig" | 46 | source "arch/arm/mach-mx1/Kconfig" |
| 32 | source "arch/arm/mach-mx2/Kconfig" | 47 | source "arch/arm/mach-mx2/Kconfig" |
| 33 | source "arch/arm/mach-mx3/Kconfig" | 48 | source "arch/arm/mach-mx3/Kconfig" |
| 49 | source "arch/arm/mach-mx25/Kconfig" | ||
| 50 | source "arch/arm/mach-mxc91231/Kconfig" | ||
| 34 | 51 | ||
| 35 | endmenu | 52 | endmenu |
| 36 | 53 | ||
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c index 92e13566cd4f..9e8fbd57495c 100644 --- a/arch/arm/plat-mxc/clock.c +++ b/arch/arm/plat-mxc/clock.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
| 40 | 40 | ||
| 41 | #include <mach/clock.h> | 41 | #include <mach/clock.h> |
| 42 | #include <mach/hardware.h> | ||
| 42 | 43 | ||
| 43 | static LIST_HEAD(clocks); | 44 | static LIST_HEAD(clocks); |
| 44 | static DEFINE_MUTEX(clocks_mutex); | 45 | static DEFINE_MUTEX(clocks_mutex); |
| @@ -47,76 +48,6 @@ static DEFINE_MUTEX(clocks_mutex); | |||
| 47 | * Standard clock functions defined in include/linux/clk.h | 48 | * Standard clock functions defined in include/linux/clk.h |
| 48 | *-------------------------------------------------------------------------*/ | 49 | *-------------------------------------------------------------------------*/ |
| 49 | 50 | ||
| 50 | /* | ||
| 51 | * All the code inside #ifndef CONFIG_COMMON_CLKDEV can be removed once all | ||
| 52 | * MXC architectures have switched to using clkdev. | ||
| 53 | */ | ||
| 54 | #ifndef CONFIG_COMMON_CLKDEV | ||
| 55 | /* | ||
| 56 | * Retrieve a clock by name. | ||
| 57 | * | ||
| 58 | * Note that we first try to use device id on the bus | ||
| 59 | * and clock name. If this fails, we try to use "<name>.<id>". If this fails, | ||
| 60 | * we try to use clock name only. | ||
| 61 | * The reference count to the clock's module owner ref count is incremented. | ||
| 62 | */ | ||
| 63 | struct clk *clk_get(struct device *dev, const char *id) | ||
| 64 | { | ||
| 65 | struct clk *p, *clk = ERR_PTR(-ENOENT); | ||
| 66 | int idno; | ||
| 67 | const char *str; | ||
| 68 | |||
| 69 | if (id == NULL) | ||
| 70 | return clk; | ||
| 71 | |||
| 72 | if (dev == NULL || dev->bus != &platform_bus_type) | ||
| 73 | idno = -1; | ||
| 74 | else | ||
| 75 | idno = to_platform_device(dev)->id; | ||
| 76 | |||
| 77 | mutex_lock(&clocks_mutex); | ||
| 78 | |||
| 79 | list_for_each_entry(p, &clocks, node) { | ||
| 80 | if (p->id == idno && | ||
| 81 | strcmp(id, p->name) == 0 && try_module_get(p->owner)) { | ||
| 82 | clk = p; | ||
| 83 | goto found; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | str = strrchr(id, '.'); | ||
| 88 | if (str) { | ||
| 89 | int cnt = str - id; | ||
| 90 | str++; | ||
| 91 | idno = simple_strtol(str, NULL, 10); | ||
| 92 | list_for_each_entry(p, &clocks, node) { | ||
| 93 | if (p->id == idno && | ||
| 94 | strlen(p->name) == cnt && | ||
| 95 | strncmp(id, p->name, cnt) == 0 && | ||
| 96 | try_module_get(p->owner)) { | ||
| 97 | clk = p; | ||
| 98 | goto found; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | list_for_each_entry(p, &clocks, node) { | ||
| 104 | if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { | ||
| 105 | clk = p; | ||
| 106 | goto found; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | printk(KERN_WARNING "clk: Unable to get requested clock: %s\n", id); | ||
| 111 | |||
| 112 | found: | ||
| 113 | mutex_unlock(&clocks_mutex); | ||
| 114 | |||
| 115 | return clk; | ||
| 116 | } | ||
| 117 | EXPORT_SYMBOL(clk_get); | ||
| 118 | #endif | ||
| 119 | |||
| 120 | static void __clk_disable(struct clk *clk) | 51 | static void __clk_disable(struct clk *clk) |
| 121 | { | 52 | { |
| 122 | if (clk == NULL || IS_ERR(clk)) | 53 | if (clk == NULL || IS_ERR(clk)) |
| @@ -193,16 +124,6 @@ unsigned long clk_get_rate(struct clk *clk) | |||
| 193 | } | 124 | } |
| 194 | EXPORT_SYMBOL(clk_get_rate); | 125 | EXPORT_SYMBOL(clk_get_rate); |
| 195 | 126 | ||
| 196 | #ifndef CONFIG_COMMON_CLKDEV | ||
| 197 | /* Decrement the clock's module reference count */ | ||
| 198 | void clk_put(struct clk *clk) | ||
| 199 | { | ||
| 200 | if (clk && !IS_ERR(clk)) | ||
| 201 | module_put(clk->owner); | ||
| 202 | } | ||
| 203 | EXPORT_SYMBOL(clk_put); | ||
| 204 | #endif | ||
| 205 | |||
| 206 | /* Round the requested clock rate to the nearest supported | 127 | /* Round the requested clock rate to the nearest supported |
| 207 | * rate that is less than or equal to the requested rate. | 128 | * rate that is less than or equal to the requested rate. |
| 208 | * This is dependent on the clock's current parent. | 129 | * This is dependent on the clock's current parent. |
| @@ -265,80 +186,6 @@ struct clk *clk_get_parent(struct clk *clk) | |||
| 265 | } | 186 | } |
| 266 | EXPORT_SYMBOL(clk_get_parent); | 187 | EXPORT_SYMBOL(clk_get_parent); |
| 267 | 188 | ||
| 268 | #ifndef CONFIG_COMMON_CLKDEV | ||
| 269 | /* | ||
| 270 | * Add a new clock to the clock tree. | ||
| 271 | */ | ||
| 272 | int clk_register(struct clk *clk) | ||
| 273 | { | ||
| 274 | if (clk == NULL || IS_ERR(clk)) | ||
| 275 | return -EINVAL; | ||
| 276 | |||
| 277 | mutex_lock(&clocks_mutex); | ||
| 278 | list_add(&clk->node, &clocks); | ||
| 279 | mutex_unlock(&clocks_mutex); | ||
| 280 | |||
| 281 | return 0; | ||
| 282 | } | ||
| 283 | EXPORT_SYMBOL(clk_register); | ||
| 284 | |||
| 285 | /* Remove a clock from the clock tree */ | ||
| 286 | void clk_unregister(struct clk *clk) | ||
| 287 | { | ||
| 288 | if (clk == NULL || IS_ERR(clk)) | ||
| 289 | return; | ||
| 290 | |||
| 291 | mutex_lock(&clocks_mutex); | ||
| 292 | list_del(&clk->node); | ||
| 293 | mutex_unlock(&clocks_mutex); | ||
| 294 | } | ||
| 295 | EXPORT_SYMBOL(clk_unregister); | ||
| 296 | |||
| 297 | #ifdef CONFIG_PROC_FS | ||
| 298 | static int mxc_clock_read_proc(char *page, char **start, off_t off, | ||
| 299 | int count, int *eof, void *data) | ||
| 300 | { | ||
| 301 | struct clk *clkp; | ||
| 302 | char *p = page; | ||
| 303 | int len; | ||
| 304 | |||
| 305 | list_for_each_entry(clkp, &clocks, node) { | ||
| 306 | p += sprintf(p, "%s-%d:\t\t%lu, %d", clkp->name, clkp->id, | ||
| 307 | clk_get_rate(clkp), clkp->usecount); | ||
| 308 | if (clkp->parent) | ||
| 309 | p += sprintf(p, ", %s-%d\n", clkp->parent->name, | ||
| 310 | clkp->parent->id); | ||
| 311 | else | ||
| 312 | p += sprintf(p, "\n"); | ||
| 313 | } | ||
| 314 | |||
| 315 | len = (p - page) - off; | ||
| 316 | if (len < 0) | ||
| 317 | len = 0; | ||
| 318 | |||
| 319 | *eof = (len <= count) ? 1 : 0; | ||
| 320 | *start = page + off; | ||
| 321 | |||
| 322 | return len; | ||
| 323 | } | ||
| 324 | |||
| 325 | static int __init mxc_setup_proc_entry(void) | ||
| 326 | { | ||
| 327 | struct proc_dir_entry *res; | ||
| 328 | |||
| 329 | res = create_proc_read_entry("cpu/clocks", 0, NULL, | ||
| 330 | mxc_clock_read_proc, NULL); | ||
| 331 | if (!res) { | ||
| 332 | printk(KERN_ERR "Failed to create proc/cpu/clocks\n"); | ||
| 333 | return -ENOMEM; | ||
| 334 | } | ||
| 335 | return 0; | ||
| 336 | } | ||
| 337 | |||
| 338 | late_initcall(mxc_setup_proc_entry); | ||
| 339 | #endif /* CONFIG_PROC_FS */ | ||
| 340 | #endif | ||
| 341 | |||
| 342 | /* | 189 | /* |
| 343 | * Get the resulting clock rate from a PLL register value and the input | 190 | * Get the resulting clock rate from a PLL register value and the input |
| 344 | * frequency. PLLs with this register layout can at least be found on | 191 | * frequency. PLLs with this register layout can at least be found on |
| @@ -363,12 +210,11 @@ unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq) | |||
| 363 | 210 | ||
| 364 | mfn_abs = mfn; | 211 | mfn_abs = mfn; |
| 365 | 212 | ||
| 366 | #if !defined CONFIG_ARCH_MX1 && !defined CONFIG_ARCH_MX21 | 213 | /* On all i.MXs except i.MX1 and i.MX21 mfn is a 10bit |
| 367 | if (mfn >= 0x200) { | 214 | * 2's complements number |
| 368 | mfn |= 0xFFFFFE00; | 215 | */ |
| 369 | mfn_abs = -mfn; | 216 | if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200) |
| 370 | } | 217 | mfn_abs = 0x400 - mfn; |
| 371 | #endif | ||
| 372 | 218 | ||
| 373 | freq *= 2; | 219 | freq *= 2; |
| 374 | freq /= pd + 1; | 220 | freq /= pd + 1; |
| @@ -376,8 +222,10 @@ unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq) | |||
| 376 | ll = (unsigned long long)freq * mfn_abs; | 222 | ll = (unsigned long long)freq * mfn_abs; |
| 377 | 223 | ||
| 378 | do_div(ll, mfd + 1); | 224 | do_div(ll, mfd + 1); |
| 379 | if (mfn < 0) | 225 | |
| 226 | if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200) | ||
| 380 | ll = -ll; | 227 | ll = -ll; |
| 228 | |||
| 381 | ll = (freq * mfi) + ll; | 229 | ll = (freq * mfi) + ll; |
| 382 | 230 | ||
| 383 | return ll; | 231 | return ll; |
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c index 7506d963be4b..cfc4a8b43e6a 100644 --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c | |||
| @@ -29,6 +29,23 @@ | |||
| 29 | static struct mxc_gpio_port *mxc_gpio_ports; | 29 | static struct mxc_gpio_port *mxc_gpio_ports; |
| 30 | static int gpio_table_size; | 30 | static int gpio_table_size; |
| 31 | 31 | ||
| 32 | #define cpu_is_mx1_mx2() (cpu_is_mx1() || cpu_is_mx2()) | ||
| 33 | |||
| 34 | #define GPIO_DR (cpu_is_mx1_mx2() ? 0x1c : 0x00) | ||
| 35 | #define GPIO_GDIR (cpu_is_mx1_mx2() ? 0x00 : 0x04) | ||
| 36 | #define GPIO_PSR (cpu_is_mx1_mx2() ? 0x24 : 0x08) | ||
| 37 | #define GPIO_ICR1 (cpu_is_mx1_mx2() ? 0x28 : 0x0C) | ||
| 38 | #define GPIO_ICR2 (cpu_is_mx1_mx2() ? 0x2C : 0x10) | ||
| 39 | #define GPIO_IMR (cpu_is_mx1_mx2() ? 0x30 : 0x14) | ||
| 40 | #define GPIO_ISR (cpu_is_mx1_mx2() ? 0x34 : 0x18) | ||
| 41 | #define GPIO_ISR (cpu_is_mx1_mx2() ? 0x34 : 0x18) | ||
| 42 | |||
| 43 | #define GPIO_INT_LOW_LEV (cpu_is_mx1_mx2() ? 0x3 : 0x0) | ||
| 44 | #define GPIO_INT_HIGH_LEV (cpu_is_mx1_mx2() ? 0x2 : 0x1) | ||
| 45 | #define GPIO_INT_RISE_EDGE (cpu_is_mx1_mx2() ? 0x0 : 0x2) | ||
| 46 | #define GPIO_INT_FALL_EDGE (cpu_is_mx1_mx2() ? 0x1 : 0x3) | ||
| 47 | #define GPIO_INT_NONE 0x4 | ||
| 48 | |||
| 32 | /* Note: This driver assumes 32 GPIOs are handled in one register */ | 49 | /* Note: This driver assumes 32 GPIOs are handled in one register */ |
| 33 | 50 | ||
| 34 | static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index) | 51 | static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index) |
| @@ -162,7 +179,6 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) | |||
| 162 | } | 179 | } |
| 163 | } | 180 | } |
| 164 | 181 | ||
| 165 | #if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX1) | ||
| 166 | /* MX1 and MX3 has one interrupt *per* gpio port */ | 182 | /* MX1 and MX3 has one interrupt *per* gpio port */ |
| 167 | static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) | 183 | static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) |
| 168 | { | 184 | { |
| @@ -174,9 +190,7 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) | |||
| 174 | 190 | ||
| 175 | mxc_gpio_irq_handler(port, irq_stat); | 191 | mxc_gpio_irq_handler(port, irq_stat); |
| 176 | } | 192 | } |
| 177 | #endif | ||
| 178 | 193 | ||
| 179 | #ifdef CONFIG_ARCH_MX2 | ||
| 180 | /* MX2 has one interrupt *for all* gpio ports */ | 194 | /* MX2 has one interrupt *for all* gpio ports */ |
| 181 | static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) | 195 | static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) |
| 182 | { | 196 | { |
| @@ -195,7 +209,6 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) | |||
| 195 | mxc_gpio_irq_handler(&port[i], irq_stat); | 209 | mxc_gpio_irq_handler(&port[i], irq_stat); |
| 196 | } | 210 | } |
| 197 | } | 211 | } |
| 198 | #endif | ||
| 199 | 212 | ||
| 200 | static struct irq_chip gpio_irq_chip = { | 213 | static struct irq_chip gpio_irq_chip = { |
| 201 | .ack = gpio_ack_irq, | 214 | .ack = gpio_ack_irq, |
| @@ -284,17 +297,18 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) | |||
| 284 | /* its a serious configuration bug when it fails */ | 297 | /* its a serious configuration bug when it fails */ |
| 285 | BUG_ON( gpiochip_add(&port[i].chip) < 0 ); | 298 | BUG_ON( gpiochip_add(&port[i].chip) < 0 ); |
| 286 | 299 | ||
| 287 | #if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX1) | 300 | if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25()) { |
| 288 | /* setup one handler for each entry */ | 301 | /* setup one handler for each entry */ |
| 289 | set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler); | 302 | set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler); |
| 290 | set_irq_data(port[i].irq, &port[i]); | 303 | set_irq_data(port[i].irq, &port[i]); |
| 291 | #endif | 304 | } |
| 305 | } | ||
| 306 | |||
| 307 | if (cpu_is_mx2()) { | ||
| 308 | /* setup one handler for all GPIO interrupts */ | ||
| 309 | set_irq_chained_handler(port[0].irq, mx2_gpio_irq_handler); | ||
| 310 | set_irq_data(port[0].irq, port); | ||
| 292 | } | 311 | } |
| 293 | 312 | ||
| 294 | #ifdef CONFIG_ARCH_MX2 | ||
| 295 | /* setup one handler for all GPIO interrupts */ | ||
| 296 | set_irq_chained_handler(port[0].irq, mx2_gpio_irq_handler); | ||
| 297 | set_irq_data(port[0].irq, port); | ||
| 298 | #endif | ||
| 299 | return 0; | 313 | return 0; |
| 300 | } | 314 | } |
diff --git a/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h b/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h index 8769e910e559..0376c133c9f4 100644 --- a/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h +++ b/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h | |||
| @@ -12,11 +12,4 @@ | |||
| 12 | #ifndef __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__ | 12 | #ifndef __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__ |
| 13 | #define __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__ | 13 | #define __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__ |
| 14 | 14 | ||
| 15 | #include <mach/hardware.h> | ||
| 16 | |||
| 17 | /* mandatory for CONFIG_DEBUG_LL */ | ||
| 18 | |||
| 19 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 20 | #define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 21 | |||
| 22 | #endif | 15 | #endif |
diff --git a/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h b/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h new file mode 100644 index 000000000000..a1fd5830af48 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 Eric Benard - eric@eukrea.com | ||
| 3 | * | ||
| 4 | * Based on board-pcm038.h which is : | ||
| 5 | * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version 2 | ||
| 10 | * of the License, or (at your option) any later version. | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
| 19 | * MA 02110-1301, USA. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #ifndef __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX27_H__ | ||
| 23 | #define __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX27_H__ | ||
| 24 | |||
| 25 | #ifndef __ASSEMBLY__ | ||
| 26 | /* | ||
| 27 | * This CPU module needs a baseboard to work. After basic initializing | ||
| 28 | * its own devices, it calls baseboard's init function. | ||
| 29 | * TODO: Add your own baseboard init function and call it from | ||
| 30 | * inside eukrea_cpuimx27_init(). | ||
| 31 | * | ||
| 32 | * This example here is for the development board. Refer | ||
| 33 | * eukrea_mbimx27-baseboard.c | ||
| 34 | */ | ||
| 35 | |||
| 36 | extern void eukrea_mbimx27_baseboard_init(void); | ||
| 37 | |||
| 38 | #endif | ||
| 39 | |||
| 40 | #endif /* __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX27_H__ */ | ||
diff --git a/arch/arm/plat-mxc/include/mach/board-mx21ads.h b/arch/arm/plat-mxc/include/mach/board-mx21ads.h index 06701df74c42..0cf4fa29510c 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx21ads.h +++ b/arch/arm/plat-mxc/include/mach/board-mx21ads.h | |||
| @@ -15,12 +15,6 @@ | |||
| 15 | #define __ASM_ARCH_MXC_BOARD_MX21ADS_H__ | 15 | #define __ASM_ARCH_MXC_BOARD_MX21ADS_H__ |
| 16 | 16 | ||
| 17 | /* | 17 | /* |
| 18 | * MXC UART EVB board level configurations | ||
| 19 | */ | ||
| 20 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 21 | #define MXC_LL_UART_VADDR AIPI_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Memory-mapped I/O on MX21ADS base board | 18 | * Memory-mapped I/O on MX21ADS base board |
| 25 | */ | 19 | */ |
| 26 | #define MX21ADS_MMIO_BASE_ADDR 0xF5000000 | 20 | #define MX21ADS_MMIO_BASE_ADDR 0xF5000000 |
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27ads.h b/arch/arm/plat-mxc/include/mach/board-mx27ads.h index d42f4e6116f8..7776d230327f 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx27ads.h +++ b/arch/arm/plat-mxc/include/mach/board-mx27ads.h | |||
| @@ -26,12 +26,6 @@ | |||
| 26 | MXC_MAX_VIRTUAL_INTS) | 26 | MXC_MAX_VIRTUAL_INTS) |
| 27 | 27 | ||
| 28 | /* | 28 | /* |
| 29 | * MXC UART EVB board level configurations | ||
| 30 | */ | ||
| 31 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 32 | #define MXC_LL_UART_VADDR AIPI_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 33 | |||
| 34 | /* | ||
| 35 | * @name Memory Size parameters | 29 | * @name Memory Size parameters |
| 36 | */ | 30 | */ |
| 37 | 31 | ||
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27lite.h b/arch/arm/plat-mxc/include/mach/board-mx27lite.h index a870f8ea2443..ea87551d2736 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx27lite.h +++ b/arch/arm/plat-mxc/include/mach/board-mx27lite.h | |||
| @@ -11,9 +11,4 @@ | |||
| 11 | #ifndef __ASM_ARCH_MXC_BOARD_MX27LITE_H__ | 11 | #ifndef __ASM_ARCH_MXC_BOARD_MX27LITE_H__ |
| 12 | #define __ASM_ARCH_MXC_BOARD_MX27LITE_H__ | 12 | #define __ASM_ARCH_MXC_BOARD_MX27LITE_H__ |
| 13 | 13 | ||
| 14 | /* mandatory for CONFIG_DEBUG_LL */ | ||
| 15 | |||
| 16 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 17 | #define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 18 | |||
| 19 | #endif /* __ASM_ARCH_MXC_BOARD_MX27LITE_H__ */ | 14 | #endif /* __ASM_ARCH_MXC_BOARD_MX27LITE_H__ */ |
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27pdk.h b/arch/arm/plat-mxc/include/mach/board-mx27pdk.h index 552b55d714d8..fec1bcfa9164 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx27pdk.h +++ b/arch/arm/plat-mxc/include/mach/board-mx27pdk.h | |||
| @@ -11,9 +11,4 @@ | |||
| 11 | #ifndef __ASM_ARCH_MXC_BOARD_MX27PDK_H__ | 11 | #ifndef __ASM_ARCH_MXC_BOARD_MX27PDK_H__ |
| 12 | #define __ASM_ARCH_MXC_BOARD_MX27PDK_H__ | 12 | #define __ASM_ARCH_MXC_BOARD_MX27PDK_H__ |
| 13 | 13 | ||
| 14 | /* mandatory for CONFIG_DEBUG_LL */ | ||
| 15 | |||
| 16 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 17 | #define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 18 | |||
| 19 | #endif /* __ASM_ARCH_MXC_BOARD_MX27PDK_H__ */ | 14 | #endif /* __ASM_ARCH_MXC_BOARD_MX27PDK_H__ */ |
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h index 06e6895f7f65..2cbfa35e82ff 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx31ads.h +++ b/arch/arm/plat-mxc/include/mach/board-mx31ads.h | |||
| @@ -114,9 +114,4 @@ | |||
| 114 | 114 | ||
| 115 | #define MXC_MAX_EXP_IO_LINES 16 | 115 | #define MXC_MAX_EXP_IO_LINES 16 |
| 116 | 116 | ||
| 117 | /* mandatory for CONFIG_DEBUG_LL */ | ||
| 118 | |||
| 119 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 120 | #define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 121 | |||
| 122 | #endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */ | 117 | #endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */ |
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lilly.h b/arch/arm/plat-mxc/include/mach/board-mx31lilly.h index 78cf31e22e4d..eb5a5024622e 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx31lilly.h +++ b/arch/arm/plat-mxc/include/mach/board-mx31lilly.h | |||
| @@ -22,11 +22,6 @@ | |||
| 22 | #ifndef __ASM_ARCH_MXC_BOARD_MX31LILLY_H__ | 22 | #ifndef __ASM_ARCH_MXC_BOARD_MX31LILLY_H__ |
| 23 | #define __ASM_ARCH_MXC_BOARD_MX31LILLY_H__ | 23 | #define __ASM_ARCH_MXC_BOARD_MX31LILLY_H__ |
| 24 | 24 | ||
| 25 | /* mandatory for CONFIG_LL_DEBUG */ | ||
| 26 | |||
| 27 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 28 | #define MXC_LL_UART_VADDR (AIPI_BASE_ADDR_VIRT + 0x0A000) | ||
| 29 | |||
| 30 | #ifndef __ASSEMBLY__ | 25 | #ifndef __ASSEMBLY__ |
| 31 | 26 | ||
| 32 | enum mx31lilly_boards { | 27 | enum mx31lilly_boards { |
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lite.h b/arch/arm/plat-mxc/include/mach/board-mx31lite.h index 52fbdf2d6f26..8e64325d6905 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx31lite.h +++ b/arch/arm/plat-mxc/include/mach/board-mx31lite.h | |||
| @@ -11,8 +11,5 @@ | |||
| 11 | #ifndef __ASM_ARCH_MXC_BOARD_MX31LITE_H__ | 11 | #ifndef __ASM_ARCH_MXC_BOARD_MX31LITE_H__ |
| 12 | #define __ASM_ARCH_MXC_BOARD_MX31LITE_H__ | 12 | #define __ASM_ARCH_MXC_BOARD_MX31LITE_H__ |
| 13 | 13 | ||
| 14 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 15 | #define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 16 | |||
| 17 | #endif /* __ASM_ARCH_MXC_BOARD_MX31LITE_H__ */ | 14 | #endif /* __ASM_ARCH_MXC_BOARD_MX31LITE_H__ */ |
| 18 | 15 | ||
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h index 303fd2434a21..d5be6b5a6acf 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h +++ b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h | |||
| @@ -19,11 +19,6 @@ | |||
| 19 | #ifndef __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ | 19 | #ifndef __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ |
| 20 | #define __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ | 20 | #define __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ |
| 21 | 21 | ||
| 22 | /* mandatory for CONFIG_DEBUG_LL */ | ||
| 23 | |||
| 24 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 25 | #define MXC_LL_UART_VADDR (AIPI_BASE_ADDR_VIRT + 0x0A000) | ||
| 26 | |||
| 27 | #ifndef __ASSEMBLY__ | 22 | #ifndef __ASSEMBLY__ |
| 28 | 23 | ||
| 29 | enum mx31moboard_boards { | 24 | enum mx31moboard_boards { |
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h b/arch/arm/plat-mxc/include/mach/board-mx31pdk.h index 519bab3eb28b..2bbd6ed17f50 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h +++ b/arch/arm/plat-mxc/include/mach/board-mx31pdk.h | |||
| @@ -11,11 +11,6 @@ | |||
| 11 | #ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__ | 11 | #ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__ |
| 12 | #define __ASM_ARCH_MXC_BOARD_MX31PDK_H__ | 12 | #define __ASM_ARCH_MXC_BOARD_MX31PDK_H__ |
| 13 | 13 | ||
| 14 | /* mandatory for CONFIG_DEBUG_LL */ | ||
| 15 | |||
| 16 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 17 | #define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 18 | |||
| 19 | /* Definitions for components on the Debug board */ | 14 | /* Definitions for components on the Debug board */ |
| 20 | 15 | ||
| 21 | /* Base address of CPLD controller on the Debug board */ | 16 | /* Base address of CPLD controller on the Debug board */ |
diff --git a/arch/arm/plat-mxc/include/mach/board-mx35pdk.h b/arch/arm/plat-mxc/include/mach/board-mx35pdk.h index 1111037d6d9d..383f1c04df06 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx35pdk.h +++ b/arch/arm/plat-mxc/include/mach/board-mx35pdk.h | |||
| @@ -19,9 +19,4 @@ | |||
| 19 | #ifndef __ASM_ARCH_MXC_BOARD_MX35PDK_H__ | 19 | #ifndef __ASM_ARCH_MXC_BOARD_MX35PDK_H__ |
| 20 | #define __ASM_ARCH_MXC_BOARD_MX35PDK_H__ | 20 | #define __ASM_ARCH_MXC_BOARD_MX35PDK_H__ |
| 21 | 21 | ||
| 22 | /* mandatory for CONFIG_DEBUG_LL */ | ||
| 23 | |||
| 24 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 25 | #define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 26 | |||
| 27 | #endif /* __ASM_ARCH_MXC_BOARD_MX35PDK_H__ */ | 22 | #endif /* __ASM_ARCH_MXC_BOARD_MX35PDK_H__ */ |
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm037.h b/arch/arm/plat-mxc/include/mach/board-pcm037.h index f0a1fa1938a2..13411709b13a 100644 --- a/arch/arm/plat-mxc/include/mach/board-pcm037.h +++ b/arch/arm/plat-mxc/include/mach/board-pcm037.h | |||
| @@ -19,9 +19,4 @@ | |||
| 19 | #ifndef __ASM_ARCH_MXC_BOARD_PCM037_H__ | 19 | #ifndef __ASM_ARCH_MXC_BOARD_PCM037_H__ |
| 20 | #define __ASM_ARCH_MXC_BOARD_PCM037_H__ | 20 | #define __ASM_ARCH_MXC_BOARD_PCM037_H__ |
| 21 | 21 | ||
| 22 | /* mandatory for CONFIG_DEBUG_LL */ | ||
| 23 | |||
| 24 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 25 | #define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 26 | |||
| 27 | #endif /* __ASM_ARCH_MXC_BOARD_PCM037_H__ */ | 22 | #endif /* __ASM_ARCH_MXC_BOARD_PCM037_H__ */ |
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm038.h b/arch/arm/plat-mxc/include/mach/board-pcm038.h index 4fcd7499e092..410f9786ed22 100644 --- a/arch/arm/plat-mxc/include/mach/board-pcm038.h +++ b/arch/arm/plat-mxc/include/mach/board-pcm038.h | |||
| @@ -19,11 +19,6 @@ | |||
| 19 | #ifndef __ASM_ARCH_MXC_BOARD_PCM038_H__ | 19 | #ifndef __ASM_ARCH_MXC_BOARD_PCM038_H__ |
| 20 | #define __ASM_ARCH_MXC_BOARD_PCM038_H__ | 20 | #define __ASM_ARCH_MXC_BOARD_PCM038_H__ |
| 21 | 21 | ||
| 22 | /* mandatory for CONFIG_DEBUG_LL */ | ||
| 23 | |||
| 24 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 25 | #define MXC_LL_UART_VADDR (AIPI_BASE_ADDR_VIRT + 0x0A000) | ||
| 26 | |||
| 27 | #ifndef __ASSEMBLY__ | 22 | #ifndef __ASSEMBLY__ |
| 28 | /* | 23 | /* |
| 29 | * This CPU module needs a baseboard to work. After basic initializing | 24 | * This CPU module needs a baseboard to work. After basic initializing |
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm043.h b/arch/arm/plat-mxc/include/mach/board-pcm043.h index 15fbdf16abcd..1ac4e1682e5c 100644 --- a/arch/arm/plat-mxc/include/mach/board-pcm043.h +++ b/arch/arm/plat-mxc/include/mach/board-pcm043.h | |||
| @@ -19,9 +19,4 @@ | |||
| 19 | #ifndef __ASM_ARCH_MXC_BOARD_PCM043_H__ | 19 | #ifndef __ASM_ARCH_MXC_BOARD_PCM043_H__ |
| 20 | #define __ASM_ARCH_MXC_BOARD_PCM043_H__ | 20 | #define __ASM_ARCH_MXC_BOARD_PCM043_H__ |
| 21 | 21 | ||
| 22 | /* mandatory for CONFIG_LL_DEBUG */ | ||
| 23 | |||
| 24 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 25 | #define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 26 | |||
| 27 | #endif /* __ASM_ARCH_MXC_BOARD_PCM043_H__ */ | 22 | #endif /* __ASM_ARCH_MXC_BOARD_PCM043_H__ */ |
diff --git a/arch/arm/plat-mxc/include/mach/board-qong.h b/arch/arm/plat-mxc/include/mach/board-qong.h index 04033ec637d2..6d88c7af4b23 100644 --- a/arch/arm/plat-mxc/include/mach/board-qong.h +++ b/arch/arm/plat-mxc/include/mach/board-qong.h | |||
| @@ -11,11 +11,6 @@ | |||
| 11 | #ifndef __ASM_ARCH_MXC_BOARD_QONG_H__ | 11 | #ifndef __ASM_ARCH_MXC_BOARD_QONG_H__ |
| 12 | #define __ASM_ARCH_MXC_BOARD_QONG_H__ | 12 | #define __ASM_ARCH_MXC_BOARD_QONG_H__ |
| 13 | 13 | ||
| 14 | /* mandatory for CONFIG_DEBUG_LL */ | ||
| 15 | |||
| 16 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 17 | #define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 18 | |||
| 19 | /* NOR FLASH */ | 14 | /* NOR FLASH */ |
| 20 | #define QONG_NOR_SIZE (128*1024*1024) | 15 | #define QONG_NOR_SIZE (128*1024*1024) |
| 21 | 16 | ||
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index 02c3cd004db3..286cb9b0a25b 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h | |||
| @@ -16,18 +16,33 @@ struct clk; | |||
| 16 | 16 | ||
| 17 | extern void mx1_map_io(void); | 17 | extern void mx1_map_io(void); |
| 18 | extern void mx21_map_io(void); | 18 | extern void mx21_map_io(void); |
| 19 | extern void mx25_map_io(void); | ||
| 19 | extern void mx27_map_io(void); | 20 | extern void mx27_map_io(void); |
| 20 | extern void mx31_map_io(void); | 21 | extern void mx31_map_io(void); |
| 21 | extern void mx35_map_io(void); | 22 | extern void mx35_map_io(void); |
| 22 | extern void mxc_init_irq(void); | 23 | extern void mxc91231_map_io(void); |
| 23 | extern void mxc_timer_init(struct clk *timer_clk); | 24 | extern void mxc_init_irq(void __iomem *); |
| 25 | extern void mx1_init_irq(void); | ||
| 26 | extern void mx21_init_irq(void); | ||
| 27 | extern void mx25_init_irq(void); | ||
| 28 | extern void mx27_init_irq(void); | ||
| 29 | extern void mx31_init_irq(void); | ||
| 30 | extern void mx35_init_irq(void); | ||
| 31 | extern void mxc91231_init_irq(void); | ||
| 32 | extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); | ||
| 24 | extern int mx1_clocks_init(unsigned long fref); | 33 | extern int mx1_clocks_init(unsigned long fref); |
| 25 | extern int mx21_clocks_init(unsigned long lref, unsigned long fref); | 34 | extern int mx21_clocks_init(unsigned long lref, unsigned long fref); |
| 35 | extern int mx25_clocks_init(unsigned long fref); | ||
| 26 | extern int mx27_clocks_init(unsigned long fref); | 36 | extern int mx27_clocks_init(unsigned long fref); |
| 27 | extern int mx31_clocks_init(unsigned long fref); | 37 | extern int mx31_clocks_init(unsigned long fref); |
| 28 | extern int mx35_clocks_init(void); | 38 | extern int mx35_clocks_init(void); |
| 39 | extern int mxc91231_clocks_init(unsigned long fref); | ||
| 29 | extern int mxc_register_gpios(void); | 40 | extern int mxc_register_gpios(void); |
| 30 | extern int mxc_register_device(struct platform_device *pdev, void *data); | 41 | extern int mxc_register_device(struct platform_device *pdev, void *data); |
| 31 | extern void mxc_set_cpu_type(unsigned int type); | 42 | extern void mxc_set_cpu_type(unsigned int type); |
| 43 | extern void mxc_arch_reset_init(void __iomem *); | ||
| 44 | extern void mxc91231_power_off(void); | ||
| 45 | extern void mxc91231_arch_reset(int, const char *); | ||
| 46 | extern void mxc91231_prepare_idle(void); | ||
| 32 | 47 | ||
| 33 | #endif | 48 | #endif |
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S index bbc5f6753cfb..15b2b148a105 100644 --- a/arch/arm/plat-mxc/include/mach/debug-macro.S +++ b/arch/arm/plat-mxc/include/mach/debug-macro.S | |||
| @@ -11,52 +11,52 @@ | |||
| 11 | * | 11 | * |
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <mach/hardware.h> | 14 | #ifdef CONFIG_ARCH_MX1 |
| 15 | 15 | #include <mach/mx1.h> | |
| 16 | #ifdef CONFIG_MACH_MX31ADS | 16 | #define UART_PADDR UART1_BASE_ADDR |
| 17 | #include <mach/board-mx31ads.h> | 17 | #define UART_VADDR IO_ADDRESS(UART1_BASE_ADDR) |
| 18 | #endif | ||
| 19 | #ifdef CONFIG_MACH_PCM037 | ||
| 20 | #include <mach/board-pcm037.h> | ||
| 21 | #endif | ||
| 22 | #ifdef CONFIG_MACH_MX31LITE | ||
| 23 | #include <mach/board-mx31lite.h> | ||
| 24 | #endif | ||
| 25 | #ifdef CONFIG_MACH_MX27ADS | ||
| 26 | #include <mach/board-mx27ads.h> | ||
| 27 | #endif | ||
| 28 | #ifdef CONFIG_MACH_MX21ADS | ||
| 29 | #include <mach/board-mx21ads.h> | ||
| 30 | #endif | 18 | #endif |
| 31 | #ifdef CONFIG_MACH_PCM038 | 19 | |
| 32 | #include <mach/board-pcm038.h> | 20 | #ifdef CONFIG_ARCH_MX25 |
| 21 | #ifdef UART_PADDR | ||
| 22 | #error "CONFIG_DEBUG_LL is incompatible with multiple archs" | ||
| 33 | #endif | 23 | #endif |
| 34 | #ifdef CONFIG_MACH_MX31_3DS | 24 | #include <mach/mx25.h> |
| 35 | #include <mach/board-mx31pdk.h> | 25 | #define UART_PADDR UART1_BASE_ADDR |
| 26 | #define UART_VADDR MX25_AIPS1_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 36 | #endif | 27 | #endif |
| 37 | #ifdef CONFIG_MACH_QONG | 28 | |
| 38 | #include <mach/board-qong.h> | 29 | #ifdef CONFIG_ARCH_MX2 |
| 30 | #ifdef UART_PADDR | ||
| 31 | #error "CONFIG_DEBUG_LL is incompatible with multiple archs" | ||
| 39 | #endif | 32 | #endif |
| 40 | #ifdef CONFIG_MACH_PCM043 | 33 | #include <mach/mx2x.h> |
| 41 | #include <mach/board-pcm043.h> | 34 | #define UART_PADDR UART1_BASE_ADDR |
| 35 | #define UART_VADDR AIPI_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 42 | #endif | 36 | #endif |
| 43 | #ifdef CONFIG_MACH_MX27_3DS | 37 | |
| 44 | #include <mach/board-mx27pdk.h> | 38 | #ifdef CONFIG_ARCH_MX3 |
| 39 | #ifdef UART_PADDR | ||
| 40 | #error "CONFIG_DEBUG_LL is incompatible with multiple archs" | ||
| 45 | #endif | 41 | #endif |
| 46 | #ifdef CONFIG_MACH_ARMADILLO5X0 | 42 | #include <mach/mx3x.h> |
| 47 | #include <mach/board-armadillo5x0.h> | 43 | #define UART_PADDR UART1_BASE_ADDR |
| 44 | #define UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) | ||
| 48 | #endif | 45 | #endif |
| 49 | #ifdef CONFIG_MACH_MX35_3DS | 46 | |
| 50 | #include <mach/board-mx35pdk.h> | 47 | #ifdef CONFIG_ARCH_MXC91231 |
| 48 | #ifdef UART_PADDR | ||
| 49 | #error "CONFIG_DEBUG_LL is incompatible with multiple archs" | ||
| 51 | #endif | 50 | #endif |
| 52 | #ifdef CONFIG_MACH_MX27LITE | 51 | #include <mach/mxc91231.h> |
| 53 | #include <mach/board-mx27lite.h> | 52 | #define UART_PADDR MXC91231_UART2_BASE_ADDR |
| 53 | #define UART_VADDR MXC91231_AIPS1_IO_ADDRESS(MXC91231_UART2_BASE_ADDR) | ||
| 54 | #endif | 54 | #endif |
| 55 | .macro addruart,rx | 55 | .macro addruart,rx |
| 56 | mrc p15, 0, \rx, c1, c0 | 56 | mrc p15, 0, \rx, c1, c0 |
| 57 | tst \rx, #1 @ MMU enabled? | 57 | tst \rx, #1 @ MMU enabled? |
| 58 | ldreq \rx, =MXC_LL_UART_PADDR @ physical | 58 | ldreq \rx, =UART_PADDR @ physical |
| 59 | ldrne \rx, =MXC_LL_UART_VADDR @ virtual | 59 | ldrne \rx, =UART_VADDR @ virtual |
| 60 | .endm | 60 | .endm |
| 61 | 61 | ||
| 62 | .macro senduart,rd,rx | 62 | .macro senduart,rd,rx |
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S index 5f01d60da845..7cf290efe768 100644 --- a/arch/arm/plat-mxc/include/mach/entry-macro.S +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S | |||
| @@ -18,7 +18,8 @@ | |||
| 18 | .endm | 18 | .endm |
| 19 | 19 | ||
| 20 | .macro get_irqnr_preamble, base, tmp | 20 | .macro get_irqnr_preamble, base, tmp |
| 21 | ldr \base, =AVIC_IO_ADDRESS(AVIC_BASE_ADDR) | 21 | ldr \base, =avic_base |
| 22 | ldr \base, [\base] | ||
| 22 | #ifdef CONFIG_MXC_IRQ_PRIOR | 23 | #ifdef CONFIG_MXC_IRQ_PRIOR |
| 23 | ldr r4, [\base, #AVIC_NIMASK] | 24 | ldr r4, [\base, #AVIC_NIMASK] |
| 24 | #endif | 25 | #endif |
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h index 42e4ee37ca1f..78db75475f69 100644 --- a/arch/arm/plat-mxc/include/mach/hardware.h +++ b/arch/arm/plat-mxc/include/mach/hardware.h | |||
| @@ -42,6 +42,14 @@ | |||
| 42 | # include <mach/mx1.h> | 42 | # include <mach/mx1.h> |
| 43 | #endif | 43 | #endif |
| 44 | 44 | ||
| 45 | #ifdef CONFIG_ARCH_MX25 | ||
| 46 | # include <mach/mx25.h> | ||
| 47 | #endif | ||
| 48 | |||
| 49 | #ifdef CONFIG_ARCH_MXC91231 | ||
| 50 | # include <mach/mxc91231.h> | ||
| 51 | #endif | ||
| 52 | |||
| 45 | #include <mach/mxc.h> | 53 | #include <mach/mxc.h> |
| 46 | 54 | ||
| 47 | #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */ | 55 | #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */ |
diff --git a/arch/arm/plat-mxc/include/mach/imxfb.h b/arch/arm/plat-mxc/include/mach/imxfb.h index 9f0101157ec1..5263506b7ddf 100644 --- a/arch/arm/plat-mxc/include/mach/imxfb.h +++ b/arch/arm/plat-mxc/include/mach/imxfb.h | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | * This structure describes the machine which we are running on. | 2 | * This structure describes the machine which we are running on. |
| 3 | */ | 3 | */ |
| 4 | 4 | ||
| 5 | #include <linux/fb.h> | ||
| 6 | |||
| 5 | #define PCR_TFT (1 << 31) | 7 | #define PCR_TFT (1 << 31) |
| 6 | #define PCR_COLOR (1 << 30) | 8 | #define PCR_COLOR (1 << 30) |
| 7 | #define PCR_PBSIZ_1 (0 << 28) | 9 | #define PCR_PBSIZ_1 (0 << 28) |
| @@ -13,7 +15,8 @@ | |||
| 13 | #define PCR_BPIX_4 (2 << 25) | 15 | #define PCR_BPIX_4 (2 << 25) |
| 14 | #define PCR_BPIX_8 (3 << 25) | 16 | #define PCR_BPIX_8 (3 << 25) |
| 15 | #define PCR_BPIX_12 (4 << 25) | 17 | #define PCR_BPIX_12 (4 << 25) |
| 16 | #define PCR_BPIX_16 (4 << 25) | 18 | #define PCR_BPIX_16 (5 << 25) |
| 19 | #define PCR_BPIX_18 (6 << 25) | ||
| 17 | #define PCR_PIXPOL (1 << 24) | 20 | #define PCR_PIXPOL (1 << 24) |
| 18 | #define PCR_FLMPOL (1 << 23) | 21 | #define PCR_FLMPOL (1 << 23) |
| 19 | #define PCR_LPPOL (1 << 22) | 22 | #define PCR_LPPOL (1 << 22) |
| @@ -46,29 +49,21 @@ | |||
| 46 | #define DMACR_HM(x) (((x) & 0xf) << 16) | 49 | #define DMACR_HM(x) (((x) & 0xf) << 16) |
| 47 | #define DMACR_TM(x) ((x) & 0xf) | 50 | #define DMACR_TM(x) ((x) & 0xf) |
| 48 | 51 | ||
| 49 | struct imx_fb_platform_data { | 52 | struct imx_fb_videomode { |
| 50 | u_long pixclock; | 53 | struct fb_videomode mode; |
| 51 | 54 | u32 pcr; | |
| 52 | u_short xres; | 55 | unsigned char bpp; |
| 53 | u_short yres; | 56 | }; |
| 54 | |||
| 55 | u_int nonstd; | ||
| 56 | u_char bpp; | ||
| 57 | u_char hsync_len; | ||
| 58 | u_char left_margin; | ||
| 59 | u_char right_margin; | ||
| 60 | 57 | ||
| 61 | u_char vsync_len; | 58 | struct imx_fb_platform_data { |
| 62 | u_char upper_margin; | 59 | struct imx_fb_videomode *mode; |
| 63 | u_char lower_margin; | 60 | int num_modes; |
| 64 | u_char sync; | ||
| 65 | 61 | ||
| 66 | u_int cmap_greyscale:1, | 62 | u_int cmap_greyscale:1, |
| 67 | cmap_inverse:1, | 63 | cmap_inverse:1, |
| 68 | cmap_static:1, | 64 | cmap_static:1, |
| 69 | unused:29; | 65 | unused:29; |
| 70 | 66 | ||
| 71 | u_int pcr; | ||
| 72 | u_int pwmr; | 67 | u_int pwmr; |
| 73 | u_int lscr1; | 68 | u_int lscr1; |
| 74 | u_int dmacr; | 69 | u_int dmacr; |
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h b/arch/arm/plat-mxc/include/mach/iomux-mx25.h new file mode 100644 index 000000000000..810c47f56e77 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/iomux-mx25.h | |||
| @@ -0,0 +1,517 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/plat-mxc/include/mach/iomux-mx25.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 by Lothar Wassmann <LW@KARO-electronics.de> | ||
| 5 | * | ||
| 6 | * based on arch/arm/mach-mx25/mx25_pins.h | ||
| 7 | * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 8 | * and | ||
| 9 | * arch/arm/plat-mxc/include/mach/iomux-mx35.h | ||
| 10 | * Copyright (C, NO_PAD_CTRL) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de> | ||
| 11 | * | ||
| 12 | * The code contained herein is licensed under the GNU General Public | ||
| 13 | * License. You may obtain a copy of the GNU General Public License | ||
| 14 | * Version 2 or later at the following locations: | ||
| 15 | * | ||
| 16 | * http://www.opensource.org/licenses/gpl-license.html | ||
| 17 | * http://www.gnu.org/copyleft/gpl.html | ||
| 18 | */ | ||
| 19 | #ifndef __IOMUX_MX25_H__ | ||
| 20 | #define __IOMUX_MX25_H__ | ||
| 21 | |||
| 22 | #include <mach/iomux-v3.h> | ||
| 23 | |||
| 24 | #ifndef GPIO_PORTA | ||
| 25 | #error Please include mach/iomux.h | ||
| 26 | #endif | ||
| 27 | |||
| 28 | /* | ||
| 29 | * | ||
| 30 | * @brief MX25 I/O Pin List | ||
| 31 | * | ||
| 32 | * @ingroup GPIO_MX25 | ||
| 33 | */ | ||
| 34 | |||
| 35 | #ifndef __ASSEMBLY__ | ||
| 36 | |||
| 37 | /* | ||
| 38 | * IOMUX/PAD Bit field definitions | ||
| 39 | */ | ||
| 40 | |||
| 41 | #define MX25_PAD_A10__A10 IOMUX_PAD(0x000, 0x008, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 42 | #define MX25_PAD_A10__GPIO_4_0 IOMUX_PAD(0x000, 0x008, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 43 | |||
| 44 | #define MX25_PAD_A13__A13 IOMUX_PAD(0x22C, 0x00c, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 45 | #define MX25_PAD_A13__GPIO_4_1 IOMUX_PAD(0x22C, 0x00c, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 46 | |||
| 47 | #define MX25_PAD_A14__A14 IOMUX_PAD(0x230, 0x010, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 48 | #define MX25_PAD_A14__GPIO_2_0 IOMUX_PAD(0x230, 0x010, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 49 | |||
| 50 | #define MX25_PAD_A15__A15 IOMUX_PAD(0x234, 0x014, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 51 | #define MX25_PAD_A15__GPIO_2_1 IOMUX_PAD(0x234, 0x014, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 52 | |||
| 53 | #define MX25_PAD_A16__A16 IOMUX_PAD(0x000, 0x018, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 54 | #define MX25_PAD_A16__GPIO_2_2 IOMUX_PAD(0x000, 0x018, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 55 | |||
| 56 | #define MX25_PAD_A17__A17 IOMUX_PAD(0x238, 0x01c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 57 | #define MX25_PAD_A17__GPIO_2_3 IOMUX_PAD(0x238, 0x01c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 58 | |||
| 59 | #define MX25_PAD_A18__A18 IOMUX_PAD(0x23c, 0x020, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 60 | #define MX25_PAD_A18__GPIO_2_4 IOMUX_PAD(0x23c, 0x020, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 61 | #define MX25_PAD_A18__FEC_COL IOMUX_PAD(0x23c, 0x020, 0x17, 0x504, 0, NO_PAD_CTL) | ||
| 62 | |||
| 63 | #define MX25_PAD_A19__A19 IOMUX_PAD(0x240, 0x024, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 64 | #define MX25_PAD_A19__FEC_RX_ER IOMUX_PAD(0x240, 0x024, 0x17, 0x518, 0, NO_PAD_CTL) | ||
| 65 | #define MX25_PAD_A19__GPIO_2_5 IOMUX_PAD(0x240, 0x024, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 66 | |||
| 67 | #define MX25_PAD_A20__A20 IOMUX_PAD(0x244, 0x028, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 68 | #define MX25_PAD_A20__GPIO_2_6 IOMUX_PAD(0x244, 0x028, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 69 | #define MX25_PAD_A20__FEC_RDATA2 IOMUX_PAD(0x244, 0x028, 0x17, 0x50c, 0, NO_PAD_CTL) | ||
| 70 | |||
| 71 | #define MX25_PAD_A21__A21 IOMUX_PAD(0x248, 0x02c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 72 | #define MX25_PAD_A21__GPIO_2_7 IOMUX_PAD(0x248, 0x02c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 73 | #define MX25_PAD_A21__FEC_RDATA3 IOMUX_PAD(0x248, 0x02c, 0x17, 0x510, 0, NO_PAD_CTL) | ||
| 74 | |||
| 75 | #define MX25_PAD_A22__A22 IOMUX_PAD(0x000, 0x030, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 76 | #define MX25_PAD_A22__GPIO_2_8 IOMUX_PAD(0x000, 0x030, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 77 | |||
| 78 | #define MX25_PAD_A23__A23 IOMUX_PAD(0x24c, 0x034, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 79 | #define MX25_PAD_A23__GPIO_2_9 IOMUX_PAD(0x24c, 0x034, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 80 | |||
| 81 | #define MX25_PAD_A24__A24 IOMUX_PAD(0x250, 0x038, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 82 | #define MX25_PAD_A24__GPIO_2_10 IOMUX_PAD(0x250, 0x038, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 83 | #define MX25_PAD_A24__FEC_RX_CLK IOMUX_PAD(0x250, 0x038, 0x17, 0x514, 0, NO_PAD_CTL) | ||
| 84 | |||
| 85 | #define MX25_PAD_A25__A25 IOMUX_PAD(0x254, 0x03c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 86 | #define MX25_PAD_A25__GPIO_2_11 IOMUX_PAD(0x254, 0x03c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 87 | #define MX25_PAD_A25__FEC_CRS IOMUX_PAD(0x254, 0x03c, 0x17, 0x508, 0, NO_PAD_CTL) | ||
| 88 | |||
| 89 | #define MX25_PAD_EB0__EB0 IOMUX_PAD(0x258, 0x040, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 90 | #define MX25_PAD_EB0__AUD4_TXD IOMUX_PAD(0x258, 0x040, 0x14, 0x464, 0, NO_PAD_CTRL) | ||
| 91 | #define MX25_PAD_EB0__GPIO_2_12 IOMUX_PAD(0x258, 0x040, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 92 | |||
| 93 | #define MX25_PAD_EB1__EB1 IOMUX_PAD(0x25c, 0x044, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 94 | #define MX25_PAD_EB1__AUD4_RXD IOMUX_PAD(0x25c, 0x044, 0x14, 0x460, 0, NO_PAD_CTRL) | ||
| 95 | #define MX25_PAD_EB1__GPIO_2_13 IOMUX_PAD(0x25c, 0x044, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 96 | |||
| 97 | #define MX25_PAD_OE__OE IOMUX_PAD(0x260, 0x048, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 98 | #define MX25_PAD_OE__AUD4_TXC IOMUX_PAD(0x260, 0x048, 0x14, 0, 0, NO_PAD_CTRL) | ||
| 99 | #define MX25_PAD_OE__GPIO_2_14 IOMUX_PAD(0x260, 0x048, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 100 | |||
| 101 | #define MX25_PAD_CS0__CS0 IOMUX_PAD(0x000, 0x04c, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 102 | #define MX25_PAD_CS0__GPIO_4_2 IOMUX_PAD(0x000, 0x04c, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 103 | |||
| 104 | #define MX25_PAD_CS1__CS1 IOMUX_PAD(0x000, 0x050, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 105 | #define MX25_PAD_CS1__GPIO_4_3 IOMUX_PAD(0x000, 0x050, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 106 | |||
| 107 | #define MX25_PAD_CS4__CS4 IOMUX_PAD(0x264, 0x054, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 108 | #define MX25_PAD_CS4__UART5_CTS IOMUX_PAD(0x264, 0x054, 0x13, 0, 0, NO_PAD_CTRL) | ||
| 109 | #define MX25_PAD_CS4__GPIO_3_20 IOMUX_PAD(0x264, 0x054, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 110 | |||
| 111 | #define MX25_PAD_CS5__CS5 IOMUX_PAD(0x268, 0x058, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 112 | #define MX25_PAD_CS5__UART5_RTS IOMUX_PAD(0x268, 0x058, 0x13, 0x574, 0, NO_PAD_CTRL) | ||
| 113 | #define MX25_PAD_CS5__GPIO_3_21 IOMUX_PAD(0x268, 0x058, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 114 | |||
| 115 | #define MX25_PAD_NF_CE0__NF_CE0 IOMUX_PAD(0x26c, 0x05c, 0x10, 0, 0, NO_PAD_CTL) | ||
| 116 | #define MX25_PAD_NF_CE0__GPIO_3_22 IOMUX_PAD(0x26c, 0x05c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 117 | |||
| 118 | #define MX25_PAD_ECB__ECB IOMUX_PAD(0x270, 0x060, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 119 | #define MX25_PAD_ECB__UART5_TXD_MUX IOMUX_PAD(0x270, 0x060, 0x13, 0, 0, NO_PAD_CTRL) | ||
| 120 | #define MX25_PAD_ECB__GPIO_3_23 IOMUX_PAD(0x270, 0x060, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 121 | |||
| 122 | #define MX25_PAD_LBA__LBA IOMUX_PAD(0x274, 0x064, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 123 | #define MX25_PAD_LBA__UART5_RXD_MUX IOMUX_PAD(0x274, 0x064, 0x13, 0x578, 0, NO_PAD_CTRL) | ||
| 124 | #define MX25_PAD_LBA__GPIO_3_24 IOMUX_PAD(0x274, 0x064, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 125 | |||
| 126 | #define MX25_PAD_BCLK__BCLK IOMUX_PAD(0x000, 0x068, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 127 | #define MX25_PAD_BCLK__GPIO_4_4 IOMUX_PAD(0x000, 0x068, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 128 | |||
| 129 | #define MX25_PAD_RW__RW IOMUX_PAD(0x278, 0x06c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 130 | #define MX25_PAD_RW__AUD4_TXFS IOMUX_PAD(0x278, 0x06c, 0x14, 0x474, 0, NO_PAD_CTRL) | ||
| 131 | #define MX25_PAD_RW__GPIO_3_25 IOMUX_PAD(0x278, 0x06c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 132 | |||
| 133 | #define MX25_PAD_NFWE_B__NFWE_B IOMUX_PAD(0x000, 0x070, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 134 | #define MX25_PAD_NFWE_B__GPIO_3_26 IOMUX_PAD(0x000, 0x070, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 135 | |||
| 136 | #define MX25_PAD_NFRE_B__NFRE_B IOMUX_PAD(0x000, 0x074, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 137 | #define MX25_PAD_NFRE_B__GPIO_3_27 IOMUX_PAD(0x000, 0x074, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 138 | |||
| 139 | #define MX25_PAD_NFALE__NFALE IOMUX_PAD(0x000, 0x078, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 140 | #define MX25_PAD_NFALE__GPIO_3_28 IOMUX_PAD(0x000, 0x078, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 141 | |||
| 142 | #define MX25_PAD_NFCLE__NFCLE IOMUX_PAD(0x000, 0x07c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 143 | #define MX25_PAD_NFCLE__GPIO_3_29 IOMUX_PAD(0x000, 0x07c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 144 | |||
| 145 | #define MX25_PAD_NFWP_B__NFWP_B IOMUX_PAD(0x000, 0x080, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 146 | #define MX25_PAD_NFWP_B__GPIO_3_30 IOMUX_PAD(0x000, 0x080, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 147 | |||
| 148 | #define MX25_PAD_NFRB__NFRB IOMUX_PAD(0x27c, 0x084, 0x10, 0, 0, PAD_CTL_PKE) | ||
| 149 | #define MX25_PAD_NFRB__GPIO_3_31 IOMUX_PAD(0x27c, 0x084, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 150 | |||
| 151 | #define MX25_PAD_D15__D15 IOMUX_PAD(0x280, 0x088, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 152 | #define MX25_PAD_D15__LD16 IOMUX_PAD(0x280, 0x088, 0x01, 0, 0, NO_PAD_CTRL) | ||
| 153 | #define MX25_PAD_D15__GPIO_4_5 IOMUX_PAD(0x280, 0x088, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 154 | |||
| 155 | #define MX25_PAD_D14__D14 IOMUX_PAD(0x284, 0x08c, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 156 | #define MX25_PAD_D14__LD17 IOMUX_PAD(0x284, 0x08c, 0x01, 0, 0, NO_PAD_CTRL) | ||
| 157 | #define MX25_PAD_D14__GPIO_4_6 IOMUX_PAD(0x284, 0x08c, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 158 | |||
| 159 | #define MX25_PAD_D13__D13 IOMUX_PAD(0x288, 0x090, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 160 | #define MX25_PAD_D13__LD18 IOMUX_PAD(0x288, 0x090, 0x01, 0, 0, NO_PAD_CTRL) | ||
| 161 | #define MX25_PAD_D13__GPIO_4_7 IOMUX_PAD(0x288, 0x090, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 162 | |||
| 163 | #define MX25_PAD_D12__D12 IOMUX_PAD(0x28c, 0x094, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 164 | #define MX25_PAD_D12__GPIO_4_8 IOMUX_PAD(0x28c, 0x094, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 165 | |||
| 166 | #define MX25_PAD_D11__D11 IOMUX_PAD(0x290, 0x098, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 167 | #define MX25_PAD_D11__GPIO_4_9 IOMUX_PAD(0x290, 0x098, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 168 | |||
| 169 | #define MX25_PAD_D10__D10 IOMUX_PAD(0x294, 0x09c, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 170 | #define MX25_PAD_D10__GPIO_4_10 IOMUX_PAD(0x294, 0x09c, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 171 | #define MX25_PAD_D10__USBOTG_OC IOMUX_PAD(0x294, 0x09c, 0x06, 0x57c, 0, PAD_CTL_PUS_100K_UP) | ||
| 172 | |||
| 173 | #define MX25_PAD_D9__D9 IOMUX_PAD(0x298, 0x0a0, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 174 | #define MX25_PAD_D9__GPIO_4_11 IOMUX_PAD(0x298, 0x0a0, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 175 | #define MX25_PAD_D9__USBH2_PWR IOMUX_PAD(0x298, 0x0a0, 0x06, 0, 0, PAD_CTL_PKE) | ||
| 176 | |||
| 177 | #define MX25_PAD_D8__D8 IOMUX_PAD(0x29c, 0x0a4, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 178 | #define MX25_PAD_D8__GPIO_4_12 IOMUX_PAD(0x29c, 0x0a4, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 179 | #define MX25_PAD_D8__USBH2_OC IOMUX_PAD(0x29c, 0x0a4, 0x06, 0x580, 0, PAD_CTL_PUS_100K_UP) | ||
| 180 | |||
| 181 | #define MX25_PAD_D7__D7 IOMUX_PAD(0x2a0, 0x0a8, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 182 | #define MX25_PAD_D7__GPIO_4_13 IOMUX_PAD(0x2a0, 0x0a8, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 183 | |||
| 184 | #define MX25_PAD_D6__D6 IOMUX_PAD(0x2a4, 0x0ac, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 185 | #define MX25_PAD_D6__GPIO_4_14 IOMUX_PAD(0x2a4, 0x0ac, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 186 | |||
| 187 | #define MX25_PAD_D5__D5 IOMUX_PAD(0x2a8, 0x0b0, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 188 | #define MX25_PAD_D5__GPIO_4_15 IOMUX_PAD(0x2a8, 0x0b0, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 189 | |||
| 190 | #define MX25_PAD_D4__D4 IOMUX_PAD(0x2ac, 0x0b4, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 191 | #define MX25_PAD_D4__GPIO_4_16 IOMUX_PAD(0x2ac, 0x0b4, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 192 | |||
| 193 | #define MX25_PAD_D3__D3 IOMUX_PAD(0x2b0, 0x0b8, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 194 | #define MX25_PAD_D3__GPIO_4_17 IOMUX_PAD(0x2b0, 0x0b8, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 195 | |||
| 196 | #define MX25_PAD_D2__D2 IOMUX_PAD(0x2b4, 0x0bc, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 197 | #define MX25_PAD_D2__GPIO_4_18 IOMUX_PAD(0x2b4, 0x0bc, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 198 | |||
| 199 | #define MX25_PAD_D1__D1 IOMUX_PAD(0x2b8, 0x0c0, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 200 | #define MX25_PAD_D1__GPIO_4_19 IOMUX_PAD(0x2b8, 0x0c0, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 201 | |||
| 202 | #define MX25_PAD_D0__D0 IOMUX_PAD(0x2bc, 0x0c4, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 203 | #define MX25_PAD_D0__GPIO_4_20 IOMUX_PAD(0x2bc, 0x0c4, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 204 | |||
| 205 | #define MX25_PAD_LD0__LD0 IOMUX_PAD(0x2c0, 0x0c8, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 206 | #define MX25_PAD_LD0__CSI_D0 IOMUX_PAD(0x2c0, 0x0c8, 0x12, 0x488, 0, NO_PAD_CTRL) | ||
| 207 | #define MX25_PAD_LD0__GPIO_2_15 IOMUX_PAD(0x2c0, 0x0c8, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 208 | |||
| 209 | #define MX25_PAD_LD1__LD1 IOMUX_PAD(0x2c4, 0x0cc, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 210 | #define MX25_PAD_LD1__CSI_D1 IOMUX_PAD(0x2c4, 0x0cc, 0x12, 0x48c, 0, NO_PAD_CTRL) | ||
| 211 | #define MX25_PAD_LD1__GPIO_2_16 IOMUX_PAD(0x2c4, 0x0cc, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 212 | |||
| 213 | #define MX25_PAD_LD2__LD2 IOMUX_PAD(0x2c8, 0x0d0, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 214 | #define MX25_PAD_LD2__GPIO_2_17 IOMUX_PAD(0x2c8, 0x0d0, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 215 | |||
| 216 | #define MX25_PAD_LD3__LD3 IOMUX_PAD(0x2cc, 0x0d4, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 217 | #define MX25_PAD_LD3__GPIO_2_18 IOMUX_PAD(0x2cc, 0x0d4, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 218 | |||
| 219 | #define MX25_PAD_LD4__LD4 IOMUX_PAD(0x2d0, 0x0d8, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 220 | #define MX25_PAD_LD4__GPIO_2_19 IOMUX_PAD(0x2d0, 0x0d8, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 221 | |||
| 222 | #define MX25_PAD_LD5__LD5 IOMUX_PAD(0x2d4, 0x0dc, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 223 | #define MX25_PAD_LD5__GPIO_1_19 IOMUX_PAD(0x2d4, 0x0dc, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 224 | |||
| 225 | #define MX25_PAD_LD6__LD6 IOMUX_PAD(0x2d8, 0x0e0, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 226 | #define MX25_PAD_LD6__GPIO_1_20 IOMUX_PAD(0x2d8, 0x0e0, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 227 | |||
| 228 | #define MX25_PAD_LD7__LD7 IOMUX_PAD(0x2dc, 0x0e4, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 229 | #define MX25_PAD_LD7__GPIO_1_21 IOMUX_PAD(0x2dc, 0x0e4, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 230 | |||
| 231 | #define MX25_PAD_LD8__LD8 IOMUX_PAD(0x2e0, 0x0e8, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 232 | #define MX25_PAD_LD8__FEC_TX_ERR IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTL) | ||
| 233 | |||
| 234 | #define MX25_PAD_LD9__LD9 IOMUX_PAD(0x2e4, 0x0ec, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 235 | #define MX25_PAD_LD9__FEC_COL IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTL) | ||
| 236 | |||
| 237 | #define MX25_PAD_LD10__LD10 IOMUX_PAD(0x2e8, 0x0f0, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 238 | #define MX25_PAD_LD10__FEC_RX_ER IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTL) | ||
| 239 | |||
| 240 | #define MX25_PAD_LD11__LD11 IOMUX_PAD(0x2ec, 0x0f4, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 241 | #define MX25_PAD_LD11__FEC_RDATA2 IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTL) | ||
| 242 | |||
| 243 | #define MX25_PAD_LD12__LD12 IOMUX_PAD(0x2f0, 0x0f8, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 244 | #define MX25_PAD_LD12__FEC_RDATA3 IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTL) | ||
| 245 | |||
| 246 | #define MX25_PAD_LD13__LD13 IOMUX_PAD(0x2f4, 0x0fc, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 247 | #define MX25_PAD_LD13__FEC_TDATA2 IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTL) | ||
| 248 | |||
| 249 | #define MX25_PAD_LD14__LD14 IOMUX_PAD(0x2f8, 0x100, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 250 | #define MX25_PAD_LD14__FEC_TDATA3 IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTL) | ||
| 251 | |||
| 252 | #define MX25_PAD_LD15__LD15 IOMUX_PAD(0x2fc, 0x104, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 253 | #define MX25_PAD_LD15__FEC_RX_CLK IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTL) | ||
| 254 | |||
| 255 | #define MX25_PAD_HSYNC__HSYNC IOMUX_PAD(0x300, 0x108, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 256 | #define MX25_PAD_HSYNC__GPIO_1_22 IOMUX_PAD(0x300, 0x108, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 257 | |||
| 258 | #define MX25_PAD_VSYNC__VSYNC IOMUX_PAD(0x304, 0x10c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 259 | #define MX25_PAD_VSYNC__GPIO_1_23 IOMUX_PAD(0x304, 0x10c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 260 | |||
| 261 | #define MX25_PAD_LSCLK__LSCLK IOMUX_PAD(0x308, 0x110, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 262 | #define MX25_PAD_LSCLK__GPIO_1_24 IOMUX_PAD(0x308, 0x110, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 263 | |||
| 264 | #define MX25_PAD_OE_ACD__OE_ACD IOMUX_PAD(0x30c, 0x114, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 265 | #define MX25_PAD_OE_ACD__GPIO_1_25 IOMUX_PAD(0x30c, 0x114, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 266 | |||
| 267 | #define MX25_PAD_CONTRAST__CONTRAST IOMUX_PAD(0x310, 0x118, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 268 | #define MX25_PAD_CONTRAST__FEC_CRS IOMUX_PAD(0x310, 0x118, 0x15, 0x508, 1, NO_PAD_CTL) | ||
| 269 | |||
| 270 | #define MX25_PAD_PWM__PWM IOMUX_PAD(0x314, 0x11c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 271 | #define MX25_PAD_PWM__GPIO_1_26 IOMUX_PAD(0x314, 0x11c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 272 | #define MX25_PAD_PWM__USBH2_OC IOMUX_PAD(0x314, 0x11c, 0x16, 0x580, 1, PAD_CTL_PUS_100K_UP) | ||
| 273 | |||
| 274 | #define MX25_PAD_CSI_D2__CSI_D2 IOMUX_PAD(0x318, 0x120, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 275 | #define MX25_PAD_CSI_D2__UART5_RXD_MUX IOMUX_PAD(0x318, 0x120, 0x11, 0x578, 1, NO_PAD_CTRL) | ||
| 276 | #define MX25_PAD_CSI_D2__GPIO_1_27 IOMUX_PAD(0x318, 0x120, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 277 | |||
| 278 | #define MX25_PAD_CSI_D3__CSI_D3 IOMUX_PAD(0x31c, 0x124, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 279 | #define MX25_PAD_CSI_D3__GPIO_1_28 IOMUX_PAD(0x31c, 0x124, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 280 | |||
| 281 | #define MX25_PAD_CSI_D4__CSI_D4 IOMUX_PAD(0x320, 0x128, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 282 | #define MX25_PAD_CSI_D4__UART5_RTS IOMUX_PAD(0x320, 0x128, 0x11, 0x574, 1, NO_PAD_CTRL) | ||
| 283 | #define MX25_PAD_CSI_D4__GPIO_1_29 IOMUX_PAD(0x320, 0x128, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 284 | |||
| 285 | #define MX25_PAD_CSI_D5__CSI_D5 IOMUX_PAD(0x324, 0x12c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 286 | #define MX25_PAD_CSI_D5__GPIO_1_30 IOMUX_PAD(0x324, 0x12c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 287 | |||
| 288 | #define MX25_PAD_CSI_D6__CSI_D6 IOMUX_PAD(0x328, 0x130, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 289 | #define MX25_PAD_CSI_D6__GPIO_1_31 IOMUX_PAD(0x328, 0x130, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 290 | |||
| 291 | #define MX25_PAD_CSI_D7__CSI_D7 IOMUX_PAD(0x32c, 0x134, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 292 | #define MX25_PAD_CSI_D7__GPIO_1_6 IOMUX_PAD(0x32c, 0x134, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 293 | |||
| 294 | #define MX25_PAD_CSI_D8__CSI_D8 IOMUX_PAD(0x330, 0x138, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 295 | #define MX25_PAD_CSI_D8__GPIO_1_7 IOMUX_PAD(0x330, 0x138, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 296 | |||
| 297 | #define MX25_PAD_CSI_D9__CSI_D9 IOMUX_PAD(0x334, 0x13c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 298 | #define MX25_PAD_CSI_D9__GPIO_4_21 IOMUX_PAD(0x334, 0x13c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 299 | |||
| 300 | #define MX25_PAD_CSI_MCLK__CSI_MCLK IOMUX_PAD(0x338, 0x140, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 301 | #define MX25_PAD_CSI_MCLK__GPIO_1_8 IOMUX_PAD(0x338, 0x140, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 302 | |||
| 303 | #define MX25_PAD_CSI_VSYNC__CSI_VSYNC IOMUX_PAD(0x33c, 0x144, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 304 | #define MX25_PAD_CSI_VSYNC__GPIO_1_9 IOMUX_PAD(0x33c, 0x144, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 305 | |||
| 306 | #define MX25_PAD_CSI_HSYNC__CSI_HSYNC IOMUX_PAD(0x340, 0x148, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 307 | #define MX25_PAD_CSI_HSYNC__GPIO_1_10 IOMUX_PAD(0x340, 0x148, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 308 | |||
| 309 | #define MX25_PAD_CSI_PIXCLK__CSI_PIXCLK IOMUX_PAD(0x344, 0x14c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 310 | #define MX25_PAD_CSI_PIXCLK__GPIO_1_11 IOMUX_PAD(0x344, 0x14c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 311 | |||
| 312 | #define MX25_PAD_I2C1_CLK__I2C1_CLK IOMUX_PAD(0x348, 0x150, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 313 | #define MX25_PAD_I2C1_CLK__GPIO_1_12 IOMUX_PAD(0x348, 0x150, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 314 | |||
| 315 | #define MX25_PAD_I2C1_DAT__I2C1_DAT IOMUX_PAD(0x34c, 0x154, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 316 | #define MX25_PAD_I2C1_DAT__GPIO_1_13 IOMUX_PAD(0x34c, 0x154, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 317 | |||
| 318 | #define MX25_PAD_CSPI1_MOSI__CSPI1_MOSI IOMUX_PAD(0x350, 0x158, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 319 | #define MX25_PAD_CSPI1_MOSI__GPIO_1_14 IOMUX_PAD(0x350, 0x158, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 320 | |||
| 321 | #define MX25_PAD_CSPI1_MISO__CSPI1_MISO IOMUX_PAD(0x354, 0x15c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 322 | #define MX25_PAD_CSPI1_MISO__GPIO_1_15 IOMUX_PAD(0x354, 0x15c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 323 | |||
| 324 | #define MX25_PAD_CSPI1_SS0__CSPI1_SS0 IOMUX_PAD(0x358, 0x160, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 325 | #define MX25_PAD_CSPI1_SS0__GPIO_1_16 IOMUX_PAD(0x358, 0x160, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 326 | |||
| 327 | #define MX25_PAD_CSPI1_SS1__CSPI1_SS1 IOMUX_PAD(0x35c, 0x164, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 328 | #define MX25_PAD_CSPI1_SS1__GPIO_1_17 IOMUX_PAD(0x35c, 0x164, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 329 | |||
| 330 | #define MX25_PAD_CSPI1_SCLK__CSPI1_SCLK IOMUX_PAD(0x360, 0x168, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 331 | #define MX25_PAD_CSPI1_SCLK__GPIO_1_18 IOMUX_PAD(0x360, 0x168, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 332 | |||
| 333 | #define MX25_PAD_CSPI1_RDY__CSPI1_RDY IOMUX_PAD(0x364, 0x16c, 0x10, 0, 0, PAD_CTL_PKE) | ||
| 334 | #define MX25_PAD_CSPI1_RDY__GPIO_2_22 IOMUX_PAD(0x364, 0x16c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 335 | |||
| 336 | #define MX25_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x368, 0x170, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN) | ||
| 337 | #define MX25_PAD_UART1_RXD__GPIO_4_22 IOMUX_PAD(0x368, 0x170, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 338 | |||
| 339 | #define MX25_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x36c, 0x174, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 340 | #define MX25_PAD_UART1_TXD__GPIO_4_23 IOMUX_PAD(0x36c, 0x174, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 341 | |||
| 342 | #define MX25_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x370, 0x178, 0x10, 0, 0, PAD_CTL_PUS_100K_UP) | ||
| 343 | #define MX25_PAD_UART1_RTS__CSI_D0 IOMUX_PAD(0x370, 0x178, 0x11, 0x488, 1, NO_PAD_CTRL) | ||
| 344 | #define MX25_PAD_UART1_RTS__GPIO_4_24 IOMUX_PAD(0x370, 0x178, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 345 | |||
| 346 | #define MX25_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x374, 0x17c, 0x10, 0, 0, PAD_CTL_PUS_100K_UP) | ||
| 347 | #define MX25_PAD_UART1_CTS__CSI_D1 IOMUX_PAD(0x374, 0x17c, 0x11, 0x48c, 1, NO_PAD_CTRL) | ||
| 348 | #define MX25_PAD_UART1_CTS__GPIO_4_25 IOMUX_PAD(0x374, 0x17c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 349 | |||
| 350 | #define MX25_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(0x378, 0x180, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 351 | #define MX25_PAD_UART2_RXD__GPIO_4_26 IOMUX_PAD(0x378, 0x180, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 352 | |||
| 353 | #define MX25_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(0x37c, 0x184, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 354 | #define MX25_PAD_UART2_TXD__GPIO_4_27 IOMUX_PAD(0x37c, 0x184, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 355 | |||
| 356 | #define MX25_PAD_UART2_RTS__UART2_RTS IOMUX_PAD(0x380, 0x188, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 357 | #define MX25_PAD_UART2_RTS__FEC_COL IOMUX_PAD(0x380, 0x188, 0x12, 0x504, 2, NO_PAD_CTL) | ||
| 358 | #define MX25_PAD_UART2_RTS__GPIO_4_28 IOMUX_PAD(0x380, 0x188, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 359 | |||
| 360 | #define MX25_PAD_UART2_CTS__FEC_RX_ER IOMUX_PAD(0x384, 0x18c, 0x12, 0x518, 2, NO_PAD_CTL) | ||
| 361 | #define MX25_PAD_UART2_CTS__UART2_CTS IOMUX_PAD(0x384, 0x18c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 362 | #define MX25_PAD_UART2_CTS__GPIO_4_29 IOMUX_PAD(0x384, 0x18c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 363 | |||
| 364 | #define MX25_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x388, 0x190, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) | ||
| 365 | #define MX25_PAD_SD1_CMD__FEC_RDATA2 IOMUX_PAD(0x388, 0x190, 0x12, 0x50c, 2, NO_PAD_CTL) | ||
| 366 | #define MX25_PAD_SD1_CMD__GPIO_2_23 IOMUX_PAD(0x388, 0x190, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 367 | |||
| 368 | #define MX25_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x38c, 0x194, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) | ||
| 369 | #define MX25_PAD_SD1_CLK__FEC_RDATA3 IOMUX_PAD(0x38c, 0x194, 0x12, 0x510, 2, NO_PAD_CTL) | ||
| 370 | #define MX25_PAD_SD1_CLK__GPIO_2_24 IOMUX_PAD(0x38c, 0x194, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 371 | |||
| 372 | #define MX25_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x390, 0x198, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) | ||
| 373 | #define MX25_PAD_SD1_DATA0__GPIO_2_25 IOMUX_PAD(0x390, 0x198, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 374 | |||
| 375 | #define MX25_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x394, 0x19c, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) | ||
| 376 | #define MX25_PAD_SD1_DATA1__AUD7_RXD IOMUX_PAD(0x394, 0x19c, 0x13, 0x478, 0, NO_PAD_CTRL) | ||
| 377 | #define MX25_PAD_SD1_DATA1__GPIO_2_26 IOMUX_PAD(0x394, 0x19c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 378 | |||
| 379 | #define MX25_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x398, 0x1a0, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) | ||
| 380 | #define MX25_PAD_SD1_DATA2__FEC_RX_CLK IOMUX_PAD(0x398, 0x1a0, 0x15, 0x514, 2, NO_PAD_CTL) | ||
| 381 | #define MX25_PAD_SD1_DATA2__GPIO_2_27 IOMUX_PAD(0x398, 0x1a0, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 382 | |||
| 383 | #define MX25_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x39c, 0x1a4, 0x10, 0, 0, PAD_CTL_PUS_47K_UP) | ||
| 384 | #define MX25_PAD_SD1_DATA3__FEC_CRS IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTL) | ||
| 385 | #define MX25_PAD_SD1_DATA3__GPIO_2_28 IOMUX_PAD(0x39c, 0x1a4, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 386 | |||
| 387 | #define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, PAD_CTL_PKE) | ||
| 388 | #define MX25_PAD_KPP_ROW0__GPIO_2_29 IOMUX_PAD(0x3a0, 0x1a8, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 389 | |||
| 390 | #define MX25_PAD_KPP_ROW1__KPP_ROW1 IOMUX_PAD(0x3a4, 0x1ac, 0x10, 0, 0, PAD_CTL_PKE) | ||
| 391 | #define MX25_PAD_KPP_ROW1__GPIO_2_30 IOMUX_PAD(0x3a4, 0x1ac, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 392 | |||
| 393 | #define MX25_PAD_KPP_ROW2__KPP_ROW2 IOMUX_PAD(0x3a8, 0x1b0, 0x10, 0, 0, PAD_CTL_PKE) | ||
| 394 | #define MX25_PAD_KPP_ROW2__CSI_D0 IOMUX_PAD(0x3a8, 0x1b0, 0x13, 0x488, 2, NO_PAD_CTRL) | ||
| 395 | #define MX25_PAD_KPP_ROW2__GPIO_2_31 IOMUX_PAD(0x3a8, 0x1b0, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 396 | |||
| 397 | #define MX25_PAD_KPP_ROW3__KPP_ROW3 IOMUX_PAD(0x3ac, 0x1b4, 0x10, 0, 0, PAD_CTL_PKE) | ||
| 398 | #define MX25_PAD_KPP_ROW3__CSI_LD1 IOMUX_PAD(0x3ac, 0x1b4, 0x13, 0x48c, 2, NO_PAD_CTRL) | ||
| 399 | #define MX25_PAD_KPP_ROW3__GPIO_3_0 IOMUX_PAD(0x3ac, 0x1b4, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 400 | |||
| 401 | #define MX25_PAD_KPP_COL0__KPP_COL0 IOMUX_PAD(0x3b0, 0x1b8, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE) | ||
| 402 | #define MX25_PAD_KPP_COL0__GPIO_3_1 IOMUX_PAD(0x3b0, 0x1b8, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 403 | |||
| 404 | #define MX25_PAD_KPP_COL1__KPP_COL1 IOMUX_PAD(0x3b4, 0x1bc, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE) | ||
| 405 | #define MX25_PAD_KPP_COL1__GPIO_3_2 IOMUX_PAD(0x3b4, 0x1bc, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 406 | |||
| 407 | #define MX25_PAD_KPP_COL2__KPP_COL2 IOMUX_PAD(0x3b8, 0x1c0, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE) | ||
| 408 | #define MX25_PAD_KPP_COL2__GPIO_3_3 IOMUX_PAD(0x3b8, 0x1c0, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 409 | |||
| 410 | #define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE) | ||
| 411 | #define MX25_PAD_KPP_COL3__GPIO_3_4 IOMUX_PAD(0x3bc, 0x1c4, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 412 | |||
| 413 | #define MX25_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTL) | ||
| 414 | #define MX25_PAD_FEC_MDC__AUD4_TXD IOMUX_PAD(0x3c0, 0x1c8, 0x12, 0x464, 1, NO_PAD_CTRL) | ||
| 415 | #define MX25_PAD_FEC_MDC__GPIO_3_5 IOMUX_PAD(0x3c0, 0x1c8, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 416 | |||
| 417 | #define MX25_PAD_FEC_MDIO__FEC_MDIO IOMUX_PAD(0x3c4, 0x1cc, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_22K_UP) | ||
| 418 | #define MX25_PAD_FEC_MDIO__AUD4_RXD IOMUX_PAD(0x3c4, 0x1cc, 0x12, 0x460, 1, NO_PAD_CTRL) | ||
| 419 | #define MX25_PAD_FEC_MDIO__GPIO_3_6 IOMUX_PAD(0x3c4, 0x1cc, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 420 | |||
| 421 | #define MX25_PAD_FEC_TDATA0__FEC_TDATA0 IOMUX_PAD(0x3c8, 0x1d0, 0x10, 0, 0, NO_PAD_CTL) | ||
| 422 | #define MX25_PAD_FEC_TDATA0__GPIO_3_7 IOMUX_PAD(0x3c8, 0x1d0, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 423 | |||
| 424 | #define MX25_PAD_FEC_TDATA1__FEC_TDATA1 IOMUX_PAD(0x3cc, 0x1d4, 0x10, 0, 0, NO_PAD_CTL) | ||
| 425 | #define MX25_PAD_FEC_TDATA1__AUD4_TXFS IOMUX_PAD(0x3cc, 0x1d4, 0x12, 0x474, 1, NO_PAD_CTRL) | ||
| 426 | #define MX25_PAD_FEC_TDATA1__GPIO_3_8 IOMUX_PAD(0x3cc, 0x1d4, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 427 | |||
| 428 | #define MX25_PAD_FEC_TX_EN__FEC_TX_EN IOMUX_PAD(0x3d0, 0x1d8, 0x10, 0, 0, NO_PAD_CTL) | ||
| 429 | #define MX25_PAD_FEC_TX_EN__GPIO_3_9 IOMUX_PAD(0x3d0, 0x1d8, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 430 | |||
| 431 | #define MX25_PAD_FEC_RDATA0__FEC_RDATA0 IOMUX_PAD(0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL) | ||
| 432 | #define MX25_PAD_FEC_RDATA0__GPIO_3_10 IOMUX_PAD(0x3d4, 0x1dc, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 433 | |||
| 434 | #define MX25_PAD_FEC_RDATA1__FEC_RDATA1 IOMUX_PAD(0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL) | ||
| 435 | #define MX25_PAD_FEC_RDATA1__GPIO_3_11 IOMUX_PAD(0x3d8, 0x1e0, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 436 | |||
| 437 | #define MX25_PAD_FEC_RX_DV__FEC_RX_DV IOMUX_PAD(0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL) | ||
| 438 | #define MX25_PAD_FEC_RX_DV__CAN2_RX IOMUX_PAD(0x3dc, 0x1e4, 0x14, 0x484, 0, PAD_CTL_PUS_22K_UP) | ||
| 439 | #define MX25_PAD_FEC_RX_DV__GPIO_3_12 IOMUX_PAD(0x3dc, 0x1e4, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 440 | |||
| 441 | #define MX25_PAD_FEC_TX_CLK__FEC_TX_CLK IOMUX_PAD(0x3e0, 0x1e8, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN) | ||
| 442 | #define MX25_PAD_FEC_TX_CLK__GPIO_3_13 IOMUX_PAD(0x3e0, 0x1e8, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 443 | |||
| 444 | #define MX25_PAD_RTCK__RTCK IOMUX_PAD(0x3e4, 0x1ec, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 445 | #define MX25_PAD_RTCK__OWIRE IOMUX_PAD(0x3e4, 0x1ec, 0x11, 0, 0, NO_PAD_CTRL) | ||
| 446 | #define MX25_PAD_RTCK__GPIO_3_14 IOMUX_PAD(0x3e4, 0x1ec, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 447 | |||
| 448 | #define MX25_PAD_DE_B__DE_B IOMUX_PAD(0x3ec, 0x1f0, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 449 | #define MX25_PAD_DE_B__GPIO_2_20 IOMUX_PAD(0x3ec, 0x1f0, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 450 | |||
| 451 | #define MX25_PAD_TDO__TDO IOMUX_PAD(0x3e8, 0x000, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 452 | |||
| 453 | #define MX25_PAD_GPIO_A__GPIO_A IOMUX_PAD(0x3f0, 0x1f4, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 454 | #define MX25_PAD_GPIO_A__CAN1_TX IOMUX_PAD(0x3f0, 0x1f4, 0x16, 0, 0, PAD_CTL_PUS_22K_UP) | ||
| 455 | #define MX25_PAD_GPIO_A__USBOTG_PWR IOMUX_PAD(0x3f0, 0x1f4, 0x12, 0, 0, PAD_CTL_PKE) | ||
| 456 | |||
| 457 | #define MX25_PAD_GPIO_B__GPIO_B IOMUX_PAD(0x3f4, 0x1f8, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 458 | #define MX25_PAD_GPIO_B__CAN1_RX IOMUX_PAD(0x3f4, 0x1f8, 0x16, 0x480, 1, PAD_CTL_PUS_22K) | ||
| 459 | #define MX25_PAD_GPIO_B__USBOTG_OC IOMUX_PAD(0x3f4, 0x1f8, 0x12, 0x57c, 1, PAD_CTL_PUS_100K_UP) | ||
| 460 | |||
| 461 | #define MX25_PAD_GPIO_C__GPIO_C IOMUX_PAD(0x3f8, 0x1fc, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 462 | #define MX25_PAD_GPIO_C__CAN2_TX IOMUX_PAD(0x3f8, 0x1fc, 0x16, 0, 0, PAD_CTL_PUS_22K_UP) | ||
| 463 | |||
| 464 | #define MX25_PAD_GPIO_D__GPIO_D IOMUX_PAD(0x3fc, 0x200, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 465 | #define MX25_PAD_GPIO_D__CAN2_RX IOMUX_PAD(0x3fc, 0x200, 0x16, 0x484, 1, PAD_CTL_PUS_22K_UP) | ||
| 466 | |||
| 467 | #define MX25_PAD_GPIO_E__GPIO_E IOMUX_PAD(0x400, 0x204, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 468 | #define MX25_PAD_GPIO_E__AUD7_TXD IOMUX_PAD(0x400, 0x204, 0x14, 0, 0, NO_PAD_CTRL) | ||
| 469 | |||
| 470 | #define MX25_PAD_GPIO_F__GPIO_F IOMUX_PAD(0x404, 0x208, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 471 | #define MX25_PAD_GPIO_F__AUD7_TXC IOMUX_PAD(0x404, 0x208, 0x14, 0, 0, NO_PAD_CTRL) | ||
| 472 | |||
| 473 | #define MX25_PAD_EXT_ARMCLK__EXT_ARMCLK IOMUX_PAD(0x000, 0x20c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 474 | #define MX25_PAD_EXT_ARMCLK__GPIO_3_15 IOMUX_PAD(0x000, 0x20c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 475 | |||
| 476 | #define MX25_PAD_UPLL_BYPCLK__UPLL_BYPCLK IOMUX_PAD(0x000, 0x210, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 477 | #define MX25_PAD_UPLL_BYPCLK__GPIO_3_16 IOMUX_PAD(0x000, 0x210, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 478 | |||
| 479 | #define MX25_PAD_VSTBY_REQ__VSTBY_REQ IOMUX_PAD(0x408, 0x214, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 480 | #define MX25_PAD_VSTBY_REQ__AUD7_TXFS IOMUX_PAD(0x408, 0x214, 0x14, 0, 0, NO_PAD_CTRL) | ||
| 481 | #define MX25_PAD_VSTBY_REQ__GPIO_3_17 IOMUX_PAD(0x408, 0x214, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 482 | #define MX25_PAD_VSTBY_ACK__VSTBY_ACK IOMUX_PAD(0x40c, 0x218, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 483 | #define MX25_PAD_VSTBY_ACK__GPIO_3_18 IOMUX_PAD(0x40c, 0x218, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 484 | |||
| 485 | #define MX25_PAD_POWER_FAIL__POWER_FAIL IOMUX_PAD(0x410, 0x21c, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 486 | #define MX25_PAD_POWER_FAIL__AUD7_RXD IOMUX_PAD(0x410, 0x21c, 0x14, 0x478, 1, NO_PAD_CTRL) | ||
| 487 | #define MX25_PAD_POWER_FAIL__GPIO_3_19 IOMUX_PAD(0x410, 0x21c, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 488 | |||
| 489 | #define MX25_PAD_CLKO__CLKO IOMUX_PAD(0x414, 0x220, 0x10, 0, 0, NO_PAD_CTRL) | ||
| 490 | #define MX25_PAD_CLKO__GPIO_2_21 IOMUX_PAD(0x414, 0x220, 0x15, 0, 0, NO_PAD_CTRL) | ||
| 491 | |||
| 492 | #define MX25_PAD_BOOT_MODE0__BOOT_MODE0 IOMUX_PAD(0x000, 0x224, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 493 | #define MX25_PAD_BOOT_MODE0__GPIO_4_30 IOMUX_PAD(0x000, 0x224, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 494 | #define MX25_PAD_BOOT_MODE1__BOOT_MODE1 IOMUX_PAD(0x000, 0x228, 0x00, 0, 0, NO_PAD_CTRL) | ||
| 495 | #define MX25_PAD_BOOT_MODE1__GPIO_4_31 IOMUX_PAD(0x000, 0x228, 0x05, 0, 0, NO_PAD_CTRL) | ||
| 496 | |||
| 497 | #define MX25_PAD_CTL_GRP_DVS_MISC IOMUX_PAD(0x418, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 498 | #define MX25_PAD_CTL_GRP_DSE_FEC IOMUX_PAD(0x41c, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 499 | #define MX25_PAD_CTL_GRP_DVS_JTAG IOMUX_PAD(0x420, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 500 | #define MX25_PAD_CTL_GRP_DSE_NFC IOMUX_PAD(0x424, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 501 | #define MX25_PAD_CTL_GRP_DSE_CSI IOMUX_PAD(0x428, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 502 | #define MX25_PAD_CTL_GRP_DSE_WEIM IOMUX_PAD(0x42c, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 503 | #define MX25_PAD_CTL_GRP_DSE_DDR IOMUX_PAD(0x430, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 504 | #define MX25_PAD_CTL_GRP_DVS_CRM IOMUX_PAD(0x434, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 505 | #define MX25_PAD_CTL_GRP_DSE_KPP IOMUX_PAD(0x438, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 506 | #define MX25_PAD_CTL_GRP_DSE_SDHC1 IOMUX_PAD(0x43c, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 507 | #define MX25_PAD_CTL_GRP_DSE_LCD IOMUX_PAD(0x440, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 508 | #define MX25_PAD_CTL_GRP_DSE_UART IOMUX_PAD(0x444, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 509 | #define MX25_PAD_CTL_GRP_DVS_NFC IOMUX_PAD(0x448, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 510 | #define MX25_PAD_CTL_GRP_DVS_CSI IOMUX_PAD(0x44c, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 511 | #define MX25_PAD_CTL_GRP_DSE_CSPI1 IOMUX_PAD(0x450, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 512 | #define MX25_PAD_CTL_GRP_DDRTYPE IOMUX_PAD(0x454, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 513 | #define MX25_PAD_CTL_GRP_DVS_SDHC1 IOMUX_PAD(0x458, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 514 | #define MX25_PAD_CTL_GRP_DVS_LCD IOMUX_PAD(0x45c, 0x000, 0, 0, 0, NO_PAD_CTRL) | ||
| 515 | |||
| 516 | #endif // __ASSEMBLY__ | ||
| 517 | #endif // __IOMUX_MX25_H__ | ||
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h index 2eb182f73876..446f86763816 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h | |||
| @@ -635,6 +635,19 @@ enum iomux_pins { | |||
| 635 | #define MX31_PIN_USBOTG_DIR__USBOTG_DIR IOMUX_MODE(MX31_PIN_USBOTG_DIR, IOMUX_CONFIG_FUNC) | 635 | #define MX31_PIN_USBOTG_DIR__USBOTG_DIR IOMUX_MODE(MX31_PIN_USBOTG_DIR, IOMUX_CONFIG_FUNC) |
| 636 | #define MX31_PIN_USBOTG_NXT__USBOTG_NXT IOMUX_MODE(MX31_PIN_USBOTG_NXT, IOMUX_CONFIG_FUNC) | 636 | #define MX31_PIN_USBOTG_NXT__USBOTG_NXT IOMUX_MODE(MX31_PIN_USBOTG_NXT, IOMUX_CONFIG_FUNC) |
| 637 | #define MX31_PIN_USBOTG_STP__USBOTG_STP IOMUX_MODE(MX31_PIN_USBOTG_STP, IOMUX_CONFIG_FUNC) | 637 | #define MX31_PIN_USBOTG_STP__USBOTG_STP IOMUX_MODE(MX31_PIN_USBOTG_STP, IOMUX_CONFIG_FUNC) |
| 638 | #define MX31_PIN_CSPI1_MOSI__USBH1_RXDM IOMUX_MODE(MX31_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT1) | ||
| 639 | #define MX31_PIN_CSPI1_MISO__USBH1_RXDP IOMUX_MODE(MX31_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT1) | ||
| 640 | #define MX31_PIN_CSPI1_SS0__USBH1_TXDM IOMUX_MODE(MX31_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT1) | ||
| 641 | #define MX31_PIN_CSPI1_SS1__USBH1_TXDP IOMUX_MODE(MX31_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT1) | ||
| 642 | #define MX31_PIN_CSPI1_SS2__USBH1_RCV IOMUX_MODE(MX31_PIN_CSPI1_SS2, IOMUX_CONFIG_ALT1) | ||
| 643 | #define MX31_PIN_CSPI1_SCLK__USBH1_OEB IOMUX_MODE(MX31_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT1) | ||
| 644 | #define MX31_PIN_CSPI1_SPI_RDY__USBH1_FS IOMUX_MODE(MX31_PIN_CSPI1_SPI_RDY, IOMUX_CONFIG_ALT1) | ||
| 645 | #define MX31_PIN_USBH2_DATA0__USBH2_DATA0 IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC) | ||
| 646 | #define MX31_PIN_USBH2_DATA1__USBH2_DATA1 IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC) | ||
| 647 | #define MX31_PIN_USBH2_CLK__USBH2_CLK IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC) | ||
| 648 | #define MX31_PIN_USBH2_DIR__USBH2_DIR IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC) | ||
| 649 | #define MX31_PIN_USBH2_NXT__USBH2_NXT IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC) | ||
| 650 | #define MX31_PIN_USBH2_STP__USBH2_STP IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC) | ||
| 638 | #define MX31_PIN_USB_OC__GPIO1_30 IOMUX_MODE(MX31_PIN_USB_OC, IOMUX_CONFIG_GPIO) | 651 | #define MX31_PIN_USB_OC__GPIO1_30 IOMUX_MODE(MX31_PIN_USB_OC, IOMUX_CONFIG_GPIO) |
| 639 | #define MX31_PIN_I2C_DAT__I2C1_SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC) | 652 | #define MX31_PIN_I2C_DAT__I2C1_SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC) |
| 640 | #define MX31_PIN_I2C_CLK__I2C1_SCL IOMUX_MODE(MX31_PIN_I2C_CLK, IOMUX_CONFIG_FUNC) | 653 | #define MX31_PIN_I2C_CLK__I2C1_SCL IOMUX_MODE(MX31_PIN_I2C_CLK, IOMUX_CONFIG_FUNC) |
| @@ -669,6 +682,18 @@ enum iomux_pins { | |||
| 669 | #define MX31_PIN_GPIO3_0__GPIO3_0 IOMUX_MODE(MX31_PIN_GPIO3_0, IOMUX_CONFIG_GPIO) | 682 | #define MX31_PIN_GPIO3_0__GPIO3_0 IOMUX_MODE(MX31_PIN_GPIO3_0, IOMUX_CONFIG_GPIO) |
| 670 | #define MX31_PIN_GPIO3_1__GPIO3_1 IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO) | 683 | #define MX31_PIN_GPIO3_1__GPIO3_1 IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO) |
| 671 | #define MX31_PIN_TXD2__GPIO1_28 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_GPIO) | 684 | #define MX31_PIN_TXD2__GPIO1_28 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_GPIO) |
| 685 | #define MX31_PIN_GPIO1_0__GPIO1_0 IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO) | ||
| 686 | #define MX31_PIN_SVEN0__GPIO2_0 IOMUX_MODE(MX31_PIN_SVEN0, IOMUX_CONFIG_GPIO) | ||
| 687 | #define MX31_PIN_STX0__GPIO2_1 IOMUX_MODE(MX31_PIN_STX0, IOMUX_CONFIG_GPIO) | ||
| 688 | #define MX31_PIN_SRX0__GPIO2_2 IOMUX_MODE(MX31_PIN_SRX0, IOMUX_CONFIG_GPIO) | ||
| 689 | #define MX31_PIN_SIMPD0__GPIO2_3 IOMUX_MODE(MX31_PIN_SIMPD0, IOMUX_CONFIG_GPIO) | ||
| 690 | #define MX31_PIN_DTR_DCE1__GPIO2_8 IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO) | ||
| 691 | #define MX31_PIN_DSR_DCE1__GPIO2_9 IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_GPIO) | ||
| 692 | #define MX31_PIN_RI_DCE1__GPIO2_10 IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_GPIO) | ||
| 693 | #define MX31_PIN_DCD_DCE1__GPIO2_11 IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_GPIO) | ||
| 694 | #define MX31_PIN_STXD5__GPIO1_21 IOMUX_MODE(MX31_PIN_STXD5, IOMUX_CONFIG_GPIO) | ||
| 695 | #define MX31_PIN_SRXD5__GPIO1_22 IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_GPIO) | ||
| 696 | |||
| 672 | 697 | ||
| 673 | /*XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed by cspi2_ss0, cspi2_ss1, cspi1_ss0 | 698 | /*XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed by cspi2_ss0, cspi2_ss1, cspi1_ss0 |
| 674 | * cspi1_ss1*/ | 699 | * cspi1_ss1*/ |
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h new file mode 100644 index 000000000000..9f13061192c8 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h | |||
| @@ -0,0 +1,287 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 3 | * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> | ||
| 4 | * Copyright (C) 2009 by Dmitriy Taychenachev <dimichxp@gmail.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef __MACH_IOMUX_MXC91231_H__ | ||
| 22 | #define __MACH_IOMUX_MXC91231_H__ | ||
| 23 | |||
| 24 | /* | ||
| 25 | * various IOMUX output functions | ||
| 26 | */ | ||
| 27 | |||
| 28 | #define IOMUX_OCONFIG_GPIO (0 << 4) /* used as GPIO */ | ||
| 29 | #define IOMUX_OCONFIG_FUNC (1 << 4) /* used as function */ | ||
| 30 | #define IOMUX_OCONFIG_ALT1 (2 << 4) /* used as alternate function 1 */ | ||
| 31 | #define IOMUX_OCONFIG_ALT2 (3 << 4) /* used as alternate function 2 */ | ||
| 32 | #define IOMUX_OCONFIG_ALT3 (4 << 4) /* used as alternate function 3 */ | ||
| 33 | #define IOMUX_OCONFIG_ALT4 (5 << 4) /* used as alternate function 4 */ | ||
| 34 | #define IOMUX_OCONFIG_ALT5 (6 << 4) /* used as alternate function 5 */ | ||
| 35 | #define IOMUX_OCONFIG_ALT6 (7 << 4) /* used as alternate function 6 */ | ||
| 36 | #define IOMUX_ICONFIG_NONE 0 /* not configured for input */ | ||
| 37 | #define IOMUX_ICONFIG_GPIO 1 /* used as GPIO */ | ||
| 38 | #define IOMUX_ICONFIG_FUNC 2 /* used as function */ | ||
| 39 | #define IOMUX_ICONFIG_ALT1 4 /* used as alternate function 1 */ | ||
| 40 | #define IOMUX_ICONFIG_ALT2 8 /* used as alternate function 2 */ | ||
| 41 | |||
| 42 | #define IOMUX_CONFIG_GPIO (IOMUX_OCONFIG_GPIO | IOMUX_ICONFIG_GPIO) | ||
| 43 | #define IOMUX_CONFIG_FUNC (IOMUX_OCONFIG_FUNC | IOMUX_ICONFIG_FUNC) | ||
| 44 | #define IOMUX_CONFIG_ALT1 (IOMUX_OCONFIG_ALT1 | IOMUX_ICONFIG_ALT1) | ||
| 45 | #define IOMUX_CONFIG_ALT2 (IOMUX_OCONFIG_ALT2 | IOMUX_ICONFIG_ALT2) | ||
| 46 | |||
| 47 | /* | ||
| 48 | * setups a single pin: | ||
| 49 | * - reserves the pin so that it is not claimed by another driver | ||
| 50 | * - setups the iomux according to the configuration | ||
| 51 | * - if the pin is configured as a GPIO, we claim it throug kernel gpiolib | ||
| 52 | */ | ||
| 53 | int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label); | ||
| 54 | /* | ||
| 55 | * setups mutliple pins | ||
| 56 | * convenient way to call the above function with tables | ||
| 57 | */ | ||
| 58 | int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count, | ||
| 59 | const char *label); | ||
| 60 | |||
| 61 | /* | ||
| 62 | * releases a single pin: | ||
| 63 | * - make it available for a future use by another driver | ||
| 64 | * - frees the GPIO if the pin was configured as GPIO | ||
| 65 | * - DOES NOT reconfigure the IOMUX in its reset state | ||
| 66 | */ | ||
| 67 | void mxc_iomux_release_pin(const unsigned int pin_mode); | ||
| 68 | /* | ||
| 69 | * releases multiple pins | ||
| 70 | * convenvient way to call the above function with tables | ||
| 71 | */ | ||
| 72 | void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count); | ||
| 73 | |||
| 74 | #define MUX_SIDE_AP (0) | ||
| 75 | #define MUX_SIDE_SP (1) | ||
| 76 | |||
| 77 | #define MUX_SIDE_SHIFT (26) | ||
| 78 | #define MUX_SIDE_MASK (0x1 << MUX_SIDE_SHIFT) | ||
| 79 | |||
| 80 | #define MUX_GPIO_PORT_SHIFT (23) | ||
| 81 | #define MUX_GPIO_PORT_MASK (0x7 << MUX_GPIO_PORT_SHIFT) | ||
| 82 | |||
| 83 | #define MUX_GPIO_PIN_SHIFT (20) | ||
| 84 | #define MUX_GPIO_PIN_MASK (0x1f << MUX_GPIO_PIN_SHIFT) | ||
| 85 | |||
| 86 | #define MUX_REG_SHIFT (15) | ||
| 87 | #define MUX_REG_MASK (0x1f << MUX_REG_SHIFT) | ||
| 88 | |||
| 89 | #define MUX_FIELD_SHIFT (13) | ||
| 90 | #define MUX_FIELD_MASK (0x3 << MUX_FIELD_SHIFT) | ||
| 91 | |||
| 92 | #define MUX_PADGRP_SHIFT (8) | ||
| 93 | #define MUX_PADGRP_MASK (0x1f << MUX_PADGRP_SHIFT) | ||
| 94 | |||
| 95 | #define MUX_PIN_MASK (0xffffff << 8) | ||
| 96 | |||
| 97 | #define GPIO_PORT_MAX (3) | ||
| 98 | |||
| 99 | #define IOMUX_PIN(side, gport, gpin, ctlreg, ctlfield, padgrp) \ | ||
| 100 | (((side) << MUX_SIDE_SHIFT) | \ | ||
| 101 | (gport << MUX_GPIO_PORT_SHIFT) | \ | ||
| 102 | ((gpin) << MUX_GPIO_PIN_SHIFT) | \ | ||
| 103 | ((ctlreg) << MUX_REG_SHIFT) | \ | ||
| 104 | ((ctlfield) << MUX_FIELD_SHIFT) | \ | ||
| 105 | ((padgrp) << MUX_PADGRP_SHIFT)) | ||
| 106 | |||
| 107 | #define MUX_MODE_OUT_SHIFT (4) | ||
| 108 | #define MUX_MODE_IN_SHIFT (0) | ||
| 109 | #define MUX_MODE_SHIFT (0) | ||
| 110 | #define MUX_MODE_MASK (0xff << MUX_MODE_SHIFT) | ||
| 111 | |||
| 112 | #define IOMUX_MODE(pin, mode) \ | ||
| 113 | (pin | (mode << MUX_MODE_SHIFT)) | ||
| 114 | |||
| 115 | enum iomux_pins { | ||
| 116 | /* AP Side pins */ | ||
| 117 | MXC91231_PIN_AP_CLE = IOMUX_PIN(0, 0, 0, 0, 0, 24), | ||
| 118 | MXC91231_PIN_AP_ALE = IOMUX_PIN(0, 0, 1, 0, 1, 24), | ||
| 119 | MXC91231_PIN_AP_CE_B = IOMUX_PIN(0, 0, 2, 0, 2, 24), | ||
| 120 | MXC91231_PIN_AP_RE_B = IOMUX_PIN(0, 0, 3, 0, 3, 24), | ||
| 121 | MXC91231_PIN_AP_WE_B = IOMUX_PIN(0, 0, 4, 1, 0, 24), | ||
| 122 | MXC91231_PIN_AP_WP_B = IOMUX_PIN(0, 0, 5, 1, 1, 24), | ||
| 123 | MXC91231_PIN_AP_BSY_B = IOMUX_PIN(0, 0, 6, 1, 2, 24), | ||
| 124 | MXC91231_PIN_AP_U1_TXD = IOMUX_PIN(0, 0, 7, 1, 3, 28), | ||
| 125 | MXC91231_PIN_AP_U1_RXD = IOMUX_PIN(0, 0, 8, 2, 0, 28), | ||
| 126 | MXC91231_PIN_AP_U1_RTS_B = IOMUX_PIN(0, 0, 9, 2, 1, 28), | ||
| 127 | MXC91231_PIN_AP_U1_CTS_B = IOMUX_PIN(0, 0, 10, 2, 2, 28), | ||
| 128 | MXC91231_PIN_AP_AD1_TXD = IOMUX_PIN(0, 0, 11, 2, 3, 9), | ||
| 129 | MXC91231_PIN_AP_AD1_RXD = IOMUX_PIN(0, 0, 12, 3, 0, 9), | ||
| 130 | MXC91231_PIN_AP_AD1_TXC = IOMUX_PIN(0, 0, 13, 3, 1, 9), | ||
| 131 | MXC91231_PIN_AP_AD1_TXFS = IOMUX_PIN(0, 0, 14, 3, 2, 9), | ||
| 132 | MXC91231_PIN_AP_AD2_TXD = IOMUX_PIN(0, 0, 15, 3, 3, 9), | ||
| 133 | MXC91231_PIN_AP_AD2_RXD = IOMUX_PIN(0, 0, 16, 4, 0, 9), | ||
| 134 | MXC91231_PIN_AP_AD2_TXC = IOMUX_PIN(0, 0, 17, 4, 1, 9), | ||
| 135 | MXC91231_PIN_AP_AD2_TXFS = IOMUX_PIN(0, 0, 18, 4, 2, 9), | ||
| 136 | MXC91231_PIN_AP_OWDAT = IOMUX_PIN(0, 0, 19, 4, 3, 28), | ||
| 137 | MXC91231_PIN_AP_IPU_LD17 = IOMUX_PIN(0, 0, 20, 5, 0, 28), | ||
| 138 | MXC91231_PIN_AP_IPU_D3_VSYNC = IOMUX_PIN(0, 0, 21, 5, 1, 28), | ||
| 139 | MXC91231_PIN_AP_IPU_D3_HSYNC = IOMUX_PIN(0, 0, 22, 5, 2, 28), | ||
| 140 | MXC91231_PIN_AP_IPU_D3_CLK = IOMUX_PIN(0, 0, 23, 5, 3, 28), | ||
| 141 | MXC91231_PIN_AP_IPU_D3_DRDY = IOMUX_PIN(0, 0, 24, 6, 0, 28), | ||
| 142 | MXC91231_PIN_AP_IPU_D3_CONTR = IOMUX_PIN(0, 0, 25, 6, 1, 28), | ||
| 143 | MXC91231_PIN_AP_IPU_D0_CS = IOMUX_PIN(0, 0, 26, 6, 2, 28), | ||
| 144 | MXC91231_PIN_AP_IPU_LD16 = IOMUX_PIN(0, 0, 27, 6, 3, 28), | ||
| 145 | MXC91231_PIN_AP_IPU_D2_CS = IOMUX_PIN(0, 0, 28, 7, 0, 28), | ||
| 146 | MXC91231_PIN_AP_IPU_PAR_RS = IOMUX_PIN(0, 0, 29, 7, 1, 28), | ||
| 147 | MXC91231_PIN_AP_IPU_D3_PS = IOMUX_PIN(0, 0, 30, 7, 2, 28), | ||
| 148 | MXC91231_PIN_AP_IPU_D3_CLS = IOMUX_PIN(0, 0, 31, 7, 3, 28), | ||
| 149 | MXC91231_PIN_AP_IPU_RD = IOMUX_PIN(0, 1, 0, 8, 0, 28), | ||
| 150 | MXC91231_PIN_AP_IPU_WR = IOMUX_PIN(0, 1, 1, 8, 1, 28), | ||
| 151 | MXC91231_PIN_AP_IPU_LD0 = IOMUX_PIN(0, 7, 0, 8, 2, 28), | ||
| 152 | MXC91231_PIN_AP_IPU_LD1 = IOMUX_PIN(0, 7, 0, 8, 3, 28), | ||
| 153 | MXC91231_PIN_AP_IPU_LD2 = IOMUX_PIN(0, 7, 0, 9, 0, 28), | ||
| 154 | MXC91231_PIN_AP_IPU_LD3 = IOMUX_PIN(0, 1, 2, 9, 1, 28), | ||
| 155 | MXC91231_PIN_AP_IPU_LD4 = IOMUX_PIN(0, 1, 3, 9, 2, 28), | ||
| 156 | MXC91231_PIN_AP_IPU_LD5 = IOMUX_PIN(0, 1, 4, 9, 3, 28), | ||
| 157 | MXC91231_PIN_AP_IPU_LD6 = IOMUX_PIN(0, 1, 5, 10, 0, 28), | ||
| 158 | MXC91231_PIN_AP_IPU_LD7 = IOMUX_PIN(0, 1, 6, 10, 1, 28), | ||
| 159 | MXC91231_PIN_AP_IPU_LD8 = IOMUX_PIN(0, 1, 7, 10, 2, 28), | ||
| 160 | MXC91231_PIN_AP_IPU_LD9 = IOMUX_PIN(0, 1, 8, 10, 3, 28), | ||
| 161 | MXC91231_PIN_AP_IPU_LD10 = IOMUX_PIN(0, 1, 9, 11, 0, 28), | ||
| 162 | MXC91231_PIN_AP_IPU_LD11 = IOMUX_PIN(0, 1, 10, 11, 1, 28), | ||
| 163 | MXC91231_PIN_AP_IPU_LD12 = IOMUX_PIN(0, 1, 11, 11, 2, 28), | ||
| 164 | MXC91231_PIN_AP_IPU_LD13 = IOMUX_PIN(0, 1, 12, 11, 3, 28), | ||
| 165 | MXC91231_PIN_AP_IPU_LD14 = IOMUX_PIN(0, 1, 13, 12, 0, 28), | ||
| 166 | MXC91231_PIN_AP_IPU_LD15 = IOMUX_PIN(0, 1, 14, 12, 1, 28), | ||
| 167 | MXC91231_PIN_AP_KPROW4 = IOMUX_PIN(0, 7, 0, 12, 2, 10), | ||
| 168 | MXC91231_PIN_AP_KPROW5 = IOMUX_PIN(0, 1, 16, 12, 3, 10), | ||
| 169 | MXC91231_PIN_AP_GPIO_AP_B17 = IOMUX_PIN(0, 1, 17, 13, 0, 10), | ||
| 170 | MXC91231_PIN_AP_GPIO_AP_B18 = IOMUX_PIN(0, 1, 18, 13, 1, 10), | ||
| 171 | MXC91231_PIN_AP_KPCOL3 = IOMUX_PIN(0, 1, 19, 13, 2, 11), | ||
| 172 | MXC91231_PIN_AP_KPCOL4 = IOMUX_PIN(0, 1, 20, 13, 3, 11), | ||
| 173 | MXC91231_PIN_AP_KPCOL5 = IOMUX_PIN(0, 1, 21, 14, 0, 11), | ||
| 174 | MXC91231_PIN_AP_GPIO_AP_B22 = IOMUX_PIN(0, 1, 22, 14, 1, 11), | ||
| 175 | MXC91231_PIN_AP_GPIO_AP_B23 = IOMUX_PIN(0, 1, 23, 14, 2, 11), | ||
| 176 | MXC91231_PIN_AP_CSI_D0 = IOMUX_PIN(0, 1, 24, 14, 3, 21), | ||
| 177 | MXC91231_PIN_AP_CSI_D1 = IOMUX_PIN(0, 1, 25, 15, 0, 21), | ||
| 178 | MXC91231_PIN_AP_CSI_D2 = IOMUX_PIN(0, 1, 26, 15, 1, 21), | ||
| 179 | MXC91231_PIN_AP_CSI_D3 = IOMUX_PIN(0, 1, 27, 15, 2, 21), | ||
| 180 | MXC91231_PIN_AP_CSI_D4 = IOMUX_PIN(0, 1, 28, 15, 3, 21), | ||
| 181 | MXC91231_PIN_AP_CSI_D5 = IOMUX_PIN(0, 1, 29, 16, 0, 21), | ||
| 182 | MXC91231_PIN_AP_CSI_D6 = IOMUX_PIN(0, 1, 30, 16, 1, 21), | ||
| 183 | MXC91231_PIN_AP_CSI_D7 = IOMUX_PIN(0, 1, 31, 16, 2, 21), | ||
| 184 | MXC91231_PIN_AP_CSI_D8 = IOMUX_PIN(0, 2, 0, 16, 3, 21), | ||
| 185 | MXC91231_PIN_AP_CSI_D9 = IOMUX_PIN(0, 2, 1, 17, 0, 21), | ||
| 186 | MXC91231_PIN_AP_CSI_MCLK = IOMUX_PIN(0, 2, 2, 17, 1, 21), | ||
| 187 | MXC91231_PIN_AP_CSI_VSYNC = IOMUX_PIN(0, 2, 3, 17, 2, 21), | ||
| 188 | MXC91231_PIN_AP_CSI_HSYNC = IOMUX_PIN(0, 2, 4, 17, 3, 21), | ||
| 189 | MXC91231_PIN_AP_CSI_PIXCLK = IOMUX_PIN(0, 2, 5, 18, 0, 21), | ||
| 190 | MXC91231_PIN_AP_I2CLK = IOMUX_PIN(0, 2, 6, 18, 1, 12), | ||
| 191 | MXC91231_PIN_AP_I2DAT = IOMUX_PIN(0, 2, 7, 18, 2, 12), | ||
| 192 | MXC91231_PIN_AP_GPIO_AP_C8 = IOMUX_PIN(0, 2, 8, 18, 3, 9), | ||
| 193 | MXC91231_PIN_AP_GPIO_AP_C9 = IOMUX_PIN(0, 2, 9, 19, 0, 9), | ||
| 194 | MXC91231_PIN_AP_GPIO_AP_C10 = IOMUX_PIN(0, 2, 10, 19, 1, 9), | ||
| 195 | MXC91231_PIN_AP_GPIO_AP_C11 = IOMUX_PIN(0, 2, 11, 19, 2, 9), | ||
| 196 | MXC91231_PIN_AP_GPIO_AP_C12 = IOMUX_PIN(0, 2, 12, 19, 3, 9), | ||
| 197 | MXC91231_PIN_AP_GPIO_AP_C13 = IOMUX_PIN(0, 2, 13, 20, 0, 28), | ||
| 198 | MXC91231_PIN_AP_GPIO_AP_C14 = IOMUX_PIN(0, 2, 14, 20, 1, 28), | ||
| 199 | MXC91231_PIN_AP_GPIO_AP_C15 = IOMUX_PIN(0, 2, 15, 20, 2, 9), | ||
| 200 | MXC91231_PIN_AP_GPIO_AP_C16 = IOMUX_PIN(0, 2, 16, 20, 3, 9), | ||
| 201 | MXC91231_PIN_AP_GPIO_AP_C17 = IOMUX_PIN(0, 2, 17, 21, 0, 9), | ||
| 202 | MXC91231_PIN_AP_ED_INT0 = IOMUX_PIN(0, 2, 18, 21, 1, 22), | ||
| 203 | MXC91231_PIN_AP_ED_INT1 = IOMUX_PIN(0, 2, 19, 21, 2, 22), | ||
| 204 | MXC91231_PIN_AP_ED_INT2 = IOMUX_PIN(0, 2, 20, 21, 3, 22), | ||
| 205 | MXC91231_PIN_AP_ED_INT3 = IOMUX_PIN(0, 2, 21, 22, 0, 22), | ||
| 206 | MXC91231_PIN_AP_ED_INT4 = IOMUX_PIN(0, 2, 22, 22, 1, 23), | ||
| 207 | MXC91231_PIN_AP_ED_INT5 = IOMUX_PIN(0, 2, 23, 22, 2, 23), | ||
| 208 | MXC91231_PIN_AP_ED_INT6 = IOMUX_PIN(0, 2, 24, 22, 3, 23), | ||
| 209 | MXC91231_PIN_AP_ED_INT7 = IOMUX_PIN(0, 2, 25, 23, 0, 23), | ||
| 210 | MXC91231_PIN_AP_U2_DSR_B = IOMUX_PIN(0, 2, 26, 23, 1, 28), | ||
| 211 | MXC91231_PIN_AP_U2_RI_B = IOMUX_PIN(0, 2, 27, 23, 2, 28), | ||
| 212 | MXC91231_PIN_AP_U2_CTS_B = IOMUX_PIN(0, 2, 28, 23, 3, 28), | ||
| 213 | MXC91231_PIN_AP_U2_DTR_B = IOMUX_PIN(0, 2, 29, 24, 0, 28), | ||
| 214 | MXC91231_PIN_AP_KPROW0 = IOMUX_PIN(0, 7, 0, 24, 1, 10), | ||
| 215 | MXC91231_PIN_AP_KPROW1 = IOMUX_PIN(0, 1, 15, 24, 2, 10), | ||
| 216 | MXC91231_PIN_AP_KPROW2 = IOMUX_PIN(0, 7, 0, 24, 3, 10), | ||
| 217 | MXC91231_PIN_AP_KPROW3 = IOMUX_PIN(0, 7, 0, 25, 0, 10), | ||
| 218 | MXC91231_PIN_AP_KPCOL0 = IOMUX_PIN(0, 7, 0, 25, 1, 11), | ||
| 219 | MXC91231_PIN_AP_KPCOL1 = IOMUX_PIN(0, 7, 0, 25, 2, 11), | ||
| 220 | MXC91231_PIN_AP_KPCOL2 = IOMUX_PIN(0, 7, 0, 25, 3, 11), | ||
| 221 | |||
| 222 | /* Shared pins */ | ||
| 223 | MXC91231_PIN_SP_U3_TXD = IOMUX_PIN(1, 3, 0, 0, 0, 28), | ||
| 224 | MXC91231_PIN_SP_U3_RXD = IOMUX_PIN(1, 3, 1, 0, 1, 28), | ||
| 225 | MXC91231_PIN_SP_U3_RTS_B = IOMUX_PIN(1, 3, 2, 0, 2, 28), | ||
| 226 | MXC91231_PIN_SP_U3_CTS_B = IOMUX_PIN(1, 3, 3, 0, 3, 28), | ||
| 227 | MXC91231_PIN_SP_USB_TXOE_B = IOMUX_PIN(1, 3, 4, 1, 0, 28), | ||
| 228 | MXC91231_PIN_SP_USB_DAT_VP = IOMUX_PIN(1, 3, 5, 1, 1, 28), | ||
| 229 | MXC91231_PIN_SP_USB_SE0_VM = IOMUX_PIN(1, 3, 6, 1, 2, 28), | ||
| 230 | MXC91231_PIN_SP_USB_RXD = IOMUX_PIN(1, 3, 7, 1, 3, 28), | ||
| 231 | MXC91231_PIN_SP_UH2_TXOE_B = IOMUX_PIN(1, 3, 8, 2, 0, 28), | ||
| 232 | MXC91231_PIN_SP_UH2_SPEED = IOMUX_PIN(1, 3, 9, 2, 1, 28), | ||
| 233 | MXC91231_PIN_SP_UH2_SUSPEN = IOMUX_PIN(1, 3, 10, 2, 2, 28), | ||
| 234 | MXC91231_PIN_SP_UH2_TXDP = IOMUX_PIN(1, 3, 11, 2, 3, 28), | ||
| 235 | MXC91231_PIN_SP_UH2_RXDP = IOMUX_PIN(1, 3, 12, 3, 0, 28), | ||
| 236 | MXC91231_PIN_SP_UH2_RXDM = IOMUX_PIN(1, 3, 13, 3, 1, 28), | ||
| 237 | MXC91231_PIN_SP_UH2_OVR = IOMUX_PIN(1, 3, 14, 3, 2, 28), | ||
| 238 | MXC91231_PIN_SP_UH2_PWR = IOMUX_PIN(1, 3, 15, 3, 3, 28), | ||
| 239 | MXC91231_PIN_SP_SD1_DAT0 = IOMUX_PIN(1, 3, 16, 4, 0, 25), | ||
| 240 | MXC91231_PIN_SP_SD1_DAT1 = IOMUX_PIN(1, 3, 17, 4, 1, 25), | ||
| 241 | MXC91231_PIN_SP_SD1_DAT2 = IOMUX_PIN(1, 3, 18, 4, 2, 25), | ||
| 242 | MXC91231_PIN_SP_SD1_DAT3 = IOMUX_PIN(1, 3, 19, 4, 3, 25), | ||
| 243 | MXC91231_PIN_SP_SD1_CMD = IOMUX_PIN(1, 3, 20, 5, 0, 25), | ||
| 244 | MXC91231_PIN_SP_SD1_CLK = IOMUX_PIN(1, 3, 21, 5, 1, 25), | ||
| 245 | MXC91231_PIN_SP_SD2_DAT0 = IOMUX_PIN(1, 3, 22, 5, 2, 26), | ||
| 246 | MXC91231_PIN_SP_SD2_DAT1 = IOMUX_PIN(1, 3, 23, 5, 3, 26), | ||
| 247 | MXC91231_PIN_SP_SD2_DAT2 = IOMUX_PIN(1, 3, 24, 6, 0, 26), | ||
| 248 | MXC91231_PIN_SP_SD2_DAT3 = IOMUX_PIN(1, 3, 25, 6, 1, 26), | ||
| 249 | MXC91231_PIN_SP_GPIO_SP_A26 = IOMUX_PIN(1, 3, 26, 6, 2, 28), | ||
| 250 | MXC91231_PIN_SP_SPI1_CLK = IOMUX_PIN(1, 3, 27, 6, 3, 13), | ||
| 251 | MXC91231_PIN_SP_SPI1_MOSI = IOMUX_PIN(1, 3, 28, 7, 0, 13), | ||
| 252 | MXC91231_PIN_SP_SPI1_MISO = IOMUX_PIN(1, 3, 29, 7, 1, 13), | ||
| 253 | MXC91231_PIN_SP_SPI1_SS0 = IOMUX_PIN(1, 3, 30, 7, 2, 13), | ||
| 254 | MXC91231_PIN_SP_SPI1_SS1 = IOMUX_PIN(1, 3, 31, 7, 3, 13), | ||
| 255 | MXC91231_PIN_SP_SD2_CMD = IOMUX_PIN(1, 7, 0, 8, 0, 26), | ||
| 256 | MXC91231_PIN_SP_SD2_CLK = IOMUX_PIN(1, 7, 0, 8, 1, 26), | ||
| 257 | MXC91231_PIN_SP_SIM1_RST_B = IOMUX_PIN(1, 2, 30, 8, 2, 28), | ||
| 258 | MXC91231_PIN_SP_SIM1_SVEN = IOMUX_PIN(1, 7, 0, 8, 3, 28), | ||
| 259 | MXC91231_PIN_SP_SIM1_CLK = IOMUX_PIN(1, 7, 0, 9, 0, 28), | ||
| 260 | MXC91231_PIN_SP_SIM1_TRXD = IOMUX_PIN(1, 7, 0, 9, 1, 28), | ||
| 261 | MXC91231_PIN_SP_SIM1_PD = IOMUX_PIN(1, 2, 31, 9, 2, 28), | ||
| 262 | MXC91231_PIN_SP_UH2_TXDM = IOMUX_PIN(1, 7, 0, 9, 3, 28), | ||
| 263 | MXC91231_PIN_SP_UH2_RXD = IOMUX_PIN(1, 7, 0, 10, 0, 28), | ||
| 264 | }; | ||
| 265 | |||
| 266 | #define PIN_AP_MAX (104) | ||
| 267 | #define PIN_SP_MAX (41) | ||
| 268 | |||
| 269 | #define PIN_MAX (PIN_AP_MAX + PIN_SP_MAX) | ||
| 270 | |||
| 271 | /* | ||
| 272 | * Convenience values for use with mxc_iomux_mode() | ||
| 273 | * | ||
| 274 | * Format here is MXC91231_PIN_(pin name)__(function) | ||
| 275 | */ | ||
| 276 | |||
| 277 | #define MXC91231_PIN_SP_USB_DAT_VP__USB_DAT_VP \ | ||
| 278 | IOMUX_MODE(MXC91231_PIN_SP_USB_DAT_VP, IOMUX_CONFIG_FUNC) | ||
| 279 | #define MXC91231_PIN_SP_USB_SE0_VM__USB_SE0_VM \ | ||
| 280 | IOMUX_MODE(MXC91231_PIN_SP_USB_SE0_VM, IOMUX_CONFIG_FUNC) | ||
| 281 | #define MXC91231_PIN_SP_USB_DAT_VP__RXD2 \ | ||
| 282 | IOMUX_MODE(MXC91231_PIN_SP_USB_DAT_VP, IOMUX_CONFIG_ALT1) | ||
| 283 | #define MXC91231_PIN_SP_USB_SE0_VM__TXD2 \ | ||
| 284 | IOMUX_MODE(MXC91231_PIN_SP_USB_SE0_VM, IOMUX_CONFIG_ALT1) | ||
| 285 | |||
| 286 | |||
| 287 | #endif /* __MACH_IOMUX_MXC91231_H__ */ | ||
diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h index 7cd84547658f..a0fa40265468 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-v3.h +++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h | |||
| @@ -68,28 +68,24 @@ struct pad_desc { | |||
| 68 | /* | 68 | /* |
| 69 | * Use to set PAD control | 69 | * Use to set PAD control |
| 70 | */ | 70 | */ |
| 71 | #define PAD_CTL_DRIVE_VOLTAGE_3_3_V 0 | ||
| 72 | #define PAD_CTL_DRIVE_VOLTAGE_1_8_V 1 | ||
| 73 | 71 | ||
| 74 | #define PAD_CTL_NO_HYSTERESIS 0 | 72 | #define PAD_CTL_DVS (1 << 13) |
| 75 | #define PAD_CTL_HYSTERESIS 1 | 73 | #define PAD_CTL_HYS (1 << 8) |
| 76 | 74 | ||
| 77 | #define PAD_CTL_PULL_DISABLED 0x0 | 75 | #define PAD_CTL_PKE (1 << 7) |
| 78 | #define PAD_CTL_PULL_KEEPER 0xa | 76 | #define PAD_CTL_PUE (1 << 6) |
| 79 | #define PAD_CTL_PULL_DOWN_100K 0xc | 77 | #define PAD_CTL_PUS_100K_DOWN (0 << 4) |
| 80 | #define PAD_CTL_PULL_UP_47K 0xd | 78 | #define PAD_CTL_PUS_47K_UP (1 << 4) |
| 81 | #define PAD_CTL_PULL_UP_100K 0xe | 79 | #define PAD_CTL_PUS_100K_UP (2 << 4) |
| 82 | #define PAD_CTL_PULL_UP_22K 0xf | 80 | #define PAD_CTL_PUS_22K_UP (3 << 4) |
| 83 | 81 | ||
| 84 | #define PAD_CTL_OUTPUT_CMOS 0 | 82 | #define PAD_CTL_ODE (1 << 3) |
| 85 | #define PAD_CTL_OUTPUT_OPEN_DRAIN 1 | ||
| 86 | 83 | ||
| 87 | #define PAD_CTL_DRIVE_STRENGTH_NORM 0 | 84 | #define PAD_CTL_DSE_STANDARD (0 << 1) |
| 88 | #define PAD_CTL_DRIVE_STRENGTH_HIGH 1 | 85 | #define PAD_CTL_DSE_HIGH (1 << 1) |
| 89 | #define PAD_CTL_DRIVE_STRENGTH_MAX 2 | 86 | #define PAD_CTL_DSE_MAX (2 << 1) |
| 90 | 87 | ||
| 91 | #define PAD_CTL_SLEW_RATE_SLOW 0 | 88 | #define PAD_CTL_SRE_FAST (1 << 0) |
| 92 | #define PAD_CTL_SLEW_RATE_FAST 1 | ||
| 93 | 89 | ||
| 94 | /* | 90 | /* |
| 95 | * setups a single pad: | 91 | * setups a single pad: |
| @@ -117,5 +113,10 @@ void mxc_iomux_v3_release_pad(struct pad_desc *pad); | |||
| 117 | */ | 113 | */ |
| 118 | void mxc_iomux_v3_release_multiple_pads(struct pad_desc *pad_list, int count); | 114 | void mxc_iomux_v3_release_multiple_pads(struct pad_desc *pad_list, int count); |
| 119 | 115 | ||
| 116 | /* | ||
| 117 | * Initialise the iomux controller | ||
| 118 | */ | ||
| 119 | void mxc_iomux_v3_init(void __iomem *iomux_v3_base); | ||
| 120 | |||
| 120 | #endif /* __MACH_IOMUX_V3_H__*/ | 121 | #endif /* __MACH_IOMUX_V3_H__*/ |
| 121 | 122 | ||
diff --git a/arch/arm/plat-mxc/include/mach/iomux.h b/arch/arm/plat-mxc/include/mach/iomux.h index 171f8adc1109..6d49f8ae3259 100644 --- a/arch/arm/plat-mxc/include/mach/iomux.h +++ b/arch/arm/plat-mxc/include/mach/iomux.h | |||
| @@ -49,6 +49,9 @@ | |||
| 49 | #ifdef CONFIG_ARCH_MX2 | 49 | #ifdef CONFIG_ARCH_MX2 |
| 50 | # define GPIO_PORT_MAX 5 | 50 | # define GPIO_PORT_MAX 5 |
| 51 | #endif | 51 | #endif |
| 52 | #ifdef CONFIG_ARCH_MX25 | ||
| 53 | # define GPIO_PORT_MAX 3 | ||
| 54 | #endif | ||
| 52 | 55 | ||
| 53 | #ifndef GPIO_PORT_MAX | 56 | #ifndef GPIO_PORT_MAX |
| 54 | # error "GPIO config port count unknown!" | 57 | # error "GPIO config port count unknown!" |
| @@ -107,6 +110,9 @@ | |||
| 107 | #include <mach/iomux-mx27.h> | 110 | #include <mach/iomux-mx27.h> |
| 108 | #endif | 111 | #endif |
| 109 | #endif | 112 | #endif |
| 113 | #ifdef CONFIG_ARCH_MX25 | ||
| 114 | #include <mach/iomux-mx25.h> | ||
| 115 | #endif | ||
| 110 | 116 | ||
| 111 | 117 | ||
| 112 | /* decode irq number to use with IMR(x), ISR(x) and friends */ | 118 | /* decode irq number to use with IMR(x), ISR(x) and friends */ |
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h index 518a36504b88..ead9d592168d 100644 --- a/arch/arm/plat-mxc/include/mach/irqs.h +++ b/arch/arm/plat-mxc/include/mach/irqs.h | |||
| @@ -24,6 +24,10 @@ | |||
| 24 | #define MXC_GPIO_IRQS (32 * 6) | 24 | #define MXC_GPIO_IRQS (32 * 6) |
| 25 | #elif defined CONFIG_ARCH_MX3 | 25 | #elif defined CONFIG_ARCH_MX3 |
| 26 | #define MXC_GPIO_IRQS (32 * 3) | 26 | #define MXC_GPIO_IRQS (32 * 3) |
| 27 | #elif defined CONFIG_ARCH_MX25 | ||
| 28 | #define MXC_GPIO_IRQS (32 * 4) | ||
| 29 | #elif defined CONFIG_ARCH_MXC91231 | ||
| 30 | #define MXC_GPIO_IRQS (32 * 4) | ||
| 27 | #endif | 31 | #endif |
| 28 | 32 | ||
| 29 | /* | 33 | /* |
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h index 6065e00176ed..d3afafdcc0e5 100644 --- a/arch/arm/plat-mxc/include/mach/memory.h +++ b/arch/arm/plat-mxc/include/mach/memory.h | |||
| @@ -22,6 +22,10 @@ | |||
| 22 | #endif | 22 | #endif |
| 23 | #elif defined CONFIG_ARCH_MX3 | 23 | #elif defined CONFIG_ARCH_MX3 |
| 24 | #define PHYS_OFFSET UL(0x80000000) | 24 | #define PHYS_OFFSET UL(0x80000000) |
| 25 | #elif defined CONFIG_ARCH_MX25 | ||
| 26 | #define PHYS_OFFSET UL(0x80000000) | ||
| 27 | #elif defined CONFIG_ARCH_MXC91231 | ||
| 28 | #define PHYS_OFFSET UL(0x90000000) | ||
| 25 | #endif | 29 | #endif |
| 26 | 30 | ||
| 27 | #if defined(CONFIG_MX1_VIDEO) | 31 | #if defined(CONFIG_MX1_VIDEO) |
diff --git a/arch/arm/plat-mxc/include/mach/mx1.h b/arch/arm/plat-mxc/include/mach/mx1.h index 1000bf330bcd..1b2890a5c452 100644 --- a/arch/arm/plat-mxc/include/mach/mx1.h +++ b/arch/arm/plat-mxc/include/mach/mx1.h | |||
| @@ -12,10 +12,6 @@ | |||
| 12 | #ifndef __ASM_ARCH_MXC_MX1_H__ | 12 | #ifndef __ASM_ARCH_MXC_MX1_H__ |
| 13 | #define __ASM_ARCH_MXC_MX1_H__ | 13 | #define __ASM_ARCH_MXC_MX1_H__ |
| 14 | 14 | ||
| 15 | #ifndef __ASM_ARCH_MXC_HARDWARE_H__ | ||
| 16 | #error "Do not include directly." | ||
| 17 | #endif | ||
| 18 | |||
| 19 | #include <mach/vmalloc.h> | 15 | #include <mach/vmalloc.h> |
| 20 | 16 | ||
| 21 | /* | 17 | /* |
| @@ -138,20 +134,6 @@ | |||
| 138 | #define GPIO_INT_PORTD 62 | 134 | #define GPIO_INT_PORTD 62 |
| 139 | #define WDT_INT 63 | 135 | #define WDT_INT 63 |
| 140 | 136 | ||
| 141 | /* gpio and gpio based interrupt handling */ | ||
| 142 | #define GPIO_DR 0x1C | ||
| 143 | #define GPIO_GDIR 0x00 | ||
| 144 | #define GPIO_PSR 0x24 | ||
| 145 | #define GPIO_ICR1 0x28 | ||
| 146 | #define GPIO_ICR2 0x2C | ||
| 147 | #define GPIO_IMR 0x30 | ||
| 148 | #define GPIO_ISR 0x34 | ||
| 149 | #define GPIO_INT_LOW_LEV 0x3 | ||
| 150 | #define GPIO_INT_HIGH_LEV 0x2 | ||
| 151 | #define GPIO_INT_RISE_EDGE 0x0 | ||
| 152 | #define GPIO_INT_FALL_EDGE 0x1 | ||
| 153 | #define GPIO_INT_NONE 0x4 | ||
| 154 | |||
| 155 | /* DMA */ | 137 | /* DMA */ |
| 156 | #define DMA_REQ_UART3_T 2 | 138 | #define DMA_REQ_UART3_T 2 |
| 157 | #define DMA_REQ_UART3_R 3 | 139 | #define DMA_REQ_UART3_R 3 |
| @@ -179,8 +161,4 @@ | |||
| 179 | #define DMA_REQ_UART1_T 30 | 161 | #define DMA_REQ_UART1_T 30 |
| 180 | #define DMA_REQ_UART1_R 31 | 162 | #define DMA_REQ_UART1_R 31 |
| 181 | 163 | ||
| 182 | /* mandatory for CONFIG_DEBUG_LL */ | ||
| 183 | #define MXC_LL_UART_PADDR UART1_BASE_ADDR | ||
| 184 | #define MXC_LL_UART_VADDR IO_ADDRESS(UART1_BASE_ADDR) | ||
| 185 | |||
| 186 | #endif /* __ASM_ARCH_MXC_MX1_H__ */ | 164 | #endif /* __ASM_ARCH_MXC_MX1_H__ */ |
diff --git a/arch/arm/plat-mxc/include/mach/mx21.h b/arch/arm/plat-mxc/include/mach/mx21.h index 8b070a041a99..21112c695ec5 100644 --- a/arch/arm/plat-mxc/include/mach/mx21.h +++ b/arch/arm/plat-mxc/include/mach/mx21.h | |||
| @@ -25,11 +25,6 @@ | |||
| 25 | #ifndef __ASM_ARCH_MXC_MX21_H__ | 25 | #ifndef __ASM_ARCH_MXC_MX21_H__ |
| 26 | #define __ASM_ARCH_MXC_MX21_H__ | 26 | #define __ASM_ARCH_MXC_MX21_H__ |
| 27 | 27 | ||
| 28 | #ifndef __ASM_ARCH_MXC_HARDWARE_H__ | ||
| 29 | #error "Do not include directly." | ||
| 30 | #endif | ||
| 31 | |||
| 32 | |||
| 33 | /* Memory regions and CS */ | 28 | /* Memory regions and CS */ |
| 34 | #define SDRAM_BASE_ADDR 0xC0000000 | 29 | #define SDRAM_BASE_ADDR 0xC0000000 |
| 35 | #define CSD1_BASE_ADDR 0xC4000000 | 30 | #define CSD1_BASE_ADDR 0xC4000000 |
diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h new file mode 100644 index 000000000000..ec64bd9a8ab1 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/mx25.h | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | #ifndef __MACH_MX25_H__ | ||
| 2 | #define __MACH_MX25_H__ | ||
| 3 | |||
| 4 | #define MX25_AIPS1_BASE_ADDR 0x43F00000 | ||
| 5 | #define MX25_AIPS1_BASE_ADDR_VIRT 0xFC000000 | ||
| 6 | #define MX25_AIPS1_SIZE SZ_1M | ||
| 7 | #define MX25_AIPS2_BASE_ADDR 0x53F00000 | ||
| 8 | #define MX25_AIPS2_BASE_ADDR_VIRT 0xFC200000 | ||
| 9 | #define MX25_AIPS2_SIZE SZ_1M | ||
| 10 | #define MX25_AVIC_BASE_ADDR 0x68000000 | ||
| 11 | #define MX25_AVIC_BASE_ADDR_VIRT 0xFC400000 | ||
| 12 | #define MX25_AVIC_SIZE SZ_1M | ||
| 13 | |||
| 14 | #define MX25_IOMUXC_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0xac000) | ||
| 15 | |||
| 16 | #define MX25_CRM_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x80000) | ||
| 17 | #define MX25_GPT1_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x90000) | ||
| 18 | #define MX25_WDOG_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xdc000) | ||
| 19 | |||
| 20 | #define MX25_GPIO1_BASE_ADDR_VIRT (MX25_AIPS2_BASE_ADDR_VIRT + 0xcc000) | ||
| 21 | #define MX25_GPIO2_BASE_ADDR_VIRT (MX25_AIPS2_BASE_ADDR_VIRT + 0xd0000) | ||
| 22 | #define MX25_GPIO3_BASE_ADDR_VIRT (MX25_AIPS2_BASE_ADDR_VIRT + 0xa4000) | ||
| 23 | #define MX25_GPIO4_BASE_ADDR_VIRT (MX25_AIPS2_BASE_ADDR_VIRT + 0x9c000) | ||
| 24 | |||
| 25 | #define MX25_AIPS1_IO_ADDRESS(x) \ | ||
| 26 | (((x) - MX25_AIPS1_BASE_ADDR) + MX25_AIPS1_BASE_ADDR_VIRT) | ||
| 27 | #define MX25_AIPS2_IO_ADDRESS(x) \ | ||
| 28 | (((x) - MX25_AIPS2_BASE_ADDR) + MX25_AIPS2_BASE_ADDR_VIRT) | ||
| 29 | #define MX25_AVIC_IO_ADDRESS(x) \ | ||
| 30 | (((x) - MX25_AVIC_BASE_ADDR) + MX25_AVIC_BASE_ADDR_VIRT) | ||
| 31 | |||
| 32 | #define __in_range(addr, name) ((addr) >= name##_BASE_ADDR && (addr) < name##_BASE_ADDR + name##_SIZE) | ||
| 33 | |||
| 34 | #define MX25_IO_ADDRESS(x) \ | ||
| 35 | (void __force __iomem *) \ | ||
| 36 | (__in_range(x, MX25_AIPS1) ? MX25_AIPS1_IO_ADDRESS(x) : \ | ||
| 37 | __in_range(x, MX25_AIPS2) ? MX25_AIPS2_IO_ADDRESS(x) : \ | ||
| 38 | __in_range(x, MX25_AVIC) ? MX25_AVIC_IO_ADDRESS(x) : \ | ||
| 39 | 0xDEADBEEF) | ||
| 40 | |||
| 41 | #define UART1_BASE_ADDR 0x43f90000 | ||
| 42 | #define UART2_BASE_ADDR 0x43f94000 | ||
| 43 | |||
| 44 | #endif /* __MACH_MX25_H__ */ | ||
diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h index 6e93f2c0b7bb..dc3ad9aa952a 100644 --- a/arch/arm/plat-mxc/include/mach/mx27.h +++ b/arch/arm/plat-mxc/include/mach/mx27.h | |||
| @@ -24,10 +24,6 @@ | |||
| 24 | #ifndef __ASM_ARCH_MXC_MX27_H__ | 24 | #ifndef __ASM_ARCH_MXC_MX27_H__ |
| 25 | #define __ASM_ARCH_MXC_MX27_H__ | 25 | #define __ASM_ARCH_MXC_MX27_H__ |
| 26 | 26 | ||
| 27 | #ifndef __ASM_ARCH_MXC_HARDWARE_H__ | ||
| 28 | #error "Do not include directly." | ||
| 29 | #endif | ||
| 30 | |||
| 31 | /* IRAM */ | 27 | /* IRAM */ |
| 32 | #define IRAM_BASE_ADDR 0xFFFF4C00 /* internal ram */ | 28 | #define IRAM_BASE_ADDR 0xFFFF4C00 /* internal ram */ |
| 33 | 29 | ||
| @@ -120,7 +116,4 @@ extern int mx27_revision(void); | |||
| 120 | 116 | ||
| 121 | /* Mandatory defines used globally */ | 117 | /* Mandatory defines used globally */ |
| 122 | 118 | ||
| 123 | /* this CPU supports up to 192 GPIOs (don't forget the baseboard!) */ | ||
| 124 | #define ARCH_NR_GPIOS (192 + 16) | ||
| 125 | |||
| 126 | #endif /* __ASM_ARCH_MXC_MX27_H__ */ | 119 | #endif /* __ASM_ARCH_MXC_MX27_H__ */ |
diff --git a/arch/arm/plat-mxc/include/mach/mx2x.h b/arch/arm/plat-mxc/include/mach/mx2x.h index fc40d3ab8c5b..db5d921e0fe6 100644 --- a/arch/arm/plat-mxc/include/mach/mx2x.h +++ b/arch/arm/plat-mxc/include/mach/mx2x.h | |||
| @@ -23,10 +23,6 @@ | |||
| 23 | #ifndef __ASM_ARCH_MXC_MX2x_H__ | 23 | #ifndef __ASM_ARCH_MXC_MX2x_H__ |
| 24 | #define __ASM_ARCH_MXC_MX2x_H__ | 24 | #define __ASM_ARCH_MXC_MX2x_H__ |
| 25 | 25 | ||
| 26 | #ifndef __ASM_ARCH_MXC_HARDWARE_H__ | ||
| 27 | #error "Do not include directly." | ||
| 28 | #endif | ||
| 29 | |||
| 30 | /* The following addresses are common between i.MX21 and i.MX27 */ | 26 | /* The following addresses are common between i.MX21 and i.MX27 */ |
| 31 | 27 | ||
| 32 | /* Register offests */ | 28 | /* Register offests */ |
| @@ -154,20 +150,6 @@ | |||
| 154 | #define MXC_INT_GPIO 8 | 150 | #define MXC_INT_GPIO 8 |
| 155 | #define MXC_INT_CSPI3 6 | 151 | #define MXC_INT_CSPI3 6 |
| 156 | 152 | ||
| 157 | /* gpio and gpio based interrupt handling */ | ||
| 158 | #define GPIO_DR 0x1C | ||
| 159 | #define GPIO_GDIR 0x00 | ||
| 160 | #define GPIO_PSR 0x24 | ||
| 161 | #define GPIO_ICR1 0x28 | ||
| 162 | #define GPIO_ICR2 0x2C | ||
| 163 | #define GPIO_IMR 0x30 | ||
| 164 | #define GPIO_ISR 0x34 | ||
| 165 | #define GPIO_INT_LOW_LEV 0x3 | ||
| 166 | #define GPIO_INT_HIGH_LEV 0x2 | ||
| 167 | #define GPIO_INT_RISE_EDGE 0x0 | ||
| 168 | #define GPIO_INT_FALL_EDGE 0x1 | ||
| 169 | #define GPIO_INT_NONE 0x4 | ||
| 170 | |||
| 171 | /* fixed DMA request numbers */ | 153 | /* fixed DMA request numbers */ |
| 172 | #define DMA_REQ_CSI_RX 31 | 154 | #define DMA_REQ_CSI_RX 31 |
| 173 | #define DMA_REQ_CSI_STAT 30 | 155 | #define DMA_REQ_CSI_STAT 30 |
diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/plat-mxc/include/mach/mx31.h index 0b06941b6139..14ac0dcc82f4 100644 --- a/arch/arm/plat-mxc/include/mach/mx31.h +++ b/arch/arm/plat-mxc/include/mach/mx31.h | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | #define MX31_IRAM_BASE_ADDR 0x1FFC0000 /* internal ram */ | 4 | #define MX31_IRAM_BASE_ADDR 0x1FFC0000 /* internal ram */ |
| 5 | #define MX31_IRAM_SIZE SZ_16K | 5 | #define MX31_IRAM_SIZE SZ_16K |
| 6 | 6 | ||
| 7 | #define OTG_BASE_ADDR (AIPS1_BASE_ADDR + 0x00088000) | 7 | #define MX31_OTG_BASE_ADDR (AIPS1_BASE_ADDR + 0x00088000) |
| 8 | #define ATA_BASE_ADDR (AIPS1_BASE_ADDR + 0x0008C000) | 8 | #define ATA_BASE_ADDR (AIPS1_BASE_ADDR + 0x0008C000) |
| 9 | #define UART4_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B0000) | 9 | #define UART4_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B0000) |
| 10 | #define UART5_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B4000) | 10 | #define UART5_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B4000) |
diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/plat-mxc/include/mach/mx35.h index 6465fefb42e3..ab4cfec6c8ab 100644 --- a/arch/arm/plat-mxc/include/mach/mx35.h +++ b/arch/arm/plat-mxc/include/mach/mx35.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #define MX35_IRAM_SIZE SZ_128K | 5 | #define MX35_IRAM_SIZE SZ_128K |
| 6 | 6 | ||
| 7 | #define MXC_FEC_BASE_ADDR 0x50038000 | 7 | #define MXC_FEC_BASE_ADDR 0x50038000 |
| 8 | #define MX35_OTG_BASE_ADDR 0x53ff4000 | ||
| 8 | #define MX35_NFC_BASE_ADDR 0xBB000000 | 9 | #define MX35_NFC_BASE_ADDR 0xBB000000 |
| 9 | 10 | ||
| 10 | /* | 11 | /* |
diff --git a/arch/arm/plat-mxc/include/mach/mx3x.h b/arch/arm/plat-mxc/include/mach/mx3x.h index b559a4bb5769..009f4440276b 100644 --- a/arch/arm/plat-mxc/include/mach/mx3x.h +++ b/arch/arm/plat-mxc/include/mach/mx3x.h | |||
| @@ -11,10 +11,6 @@ | |||
| 11 | #ifndef __ASM_ARCH_MXC_MX31_H__ | 11 | #ifndef __ASM_ARCH_MXC_MX31_H__ |
| 12 | #define __ASM_ARCH_MXC_MX31_H__ | 12 | #define __ASM_ARCH_MXC_MX31_H__ |
| 13 | 13 | ||
| 14 | #ifndef __ASM_ARCH_MXC_HARDWARE_H__ | ||
| 15 | #error "Do not include directly." | ||
| 16 | #endif | ||
| 17 | |||
| 18 | /* | 14 | /* |
| 19 | * MX31 memory map: | 15 | * MX31 memory map: |
| 20 | * | 16 | * |
| @@ -263,25 +259,8 @@ | |||
| 263 | #define SYSTEM_REV_MIN CHIP_REV_1_0 | 259 | #define SYSTEM_REV_MIN CHIP_REV_1_0 |
| 264 | #define SYSTEM_REV_NUM 3 | 260 | #define SYSTEM_REV_NUM 3 |
| 265 | 261 | ||
| 266 | /* gpio and gpio based interrupt handling */ | ||
| 267 | #define GPIO_DR 0x00 | ||
| 268 | #define GPIO_GDIR 0x04 | ||
| 269 | #define GPIO_PSR 0x08 | ||
| 270 | #define GPIO_ICR1 0x0C | ||
| 271 | #define GPIO_ICR2 0x10 | ||
| 272 | #define GPIO_IMR 0x14 | ||
| 273 | #define GPIO_ISR 0x18 | ||
| 274 | #define GPIO_INT_LOW_LEV 0x0 | ||
| 275 | #define GPIO_INT_HIGH_LEV 0x1 | ||
| 276 | #define GPIO_INT_RISE_EDGE 0x2 | ||
| 277 | #define GPIO_INT_FALL_EDGE 0x3 | ||
| 278 | #define GPIO_INT_NONE 0x4 | ||
| 279 | |||
| 280 | /* Mandatory defines used globally */ | 262 | /* Mandatory defines used globally */ |
| 281 | 263 | ||
| 282 | /* this CPU supports up to 96 GPIOs */ | ||
| 283 | #define ARCH_NR_GPIOS 96 | ||
| 284 | |||
| 285 | #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) | 264 | #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) |
| 286 | 265 | ||
| 287 | extern unsigned int system_rev; | 266 | extern unsigned int system_rev; |
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h index 5fa2a07f4eaf..51990536b845 100644 --- a/arch/arm/plat-mxc/include/mach/mxc.h +++ b/arch/arm/plat-mxc/include/mach/mxc.h | |||
| @@ -26,9 +26,11 @@ | |||
| 26 | 26 | ||
| 27 | #define MXC_CPU_MX1 1 | 27 | #define MXC_CPU_MX1 1 |
| 28 | #define MXC_CPU_MX21 21 | 28 | #define MXC_CPU_MX21 21 |
| 29 | #define MXC_CPU_MX25 25 | ||
| 29 | #define MXC_CPU_MX27 27 | 30 | #define MXC_CPU_MX27 27 |
| 30 | #define MXC_CPU_MX31 31 | 31 | #define MXC_CPU_MX31 31 |
| 31 | #define MXC_CPU_MX35 35 | 32 | #define MXC_CPU_MX35 35 |
| 33 | #define MXC_CPU_MXC91231 91231 | ||
| 32 | 34 | ||
| 33 | #ifndef __ASSEMBLY__ | 35 | #ifndef __ASSEMBLY__ |
| 34 | extern unsigned int __mxc_cpu_type; | 36 | extern unsigned int __mxc_cpu_type; |
| @@ -58,6 +60,18 @@ extern unsigned int __mxc_cpu_type; | |||
| 58 | # define cpu_is_mx21() (0) | 60 | # define cpu_is_mx21() (0) |
| 59 | #endif | 61 | #endif |
| 60 | 62 | ||
| 63 | #ifdef CONFIG_ARCH_MX25 | ||
| 64 | # ifdef mxc_cpu_type | ||
| 65 | # undef mxc_cpu_type | ||
| 66 | # define mxc_cpu_type __mxc_cpu_type | ||
| 67 | # else | ||
| 68 | # define mxc_cpu_type MXC_CPU_MX25 | ||
| 69 | # endif | ||
| 70 | # define cpu_is_mx25() (mxc_cpu_type == MXC_CPU_MX25) | ||
| 71 | #else | ||
| 72 | # define cpu_is_mx25() (0) | ||
| 73 | #endif | ||
| 74 | |||
| 61 | #ifdef CONFIG_MACH_MX27 | 75 | #ifdef CONFIG_MACH_MX27 |
| 62 | # ifdef mxc_cpu_type | 76 | # ifdef mxc_cpu_type |
| 63 | # undef mxc_cpu_type | 77 | # undef mxc_cpu_type |
| @@ -94,13 +108,25 @@ extern unsigned int __mxc_cpu_type; | |||
| 94 | # define cpu_is_mx35() (0) | 108 | # define cpu_is_mx35() (0) |
| 95 | #endif | 109 | #endif |
| 96 | 110 | ||
| 111 | #ifdef CONFIG_ARCH_MXC91231 | ||
| 112 | # ifdef mxc_cpu_type | ||
| 113 | # undef mxc_cpu_type | ||
| 114 | # define mxc_cpu_type __mxc_cpu_type | ||
| 115 | # else | ||
| 116 | # define mxc_cpu_type MXC_CPU_MXC91231 | ||
| 117 | # endif | ||
| 118 | # define cpu_is_mxc91231() (mxc_cpu_type == MXC_CPU_MXC91231) | ||
| 119 | #else | ||
| 120 | # define cpu_is_mxc91231() (0) | ||
| 121 | #endif | ||
| 122 | |||
| 97 | #if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2) | 123 | #if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2) |
| 98 | #define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10) | 124 | #define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10) |
| 99 | #define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x4) | 125 | #define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x4) |
| 100 | #define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x8) | 126 | #define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x8) |
| 101 | #endif | 127 | #endif |
| 102 | 128 | ||
| 103 | #define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35()) | 129 | #define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35() || cpu_is_mxc91231()) |
| 104 | #define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27()) | 130 | #define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27()) |
| 105 | 131 | ||
| 106 | #endif /* __ASM_ARCH_MXC_H__ */ | 132 | #endif /* __ASM_ARCH_MXC_H__ */ |
diff --git a/arch/arm/plat-mxc/include/mach/mxc91231.h b/arch/arm/plat-mxc/include/mach/mxc91231.h new file mode 100644 index 000000000000..81484d1ef232 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/mxc91231.h | |||
| @@ -0,0 +1,315 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 3 | * - Platform specific register memory map | ||
| 4 | * | ||
| 5 | * Copyright 2005-2007 Motorola, Inc. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | ||
| 21 | #ifndef __MACH_MXC91231_H__ | ||
| 22 | #define __MACH_MXC91231_H__ | ||
| 23 | |||
| 24 | /* | ||
| 25 | * L2CC | ||
| 26 | */ | ||
| 27 | #define MXC91231_L2CC_BASE_ADDR 0x30000000 | ||
| 28 | #define MXC91231_L2CC_BASE_ADDR_VIRT 0xF9000000 | ||
| 29 | #define MXC91231_L2CC_SIZE SZ_64K | ||
| 30 | |||
| 31 | /* | ||
| 32 | * AIPS 1 | ||
| 33 | */ | ||
| 34 | #define MXC91231_AIPS1_BASE_ADDR 0x43F00000 | ||
| 35 | #define MXC91231_AIPS1_BASE_ADDR_VIRT 0xFC000000 | ||
| 36 | #define MXC91231_AIPS1_SIZE SZ_1M | ||
| 37 | |||
| 38 | #define MXC91231_AIPS1_CTRL_BASE_ADDR MXC91231_AIPS1_BASE_ADDR | ||
| 39 | #define MXC91231_MAX_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x04000) | ||
| 40 | #define MXC91231_EVTMON_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x08000) | ||
| 41 | #define MXC91231_CLKCTL_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x0C000) | ||
| 42 | #define MXC91231_ETB_SLOT4_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x10000) | ||
| 43 | #define MXC91231_ETB_SLOT5_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x14000) | ||
| 44 | #define MXC91231_ECT_CTIO_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x18000) | ||
| 45 | #define MXC91231_I2C_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x80000) | ||
| 46 | #define MXC91231_MU_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x88000) | ||
| 47 | #define MXC91231_UART1_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x90000) | ||
| 48 | #define MXC91231_UART2_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x94000) | ||
| 49 | #define MXC91231_DSM_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x98000) | ||
| 50 | #define MXC91231_OWIRE_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x9C000) | ||
| 51 | #define MXC91231_SSI1_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0xA0000) | ||
| 52 | #define MXC91231_KPP_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0xA8000) | ||
| 53 | #define MXC91231_IOMUX_AP_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0xAC000) | ||
| 54 | #define MXC91231_CTI_AP_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0xB8000) | ||
| 55 | |||
| 56 | /* | ||
| 57 | * AIPS 2 | ||
| 58 | */ | ||
| 59 | #define MXC91231_AIPS2_BASE_ADDR 0x53F00000 | ||
| 60 | #define MXC91231_AIPS2_BASE_ADDR_VIRT 0xFC100000 | ||
| 61 | #define MXC91231_AIPS2_SIZE SZ_1M | ||
| 62 | |||
| 63 | #define MXC91231_GEMK_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0x8C000) | ||
| 64 | #define MXC91231_GPT1_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0x90000) | ||
| 65 | #define MXC91231_EPIT1_AP_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0x94000) | ||
| 66 | #define MXC91231_SCC_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xAC000) | ||
| 67 | #define MXC91231_RNGA_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xB0000) | ||
| 68 | #define MXC91231_IPU_CTRL_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xC0000) | ||
| 69 | #define MXC91231_AUDMUX_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xC4000) | ||
| 70 | #define MXC91231_EDIO_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xC8000) | ||
| 71 | #define MXC91231_GPIO1_AP_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xCC000) | ||
| 72 | #define MXC91231_GPIO2_AP_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xD0000) | ||
| 73 | #define MXC91231_SDMA_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xD4000) | ||
| 74 | #define MXC91231_RTC_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xD8000) | ||
| 75 | #define MXC91231_WDOG1_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xDC000) | ||
| 76 | #define MXC91231_PWM_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xE0000) | ||
| 77 | #define MXC91231_GPIO3_AP_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xE4000) | ||
| 78 | #define MXC91231_WDOG2_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xE8000) | ||
| 79 | #define MXC91231_RTIC_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xEC000) | ||
| 80 | #define MXC91231_LPMC_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xF0000) | ||
| 81 | |||
| 82 | /* | ||
| 83 | * SPBA global module 0 | ||
| 84 | */ | ||
| 85 | #define MXC91231_SPBA0_BASE_ADDR 0x50000000 | ||
| 86 | #define MXC91231_SPBA0_BASE_ADDR_VIRT 0xFC200000 | ||
| 87 | #define MXC91231_SPBA0_SIZE SZ_1M | ||
| 88 | |||
| 89 | #define MXC91231_MMC_SDHC1_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x04000) | ||
| 90 | #define MXC91231_MMC_SDHC2_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x08000) | ||
| 91 | #define MXC91231_UART3_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x0C000) | ||
| 92 | #define MXC91231_CSPI2_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x10000) | ||
| 93 | #define MXC91231_SSI2_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x14000) | ||
| 94 | #define MXC91231_SIM_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x18000) | ||
| 95 | #define MXC91231_IIM_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x1C000) | ||
| 96 | #define MXC91231_CTI_SDMA_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x20000) | ||
| 97 | #define MXC91231_USBOTG_CTRL_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x24000) | ||
| 98 | #define MXC91231_USBOTG_DATA_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x28000) | ||
| 99 | #define MXC91231_CSPI1_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x30000) | ||
| 100 | #define MXC91231_SPBA_CTRL_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x3C000) | ||
| 101 | #define MXC91231_IOMUX_COM_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x40000) | ||
| 102 | #define MXC91231_CRM_COM_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x44000) | ||
| 103 | #define MXC91231_CRM_AP_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x48000) | ||
| 104 | #define MXC91231_PLL0_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x4C000) | ||
| 105 | #define MXC91231_PLL1_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x50000) | ||
| 106 | #define MXC91231_PLL2_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x54000) | ||
| 107 | #define MXC91231_GPIO4_SH_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x58000) | ||
| 108 | #define MXC91231_HAC_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x5C000) | ||
| 109 | #define MXC91231_SAHARA_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x5C000) | ||
| 110 | #define MXC91231_PLL3_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x60000) | ||
| 111 | |||
| 112 | /* | ||
| 113 | * SPBA global module 1 | ||
| 114 | */ | ||
| 115 | #define MXC91231_SPBA1_BASE_ADDR 0x52000000 | ||
| 116 | #define MXC91231_SPBA1_BASE_ADDR_VIRT 0xFC300000 | ||
| 117 | #define MXC91231_SPBA1_SIZE SZ_1M | ||
| 118 | |||
| 119 | #define MXC91231_MQSPI_BASE_ADDR (MXC91231_SPBA1_BASE_ADDR + 0x34000) | ||
| 120 | #define MXC91231_EL1T_BASE_ADDR (MXC91231_SPBA1_BASE_ADDR + 0x38000) | ||
| 121 | |||
| 122 | /*! | ||
| 123 | * Defines for SPBA modules | ||
| 124 | */ | ||
| 125 | #define MXC91231_SPBA_SDHC1 0x04 | ||
| 126 | #define MXC91231_SPBA_SDHC2 0x08 | ||
| 127 | #define MXC91231_SPBA_UART3 0x0C | ||
| 128 | #define MXC91231_SPBA_CSPI2 0x10 | ||
| 129 | #define MXC91231_SPBA_SSI2 0x14 | ||
| 130 | #define MXC91231_SPBA_SIM 0x18 | ||
| 131 | #define MXC91231_SPBA_IIM 0x1C | ||
| 132 | #define MXC91231_SPBA_CTI_SDMA 0x20 | ||
| 133 | #define MXC91231_SPBA_USBOTG_CTRL_REGS 0x24 | ||
| 134 | #define MXC91231_SPBA_USBOTG_DATA_REGS 0x28 | ||
| 135 | #define MXC91231_SPBA_CSPI1 0x30 | ||
| 136 | #define MXC91231_SPBA_MQSPI 0x34 | ||
| 137 | #define MXC91231_SPBA_EL1T 0x38 | ||
| 138 | #define MXC91231_SPBA_IOMUX 0x40 | ||
| 139 | #define MXC91231_SPBA_CRM_COM 0x44 | ||
| 140 | #define MXC91231_SPBA_CRM_AP 0x48 | ||
| 141 | #define MXC91231_SPBA_PLL0 0x4C | ||
| 142 | #define MXC91231_SPBA_PLL1 0x50 | ||
| 143 | #define MXC91231_SPBA_PLL2 0x54 | ||
| 144 | #define MXC91231_SPBA_GPIO4 0x58 | ||
| 145 | #define MXC91231_SPBA_SAHARA 0x5C | ||
| 146 | |||
| 147 | /* | ||
| 148 | * ROMP and AVIC | ||
| 149 | */ | ||
| 150 | #define MXC91231_ROMP_BASE_ADDR 0x60000000 | ||
| 151 | #define MXC91231_ROMP_BASE_ADDR_VIRT 0xFC400000 | ||
| 152 | #define MXC91231_ROMP_SIZE SZ_64K | ||
| 153 | |||
| 154 | #define MXC91231_AVIC_BASE_ADDR 0x68000000 | ||
| 155 | #define MXC91231_AVIC_BASE_ADDR_VIRT 0xFC410000 | ||
| 156 | #define MXC91231_AVIC_SIZE SZ_64K | ||
| 157 | |||
| 158 | /* | ||
| 159 | * NAND, SDRAM, WEIM, M3IF, EMI controllers | ||
| 160 | */ | ||
| 161 | #define MXC91231_X_MEMC_BASE_ADDR 0xB8000000 | ||
| 162 | #define MXC91231_X_MEMC_BASE_ADDR_VIRT 0xFC420000 | ||
| 163 | #define MXC91231_X_MEMC_SIZE SZ_64K | ||
| 164 | |||
| 165 | #define MXC91231_NFC_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x0000) | ||
| 166 | #define MXC91231_ESDCTL_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x1000) | ||
| 167 | #define MXC91231_WEIM_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x2000) | ||
| 168 | #define MXC91231_M3IF_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x3000) | ||
| 169 | #define MXC91231_EMI_CTL_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x4000) | ||
| 170 | |||
| 171 | /* | ||
| 172 | * Memory regions and CS | ||
| 173 | * CPLD is connected on CS4 | ||
| 174 | * CS5 is TP1021 or it is not connected | ||
| 175 | * */ | ||
| 176 | #define MXC91231_FB_RAM_BASE_ADDR 0x78000000 | ||
| 177 | #define MXC91231_FB_RAM_SIZE SZ_256K | ||
| 178 | #define MXC91231_CSD0_BASE_ADDR 0x80000000 | ||
| 179 | #define MXC91231_CSD1_BASE_ADDR 0x90000000 | ||
| 180 | #define MXC91231_CS0_BASE_ADDR 0xA0000000 | ||
| 181 | #define MXC91231_CS1_BASE_ADDR 0xA8000000 | ||
| 182 | #define MXC91231_CS2_BASE_ADDR 0xB0000000 | ||
| 183 | #define MXC91231_CS3_BASE_ADDR 0xB2000000 | ||
| 184 | #define MXC91231_CS4_BASE_ADDR 0xB4000000 | ||
| 185 | #define MXC91231_CS5_BASE_ADDR 0xB6000000 | ||
| 186 | |||
| 187 | /* Is given address belongs to the specified memory region? */ | ||
| 188 | #define ADDRESS_IN_REGION(addr, start, size) \ | ||
| 189 | (((addr) >= (start)) && ((addr) < (start)+(size))) | ||
| 190 | |||
| 191 | /* Is given address belongs to the specified named `module'? */ | ||
| 192 | #define MXC91231_IS_MODULE(addr, module) \ | ||
| 193 | ADDRESS_IN_REGION(addr, MXC91231_ ## module ## _BASE_ADDR, \ | ||
| 194 | MXC91231_ ## module ## _SIZE) | ||
| 195 | /* | ||
| 196 | * This macro defines the physical to virtual address mapping for all the | ||
| 197 | * peripheral modules. It is used by passing in the physical address as x | ||
| 198 | * and returning the virtual address. If the physical address is not mapped, | ||
| 199 | * it returns 0xDEADBEEF | ||
| 200 | */ | ||
| 201 | |||
| 202 | #define MXC91231_IO_ADDRESS(x) \ | ||
| 203 | (void __iomem *) \ | ||
| 204 | (MXC91231_IS_MODULE(x, L2CC) ? MXC91231_L2CC_IO_ADDRESS(x) : \ | ||
| 205 | MXC91231_IS_MODULE(x, AIPS1) ? MXC91231_AIPS1_IO_ADDRESS(x) : \ | ||
| 206 | MXC91231_IS_MODULE(x, AIPS2) ? MXC91231_AIPS2_IO_ADDRESS(x) : \ | ||
| 207 | MXC91231_IS_MODULE(x, SPBA0) ? MXC91231_SPBA0_IO_ADDRESS(x) : \ | ||
| 208 | MXC91231_IS_MODULE(x, SPBA1) ? MXC91231_SPBA1_IO_ADDRESS(x) : \ | ||
| 209 | MXC91231_IS_MODULE(x, ROMP) ? MXC91231_ROMP_IO_ADDRESS(x) : \ | ||
| 210 | MXC91231_IS_MODULE(x, AVIC) ? MXC91231_AVIC_IO_ADDRESS(x) : \ | ||
| 211 | MXC91231_IS_MODULE(x, X_MEMC) ? MXC91231_X_MEMC_IO_ADDRESS(x) : \ | ||
| 212 | 0xDEADBEEF) | ||
| 213 | |||
| 214 | |||
| 215 | /* | ||
| 216 | * define the address mapping macros: in physical address order | ||
| 217 | */ | ||
| 218 | #define MXC91231_L2CC_IO_ADDRESS(x) \ | ||
| 219 | (((x) - MXC91231_L2CC_BASE_ADDR) + MXC91231_L2CC_BASE_ADDR_VIRT) | ||
| 220 | |||
| 221 | #define MXC91231_AIPS1_IO_ADDRESS(x) \ | ||
| 222 | (((x) - MXC91231_AIPS1_BASE_ADDR) + MXC91231_AIPS1_BASE_ADDR_VIRT) | ||
| 223 | |||
| 224 | #define MXC91231_SPBA0_IO_ADDRESS(x) \ | ||
| 225 | (((x) - MXC91231_SPBA0_BASE_ADDR) + MXC91231_SPBA0_BASE_ADDR_VIRT) | ||
| 226 | |||
| 227 | #define MXC91231_SPBA1_IO_ADDRESS(x) \ | ||
| 228 | (((x) - MXC91231_SPBA1_BASE_ADDR) + MXC91231_SPBA1_BASE_ADDR_VIRT) | ||
| 229 | |||
| 230 | #define MXC91231_AIPS2_IO_ADDRESS(x) \ | ||
| 231 | (((x) - MXC91231_AIPS2_BASE_ADDR) + MXC91231_AIPS2_BASE_ADDR_VIRT) | ||
| 232 | |||
| 233 | #define MXC91231_ROMP_IO_ADDRESS(x) \ | ||
| 234 | (((x) - MXC91231_ROMP_BASE_ADDR) + MXC91231_ROMP_BASE_ADDR_VIRT) | ||
| 235 | |||
| 236 | #define MXC91231_AVIC_IO_ADDRESS(x) \ | ||
| 237 | (((x) - MXC91231_AVIC_BASE_ADDR) + MXC91231_AVIC_BASE_ADDR_VIRT) | ||
| 238 | |||
| 239 | #define MXC91231_X_MEMC_IO_ADDRESS(x) \ | ||
| 240 | (((x) - MXC91231_X_MEMC_BASE_ADDR) + MXC91231_X_MEMC_BASE_ADDR_VIRT) | ||
| 241 | |||
| 242 | /* | ||
| 243 | * Interrupt numbers | ||
| 244 | */ | ||
| 245 | #define MXC91231_INT_GPIO3 0 | ||
| 246 | #define MXC91231_INT_EL1T_CI 1 | ||
| 247 | #define MXC91231_INT_EL1T_RFCI 2 | ||
| 248 | #define MXC91231_INT_EL1T_RFI 3 | ||
| 249 | #define MXC91231_INT_EL1T_MCU 4 | ||
| 250 | #define MXC91231_INT_EL1T_IPI 5 | ||
| 251 | #define MXC91231_INT_MU_GEN 6 | ||
| 252 | #define MXC91231_INT_GPIO4 7 | ||
| 253 | #define MXC91231_INT_MMC_SDHC2 8 | ||
| 254 | #define MXC91231_INT_MMC_SDHC1 9 | ||
| 255 | #define MXC91231_INT_I2C 10 | ||
| 256 | #define MXC91231_INT_SSI2 11 | ||
| 257 | #define MXC91231_INT_SSI1 12 | ||
| 258 | #define MXC91231_INT_CSPI2 13 | ||
| 259 | #define MXC91231_INT_CSPI1 14 | ||
| 260 | #define MXC91231_INT_RTIC 15 | ||
| 261 | #define MXC91231_INT_SAHARA 15 | ||
| 262 | #define MXC91231_INT_HAC 15 | ||
| 263 | #define MXC91231_INT_UART3_RX 16 | ||
| 264 | #define MXC91231_INT_UART3_TX 17 | ||
| 265 | #define MXC91231_INT_UART3_MINT 18 | ||
| 266 | #define MXC91231_INT_ECT 19 | ||
| 267 | #define MXC91231_INT_SIM_IPB 20 | ||
| 268 | #define MXC91231_INT_SIM_DATA 21 | ||
| 269 | #define MXC91231_INT_RNGA 22 | ||
| 270 | #define MXC91231_INT_DSM_AP 23 | ||
| 271 | #define MXC91231_INT_KPP 24 | ||
| 272 | #define MXC91231_INT_RTC 25 | ||
| 273 | #define MXC91231_INT_PWM 26 | ||
| 274 | #define MXC91231_INT_GEMK_AP 27 | ||
| 275 | #define MXC91231_INT_EPIT 28 | ||
| 276 | #define MXC91231_INT_GPT 29 | ||
| 277 | #define MXC91231_INT_UART2_RX 30 | ||
| 278 | #define MXC91231_INT_UART2_TX 31 | ||
| 279 | #define MXC91231_INT_UART2_MINT 32 | ||
| 280 | #define MXC91231_INT_NANDFC 33 | ||
| 281 | #define MXC91231_INT_SDMA 34 | ||
| 282 | #define MXC91231_INT_USB_WAKEUP 35 | ||
| 283 | #define MXC91231_INT_USB_SOF 36 | ||
| 284 | #define MXC91231_INT_PMU_EVTMON 37 | ||
| 285 | #define MXC91231_INT_USB_FUNC 38 | ||
| 286 | #define MXC91231_INT_USB_DMA 39 | ||
| 287 | #define MXC91231_INT_USB_CTRL 40 | ||
| 288 | #define MXC91231_INT_IPU_ERR 41 | ||
| 289 | #define MXC91231_INT_IPU_SYN 42 | ||
| 290 | #define MXC91231_INT_UART1_RX 43 | ||
| 291 | #define MXC91231_INT_UART1_TX 44 | ||
| 292 | #define MXC91231_INT_UART1_MINT 45 | ||
| 293 | #define MXC91231_INT_IIM 46 | ||
| 294 | #define MXC91231_INT_MU_RX_OR 47 | ||
| 295 | #define MXC91231_INT_MU_TX_OR 48 | ||
| 296 | #define MXC91231_INT_SCC_SCM 49 | ||
| 297 | #define MXC91231_INT_SCC_SMN 50 | ||
| 298 | #define MXC91231_INT_GPIO2 51 | ||
| 299 | #define MXC91231_INT_GPIO1 52 | ||
| 300 | #define MXC91231_INT_MQSPI1 53 | ||
| 301 | #define MXC91231_INT_MQSPI2 54 | ||
| 302 | #define MXC91231_INT_WDOG2 55 | ||
| 303 | #define MXC91231_INT_EXT_INT7 56 | ||
| 304 | #define MXC91231_INT_EXT_INT6 57 | ||
| 305 | #define MXC91231_INT_EXT_INT5 58 | ||
| 306 | #define MXC91231_INT_EXT_INT4 59 | ||
| 307 | #define MXC91231_INT_EXT_INT3 60 | ||
| 308 | #define MXC91231_INT_EXT_INT2 61 | ||
| 309 | #define MXC91231_INT_EXT_INT1 62 | ||
| 310 | #define MXC91231_INT_EXT_INT0 63 | ||
| 311 | |||
| 312 | #define MXC91231_MAX_INT_LINES 63 | ||
| 313 | #define MXC91231_MAX_EXT_LINES 8 | ||
| 314 | |||
| 315 | #endif /* __MACH_MXC91231_H__ */ | ||
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h index e56241af870e..ef00199568de 100644 --- a/arch/arm/plat-mxc/include/mach/system.h +++ b/arch/arm/plat-mxc/include/mach/system.h | |||
| @@ -21,8 +21,18 @@ | |||
| 21 | #ifndef __ASM_ARCH_MXC_SYSTEM_H__ | 21 | #ifndef __ASM_ARCH_MXC_SYSTEM_H__ |
| 22 | #define __ASM_ARCH_MXC_SYSTEM_H__ | 22 | #define __ASM_ARCH_MXC_SYSTEM_H__ |
| 23 | 23 | ||
| 24 | #include <mach/hardware.h> | ||
| 25 | #include <mach/common.h> | ||
| 26 | |||
| 24 | static inline void arch_idle(void) | 27 | static inline void arch_idle(void) |
| 25 | { | 28 | { |
| 29 | #ifdef CONFIG_ARCH_MXC91231 | ||
| 30 | if (cpu_is_mxc91231()) { | ||
| 31 | /* Need this to set DSM low-power mode */ | ||
| 32 | mxc91231_prepare_idle(); | ||
| 33 | } | ||
| 34 | #endif | ||
| 35 | |||
| 26 | cpu_do_idle(); | 36 | cpu_do_idle(); |
| 27 | } | 37 | } |
| 28 | 38 | ||
diff --git a/arch/arm/plat-mxc/include/mach/timex.h b/arch/arm/plat-mxc/include/mach/timex.h index 07b4a73c9d2f..527a6c24788e 100644 --- a/arch/arm/plat-mxc/include/mach/timex.h +++ b/arch/arm/plat-mxc/include/mach/timex.h | |||
| @@ -26,6 +26,10 @@ | |||
| 26 | #define CLOCK_TICK_RATE 13300000 | 26 | #define CLOCK_TICK_RATE 13300000 |
| 27 | #elif defined CONFIG_ARCH_MX3 | 27 | #elif defined CONFIG_ARCH_MX3 |
| 28 | #define CLOCK_TICK_RATE 16625000 | 28 | #define CLOCK_TICK_RATE 16625000 |
| 29 | #elif defined CONFIG_ARCH_MX25 | ||
| 30 | #define CLOCK_TICK_RATE 16000000 | ||
| 31 | #elif defined CONFIG_ARCH_MXC91231 | ||
| 32 | #define CLOCK_TICK_RATE 13000000 | ||
| 29 | #endif | 33 | #endif |
| 30 | 34 | ||
| 31 | #endif /* __ASM_ARCH_MXC_TIMEX_H__ */ | 35 | #endif /* __ASM_ARCH_MXC_TIMEX_H__ */ |
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h index de6fe0365982..082a3908256b 100644 --- a/arch/arm/plat-mxc/include/mach/uncompress.h +++ b/arch/arm/plat-mxc/include/mach/uncompress.h | |||
| @@ -26,8 +26,11 @@ | |||
| 26 | #define __MXC_BOOT_UNCOMPRESS | 26 | #define __MXC_BOOT_UNCOMPRESS |
| 27 | 27 | ||
| 28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
| 29 | #include <asm/mach-types.h> | ||
| 29 | 30 | ||
| 30 | #define UART(x) (*(volatile unsigned long *)(serial_port + (x))) | 31 | static unsigned long uart_base; |
| 32 | |||
| 33 | #define UART(x) (*(volatile unsigned long *)(uart_base + (x))) | ||
| 31 | 34 | ||
| 32 | #define USR2 0x98 | 35 | #define USR2 0x98 |
| 33 | #define USR2_TXFE (1<<14) | 36 | #define USR2_TXFE (1<<14) |
| @@ -46,19 +49,10 @@ | |||
| 46 | 49 | ||
| 47 | static void putc(int ch) | 50 | static void putc(int ch) |
| 48 | { | 51 | { |
| 49 | static unsigned long serial_port = 0; | 52 | if (!uart_base) |
| 50 | 53 | return; | |
| 51 | if (unlikely(serial_port == 0)) { | 54 | if (!(UART(UCR1) & UCR1_UARTEN)) |
| 52 | do { | 55 | return; |
| 53 | serial_port = UART1_BASE_ADDR; | ||
| 54 | if (UART(UCR1) & UCR1_UARTEN) | ||
| 55 | break; | ||
| 56 | serial_port = UART2_BASE_ADDR; | ||
| 57 | if (UART(UCR1) & UCR1_UARTEN) | ||
| 58 | break; | ||
| 59 | return; | ||
| 60 | } while (0); | ||
| 61 | } | ||
| 62 | 56 | ||
| 63 | while (!(UART(USR2) & USR2_TXFE)) | 57 | while (!(UART(USR2) & USR2_TXFE)) |
| 64 | barrier(); | 58 | barrier(); |
| @@ -68,11 +62,49 @@ static void putc(int ch) | |||
| 68 | 62 | ||
| 69 | #define flush() do { } while (0) | 63 | #define flush() do { } while (0) |
| 70 | 64 | ||
| 71 | /* | 65 | #define MX1_UART1_BASE_ADDR 0x00206000 |
| 72 | * nothing to do | 66 | #define MX25_UART1_BASE_ADDR 0x43f90000 |
| 73 | */ | 67 | #define MX2X_UART1_BASE_ADDR 0x1000a000 |
| 74 | #define arch_decomp_setup() | 68 | #define MX3X_UART1_BASE_ADDR 0x43F90000 |
| 69 | #define MX3X_UART2_BASE_ADDR 0x43F94000 | ||
| 70 | |||
| 71 | static __inline__ void __arch_decomp_setup(unsigned long arch_id) | ||
| 72 | { | ||
| 73 | switch (arch_id) { | ||
| 74 | case MACH_TYPE_MX1ADS: | ||
| 75 | case MACH_TYPE_SCB9328: | ||
| 76 | uart_base = MX1_UART1_BASE_ADDR; | ||
| 77 | break; | ||
| 78 | case MACH_TYPE_MX25_3DS: | ||
| 79 | uart_base = MX25_UART1_BASE_ADDR; | ||
| 80 | break; | ||
| 81 | case MACH_TYPE_IMX27LITE: | ||
| 82 | case MACH_TYPE_MX27_3DS: | ||
| 83 | case MACH_TYPE_MX27ADS: | ||
| 84 | case MACH_TYPE_PCM038: | ||
| 85 | case MACH_TYPE_MX21ADS: | ||
| 86 | uart_base = MX2X_UART1_BASE_ADDR; | ||
| 87 | break; | ||
| 88 | case MACH_TYPE_MX31LITE: | ||
| 89 | case MACH_TYPE_ARMADILLO5X0: | ||
| 90 | case MACH_TYPE_MX31MOBOARD: | ||
| 91 | case MACH_TYPE_QONG: | ||
| 92 | case MACH_TYPE_MX31_3DS: | ||
| 93 | case MACH_TYPE_PCM037: | ||
| 94 | case MACH_TYPE_MX31ADS: | ||
| 95 | case MACH_TYPE_MX35_3DS: | ||
| 96 | case MACH_TYPE_PCM043: | ||
| 97 | uart_base = MX3X_UART1_BASE_ADDR; | ||
| 98 | break; | ||
| 99 | case MACH_TYPE_MAGX_ZN5: | ||
| 100 | uart_base = MX3X_UART2_BASE_ADDR; | ||
| 101 | break; | ||
| 102 | default: | ||
| 103 | break; | ||
| 104 | } | ||
| 105 | } | ||
| 75 | 106 | ||
| 107 | #define arch_decomp_setup() __arch_decomp_setup(arch_id) | ||
| 76 | #define arch_decomp_wdog() | 108 | #define arch_decomp_wdog() |
| 77 | 109 | ||
| 78 | #endif /* __ASM_ARCH_MXC_UNCOMPRESS_H__ */ | 110 | #endif /* __ASM_ARCH_MXC_UNCOMPRESS_H__ */ |
diff --git a/arch/arm/plat-mxc/iomux-v3.c b/arch/arm/plat-mxc/iomux-v3.c index 77a078f9513f..851ca99bf1b1 100644 --- a/arch/arm/plat-mxc/iomux-v3.c +++ b/arch/arm/plat-mxc/iomux-v3.c | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | #include <asm/mach/map.h> | 29 | #include <asm/mach/map.h> |
| 30 | #include <mach/iomux-v3.h> | 30 | #include <mach/iomux-v3.h> |
| 31 | 31 | ||
| 32 | #define IOMUX_BASE IO_ADDRESS(IOMUXC_BASE_ADDR) | 32 | static void __iomem *base; |
| 33 | 33 | ||
| 34 | static unsigned long iomux_v3_pad_alloc_map[0x200 / BITS_PER_LONG]; | 34 | static unsigned long iomux_v3_pad_alloc_map[0x200 / BITS_PER_LONG]; |
| 35 | 35 | ||
| @@ -45,14 +45,14 @@ int mxc_iomux_v3_setup_pad(struct pad_desc *pad) | |||
| 45 | if (test_and_set_bit(pad_ofs >> 2, iomux_v3_pad_alloc_map)) | 45 | if (test_and_set_bit(pad_ofs >> 2, iomux_v3_pad_alloc_map)) |
| 46 | return -EBUSY; | 46 | return -EBUSY; |
| 47 | if (pad->mux_ctrl_ofs) | 47 | if (pad->mux_ctrl_ofs) |
| 48 | __raw_writel(pad->mux_mode, IOMUX_BASE + pad->mux_ctrl_ofs); | 48 | __raw_writel(pad->mux_mode, base + pad->mux_ctrl_ofs); |
| 49 | 49 | ||
| 50 | if (pad->select_input_ofs) | 50 | if (pad->select_input_ofs) |
| 51 | __raw_writel(pad->select_input, | 51 | __raw_writel(pad->select_input, |
| 52 | IOMUX_BASE + pad->select_input_ofs); | 52 | base + pad->select_input_ofs); |
| 53 | 53 | ||
| 54 | if (!(pad->pad_ctrl & NO_PAD_CTRL)) | 54 | if (!(pad->pad_ctrl & NO_PAD_CTRL) && pad->pad_ctrl_ofs) |
| 55 | __raw_writel(pad->pad_ctrl, IOMUX_BASE + pad->pad_ctrl_ofs); | 55 | __raw_writel(pad->pad_ctrl, base + pad->pad_ctrl_ofs); |
| 56 | return 0; | 56 | return 0; |
| 57 | } | 57 | } |
| 58 | EXPORT_SYMBOL(mxc_iomux_v3_setup_pad); | 58 | EXPORT_SYMBOL(mxc_iomux_v3_setup_pad); |
| @@ -96,3 +96,8 @@ void mxc_iomux_v3_release_multiple_pads(struct pad_desc *pad_list, int count) | |||
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| 98 | EXPORT_SYMBOL(mxc_iomux_v3_release_multiple_pads); | 98 | EXPORT_SYMBOL(mxc_iomux_v3_release_multiple_pads); |
| 99 | |||
| 100 | void mxc_iomux_v3_init(void __iomem *iomux_v3_base) | ||
| 101 | { | ||
| 102 | base = iomux_v3_base; | ||
| 103 | } | ||
diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c index 8aee76304f8f..778ddfe57d89 100644 --- a/arch/arm/plat-mxc/irq.c +++ b/arch/arm/plat-mxc/irq.c | |||
| @@ -44,7 +44,7 @@ | |||
| 44 | #define AVIC_FIPNDH 0x60 /* fast int pending high */ | 44 | #define AVIC_FIPNDH 0x60 /* fast int pending high */ |
| 45 | #define AVIC_FIPNDL 0x64 /* fast int pending low */ | 45 | #define AVIC_FIPNDL 0x64 /* fast int pending low */ |
| 46 | 46 | ||
| 47 | static void __iomem *avic_base; | 47 | void __iomem *avic_base; |
| 48 | 48 | ||
| 49 | int imx_irq_set_priority(unsigned char irq, unsigned char prio) | 49 | int imx_irq_set_priority(unsigned char irq, unsigned char prio) |
| 50 | { | 50 | { |
| @@ -113,11 +113,11 @@ static struct irq_chip mxc_avic_chip = { | |||
| 113 | * interrupts. It registers the interrupt enable and disable functions | 113 | * interrupts. It registers the interrupt enable and disable functions |
| 114 | * to the kernel for each interrupt source. | 114 | * to the kernel for each interrupt source. |
| 115 | */ | 115 | */ |
| 116 | void __init mxc_init_irq(void) | 116 | void __init mxc_init_irq(void __iomem *irqbase) |
| 117 | { | 117 | { |
| 118 | int i; | 118 | int i; |
| 119 | 119 | ||
| 120 | avic_base = IO_ADDRESS(AVIC_BASE_ADDR); | 120 | avic_base = irqbase; |
| 121 | 121 | ||
| 122 | /* put the AVIC into the reset value with | 122 | /* put the AVIC into the reset value with |
| 123 | * all interrupts disabled | 123 | * all interrupts disabled |
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c index ae34198a79dd..5cdbd605ac05 100644 --- a/arch/arm/plat-mxc/pwm.c +++ b/arch/arm/plat-mxc/pwm.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #define MX3_PWMPR 0x10 /* PWM Period Register */ | 32 | #define MX3_PWMPR 0x10 /* PWM Period Register */ |
| 33 | #define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4) | 33 | #define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4) |
| 34 | #define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) | 34 | #define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) |
| 35 | #define MX3_PWMCR_CLKSRC_IPG (1 << 16) | ||
| 35 | #define MX3_PWMCR_EN (1 << 0) | 36 | #define MX3_PWMCR_EN (1 << 0) |
| 36 | 37 | ||
| 37 | 38 | ||
| @@ -55,9 +56,11 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) | |||
| 55 | if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) | 56 | if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) |
| 56 | return -EINVAL; | 57 | return -EINVAL; |
| 57 | 58 | ||
| 58 | if (cpu_is_mx27() || cpu_is_mx3()) { | 59 | if (cpu_is_mx27() || cpu_is_mx3() || cpu_is_mx25()) { |
| 59 | unsigned long long c; | 60 | unsigned long long c; |
| 60 | unsigned long period_cycles, duty_cycles, prescale; | 61 | unsigned long period_cycles, duty_cycles, prescale; |
| 62 | u32 cr; | ||
| 63 | |||
| 61 | c = clk_get_rate(pwm->clk); | 64 | c = clk_get_rate(pwm->clk); |
| 62 | c = c * period_ns; | 65 | c = c * period_ns; |
| 63 | do_div(c, 1000000000); | 66 | do_div(c, 1000000000); |
| @@ -72,9 +75,15 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) | |||
| 72 | 75 | ||
| 73 | writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR); | 76 | writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR); |
| 74 | writel(period_cycles, pwm->mmio_base + MX3_PWMPR); | 77 | writel(period_cycles, pwm->mmio_base + MX3_PWMPR); |
| 75 | writel(MX3_PWMCR_PRESCALER(prescale - 1) | | 78 | |
| 76 | MX3_PWMCR_CLKSRC_IPG_HIGH | MX3_PWMCR_EN, | 79 | cr = MX3_PWMCR_PRESCALER(prescale) | MX3_PWMCR_EN; |
| 77 | pwm->mmio_base + MX3_PWMCR); | 80 | |
| 81 | if (cpu_is_mx25()) | ||
| 82 | cr |= MX3_PWMCR_CLKSRC_IPG; | ||
| 83 | else | ||
| 84 | cr |= MX3_PWMCR_CLKSRC_IPG_HIGH; | ||
| 85 | |||
| 86 | writel(cr, pwm->mmio_base + MX3_PWMCR); | ||
| 78 | } else if (cpu_is_mx1() || cpu_is_mx21()) { | 87 | } else if (cpu_is_mx1() || cpu_is_mx21()) { |
| 79 | /* The PWM subsystem allows for exact frequencies. However, | 88 | /* The PWM subsystem allows for exact frequencies. However, |
| 80 | * I cannot connect a scope on my device to the PWM line and | 89 | * I cannot connect a scope on my device to the PWM line and |
| @@ -118,6 +127,8 @@ EXPORT_SYMBOL(pwm_enable); | |||
| 118 | 127 | ||
| 119 | void pwm_disable(struct pwm_device *pwm) | 128 | void pwm_disable(struct pwm_device *pwm) |
| 120 | { | 129 | { |
| 130 | writel(0, pwm->mmio_base + MX3_PWMCR); | ||
| 131 | |||
| 121 | if (pwm->clk_enabled) { | 132 | if (pwm->clk_enabled) { |
| 122 | clk_disable(pwm->clk); | 133 | clk_disable(pwm->clk); |
| 123 | pwm->clk_enabled = 0; | 134 | pwm->clk_enabled = 0; |
diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c index 79c37577c916..97f42799fa58 100644 --- a/arch/arm/plat-mxc/system.c +++ b/arch/arm/plat-mxc/system.c | |||
| @@ -27,32 +27,38 @@ | |||
| 27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
| 28 | 28 | ||
| 29 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
| 30 | #include <mach/common.h> | ||
| 30 | #include <asm/proc-fns.h> | 31 | #include <asm/proc-fns.h> |
| 31 | #include <asm/system.h> | 32 | #include <asm/system.h> |
| 32 | 33 | ||
| 33 | #ifdef CONFIG_ARCH_MX1 | 34 | static void __iomem *wdog_base; |
| 34 | #define WDOG_WCR_REG IO_ADDRESS(WDT_BASE_ADDR) | ||
| 35 | #define WDOG_WCR_ENABLE (1 << 0) | ||
| 36 | #else | ||
| 37 | #define WDOG_WCR_REG IO_ADDRESS(WDOG_BASE_ADDR) | ||
| 38 | #define WDOG_WCR_ENABLE (1 << 2) | ||
| 39 | #endif | ||
| 40 | 35 | ||
| 41 | /* | 36 | /* |
| 42 | * Reset the system. It is called by machine_restart(). | 37 | * Reset the system. It is called by machine_restart(). |
| 43 | */ | 38 | */ |
| 44 | void arch_reset(char mode, const char *cmd) | 39 | void arch_reset(char mode, const char *cmd) |
| 45 | { | 40 | { |
| 46 | if (!cpu_is_mx1()) { | 41 | unsigned int wcr_enable; |
| 42 | |||
| 43 | #ifdef CONFIG_ARCH_MXC91231 | ||
| 44 | if (cpu_is_mxc91231()) { | ||
| 45 | mxc91231_arch_reset(mode, cmd); | ||
| 46 | return; | ||
| 47 | } | ||
| 48 | #endif | ||
| 49 | if (cpu_is_mx1()) { | ||
| 50 | wcr_enable = (1 << 0); | ||
| 51 | } else { | ||
| 47 | struct clk *clk; | 52 | struct clk *clk; |
| 48 | 53 | ||
| 49 | clk = clk_get_sys("imx-wdt.0", NULL); | 54 | clk = clk_get_sys("imx-wdt.0", NULL); |
| 50 | if (!IS_ERR(clk)) | 55 | if (!IS_ERR(clk)) |
| 51 | clk_enable(clk); | 56 | clk_enable(clk); |
| 57 | wcr_enable = (1 << 2); | ||
| 52 | } | 58 | } |
| 53 | 59 | ||
| 54 | /* Assert SRS signal */ | 60 | /* Assert SRS signal */ |
| 55 | __raw_writew(WDOG_WCR_ENABLE, WDOG_WCR_REG); | 61 | __raw_writew(wcr_enable, wdog_base); |
| 56 | 62 | ||
| 57 | /* wait for reset to assert... */ | 63 | /* wait for reset to assert... */ |
| 58 | mdelay(500); | 64 | mdelay(500); |
| @@ -65,3 +71,8 @@ void arch_reset(char mode, const char *cmd) | |||
| 65 | /* we'll take a jump through zero as a poor second */ | 71 | /* we'll take a jump through zero as a poor second */ |
| 66 | cpu_reset(0); | 72 | cpu_reset(0); |
| 67 | } | 73 | } |
| 74 | |||
| 75 | void mxc_arch_reset_init(void __iomem *base) | ||
| 76 | { | ||
| 77 | wdog_base = base; | ||
| 78 | } | ||
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index 88fb3a57e029..844567ee35fe 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c | |||
| @@ -47,7 +47,7 @@ | |||
| 47 | #define MX2_TSTAT_CAPT (1 << 1) | 47 | #define MX2_TSTAT_CAPT (1 << 1) |
| 48 | #define MX2_TSTAT_COMP (1 << 0) | 48 | #define MX2_TSTAT_COMP (1 << 0) |
| 49 | 49 | ||
| 50 | /* MX31, MX35 */ | 50 | /* MX31, MX35, MX25, MXC91231 */ |
| 51 | #define MX3_TCTL_WAITEN (1 << 3) | 51 | #define MX3_TCTL_WAITEN (1 << 3) |
| 52 | #define MX3_TCTL_CLK_IPG (1 << 6) | 52 | #define MX3_TCTL_CLK_IPG (1 << 6) |
| 53 | #define MX3_TCTL_FRR (1 << 9) | 53 | #define MX3_TCTL_FRR (1 << 9) |
| @@ -66,7 +66,7 @@ static inline void gpt_irq_disable(void) | |||
| 66 | { | 66 | { |
| 67 | unsigned int tmp; | 67 | unsigned int tmp; |
| 68 | 68 | ||
| 69 | if (cpu_is_mx3()) | 69 | if (cpu_is_mx3() || cpu_is_mx25()) |
| 70 | __raw_writel(0, timer_base + MX3_IR); | 70 | __raw_writel(0, timer_base + MX3_IR); |
| 71 | else { | 71 | else { |
| 72 | tmp = __raw_readl(timer_base + MXC_TCTL); | 72 | tmp = __raw_readl(timer_base + MXC_TCTL); |
| @@ -76,7 +76,7 @@ static inline void gpt_irq_disable(void) | |||
| 76 | 76 | ||
| 77 | static inline void gpt_irq_enable(void) | 77 | static inline void gpt_irq_enable(void) |
| 78 | { | 78 | { |
| 79 | if (cpu_is_mx3()) | 79 | if (cpu_is_mx3() || cpu_is_mx25()) |
| 80 | __raw_writel(1<<0, timer_base + MX3_IR); | 80 | __raw_writel(1<<0, timer_base + MX3_IR); |
| 81 | else { | 81 | else { |
| 82 | __raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN, | 82 | __raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN, |
| @@ -90,7 +90,7 @@ static void gpt_irq_acknowledge(void) | |||
| 90 | __raw_writel(0, timer_base + MX1_2_TSTAT); | 90 | __raw_writel(0, timer_base + MX1_2_TSTAT); |
| 91 | if (cpu_is_mx2()) | 91 | if (cpu_is_mx2()) |
| 92 | __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, timer_base + MX1_2_TSTAT); | 92 | __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, timer_base + MX1_2_TSTAT); |
| 93 | if (cpu_is_mx3()) | 93 | if (cpu_is_mx3() || cpu_is_mx25()) |
| 94 | __raw_writel(MX3_TSTAT_OF1, timer_base + MX3_TSTAT); | 94 | __raw_writel(MX3_TSTAT_OF1, timer_base + MX3_TSTAT); |
| 95 | } | 95 | } |
| 96 | 96 | ||
| @@ -117,7 +117,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk) | |||
| 117 | { | 117 | { |
| 118 | unsigned int c = clk_get_rate(timer_clk); | 118 | unsigned int c = clk_get_rate(timer_clk); |
| 119 | 119 | ||
| 120 | if (cpu_is_mx3()) | 120 | if (cpu_is_mx3() || cpu_is_mx25()) |
| 121 | clocksource_mxc.read = mx3_get_cycles; | 121 | clocksource_mxc.read = mx3_get_cycles; |
| 122 | 122 | ||
| 123 | clocksource_mxc.mult = clocksource_hz2mult(c, | 123 | clocksource_mxc.mult = clocksource_hz2mult(c, |
| @@ -180,7 +180,7 @@ static void mxc_set_mode(enum clock_event_mode mode, | |||
| 180 | 180 | ||
| 181 | if (mode != clockevent_mode) { | 181 | if (mode != clockevent_mode) { |
| 182 | /* Set event time into far-far future */ | 182 | /* Set event time into far-far future */ |
| 183 | if (cpu_is_mx3()) | 183 | if (cpu_is_mx3() || cpu_is_mx25()) |
| 184 | __raw_writel(__raw_readl(timer_base + MX3_TCN) - 3, | 184 | __raw_writel(__raw_readl(timer_base + MX3_TCN) - 3, |
| 185 | timer_base + MX3_TCMP); | 185 | timer_base + MX3_TCMP); |
| 186 | else | 186 | else |
| @@ -233,7 +233,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) | |||
| 233 | struct clock_event_device *evt = &clockevent_mxc; | 233 | struct clock_event_device *evt = &clockevent_mxc; |
| 234 | uint32_t tstat; | 234 | uint32_t tstat; |
| 235 | 235 | ||
| 236 | if (cpu_is_mx3()) | 236 | if (cpu_is_mx3() || cpu_is_mx25()) |
| 237 | tstat = __raw_readl(timer_base + MX3_TSTAT); | 237 | tstat = __raw_readl(timer_base + MX3_TSTAT); |
| 238 | else | 238 | else |
| 239 | tstat = __raw_readl(timer_base + MX1_2_TSTAT); | 239 | tstat = __raw_readl(timer_base + MX1_2_TSTAT); |
| @@ -264,7 +264,7 @@ static int __init mxc_clockevent_init(struct clk *timer_clk) | |||
| 264 | { | 264 | { |
| 265 | unsigned int c = clk_get_rate(timer_clk); | 265 | unsigned int c = clk_get_rate(timer_clk); |
| 266 | 266 | ||
| 267 | if (cpu_is_mx3()) | 267 | if (cpu_is_mx3() || cpu_is_mx25()) |
| 268 | clockevent_mxc.set_next_event = mx3_set_next_event; | 268 | clockevent_mxc.set_next_event = mx3_set_next_event; |
| 269 | 269 | ||
| 270 | clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC, | 270 | clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC, |
| @@ -281,30 +281,13 @@ static int __init mxc_clockevent_init(struct clk *timer_clk) | |||
| 281 | return 0; | 281 | return 0; |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | void __init mxc_timer_init(struct clk *timer_clk) | 284 | void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) |
| 285 | { | 285 | { |
| 286 | uint32_t tctl_val; | 286 | uint32_t tctl_val; |
| 287 | int irq; | ||
| 288 | 287 | ||
| 289 | clk_enable(timer_clk); | 288 | clk_enable(timer_clk); |
| 290 | 289 | ||
| 291 | if (cpu_is_mx1()) { | 290 | timer_base = base; |
| 292 | #ifdef CONFIG_ARCH_MX1 | ||
| 293 | timer_base = IO_ADDRESS(TIM1_BASE_ADDR); | ||
| 294 | irq = TIM1_INT; | ||
| 295 | #endif | ||
| 296 | } else if (cpu_is_mx2()) { | ||
| 297 | #ifdef CONFIG_ARCH_MX2 | ||
| 298 | timer_base = IO_ADDRESS(GPT1_BASE_ADDR); | ||
| 299 | irq = MXC_INT_GPT1; | ||
| 300 | #endif | ||
| 301 | } else if (cpu_is_mx3()) { | ||
| 302 | #ifdef CONFIG_ARCH_MX3 | ||
| 303 | timer_base = IO_ADDRESS(GPT1_BASE_ADDR); | ||
| 304 | irq = MXC_INT_GPT; | ||
| 305 | #endif | ||
| 306 | } else | ||
| 307 | BUG(); | ||
| 308 | 291 | ||
| 309 | /* | 292 | /* |
| 310 | * Initialise to a known state (all timers off, and timing reset) | 293 | * Initialise to a known state (all timers off, and timing reset) |
| @@ -313,7 +296,7 @@ void __init mxc_timer_init(struct clk *timer_clk) | |||
| 313 | __raw_writel(0, timer_base + MXC_TCTL); | 296 | __raw_writel(0, timer_base + MXC_TCTL); |
| 314 | __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ | 297 | __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ |
| 315 | 298 | ||
| 316 | if (cpu_is_mx3()) | 299 | if (cpu_is_mx3() || cpu_is_mx25()) |
| 317 | tctl_val = MX3_TCTL_CLK_IPG | MX3_TCTL_FRR | MX3_TCTL_WAITEN | MXC_TCTL_TEN; | 300 | tctl_val = MX3_TCTL_CLK_IPG | MX3_TCTL_FRR | MX3_TCTL_WAITEN | MXC_TCTL_TEN; |
| 318 | else | 301 | else |
| 319 | tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; | 302 | tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; |
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index e3ac94f09006..9b00f4cbc903 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c | |||
| @@ -1127,6 +1127,11 @@ int omap_dma_running(void) | |||
| 1127 | void omap_dma_link_lch(int lch_head, int lch_queue) | 1127 | void omap_dma_link_lch(int lch_head, int lch_queue) |
| 1128 | { | 1128 | { |
| 1129 | if (omap_dma_in_1510_mode()) { | 1129 | if (omap_dma_in_1510_mode()) { |
| 1130 | if (lch_head == lch_queue) { | ||
| 1131 | dma_write(dma_read(CCR(lch_head)) | (3 << 8), | ||
| 1132 | CCR(lch_head)); | ||
| 1133 | return; | ||
| 1134 | } | ||
| 1130 | printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); | 1135 | printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); |
| 1131 | BUG(); | 1136 | BUG(); |
| 1132 | return; | 1137 | return; |
| @@ -1149,6 +1154,11 @@ EXPORT_SYMBOL(omap_dma_link_lch); | |||
| 1149 | void omap_dma_unlink_lch(int lch_head, int lch_queue) | 1154 | void omap_dma_unlink_lch(int lch_head, int lch_queue) |
| 1150 | { | 1155 | { |
| 1151 | if (omap_dma_in_1510_mode()) { | 1156 | if (omap_dma_in_1510_mode()) { |
| 1157 | if (lch_head == lch_queue) { | ||
| 1158 | dma_write(dma_read(CCR(lch_head)) & ~(3 << 8), | ||
| 1159 | CCR(lch_head)); | ||
| 1160 | return; | ||
| 1161 | } | ||
| 1152 | printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); | 1162 | printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); |
| 1153 | BUG(); | 1163 | BUG(); |
| 1154 | return; | 1164 | return; |
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 9298bc0ab171..fd21937fe110 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
| @@ -138,6 +138,32 @@ | |||
| 138 | #define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 | 138 | #define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 |
| 139 | #define OMAP24XX_GPIO_SETDATAOUT 0x0094 | 139 | #define OMAP24XX_GPIO_SETDATAOUT 0x0094 |
| 140 | 140 | ||
| 141 | #define OMAP4_GPIO_REVISION 0x0000 | ||
| 142 | #define OMAP4_GPIO_SYSCONFIG 0x0010 | ||
| 143 | #define OMAP4_GPIO_EOI 0x0020 | ||
| 144 | #define OMAP4_GPIO_IRQSTATUSRAW0 0x0024 | ||
| 145 | #define OMAP4_GPIO_IRQSTATUSRAW1 0x0028 | ||
| 146 | #define OMAP4_GPIO_IRQSTATUS0 0x002c | ||
| 147 | #define OMAP4_GPIO_IRQSTATUS1 0x0030 | ||
| 148 | #define OMAP4_GPIO_IRQSTATUSSET0 0x0034 | ||
| 149 | #define OMAP4_GPIO_IRQSTATUSSET1 0x0038 | ||
| 150 | #define OMAP4_GPIO_IRQSTATUSCLR0 0x003c | ||
| 151 | #define OMAP4_GPIO_IRQSTATUSCLR1 0x0040 | ||
| 152 | #define OMAP4_GPIO_IRQWAKEN0 0x0044 | ||
| 153 | #define OMAP4_GPIO_IRQWAKEN1 0x0048 | ||
| 154 | #define OMAP4_GPIO_SYSSTATUS 0x0104 | ||
| 155 | #define OMAP4_GPIO_CTRL 0x0130 | ||
| 156 | #define OMAP4_GPIO_OE 0x0134 | ||
| 157 | #define OMAP4_GPIO_DATAIN 0x0138 | ||
| 158 | #define OMAP4_GPIO_DATAOUT 0x013c | ||
| 159 | #define OMAP4_GPIO_LEVELDETECT0 0x0140 | ||
| 160 | #define OMAP4_GPIO_LEVELDETECT1 0x0144 | ||
| 161 | #define OMAP4_GPIO_RISINGDETECT 0x0148 | ||
| 162 | #define OMAP4_GPIO_FALLINGDETECT 0x014c | ||
| 163 | #define OMAP4_GPIO_DEBOUNCENABLE 0x0150 | ||
| 164 | #define OMAP4_GPIO_DEBOUNCINGTIME 0x0154 | ||
| 165 | #define OMAP4_GPIO_CLEARDATAOUT 0x0190 | ||
| 166 | #define OMAP4_GPIO_SETDATAOUT 0x0194 | ||
| 141 | /* | 167 | /* |
| 142 | * omap34xx specific GPIO registers | 168 | * omap34xx specific GPIO registers |
| 143 | */ | 169 | */ |
| @@ -386,12 +412,16 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) | |||
| 386 | reg += OMAP850_GPIO_DIR_CONTROL; | 412 | reg += OMAP850_GPIO_DIR_CONTROL; |
| 387 | break; | 413 | break; |
| 388 | #endif | 414 | #endif |
| 389 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | 415 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 390 | defined(CONFIG_ARCH_OMAP4) | ||
| 391 | case METHOD_GPIO_24XX: | 416 | case METHOD_GPIO_24XX: |
| 392 | reg += OMAP24XX_GPIO_OE; | 417 | reg += OMAP24XX_GPIO_OE; |
| 393 | break; | 418 | break; |
| 394 | #endif | 419 | #endif |
| 420 | #if defined(CONFIG_ARCH_OMAP4) | ||
| 421 | case METHOD_GPIO_24XX: | ||
| 422 | reg += OMAP4_GPIO_OE; | ||
| 423 | break; | ||
| 424 | #endif | ||
| 395 | default: | 425 | default: |
| 396 | WARN_ON(1); | 426 | WARN_ON(1); |
| 397 | return; | 427 | return; |
| @@ -459,8 +489,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) | |||
| 459 | l &= ~(1 << gpio); | 489 | l &= ~(1 << gpio); |
| 460 | break; | 490 | break; |
| 461 | #endif | 491 | #endif |
| 462 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | 492 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 463 | defined(CONFIG_ARCH_OMAP4) | ||
| 464 | case METHOD_GPIO_24XX: | 493 | case METHOD_GPIO_24XX: |
| 465 | if (enable) | 494 | if (enable) |
| 466 | reg += OMAP24XX_GPIO_SETDATAOUT; | 495 | reg += OMAP24XX_GPIO_SETDATAOUT; |
| @@ -469,6 +498,15 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) | |||
| 469 | l = 1 << gpio; | 498 | l = 1 << gpio; |
| 470 | break; | 499 | break; |
| 471 | #endif | 500 | #endif |
| 501 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 502 | case METHOD_GPIO_24XX: | ||
| 503 | if (enable) | ||
| 504 | reg += OMAP4_GPIO_SETDATAOUT; | ||
| 505 | else | ||
| 506 | reg += OMAP4_GPIO_CLEARDATAOUT; | ||
| 507 | l = 1 << gpio; | ||
| 508 | break; | ||
| 509 | #endif | ||
| 472 | default: | 510 | default: |
| 473 | WARN_ON(1); | 511 | WARN_ON(1); |
| 474 | return; | 512 | return; |
| @@ -509,12 +547,16 @@ static int _get_gpio_datain(struct gpio_bank *bank, int gpio) | |||
| 509 | reg += OMAP850_GPIO_DATA_INPUT; | 547 | reg += OMAP850_GPIO_DATA_INPUT; |
| 510 | break; | 548 | break; |
| 511 | #endif | 549 | #endif |
| 512 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | 550 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 513 | defined(CONFIG_ARCH_OMAP4) | ||
| 514 | case METHOD_GPIO_24XX: | 551 | case METHOD_GPIO_24XX: |
| 515 | reg += OMAP24XX_GPIO_DATAIN; | 552 | reg += OMAP24XX_GPIO_DATAIN; |
| 516 | break; | 553 | break; |
| 517 | #endif | 554 | #endif |
| 555 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 556 | case METHOD_GPIO_24XX: | ||
| 557 | reg += OMAP4_GPIO_DATAIN; | ||
| 558 | break; | ||
| 559 | #endif | ||
| 518 | default: | 560 | default: |
| 519 | return -EINVAL; | 561 | return -EINVAL; |
| 520 | } | 562 | } |
| @@ -589,7 +631,11 @@ void omap_set_gpio_debounce(int gpio, int enable) | |||
| 589 | 631 | ||
| 590 | bank = get_gpio_bank(gpio); | 632 | bank = get_gpio_bank(gpio); |
| 591 | reg = bank->base; | 633 | reg = bank->base; |
| 634 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 635 | reg += OMAP4_GPIO_DEBOUNCENABLE; | ||
| 636 | #else | ||
| 592 | reg += OMAP24XX_GPIO_DEBOUNCE_EN; | 637 | reg += OMAP24XX_GPIO_DEBOUNCE_EN; |
| 638 | #endif | ||
| 593 | 639 | ||
| 594 | spin_lock_irqsave(&bank->lock, flags); | 640 | spin_lock_irqsave(&bank->lock, flags); |
| 595 | val = __raw_readl(reg); | 641 | val = __raw_readl(reg); |
| @@ -626,7 +672,11 @@ void omap_set_gpio_debounce_time(int gpio, int enc_time) | |||
| 626 | reg = bank->base; | 672 | reg = bank->base; |
| 627 | 673 | ||
| 628 | enc_time &= 0xff; | 674 | enc_time &= 0xff; |
| 675 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 676 | reg += OMAP4_GPIO_DEBOUNCINGTIME; | ||
| 677 | #else | ||
| 629 | reg += OMAP24XX_GPIO_DEBOUNCE_VAL; | 678 | reg += OMAP24XX_GPIO_DEBOUNCE_VAL; |
| 679 | #endif | ||
| 630 | __raw_writel(enc_time, reg); | 680 | __raw_writel(enc_time, reg); |
| 631 | } | 681 | } |
| 632 | EXPORT_SYMBOL(omap_set_gpio_debounce_time); | 682 | EXPORT_SYMBOL(omap_set_gpio_debounce_time); |
| @@ -638,23 +688,46 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, | |||
| 638 | { | 688 | { |
| 639 | void __iomem *base = bank->base; | 689 | void __iomem *base = bank->base; |
| 640 | u32 gpio_bit = 1 << gpio; | 690 | u32 gpio_bit = 1 << gpio; |
| 691 | u32 val; | ||
| 641 | 692 | ||
| 642 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, | 693 | if (cpu_is_omap44xx()) { |
| 643 | trigger & IRQ_TYPE_LEVEL_LOW); | 694 | MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit, |
| 644 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, | 695 | trigger & IRQ_TYPE_LEVEL_LOW); |
| 645 | trigger & IRQ_TYPE_LEVEL_HIGH); | 696 | MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit, |
| 646 | MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, | 697 | trigger & IRQ_TYPE_LEVEL_HIGH); |
| 647 | trigger & IRQ_TYPE_EDGE_RISING); | 698 | MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit, |
| 648 | MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, | 699 | trigger & IRQ_TYPE_EDGE_RISING); |
| 649 | trigger & IRQ_TYPE_EDGE_FALLING); | 700 | MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit, |
| 650 | 701 | trigger & IRQ_TYPE_EDGE_FALLING); | |
| 702 | } else { | ||
| 703 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, | ||
| 704 | trigger & IRQ_TYPE_LEVEL_LOW); | ||
| 705 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, | ||
| 706 | trigger & IRQ_TYPE_LEVEL_HIGH); | ||
| 707 | MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, | ||
| 708 | trigger & IRQ_TYPE_EDGE_RISING); | ||
| 709 | MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, | ||
| 710 | trigger & IRQ_TYPE_EDGE_FALLING); | ||
| 711 | } | ||
| 651 | if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { | 712 | if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { |
| 652 | if (trigger != 0) | 713 | if (cpu_is_omap44xx()) { |
| 653 | __raw_writel(1 << gpio, bank->base | 714 | if (trigger != 0) |
| 715 | __raw_writel(1 << gpio, bank->base+ | ||
| 716 | OMAP4_GPIO_IRQWAKEN0); | ||
| 717 | else { | ||
| 718 | val = __raw_readl(bank->base + | ||
| 719 | OMAP4_GPIO_IRQWAKEN0); | ||
| 720 | __raw_writel(val & (~(1 << gpio)), bank->base + | ||
| 721 | OMAP4_GPIO_IRQWAKEN0); | ||
| 722 | } | ||
| 723 | } else { | ||
| 724 | if (trigger != 0) | ||
| 725 | __raw_writel(1 << gpio, bank->base | ||
| 654 | + OMAP24XX_GPIO_SETWKUENA); | 726 | + OMAP24XX_GPIO_SETWKUENA); |
| 655 | else | 727 | else |
| 656 | __raw_writel(1 << gpio, bank->base | 728 | __raw_writel(1 << gpio, bank->base |
| 657 | + OMAP24XX_GPIO_CLEARWKUENA); | 729 | + OMAP24XX_GPIO_CLEARWKUENA); |
| 730 | } | ||
| 658 | } else { | 731 | } else { |
| 659 | if (trigger != 0) | 732 | if (trigger != 0) |
| 660 | bank->enabled_non_wakeup_gpios |= gpio_bit; | 733 | bank->enabled_non_wakeup_gpios |= gpio_bit; |
| @@ -662,9 +735,15 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, | |||
| 662 | bank->enabled_non_wakeup_gpios &= ~gpio_bit; | 735 | bank->enabled_non_wakeup_gpios &= ~gpio_bit; |
| 663 | } | 736 | } |
| 664 | 737 | ||
| 665 | bank->level_mask = | 738 | if (cpu_is_omap44xx()) { |
| 666 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) | | 739 | bank->level_mask = |
| 667 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); | 740 | __raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT0) | |
| 741 | __raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT1); | ||
| 742 | } else { | ||
| 743 | bank->level_mask = | ||
| 744 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) | | ||
| 745 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); | ||
| 746 | } | ||
| 668 | } | 747 | } |
| 669 | #endif | 748 | #endif |
| 670 | 749 | ||
| @@ -828,12 +907,16 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) | |||
| 828 | reg += OMAP850_GPIO_INT_STATUS; | 907 | reg += OMAP850_GPIO_INT_STATUS; |
| 829 | break; | 908 | break; |
| 830 | #endif | 909 | #endif |
| 831 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | 910 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 832 | defined(CONFIG_ARCH_OMAP4) | ||
| 833 | case METHOD_GPIO_24XX: | 911 | case METHOD_GPIO_24XX: |
| 834 | reg += OMAP24XX_GPIO_IRQSTATUS1; | 912 | reg += OMAP24XX_GPIO_IRQSTATUS1; |
| 835 | break; | 913 | break; |
| 836 | #endif | 914 | #endif |
| 915 | #if defined(CONFIG_ARCH_OMAP4) | ||
| 916 | case METHOD_GPIO_24XX: | ||
| 917 | reg += OMAP4_GPIO_IRQSTATUS0; | ||
| 918 | break; | ||
| 919 | #endif | ||
| 837 | default: | 920 | default: |
| 838 | WARN_ON(1); | 921 | WARN_ON(1); |
| 839 | return; | 922 | return; |
| @@ -843,12 +926,16 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) | |||
| 843 | /* Workaround for clearing DSP GPIO interrupts to allow retention */ | 926 | /* Workaround for clearing DSP GPIO interrupts to allow retention */ |
| 844 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 927 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 845 | reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2; | 928 | reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2; |
| 846 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) | 929 | #endif |
| 930 | #if defined(CONFIG_ARCH_OMAP4) | ||
| 931 | reg = bank->base + OMAP4_GPIO_IRQSTATUS1; | ||
| 932 | #endif | ||
| 933 | if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap44xx()) { | ||
| 847 | __raw_writel(gpio_mask, reg); | 934 | __raw_writel(gpio_mask, reg); |
| 848 | 935 | ||
| 849 | /* Flush posted write for the irq status to avoid spurious interrupts */ | 936 | /* Flush posted write for the irq status to avoid spurious interrupts */ |
| 850 | __raw_readl(reg); | 937 | __raw_readl(reg); |
| 851 | #endif | 938 | } |
| 852 | } | 939 | } |
| 853 | 940 | ||
| 854 | static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) | 941 | static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) |
| @@ -898,13 +985,18 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) | |||
| 898 | inv = 1; | 985 | inv = 1; |
| 899 | break; | 986 | break; |
| 900 | #endif | 987 | #endif |
| 901 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | 988 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 902 | defined(CONFIG_ARCH_OMAP4) | ||
| 903 | case METHOD_GPIO_24XX: | 989 | case METHOD_GPIO_24XX: |
| 904 | reg += OMAP24XX_GPIO_IRQENABLE1; | 990 | reg += OMAP24XX_GPIO_IRQENABLE1; |
| 905 | mask = 0xffffffff; | 991 | mask = 0xffffffff; |
| 906 | break; | 992 | break; |
| 907 | #endif | 993 | #endif |
| 994 | #if defined(CONFIG_ARCH_OMAP4) | ||
| 995 | case METHOD_GPIO_24XX: | ||
| 996 | reg += OMAP4_GPIO_IRQSTATUSSET0; | ||
| 997 | mask = 0xffffffff; | ||
| 998 | break; | ||
| 999 | #endif | ||
| 908 | default: | 1000 | default: |
| 909 | WARN_ON(1); | 1001 | WARN_ON(1); |
| 910 | return 0; | 1002 | return 0; |
| @@ -972,8 +1064,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab | |||
| 972 | l |= gpio_mask; | 1064 | l |= gpio_mask; |
| 973 | break; | 1065 | break; |
| 974 | #endif | 1066 | #endif |
| 975 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | 1067 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 976 | defined(CONFIG_ARCH_OMAP4) | ||
| 977 | case METHOD_GPIO_24XX: | 1068 | case METHOD_GPIO_24XX: |
| 978 | if (enable) | 1069 | if (enable) |
| 979 | reg += OMAP24XX_GPIO_SETIRQENABLE1; | 1070 | reg += OMAP24XX_GPIO_SETIRQENABLE1; |
| @@ -982,6 +1073,15 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab | |||
| 982 | l = gpio_mask; | 1073 | l = gpio_mask; |
| 983 | break; | 1074 | break; |
| 984 | #endif | 1075 | #endif |
| 1076 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 1077 | case METHOD_GPIO_24XX: | ||
| 1078 | if (enable) | ||
| 1079 | reg += OMAP4_GPIO_IRQSTATUSSET0; | ||
| 1080 | else | ||
| 1081 | reg += OMAP4_GPIO_IRQSTATUSCLR0; | ||
| 1082 | l = gpio_mask; | ||
| 1083 | break; | ||
| 1084 | #endif | ||
| 985 | default: | 1085 | default: |
| 986 | WARN_ON(1); | 1086 | WARN_ON(1); |
| 987 | return; | 1087 | return; |
| @@ -1157,11 +1257,14 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
| 1157 | if (bank->method == METHOD_GPIO_850) | 1257 | if (bank->method == METHOD_GPIO_850) |
| 1158 | isr_reg = bank->base + OMAP850_GPIO_INT_STATUS; | 1258 | isr_reg = bank->base + OMAP850_GPIO_INT_STATUS; |
| 1159 | #endif | 1259 | #endif |
| 1160 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | 1260 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 1161 | defined(CONFIG_ARCH_OMAP4) | ||
| 1162 | if (bank->method == METHOD_GPIO_24XX) | 1261 | if (bank->method == METHOD_GPIO_24XX) |
| 1163 | isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; | 1262 | isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; |
| 1164 | #endif | 1263 | #endif |
| 1264 | #if defined(CONFIG_ARCH_OMAP4) | ||
| 1265 | if (bank->method == METHOD_GPIO_24XX) | ||
| 1266 | isr_reg = bank->base + OMAP4_GPIO_IRQSTATUS0; | ||
| 1267 | #endif | ||
| 1165 | while(1) { | 1268 | while(1) { |
| 1166 | u32 isr_saved, level_mask = 0; | 1269 | u32 isr_saved, level_mask = 0; |
| 1167 | u32 enabled; | 1270 | u32 enabled; |
| @@ -1638,7 +1741,7 @@ static int __init _omap_gpio_init(void) | |||
| 1638 | 1741 | ||
| 1639 | gpio_bank_count = OMAP34XX_NR_GPIOS; | 1742 | gpio_bank_count = OMAP34XX_NR_GPIOS; |
| 1640 | gpio_bank = gpio_bank_44xx; | 1743 | gpio_bank = gpio_bank_44xx; |
| 1641 | rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); | 1744 | rev = __raw_readl(gpio_bank[0].base + OMAP4_GPIO_REVISION); |
| 1642 | printk(KERN_INFO "OMAP44xx GPIO hardware version %d.%d\n", | 1745 | printk(KERN_INFO "OMAP44xx GPIO hardware version %d.%d\n", |
| 1643 | (rev >> 4) & 0x0f, rev & 0x0f); | 1746 | (rev >> 4) & 0x0f, rev & 0x0f); |
| 1644 | } | 1747 | } |
| @@ -1672,7 +1775,16 @@ static int __init _omap_gpio_init(void) | |||
| 1672 | static const u32 non_wakeup_gpios[] = { | 1775 | static const u32 non_wakeup_gpios[] = { |
| 1673 | 0xe203ffc0, 0x08700040 | 1776 | 0xe203ffc0, 0x08700040 |
| 1674 | }; | 1777 | }; |
| 1675 | 1778 | if (cpu_is_omap44xx()) { | |
| 1779 | __raw_writel(0xffffffff, bank->base + | ||
| 1780 | OMAP4_GPIO_IRQSTATUSCLR0); | ||
| 1781 | __raw_writew(0x0015, bank->base + | ||
| 1782 | OMAP4_GPIO_SYSCONFIG); | ||
| 1783 | __raw_writel(0x00000000, bank->base + | ||
| 1784 | OMAP4_GPIO_DEBOUNCENABLE); | ||
| 1785 | /* Initialize interface clock ungated, module enabled */ | ||
| 1786 | __raw_writel(0, bank->base + OMAP4_GPIO_CTRL); | ||
| 1787 | } else { | ||
| 1676 | __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1); | 1788 | __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1); |
| 1677 | __raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1); | 1789 | __raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1); |
| 1678 | __raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG); | 1790 | __raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG); |
| @@ -1680,12 +1792,12 @@ static int __init _omap_gpio_init(void) | |||
| 1680 | 1792 | ||
| 1681 | /* Initialize interface clock ungated, module enabled */ | 1793 | /* Initialize interface clock ungated, module enabled */ |
| 1682 | __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); | 1794 | __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); |
| 1795 | } | ||
| 1683 | if (i < ARRAY_SIZE(non_wakeup_gpios)) | 1796 | if (i < ARRAY_SIZE(non_wakeup_gpios)) |
| 1684 | bank->non_wakeup_gpios = non_wakeup_gpios[i]; | 1797 | bank->non_wakeup_gpios = non_wakeup_gpios[i]; |
| 1685 | gpio_count = 32; | 1798 | gpio_count = 32; |
| 1686 | } | 1799 | } |
| 1687 | #endif | 1800 | #endif |
| 1688 | |||
| 1689 | /* REVISIT eventually switch from OMAP-specific gpio structs | 1801 | /* REVISIT eventually switch from OMAP-specific gpio structs |
| 1690 | * over to the generic ones | 1802 | * over to the generic ones |
| 1691 | */ | 1803 | */ |
| @@ -1771,14 +1883,20 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) | |||
| 1771 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; | 1883 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; |
| 1772 | break; | 1884 | break; |
| 1773 | #endif | 1885 | #endif |
| 1774 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | 1886 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 1775 | defined(CONFIG_ARCH_OMAP4) | ||
| 1776 | case METHOD_GPIO_24XX: | 1887 | case METHOD_GPIO_24XX: |
| 1777 | wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN; | 1888 | wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN; |
| 1778 | wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; | 1889 | wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; |
| 1779 | wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; | 1890 | wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; |
| 1780 | break; | 1891 | break; |
| 1781 | #endif | 1892 | #endif |
| 1893 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 1894 | case METHOD_GPIO_24XX: | ||
| 1895 | wake_status = bank->base + OMAP4_GPIO_IRQWAKEN0; | ||
| 1896 | wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0; | ||
| 1897 | wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0; | ||
| 1898 | break; | ||
| 1899 | #endif | ||
| 1782 | default: | 1900 | default: |
| 1783 | continue; | 1901 | continue; |
| 1784 | } | 1902 | } |
| @@ -1813,13 +1931,18 @@ static int omap_gpio_resume(struct sys_device *dev) | |||
| 1813 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; | 1931 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; |
| 1814 | break; | 1932 | break; |
| 1815 | #endif | 1933 | #endif |
| 1816 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | 1934 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 1817 | defined(CONFIG_ARCH_OMAP4) | ||
| 1818 | case METHOD_GPIO_24XX: | 1935 | case METHOD_GPIO_24XX: |
| 1819 | wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; | 1936 | wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; |
| 1820 | wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; | 1937 | wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; |
| 1821 | break; | 1938 | break; |
| 1822 | #endif | 1939 | #endif |
| 1940 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 1941 | case METHOD_GPIO_24XX: | ||
| 1942 | wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0; | ||
| 1943 | wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0; | ||
| 1944 | break; | ||
| 1945 | #endif | ||
| 1823 | default: | 1946 | default: |
| 1824 | continue; | 1947 | continue; |
| 1825 | } | 1948 | } |
| @@ -1863,21 +1986,29 @@ void omap2_gpio_prepare_for_retention(void) | |||
| 1863 | 1986 | ||
| 1864 | if (!(bank->enabled_non_wakeup_gpios)) | 1987 | if (!(bank->enabled_non_wakeup_gpios)) |
| 1865 | continue; | 1988 | continue; |
| 1866 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | 1989 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 1867 | defined(CONFIG_ARCH_OMAP4) | ||
| 1868 | bank->saved_datain = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN); | 1990 | bank->saved_datain = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN); |
| 1869 | l1 = __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); | 1991 | l1 = __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); |
| 1870 | l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT); | 1992 | l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT); |
| 1871 | #endif | 1993 | #endif |
| 1994 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 1995 | bank->saved_datain = __raw_readl(bank->base + | ||
| 1996 | OMAP4_GPIO_DATAIN); | ||
| 1997 | l1 = __raw_readl(bank->base + OMAP4_GPIO_FALLINGDETECT); | ||
| 1998 | l2 = __raw_readl(bank->base + OMAP4_GPIO_RISINGDETECT); | ||
| 1999 | #endif | ||
| 1872 | bank->saved_fallingdetect = l1; | 2000 | bank->saved_fallingdetect = l1; |
| 1873 | bank->saved_risingdetect = l2; | 2001 | bank->saved_risingdetect = l2; |
| 1874 | l1 &= ~bank->enabled_non_wakeup_gpios; | 2002 | l1 &= ~bank->enabled_non_wakeup_gpios; |
| 1875 | l2 &= ~bank->enabled_non_wakeup_gpios; | 2003 | l2 &= ~bank->enabled_non_wakeup_gpios; |
| 1876 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | 2004 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 1877 | defined(CONFIG_ARCH_OMAP4) | ||
| 1878 | __raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT); | 2005 | __raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT); |
| 1879 | __raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT); | 2006 | __raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT); |
| 1880 | #endif | 2007 | #endif |
| 2008 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 2009 | __raw_writel(l1, bank->base + OMAP4_GPIO_FALLINGDETECT); | ||
| 2010 | __raw_writel(l2, bank->base + OMAP4_GPIO_RISINGDETECT); | ||
| 2011 | #endif | ||
| 1881 | c++; | 2012 | c++; |
| 1882 | } | 2013 | } |
| 1883 | if (!c) { | 2014 | if (!c) { |
| @@ -1899,27 +2030,29 @@ void omap2_gpio_resume_after_retention(void) | |||
| 1899 | 2030 | ||
| 1900 | if (!(bank->enabled_non_wakeup_gpios)) | 2031 | if (!(bank->enabled_non_wakeup_gpios)) |
| 1901 | continue; | 2032 | continue; |
| 1902 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | 2033 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 1903 | defined(CONFIG_ARCH_OMAP4) | ||
| 1904 | __raw_writel(bank->saved_fallingdetect, | 2034 | __raw_writel(bank->saved_fallingdetect, |
| 1905 | bank->base + OMAP24XX_GPIO_FALLINGDETECT); | 2035 | bank->base + OMAP24XX_GPIO_FALLINGDETECT); |
| 1906 | __raw_writel(bank->saved_risingdetect, | 2036 | __raw_writel(bank->saved_risingdetect, |
| 1907 | bank->base + OMAP24XX_GPIO_RISINGDETECT); | 2037 | bank->base + OMAP24XX_GPIO_RISINGDETECT); |
| 2038 | l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN); | ||
| 2039 | #endif | ||
| 2040 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 2041 | __raw_writel(bank->saved_fallingdetect, | ||
| 2042 | bank->base + OMAP4_GPIO_FALLINGDETECT); | ||
| 2043 | __raw_writel(bank->saved_risingdetect, | ||
| 2044 | bank->base + OMAP4_GPIO_RISINGDETECT); | ||
| 2045 | l = __raw_readl(bank->base + OMAP4_GPIO_DATAIN); | ||
| 1908 | #endif | 2046 | #endif |
| 1909 | /* Check if any of the non-wakeup interrupt GPIOs have changed | 2047 | /* Check if any of the non-wakeup interrupt GPIOs have changed |
| 1910 | * state. If so, generate an IRQ by software. This is | 2048 | * state. If so, generate an IRQ by software. This is |
| 1911 | * horribly racy, but it's the best we can do to work around | 2049 | * horribly racy, but it's the best we can do to work around |
| 1912 | * this silicon bug. */ | 2050 | * this silicon bug. */ |
| 1913 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | ||
| 1914 | defined(CONFIG_ARCH_OMAP4) | ||
| 1915 | l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN); | ||
| 1916 | #endif | ||
| 1917 | l ^= bank->saved_datain; | 2051 | l ^= bank->saved_datain; |
| 1918 | l &= bank->non_wakeup_gpios; | 2052 | l &= bank->non_wakeup_gpios; |
| 1919 | if (l) { | 2053 | if (l) { |
| 1920 | u32 old0, old1; | 2054 | u32 old0, old1; |
| 1921 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ | 2055 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
| 1922 | defined(CONFIG_ARCH_OMAP4) | ||
| 1923 | old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0); | 2056 | old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0); |
| 1924 | old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); | 2057 | old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); |
| 1925 | __raw_writel(old0 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT0); | 2058 | __raw_writel(old0 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT0); |
| @@ -1927,6 +2060,20 @@ void omap2_gpio_resume_after_retention(void) | |||
| 1927 | __raw_writel(old0, bank->base + OMAP24XX_GPIO_LEVELDETECT0); | 2060 | __raw_writel(old0, bank->base + OMAP24XX_GPIO_LEVELDETECT0); |
| 1928 | __raw_writel(old1, bank->base + OMAP24XX_GPIO_LEVELDETECT1); | 2061 | __raw_writel(old1, bank->base + OMAP24XX_GPIO_LEVELDETECT1); |
| 1929 | #endif | 2062 | #endif |
| 2063 | #ifdef CONFIG_ARCH_OMAP4 | ||
| 2064 | old0 = __raw_readl(bank->base + | ||
| 2065 | OMAP4_GPIO_LEVELDETECT0); | ||
| 2066 | old1 = __raw_readl(bank->base + | ||
| 2067 | OMAP4_GPIO_LEVELDETECT1); | ||
| 2068 | __raw_writel(old0 | l, bank->base + | ||
| 2069 | OMAP4_GPIO_LEVELDETECT0); | ||
| 2070 | __raw_writel(old1 | l, bank->base + | ||
| 2071 | OMAP4_GPIO_LEVELDETECT1); | ||
| 2072 | __raw_writel(old0, bank->base + | ||
| 2073 | OMAP4_GPIO_LEVELDETECT0); | ||
| 2074 | __raw_writel(old1, bank->base + | ||
| 2075 | OMAP4_GPIO_LEVELDETECT1); | ||
| 2076 | #endif | ||
| 1930 | } | 2077 | } |
| 1931 | } | 2078 | } |
| 1932 | 2079 | ||
diff --git a/arch/arm/plat-omap/include/mach/dma.h b/arch/arm/plat-omap/include/mach/dma.h index 7b939cc01962..72f680b7180d 100644 --- a/arch/arm/plat-omap/include/mach/dma.h +++ b/arch/arm/plat-omap/include/mach/dma.h | |||
| @@ -122,6 +122,11 @@ | |||
| 122 | #define OMAP_DMA4_CCFN(n) (0x60 * (n) + 0xc0) | 122 | #define OMAP_DMA4_CCFN(n) (0x60 * (n) + 0xc0) |
| 123 | #define OMAP_DMA4_COLOR(n) (0x60 * (n) + 0xc4) | 123 | #define OMAP_DMA4_COLOR(n) (0x60 * (n) + 0xc4) |
| 124 | 124 | ||
| 125 | /* Additional registers available on OMAP4 */ | ||
| 126 | #define OMAP_DMA4_CDP(n) (0x60 * (n) + 0xd0) | ||
| 127 | #define OMAP_DMA4_CNDP(n) (0x60 * (n) + 0xd4) | ||
| 128 | #define OMAP_DMA4_CCDN(n) (0x60 * (n) + 0xd8) | ||
| 129 | |||
| 125 | /* Dummy defines to keep multi-omap compiles happy */ | 130 | /* Dummy defines to keep multi-omap compiles happy */ |
| 126 | #define OMAP1_DMA_REVISION 0 | 131 | #define OMAP1_DMA_REVISION 0 |
| 127 | #define OMAP1_DMA_IRQSTATUS_L0 0 | 132 | #define OMAP1_DMA_IRQSTATUS_L0 0 |
| @@ -311,6 +316,89 @@ | |||
| 311 | #define OMAP34XX_DMA_USIM_TX 79 /* S_DMA_78 */ | 316 | #define OMAP34XX_DMA_USIM_TX 79 /* S_DMA_78 */ |
| 312 | #define OMAP34XX_DMA_USIM_RX 80 /* S_DMA_79 */ | 317 | #define OMAP34XX_DMA_USIM_RX 80 /* S_DMA_79 */ |
| 313 | 318 | ||
| 319 | /* DMA request lines for 44xx */ | ||
| 320 | #define OMAP44XX_DMA_DSS_DISPC_REQ 6 /* S_DMA_5 */ | ||
| 321 | #define OMAP44XX_DMA_SYS_REQ2 7 /* S_DMA_6 */ | ||
| 322 | #define OMAP44XX_DMA_ISS_REQ1 9 /* S_DMA_8 */ | ||
| 323 | #define OMAP44XX_DMA_ISS_REQ2 10 /* S_DMA_9 */ | ||
| 324 | #define OMAP44XX_DMA_ISS_REQ3 12 /* S_DMA_11 */ | ||
| 325 | #define OMAP44XX_DMA_ISS_REQ4 13 /* S_DMA_12 */ | ||
| 326 | #define OMAP44XX_DMA_DSS_RFBI_REQ 14 /* S_DMA_13 */ | ||
| 327 | #define OMAP44XX_DMA_SPI3_TX0 15 /* S_DMA_14 */ | ||
| 328 | #define OMAP44XX_DMA_SPI3_RX0 16 /* S_DMA_15 */ | ||
| 329 | #define OMAP44XX_DMA_MCBSP2_TX 17 /* S_DMA_16 */ | ||
| 330 | #define OMAP44XX_DMA_MCBSP2_RX 18 /* S_DMA_17 */ | ||
| 331 | #define OMAP44XX_DMA_MCBSP3_TX 19 /* S_DMA_18 */ | ||
| 332 | #define OMAP44XX_DMA_MCBSP3_RX 20 /* S_DMA_19 */ | ||
| 333 | #define OMAP44XX_DMA_SPI3_TX1 23 /* S_DMA_22 */ | ||
| 334 | #define OMAP44XX_DMA_SPI3_RX1 24 /* S_DMA_23 */ | ||
| 335 | #define OMAP44XX_DMA_I2C3_TX 25 /* S_DMA_24 */ | ||
| 336 | #define OMAP44XX_DMA_I2C3_RX 26 /* S_DMA_25 */ | ||
| 337 | #define OMAP44XX_DMA_I2C1_TX 27 /* S_DMA_26 */ | ||
| 338 | #define OMAP44XX_DMA_I2C1_RX 28 /* S_DMA_27 */ | ||
| 339 | #define OMAP44XX_DMA_I2C2_TX 29 /* S_DMA_28 */ | ||
| 340 | #define OMAP44XX_DMA_I2C2_RX 30 /* S_DMA_29 */ | ||
| 341 | #define OMAP44XX_DMA_MCBSP4_TX 31 /* S_DMA_30 */ | ||
| 342 | #define OMAP44XX_DMA_MCBSP4_RX 32 /* S_DMA_31 */ | ||
| 343 | #define OMAP44XX_DMA_MCBSP1_TX 33 /* S_DMA_32 */ | ||
| 344 | #define OMAP44XX_DMA_MCBSP1_RX 34 /* S_DMA_33 */ | ||
| 345 | #define OMAP44XX_DMA_SPI1_TX0 35 /* S_DMA_34 */ | ||
| 346 | #define OMAP44XX_DMA_SPI1_RX0 36 /* S_DMA_35 */ | ||
| 347 | #define OMAP44XX_DMA_SPI1_TX1 37 /* S_DMA_36 */ | ||
| 348 | #define OMAP44XX_DMA_SPI1_RX1 38 /* S_DMA_37 */ | ||
| 349 | #define OMAP44XX_DMA_SPI1_TX2 39 /* S_DMA_38 */ | ||
| 350 | #define OMAP44XX_DMA_SPI1_RX2 40 /* S_DMA_39 */ | ||
| 351 | #define OMAP44XX_DMA_SPI1_TX3 41 /* S_DMA_40 */ | ||
| 352 | #define OMAP44XX_DMA_SPI1_RX3 42 /* S_DMA_41 */ | ||
| 353 | #define OMAP44XX_DMA_SPI2_TX0 43 /* S_DMA_42 */ | ||
| 354 | #define OMAP44XX_DMA_SPI2_RX0 44 /* S_DMA_43 */ | ||
| 355 | #define OMAP44XX_DMA_SPI2_TX1 45 /* S_DMA_44 */ | ||
| 356 | #define OMAP44XX_DMA_SPI2_RX1 46 /* S_DMA_45 */ | ||
| 357 | #define OMAP44XX_DMA_MMC2_TX 47 /* S_DMA_46 */ | ||
| 358 | #define OMAP44XX_DMA_MMC2_RX 48 /* S_DMA_47 */ | ||
| 359 | #define OMAP44XX_DMA_UART1_TX 49 /* S_DMA_48 */ | ||
| 360 | #define OMAP44XX_DMA_UART1_RX 50 /* S_DMA_49 */ | ||
| 361 | #define OMAP44XX_DMA_UART2_TX 51 /* S_DMA_50 */ | ||
| 362 | #define OMAP44XX_DMA_UART2_RX 52 /* S_DMA_51 */ | ||
| 363 | #define OMAP44XX_DMA_UART3_TX 53 /* S_DMA_52 */ | ||
| 364 | #define OMAP44XX_DMA_UART3_RX 54 /* S_DMA_53 */ | ||
| 365 | #define OMAP44XX_DMA_UART4_TX 55 /* S_DMA_54 */ | ||
| 366 | #define OMAP44XX_DMA_UART4_RX 56 /* S_DMA_55 */ | ||
| 367 | #define OMAP44XX_DMA_MMC4_TX 57 /* S_DMA_56 */ | ||
| 368 | #define OMAP44XX_DMA_MMC4_RX 58 /* S_DMA_57 */ | ||
| 369 | #define OMAP44XX_DMA_MMC5_TX 59 /* S_DMA_58 */ | ||
| 370 | #define OMAP44XX_DMA_MMC5_RX 60 /* S_DMA_59 */ | ||
| 371 | #define OMAP44XX_DMA_MMC1_TX 61 /* S_DMA_60 */ | ||
| 372 | #define OMAP44XX_DMA_MMC1_RX 62 /* S_DMA_61 */ | ||
| 373 | #define OMAP44XX_DMA_SYS_REQ3 64 /* S_DMA_63 */ | ||
| 374 | #define OMAP44XX_DMA_MCPDM_UP 65 /* S_DMA_64 */ | ||
| 375 | #define OMAP44XX_DMA_MCPDM_DL 66 /* S_DMA_65 */ | ||
| 376 | #define OMAP44XX_DMA_SPI4_TX0 70 /* S_DMA_69 */ | ||
| 377 | #define OMAP44XX_DMA_SPI4_RX0 71 /* S_DMA_70 */ | ||
| 378 | #define OMAP44XX_DMA_DSS_DSI1_REQ0 72 /* S_DMA_71 */ | ||
| 379 | #define OMAP44XX_DMA_DSS_DSI1_REQ1 73 /* S_DMA_72 */ | ||
| 380 | #define OMAP44XX_DMA_DSS_DSI1_REQ2 74 /* S_DMA_73 */ | ||
| 381 | #define OMAP44XX_DMA_DSS_DSI1_REQ3 75 /* S_DMA_74 */ | ||
| 382 | #define OMAP44XX_DMA_DSS_HDMI_REQ 76 /* S_DMA_75 */ | ||
| 383 | #define OMAP44XX_DMA_MMC3_TX 77 /* S_DMA_76 */ | ||
| 384 | #define OMAP44XX_DMA_MMC3_RX 78 /* S_DMA_77 */ | ||
| 385 | #define OMAP44XX_DMA_USIM_TX 79 /* S_DMA_78 */ | ||
| 386 | #define OMAP44XX_DMA_USIM_RX 80 /* S_DMA_79 */ | ||
| 387 | #define OMAP44XX_DMA_DSS_DSI2_REQ0 81 /* S_DMA_80 */ | ||
| 388 | #define OMAP44XX_DMA_DSS_DSI2_REQ1 82 /* S_DMA_81 */ | ||
| 389 | #define OMAP44XX_DMA_DSS_DSI2_REQ2 83 /* S_DMA_82 */ | ||
| 390 | #define OMAP44XX_DMA_DSS_DSI2_REQ3 84 /* S_DMA_83 */ | ||
| 391 | #define OMAP44XX_DMA_ABE_REQ0 101 /* S_DMA_100 */ | ||
| 392 | #define OMAP44XX_DMA_ABE_REQ1 102 /* S_DMA_101 */ | ||
| 393 | #define OMAP44XX_DMA_ABE_REQ2 103 /* S_DMA_102 */ | ||
| 394 | #define OMAP44XX_DMA_ABE_REQ3 104 /* S_DMA_103 */ | ||
| 395 | #define OMAP44XX_DMA_ABE_REQ4 105 /* S_DMA_104 */ | ||
| 396 | #define OMAP44XX_DMA_ABE_REQ5 106 /* S_DMA_105 */ | ||
| 397 | #define OMAP44XX_DMA_ABE_REQ6 107 /* S_DMA_106 */ | ||
| 398 | #define OMAP44XX_DMA_ABE_REQ7 108 /* S_DMA_107 */ | ||
| 399 | #define OMAP44XX_DMA_I2C4_TX 124 /* S_DMA_123 */ | ||
| 400 | #define OMAP44XX_DMA_I2C4_RX 125 /* S_DMA_124 */ | ||
| 401 | |||
| 314 | /*----------------------------------------------------------------------------*/ | 402 | /*----------------------------------------------------------------------------*/ |
| 315 | 403 | ||
| 316 | /* Hardware registers for LCD DMA */ | 404 | /* Hardware registers for LCD DMA */ |
diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index bb154ea76769..e0d6eca222cc 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h | |||
| @@ -53,6 +53,11 @@ | |||
| 53 | #define OMAP34XX_MCBSP4_BASE 0x49026000 | 53 | #define OMAP34XX_MCBSP4_BASE 0x49026000 |
| 54 | #define OMAP34XX_MCBSP5_BASE 0x48096000 | 54 | #define OMAP34XX_MCBSP5_BASE 0x48096000 |
| 55 | 55 | ||
| 56 | #define OMAP44XX_MCBSP1_BASE 0x49022000 | ||
| 57 | #define OMAP44XX_MCBSP2_BASE 0x49024000 | ||
| 58 | #define OMAP44XX_MCBSP3_BASE 0x49026000 | ||
| 59 | #define OMAP44XX_MCBSP4_BASE 0x48074000 | ||
| 60 | |||
| 56 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) | 61 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) |
| 57 | 62 | ||
| 58 | #define OMAP_MCBSP_REG_DRR2 0x00 | 63 | #define OMAP_MCBSP_REG_DRR2 0x00 |
| @@ -98,7 +103,8 @@ | |||
| 98 | #define AUDIO_DMA_TX OMAP_DMA_MCBSP1_TX | 103 | #define AUDIO_DMA_TX OMAP_DMA_MCBSP1_TX |
| 99 | #define AUDIO_DMA_RX OMAP_DMA_MCBSP1_RX | 104 | #define AUDIO_DMA_RX OMAP_DMA_MCBSP1_RX |
| 100 | 105 | ||
| 101 | #elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 106 | #elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ |
| 107 | defined(CONFIG_ARCH_OMAP4) | ||
| 102 | 108 | ||
| 103 | #define OMAP_MCBSP_REG_DRR2 0x00 | 109 | #define OMAP_MCBSP_REG_DRR2 0x00 |
| 104 | #define OMAP_MCBSP_REG_DRR1 0x04 | 110 | #define OMAP_MCBSP_REG_DRR1 0x04 |
| @@ -134,6 +140,11 @@ | |||
| 134 | #define OMAP_MCBSP_REG_XCERG 0x74 | 140 | #define OMAP_MCBSP_REG_XCERG 0x74 |
| 135 | #define OMAP_MCBSP_REG_XCERH 0x78 | 141 | #define OMAP_MCBSP_REG_XCERH 0x78 |
| 136 | #define OMAP_MCBSP_REG_SYSCON 0x8C | 142 | #define OMAP_MCBSP_REG_SYSCON 0x8C |
| 143 | #define OMAP_MCBSP_REG_THRSH2 0x90 | ||
| 144 | #define OMAP_MCBSP_REG_THRSH1 0x94 | ||
| 145 | #define OMAP_MCBSP_REG_IRQST 0xA0 | ||
| 146 | #define OMAP_MCBSP_REG_IRQEN 0xA4 | ||
| 147 | #define OMAP_MCBSP_REG_WAKEUPEN 0xA8 | ||
| 137 | #define OMAP_MCBSP_REG_XCCR 0xAC | 148 | #define OMAP_MCBSP_REG_XCCR 0xAC |
| 138 | #define OMAP_MCBSP_REG_RCCR 0xB0 | 149 | #define OMAP_MCBSP_REG_RCCR 0xB0 |
| 139 | 150 | ||
| @@ -249,8 +260,27 @@ | |||
| 249 | #define RDISABLE 0x0001 | 260 | #define RDISABLE 0x0001 |
| 250 | 261 | ||
| 251 | /********************** McBSP SYSCONFIG bit definitions ********************/ | 262 | /********************** McBSP SYSCONFIG bit definitions ********************/ |
| 263 | #define CLOCKACTIVITY(value) ((value)<<8) | ||
| 264 | #define SIDLEMODE(value) ((value)<<3) | ||
| 265 | #define ENAWAKEUP 0x0004 | ||
| 252 | #define SOFTRST 0x0002 | 266 | #define SOFTRST 0x0002 |
| 253 | 267 | ||
| 268 | /********************** McBSP DMA operating modes **************************/ | ||
| 269 | #define MCBSP_DMA_MODE_ELEMENT 0 | ||
| 270 | #define MCBSP_DMA_MODE_THRESHOLD 1 | ||
| 271 | #define MCBSP_DMA_MODE_FRAME 2 | ||
| 272 | |||
| 273 | /********************** McBSP WAKEUPEN bit definitions *********************/ | ||
| 274 | #define XEMPTYEOFEN 0x4000 | ||
| 275 | #define XRDYEN 0x0400 | ||
| 276 | #define XEOFEN 0x0200 | ||
| 277 | #define XFSXEN 0x0100 | ||
| 278 | #define XSYNCERREN 0x0080 | ||
| 279 | #define RRDYEN 0x0008 | ||
| 280 | #define REOFEN 0x0004 | ||
| 281 | #define RFSREN 0x0002 | ||
| 282 | #define RSYNCERREN 0x0001 | ||
| 283 | |||
| 254 | /* we don't do multichannel for now */ | 284 | /* we don't do multichannel for now */ |
| 255 | struct omap_mcbsp_reg_cfg { | 285 | struct omap_mcbsp_reg_cfg { |
| 256 | u16 spcr2; | 286 | u16 spcr2; |
| @@ -344,6 +374,9 @@ struct omap_mcbsp_platform_data { | |||
| 344 | u8 dma_rx_sync, dma_tx_sync; | 374 | u8 dma_rx_sync, dma_tx_sync; |
| 345 | u16 rx_irq, tx_irq; | 375 | u16 rx_irq, tx_irq; |
| 346 | struct omap_mcbsp_ops *ops; | 376 | struct omap_mcbsp_ops *ops; |
| 377 | #ifdef CONFIG_ARCH_OMAP34XX | ||
| 378 | u16 buffer_size; | ||
| 379 | #endif | ||
| 347 | }; | 380 | }; |
| 348 | 381 | ||
| 349 | struct omap_mcbsp { | 382 | struct omap_mcbsp { |
| @@ -377,6 +410,11 @@ struct omap_mcbsp { | |||
| 377 | struct omap_mcbsp_platform_data *pdata; | 410 | struct omap_mcbsp_platform_data *pdata; |
| 378 | struct clk *iclk; | 411 | struct clk *iclk; |
| 379 | struct clk *fclk; | 412 | struct clk *fclk; |
| 413 | #ifdef CONFIG_ARCH_OMAP34XX | ||
| 414 | int dma_op_mode; | ||
| 415 | u16 max_tx_thres; | ||
| 416 | u16 max_rx_thres; | ||
| 417 | #endif | ||
| 380 | }; | 418 | }; |
| 381 | extern struct omap_mcbsp **mcbsp_ptr; | 419 | extern struct omap_mcbsp **mcbsp_ptr; |
| 382 | extern int omap_mcbsp_count; | 420 | extern int omap_mcbsp_count; |
| @@ -385,10 +423,25 @@ int omap_mcbsp_init(void); | |||
| 385 | void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, | 423 | void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, |
| 386 | int size); | 424 | int size); |
| 387 | void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); | 425 | void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); |
| 426 | #ifdef CONFIG_ARCH_OMAP34XX | ||
| 427 | void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); | ||
| 428 | void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); | ||
| 429 | u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); | ||
| 430 | u16 omap_mcbsp_get_max_rx_threshold(unsigned int id); | ||
| 431 | int omap_mcbsp_get_dma_op_mode(unsigned int id); | ||
| 432 | #else | ||
| 433 | static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) | ||
| 434 | { } | ||
| 435 | static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) | ||
| 436 | { } | ||
| 437 | static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; } | ||
| 438 | static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; } | ||
| 439 | static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; } | ||
| 440 | #endif | ||
| 388 | int omap_mcbsp_request(unsigned int id); | 441 | int omap_mcbsp_request(unsigned int id); |
| 389 | void omap_mcbsp_free(unsigned int id); | 442 | void omap_mcbsp_free(unsigned int id); |
| 390 | void omap_mcbsp_start(unsigned int id); | 443 | void omap_mcbsp_start(unsigned int id, int tx, int rx); |
| 391 | void omap_mcbsp_stop(unsigned int id); | 444 | void omap_mcbsp_stop(unsigned int id, int tx, int rx); |
| 392 | void omap_mcbsp_xmit_word(unsigned int id, u32 word); | 445 | void omap_mcbsp_xmit_word(unsigned int id, u32 word); |
| 393 | u32 omap_mcbsp_recv_word(unsigned int id); | 446 | u32 omap_mcbsp_recv_word(unsigned int id); |
| 394 | 447 | ||
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index efa0e0111f38..88ac9768f1c1 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
| @@ -191,13 +191,177 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) | |||
| 191 | OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2); | 191 | OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2); |
| 192 | OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1); | 192 | OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1); |
| 193 | OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0); | 193 | OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0); |
| 194 | if (cpu_is_omap2430() || cpu_is_omap34xx()) { | 194 | if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { |
| 195 | OMAP_MCBSP_WRITE(io_base, XCCR, config->xccr); | 195 | OMAP_MCBSP_WRITE(io_base, XCCR, config->xccr); |
| 196 | OMAP_MCBSP_WRITE(io_base, RCCR, config->rccr); | 196 | OMAP_MCBSP_WRITE(io_base, RCCR, config->rccr); |
| 197 | } | 197 | } |
| 198 | } | 198 | } |
| 199 | EXPORT_SYMBOL(omap_mcbsp_config); | 199 | EXPORT_SYMBOL(omap_mcbsp_config); |
| 200 | 200 | ||
| 201 | #ifdef CONFIG_ARCH_OMAP34XX | ||
| 202 | /* | ||
| 203 | * omap_mcbsp_set_tx_threshold configures how to deal | ||
| 204 | * with transmit threshold. the threshold value and handler can be | ||
| 205 | * configure in here. | ||
| 206 | */ | ||
| 207 | void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) | ||
| 208 | { | ||
| 209 | struct omap_mcbsp *mcbsp; | ||
| 210 | void __iomem *io_base; | ||
| 211 | |||
| 212 | if (!cpu_is_omap34xx()) | ||
| 213 | return; | ||
| 214 | |||
| 215 | if (!omap_mcbsp_check_valid_id(id)) { | ||
| 216 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
| 217 | return; | ||
| 218 | } | ||
| 219 | mcbsp = id_to_mcbsp_ptr(id); | ||
| 220 | io_base = mcbsp->io_base; | ||
| 221 | |||
| 222 | OMAP_MCBSP_WRITE(io_base, THRSH2, threshold); | ||
| 223 | } | ||
| 224 | EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold); | ||
| 225 | |||
| 226 | /* | ||
| 227 | * omap_mcbsp_set_rx_threshold configures how to deal | ||
| 228 | * with receive threshold. the threshold value and handler can be | ||
| 229 | * configure in here. | ||
| 230 | */ | ||
| 231 | void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) | ||
| 232 | { | ||
| 233 | struct omap_mcbsp *mcbsp; | ||
| 234 | void __iomem *io_base; | ||
| 235 | |||
| 236 | if (!cpu_is_omap34xx()) | ||
| 237 | return; | ||
| 238 | |||
| 239 | if (!omap_mcbsp_check_valid_id(id)) { | ||
| 240 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
| 241 | return; | ||
| 242 | } | ||
| 243 | mcbsp = id_to_mcbsp_ptr(id); | ||
| 244 | io_base = mcbsp->io_base; | ||
| 245 | |||
| 246 | OMAP_MCBSP_WRITE(io_base, THRSH1, threshold); | ||
| 247 | } | ||
| 248 | EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold); | ||
| 249 | |||
| 250 | /* | ||
| 251 | * omap_mcbsp_get_max_tx_thres just return the current configured | ||
| 252 | * maximum threshold for transmission | ||
| 253 | */ | ||
| 254 | u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) | ||
| 255 | { | ||
| 256 | struct omap_mcbsp *mcbsp; | ||
| 257 | |||
| 258 | if (!omap_mcbsp_check_valid_id(id)) { | ||
| 259 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
| 260 | return -ENODEV; | ||
| 261 | } | ||
| 262 | mcbsp = id_to_mcbsp_ptr(id); | ||
| 263 | |||
| 264 | return mcbsp->max_tx_thres; | ||
| 265 | } | ||
| 266 | EXPORT_SYMBOL(omap_mcbsp_get_max_tx_threshold); | ||
| 267 | |||
| 268 | /* | ||
| 269 | * omap_mcbsp_get_max_rx_thres just return the current configured | ||
| 270 | * maximum threshold for reception | ||
| 271 | */ | ||
| 272 | u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) | ||
| 273 | { | ||
| 274 | struct omap_mcbsp *mcbsp; | ||
| 275 | |||
| 276 | if (!omap_mcbsp_check_valid_id(id)) { | ||
| 277 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
| 278 | return -ENODEV; | ||
| 279 | } | ||
| 280 | mcbsp = id_to_mcbsp_ptr(id); | ||
| 281 | |||
| 282 | return mcbsp->max_rx_thres; | ||
| 283 | } | ||
| 284 | EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold); | ||
| 285 | |||
| 286 | /* | ||
| 287 | * omap_mcbsp_get_dma_op_mode just return the current configured | ||
| 288 | * operating mode for the mcbsp channel | ||
| 289 | */ | ||
| 290 | int omap_mcbsp_get_dma_op_mode(unsigned int id) | ||
| 291 | { | ||
| 292 | struct omap_mcbsp *mcbsp; | ||
| 293 | int dma_op_mode; | ||
| 294 | |||
| 295 | if (!omap_mcbsp_check_valid_id(id)) { | ||
| 296 | printk(KERN_ERR "%s: Invalid id (%u)\n", __func__, id + 1); | ||
| 297 | return -ENODEV; | ||
| 298 | } | ||
| 299 | mcbsp = id_to_mcbsp_ptr(id); | ||
| 300 | |||
| 301 | spin_lock_irq(&mcbsp->lock); | ||
| 302 | dma_op_mode = mcbsp->dma_op_mode; | ||
| 303 | spin_unlock_irq(&mcbsp->lock); | ||
| 304 | |||
| 305 | return dma_op_mode; | ||
| 306 | } | ||
| 307 | EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode); | ||
| 308 | |||
| 309 | static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) | ||
| 310 | { | ||
| 311 | /* | ||
| 312 | * Enable wakup behavior, smart idle and all wakeups | ||
| 313 | * REVISIT: some wakeups may be unnecessary | ||
| 314 | */ | ||
| 315 | if (cpu_is_omap34xx()) { | ||
| 316 | u16 syscon; | ||
| 317 | |||
| 318 | syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON); | ||
| 319 | syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03)); | ||
| 320 | |||
| 321 | spin_lock_irq(&mcbsp->lock); | ||
| 322 | if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) { | ||
| 323 | syscon |= (ENAWAKEUP | SIDLEMODE(0x02) | | ||
| 324 | CLOCKACTIVITY(0x02)); | ||
| 325 | OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN, | ||
| 326 | XRDYEN | RRDYEN); | ||
| 327 | } else { | ||
| 328 | syscon |= SIDLEMODE(0x01); | ||
| 329 | } | ||
| 330 | spin_unlock_irq(&mcbsp->lock); | ||
| 331 | |||
| 332 | OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon); | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) | ||
| 337 | { | ||
| 338 | /* | ||
| 339 | * Disable wakup behavior, smart idle and all wakeups | ||
| 340 | */ | ||
| 341 | if (cpu_is_omap34xx()) { | ||
| 342 | u16 syscon; | ||
| 343 | |||
| 344 | syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON); | ||
| 345 | syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03)); | ||
| 346 | /* | ||
| 347 | * HW bug workaround - If no_idle mode is taken, we need to | ||
| 348 | * go to smart_idle before going to always_idle, or the | ||
| 349 | * device will not hit retention anymore. | ||
| 350 | */ | ||
| 351 | syscon |= SIDLEMODE(0x02); | ||
| 352 | OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon); | ||
| 353 | |||
| 354 | syscon &= ~(SIDLEMODE(0x03)); | ||
| 355 | OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon); | ||
| 356 | |||
| 357 | OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN, 0); | ||
| 358 | } | ||
| 359 | } | ||
| 360 | #else | ||
| 361 | static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) {} | ||
| 362 | static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) {} | ||
| 363 | #endif | ||
| 364 | |||
| 201 | /* | 365 | /* |
| 202 | * We can choose between IRQ based or polled IO. | 366 | * We can choose between IRQ based or polled IO. |
| 203 | * This needs to be called before omap_mcbsp_request(). | 367 | * This needs to be called before omap_mcbsp_request(). |
| @@ -257,6 +421,9 @@ int omap_mcbsp_request(unsigned int id) | |||
| 257 | clk_enable(mcbsp->iclk); | 421 | clk_enable(mcbsp->iclk); |
| 258 | clk_enable(mcbsp->fclk); | 422 | clk_enable(mcbsp->fclk); |
| 259 | 423 | ||
| 424 | /* Do procedure specific to omap34xx arch, if applicable */ | ||
| 425 | omap34xx_mcbsp_request(mcbsp); | ||
| 426 | |||
| 260 | /* | 427 | /* |
| 261 | * Make sure that transmitter, receiver and sample-rate generator are | 428 | * Make sure that transmitter, receiver and sample-rate generator are |
| 262 | * not running before activating IRQs. | 429 | * not running before activating IRQs. |
| @@ -305,6 +472,9 @@ void omap_mcbsp_free(unsigned int id) | |||
| 305 | if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) | 472 | if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) |
| 306 | mcbsp->pdata->ops->free(id); | 473 | mcbsp->pdata->ops->free(id); |
| 307 | 474 | ||
| 475 | /* Do procedure specific to omap34xx arch, if applicable */ | ||
| 476 | omap34xx_mcbsp_free(mcbsp); | ||
| 477 | |||
| 308 | clk_disable(mcbsp->fclk); | 478 | clk_disable(mcbsp->fclk); |
| 309 | clk_disable(mcbsp->iclk); | 479 | clk_disable(mcbsp->iclk); |
| 310 | 480 | ||
| @@ -328,14 +498,15 @@ void omap_mcbsp_free(unsigned int id) | |||
| 328 | EXPORT_SYMBOL(omap_mcbsp_free); | 498 | EXPORT_SYMBOL(omap_mcbsp_free); |
| 329 | 499 | ||
| 330 | /* | 500 | /* |
| 331 | * Here we start the McBSP, by enabling the sample | 501 | * Here we start the McBSP, by enabling transmitter, receiver or both. |
| 332 | * generator, both transmitter and receivers, | 502 | * If no transmitter or receiver is active prior calling, then sample-rate |
| 333 | * and the frame sync. | 503 | * generator and frame sync are started. |
| 334 | */ | 504 | */ |
| 335 | void omap_mcbsp_start(unsigned int id) | 505 | void omap_mcbsp_start(unsigned int id, int tx, int rx) |
| 336 | { | 506 | { |
| 337 | struct omap_mcbsp *mcbsp; | 507 | struct omap_mcbsp *mcbsp; |
| 338 | void __iomem *io_base; | 508 | void __iomem *io_base; |
| 509 | int idle; | ||
| 339 | u16 w; | 510 | u16 w; |
| 340 | 511 | ||
| 341 | if (!omap_mcbsp_check_valid_id(id)) { | 512 | if (!omap_mcbsp_check_valid_id(id)) { |
| @@ -348,32 +519,58 @@ void omap_mcbsp_start(unsigned int id) | |||
| 348 | mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7; | 519 | mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7; |
| 349 | mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7; | 520 | mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7; |
| 350 | 521 | ||
| 351 | /* Start the sample generator */ | 522 | idle = !((OMAP_MCBSP_READ(io_base, SPCR2) | |
| 352 | w = OMAP_MCBSP_READ(io_base, SPCR2); | 523 | OMAP_MCBSP_READ(io_base, SPCR1)) & 1); |
| 353 | OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6)); | 524 | |
| 525 | if (idle) { | ||
| 526 | /* Start the sample generator */ | ||
| 527 | w = OMAP_MCBSP_READ(io_base, SPCR2); | ||
| 528 | OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6)); | ||
| 529 | } | ||
| 354 | 530 | ||
| 355 | /* Enable transmitter and receiver */ | 531 | /* Enable transmitter and receiver */ |
| 532 | tx &= 1; | ||
| 356 | w = OMAP_MCBSP_READ(io_base, SPCR2); | 533 | w = OMAP_MCBSP_READ(io_base, SPCR2); |
| 357 | OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1); | 534 | OMAP_MCBSP_WRITE(io_base, SPCR2, w | tx); |
| 358 | 535 | ||
| 536 | rx &= 1; | ||
| 359 | w = OMAP_MCBSP_READ(io_base, SPCR1); | 537 | w = OMAP_MCBSP_READ(io_base, SPCR1); |
| 360 | OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1); | 538 | OMAP_MCBSP_WRITE(io_base, SPCR1, w | rx); |
| 361 | 539 | ||
| 362 | udelay(100); | 540 | /* |
| 541 | * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec | ||
| 542 | * REVISIT: 100us may give enough time for two CLKSRG, however | ||
| 543 | * due to some unknown PM related, clock gating etc. reason it | ||
| 544 | * is now at 500us. | ||
| 545 | */ | ||
| 546 | udelay(500); | ||
| 363 | 547 | ||
| 364 | /* Start frame sync */ | 548 | if (idle) { |
| 365 | w = OMAP_MCBSP_READ(io_base, SPCR2); | 549 | /* Start frame sync */ |
| 366 | OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7)); | 550 | w = OMAP_MCBSP_READ(io_base, SPCR2); |
| 551 | OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7)); | ||
| 552 | } | ||
| 553 | |||
| 554 | if (cpu_is_omap2430() || cpu_is_omap34xx()) { | ||
| 555 | /* Release the transmitter and receiver */ | ||
| 556 | w = OMAP_MCBSP_READ(io_base, XCCR); | ||
| 557 | w &= ~(tx ? XDISABLE : 0); | ||
| 558 | OMAP_MCBSP_WRITE(io_base, XCCR, w); | ||
| 559 | w = OMAP_MCBSP_READ(io_base, RCCR); | ||
| 560 | w &= ~(rx ? RDISABLE : 0); | ||
| 561 | OMAP_MCBSP_WRITE(io_base, RCCR, w); | ||
| 562 | } | ||
| 367 | 563 | ||
| 368 | /* Dump McBSP Regs */ | 564 | /* Dump McBSP Regs */ |
| 369 | omap_mcbsp_dump_reg(id); | 565 | omap_mcbsp_dump_reg(id); |
| 370 | } | 566 | } |
| 371 | EXPORT_SYMBOL(omap_mcbsp_start); | 567 | EXPORT_SYMBOL(omap_mcbsp_start); |
| 372 | 568 | ||
| 373 | void omap_mcbsp_stop(unsigned int id) | 569 | void omap_mcbsp_stop(unsigned int id, int tx, int rx) |
| 374 | { | 570 | { |
| 375 | struct omap_mcbsp *mcbsp; | 571 | struct omap_mcbsp *mcbsp; |
| 376 | void __iomem *io_base; | 572 | void __iomem *io_base; |
| 573 | int idle; | ||
| 377 | u16 w; | 574 | u16 w; |
| 378 | 575 | ||
| 379 | if (!omap_mcbsp_check_valid_id(id)) { | 576 | if (!omap_mcbsp_check_valid_id(id)) { |
| @@ -385,16 +582,33 @@ void omap_mcbsp_stop(unsigned int id) | |||
| 385 | io_base = mcbsp->io_base; | 582 | io_base = mcbsp->io_base; |
| 386 | 583 | ||
| 387 | /* Reset transmitter */ | 584 | /* Reset transmitter */ |
| 585 | tx &= 1; | ||
| 586 | if (cpu_is_omap2430() || cpu_is_omap34xx()) { | ||
| 587 | w = OMAP_MCBSP_READ(io_base, XCCR); | ||
| 588 | w |= (tx ? XDISABLE : 0); | ||
| 589 | OMAP_MCBSP_WRITE(io_base, XCCR, w); | ||
| 590 | } | ||
| 388 | w = OMAP_MCBSP_READ(io_base, SPCR2); | 591 | w = OMAP_MCBSP_READ(io_base, SPCR2); |
| 389 | OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1)); | 592 | OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~tx); |
| 390 | 593 | ||
| 391 | /* Reset receiver */ | 594 | /* Reset receiver */ |
| 595 | rx &= 1; | ||
| 596 | if (cpu_is_omap2430() || cpu_is_omap34xx()) { | ||
| 597 | w = OMAP_MCBSP_READ(io_base, RCCR); | ||
| 598 | w |= (tx ? RDISABLE : 0); | ||
| 599 | OMAP_MCBSP_WRITE(io_base, RCCR, w); | ||
| 600 | } | ||
| 392 | w = OMAP_MCBSP_READ(io_base, SPCR1); | 601 | w = OMAP_MCBSP_READ(io_base, SPCR1); |
| 393 | OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1)); | 602 | OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~rx); |
| 394 | 603 | ||
| 395 | /* Reset the sample rate generator */ | 604 | idle = !((OMAP_MCBSP_READ(io_base, SPCR2) | |
| 396 | w = OMAP_MCBSP_READ(io_base, SPCR2); | 605 | OMAP_MCBSP_READ(io_base, SPCR1)) & 1); |
| 397 | OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6)); | 606 | |
| 607 | if (idle) { | ||
| 608 | /* Reset the sample rate generator */ | ||
| 609 | w = OMAP_MCBSP_READ(io_base, SPCR2); | ||
| 610 | OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6)); | ||
| 611 | } | ||
| 398 | } | 612 | } |
| 399 | EXPORT_SYMBOL(omap_mcbsp_stop); | 613 | EXPORT_SYMBOL(omap_mcbsp_stop); |
| 400 | 614 | ||
| @@ -883,6 +1097,149 @@ void omap_mcbsp_set_spi_mode(unsigned int id, | |||
| 883 | } | 1097 | } |
| 884 | EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); | 1098 | EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); |
| 885 | 1099 | ||
| 1100 | #ifdef CONFIG_ARCH_OMAP34XX | ||
| 1101 | #define max_thres(m) (mcbsp->pdata->buffer_size) | ||
| 1102 | #define valid_threshold(m, val) ((val) <= max_thres(m)) | ||
| 1103 | #define THRESHOLD_PROP_BUILDER(prop) \ | ||
| 1104 | static ssize_t prop##_show(struct device *dev, \ | ||
| 1105 | struct device_attribute *attr, char *buf) \ | ||
| 1106 | { \ | ||
| 1107 | struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \ | ||
| 1108 | \ | ||
| 1109 | return sprintf(buf, "%u\n", mcbsp->prop); \ | ||
| 1110 | } \ | ||
| 1111 | \ | ||
| 1112 | static ssize_t prop##_store(struct device *dev, \ | ||
| 1113 | struct device_attribute *attr, \ | ||
| 1114 | const char *buf, size_t size) \ | ||
| 1115 | { \ | ||
| 1116 | struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \ | ||
| 1117 | unsigned long val; \ | ||
| 1118 | int status; \ | ||
| 1119 | \ | ||
| 1120 | status = strict_strtoul(buf, 0, &val); \ | ||
| 1121 | if (status) \ | ||
| 1122 | return status; \ | ||
| 1123 | \ | ||
| 1124 | if (!valid_threshold(mcbsp, val)) \ | ||
| 1125 | return -EDOM; \ | ||
| 1126 | \ | ||
| 1127 | mcbsp->prop = val; \ | ||
| 1128 | return size; \ | ||
| 1129 | } \ | ||
| 1130 | \ | ||
| 1131 | static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store); | ||
| 1132 | |||
| 1133 | THRESHOLD_PROP_BUILDER(max_tx_thres); | ||
| 1134 | THRESHOLD_PROP_BUILDER(max_rx_thres); | ||
| 1135 | |||
| 1136 | static const char *dma_op_modes[] = { | ||
| 1137 | "element", "threshold", "frame", | ||
| 1138 | }; | ||
| 1139 | |||
| 1140 | static ssize_t dma_op_mode_show(struct device *dev, | ||
| 1141 | struct device_attribute *attr, char *buf) | ||
| 1142 | { | ||
| 1143 | struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); | ||
| 1144 | int dma_op_mode, i = 0; | ||
| 1145 | ssize_t len = 0; | ||
| 1146 | const char * const *s; | ||
| 1147 | |||
| 1148 | spin_lock_irq(&mcbsp->lock); | ||
| 1149 | dma_op_mode = mcbsp->dma_op_mode; | ||
| 1150 | spin_unlock_irq(&mcbsp->lock); | ||
| 1151 | |||
| 1152 | for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) { | ||
| 1153 | if (dma_op_mode == i) | ||
| 1154 | len += sprintf(buf + len, "[%s] ", *s); | ||
| 1155 | else | ||
| 1156 | len += sprintf(buf + len, "%s ", *s); | ||
| 1157 | } | ||
| 1158 | len += sprintf(buf + len, "\n"); | ||
| 1159 | |||
| 1160 | return len; | ||
| 1161 | } | ||
| 1162 | |||
| 1163 | static ssize_t dma_op_mode_store(struct device *dev, | ||
| 1164 | struct device_attribute *attr, | ||
| 1165 | const char *buf, size_t size) | ||
| 1166 | { | ||
| 1167 | struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); | ||
| 1168 | const char * const *s; | ||
| 1169 | int i = 0; | ||
| 1170 | |||
| 1171 | for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) | ||
| 1172 | if (sysfs_streq(buf, *s)) | ||
| 1173 | break; | ||
| 1174 | |||
| 1175 | if (i == ARRAY_SIZE(dma_op_modes)) | ||
| 1176 | return -EINVAL; | ||
| 1177 | |||
| 1178 | spin_lock_irq(&mcbsp->lock); | ||
| 1179 | if (!mcbsp->free) { | ||
| 1180 | size = -EBUSY; | ||
| 1181 | goto unlock; | ||
| 1182 | } | ||
| 1183 | mcbsp->dma_op_mode = i; | ||
| 1184 | |||
| 1185 | unlock: | ||
| 1186 | spin_unlock_irq(&mcbsp->lock); | ||
| 1187 | |||
| 1188 | return size; | ||
| 1189 | } | ||
| 1190 | |||
| 1191 | static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store); | ||
| 1192 | |||
| 1193 | static const struct attribute *additional_attrs[] = { | ||
| 1194 | &dev_attr_max_tx_thres.attr, | ||
| 1195 | &dev_attr_max_rx_thres.attr, | ||
| 1196 | &dev_attr_dma_op_mode.attr, | ||
| 1197 | NULL, | ||
| 1198 | }; | ||
| 1199 | |||
| 1200 | static const struct attribute_group additional_attr_group = { | ||
| 1201 | .attrs = (struct attribute **)additional_attrs, | ||
| 1202 | }; | ||
| 1203 | |||
| 1204 | static inline int __devinit omap_additional_add(struct device *dev) | ||
| 1205 | { | ||
| 1206 | return sysfs_create_group(&dev->kobj, &additional_attr_group); | ||
| 1207 | } | ||
| 1208 | |||
| 1209 | static inline void __devexit omap_additional_remove(struct device *dev) | ||
| 1210 | { | ||
| 1211 | sysfs_remove_group(&dev->kobj, &additional_attr_group); | ||
| 1212 | } | ||
| 1213 | |||
| 1214 | static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) | ||
| 1215 | { | ||
| 1216 | mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT; | ||
| 1217 | if (cpu_is_omap34xx()) { | ||
| 1218 | mcbsp->max_tx_thres = max_thres(mcbsp); | ||
| 1219 | mcbsp->max_rx_thres = max_thres(mcbsp); | ||
| 1220 | /* | ||
| 1221 | * REVISIT: Set dmap_op_mode to THRESHOLD as default | ||
| 1222 | * for mcbsp2 instances. | ||
| 1223 | */ | ||
| 1224 | if (omap_additional_add(mcbsp->dev)) | ||
| 1225 | dev_warn(mcbsp->dev, | ||
| 1226 | "Unable to create additional controls\n"); | ||
| 1227 | } else { | ||
| 1228 | mcbsp->max_tx_thres = -EINVAL; | ||
| 1229 | mcbsp->max_rx_thres = -EINVAL; | ||
| 1230 | } | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) | ||
| 1234 | { | ||
| 1235 | if (cpu_is_omap34xx()) | ||
| 1236 | omap_additional_remove(mcbsp->dev); | ||
| 1237 | } | ||
| 1238 | #else | ||
| 1239 | static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {} | ||
| 1240 | static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {} | ||
| 1241 | #endif /* CONFIG_ARCH_OMAP34XX */ | ||
| 1242 | |||
| 886 | /* | 1243 | /* |
| 887 | * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. | 1244 | * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. |
| 888 | * 730 has only 2 McBSP, and both of them are MPU peripherals. | 1245 | * 730 has only 2 McBSP, and both of them are MPU peripherals. |
| @@ -953,6 +1310,10 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) | |||
| 953 | mcbsp->dev = &pdev->dev; | 1310 | mcbsp->dev = &pdev->dev; |
| 954 | mcbsp_ptr[id] = mcbsp; | 1311 | mcbsp_ptr[id] = mcbsp; |
| 955 | platform_set_drvdata(pdev, mcbsp); | 1312 | platform_set_drvdata(pdev, mcbsp); |
| 1313 | |||
| 1314 | /* Initialize mcbsp properties for OMAP34XX if needed / applicable */ | ||
| 1315 | omap34xx_device_init(mcbsp); | ||
| 1316 | |||
| 956 | return 0; | 1317 | return 0; |
| 957 | 1318 | ||
| 958 | err_fclk: | 1319 | err_fclk: |
| @@ -976,6 +1337,8 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev) | |||
| 976 | mcbsp->pdata->ops->free) | 1337 | mcbsp->pdata->ops->free) |
| 977 | mcbsp->pdata->ops->free(mcbsp->id); | 1338 | mcbsp->pdata->ops->free(mcbsp->id); |
| 978 | 1339 | ||
| 1340 | omap34xx_device_exit(mcbsp); | ||
| 1341 | |||
| 979 | clk_disable(mcbsp->fclk); | 1342 | clk_disable(mcbsp->fclk); |
| 980 | clk_disable(mcbsp->iclk); | 1343 | clk_disable(mcbsp->iclk); |
| 981 | clk_put(mcbsp->fclk); | 1344 | clk_put(mcbsp->fclk); |
diff --git a/arch/arm/plat-orion/include/plat/gpio.h b/arch/arm/plat-orion/include/plat/gpio.h index 9646a94ed3d0..07c430fdc9ef 100644 --- a/arch/arm/plat-orion/include/plat/gpio.h +++ b/arch/arm/plat-orion/include/plat/gpio.h | |||
| @@ -11,6 +11,8 @@ | |||
| 11 | #ifndef __PLAT_GPIO_H | 11 | #ifndef __PLAT_GPIO_H |
| 12 | #define __PLAT_GPIO_H | 12 | #define __PLAT_GPIO_H |
| 13 | 13 | ||
| 14 | #include <linux/init.h> | ||
| 15 | |||
| 14 | /* | 16 | /* |
| 15 | * GENERIC_GPIO primitives. | 17 | * GENERIC_GPIO primitives. |
| 16 | */ | 18 | */ |
diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig index 935c7558469b..8931c5f0e46b 100644 --- a/arch/arm/plat-s3c/Kconfig +++ b/arch/arm/plat-s3c/Kconfig | |||
| @@ -198,4 +198,9 @@ config S3C_DEV_USB_HSOTG | |||
| 198 | help | 198 | help |
| 199 | Compile in platform device definition for USB high-speed OtG | 199 | Compile in platform device definition for USB high-speed OtG |
| 200 | 200 | ||
| 201 | config S3C_DEV_NAND | ||
| 202 | bool | ||
| 203 | help | ||
| 204 | Compile in platform device definition for NAND controller | ||
| 205 | |||
| 201 | endif | 206 | endif |
diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile index 0761766b1833..3c09109e9e84 100644 --- a/arch/arm/plat-s3c/Makefile +++ b/arch/arm/plat-s3c/Makefile | |||
| @@ -28,13 +28,17 @@ obj-$(CONFIG_PM) += pm.o | |||
| 28 | obj-$(CONFIG_PM) += pm-gpio.o | 28 | obj-$(CONFIG_PM) += pm-gpio.o |
| 29 | obj-$(CONFIG_S3C2410_PM_CHECK) += pm-check.o | 29 | obj-$(CONFIG_S3C2410_PM_CHECK) += pm-check.o |
| 30 | 30 | ||
| 31 | # PWM support | ||
| 32 | |||
| 33 | obj-$(CONFIG_HAVE_PWM) += pwm.o | ||
| 34 | |||
| 31 | # devices | 35 | # devices |
| 32 | 36 | ||
| 33 | obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o | 37 | obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o |
| 34 | obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o | 38 | obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o |
| 35 | obj-y += dev-i2c0.o | 39 | obj-y += dev-i2c0.o |
| 36 | obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o | 40 | obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o |
| 37 | obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += dev-audio.o | ||
| 38 | obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o | 41 | obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o |
| 39 | obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o | 42 | obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o |
| 40 | obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o | 43 | obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o |
| 44 | obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o | ||
diff --git a/arch/arm/plat-s3c/dev-nand.c b/arch/arm/plat-s3c/dev-nand.c new file mode 100644 index 000000000000..4e5323732434 --- /dev/null +++ b/arch/arm/plat-s3c/dev-nand.c | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * S3C series device definition for nand device | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/kernel.h> | ||
| 10 | #include <linux/platform_device.h> | ||
| 11 | |||
| 12 | #include <mach/map.h> | ||
| 13 | #include <plat/devs.h> | ||
| 14 | |||
| 15 | static struct resource s3c_nand_resource[] = { | ||
| 16 | [0] = { | ||
| 17 | .start = S3C_PA_NAND, | ||
| 18 | .end = S3C_PA_NAND + SZ_1M, | ||
| 19 | .flags = IORESOURCE_MEM, | ||
| 20 | } | ||
| 21 | }; | ||
| 22 | |||
| 23 | struct platform_device s3c_device_nand = { | ||
| 24 | .name = "s3c2410-nand", | ||
| 25 | .id = -1, | ||
| 26 | .num_resources = ARRAY_SIZE(s3c_nand_resource), | ||
| 27 | .resource = s3c_nand_resource, | ||
| 28 | }; | ||
| 29 | |||
| 30 | EXPORT_SYMBOL(s3c_device_nand); | ||
diff --git a/arch/arm/plat-s3c/include/plat/adc.h b/arch/arm/plat-s3c/include/plat/adc.h index d847bd476b6c..5f3b1cd53b90 100644 --- a/arch/arm/plat-s3c/include/plat/adc.h +++ b/arch/arm/plat-s3c/include/plat/adc.h | |||
| @@ -19,10 +19,14 @@ struct s3c_adc_client; | |||
| 19 | extern int s3c_adc_start(struct s3c_adc_client *client, | 19 | extern int s3c_adc_start(struct s3c_adc_client *client, |
| 20 | unsigned int channel, unsigned int nr_samples); | 20 | unsigned int channel, unsigned int nr_samples); |
| 21 | 21 | ||
| 22 | extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch); | ||
| 23 | |||
| 22 | extern struct s3c_adc_client * | 24 | extern struct s3c_adc_client * |
| 23 | s3c_adc_register(struct platform_device *pdev, | 25 | s3c_adc_register(struct platform_device *pdev, |
| 24 | void (*select)(unsigned selected), | 26 | void (*select)(struct s3c_adc_client *client, |
| 25 | void (*conv)(unsigned d0, unsigned d1, | 27 | unsigned selected), |
| 28 | void (*conv)(struct s3c_adc_client *client, | ||
| 29 | unsigned d0, unsigned d1, | ||
| 26 | unsigned *samples_left), | 30 | unsigned *samples_left), |
| 27 | unsigned int is_ts); | 31 | unsigned int is_ts); |
| 28 | 32 | ||
diff --git a/arch/arm/plat-s3c/include/plat/audio-simtec.h b/arch/arm/plat-s3c/include/plat/audio-simtec.h new file mode 100644 index 000000000000..0f440b9168db --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/audio-simtec.h | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | /* arch/arm/plat-s3c/include/plat/audio-simtec.h | ||
| 2 | * | ||
| 3 | * Copyright 2008 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * Simtec Audio support. | ||
| 12 | */ | ||
| 13 | |||
| 14 | /** | ||
| 15 | * struct s3c24xx_audio_simtec_pdata - platform data for simtec audio | ||
| 16 | * @use_mpllin: Select codec clock from MPLLin | ||
| 17 | * @output_cdclk: Need to output CDCLK to the codec | ||
| 18 | * @have_mic: Set if we have a MIC socket | ||
| 19 | * @have_lout: Set if we have a LineOut socket | ||
| 20 | * @amp_gpio: GPIO pin to enable the AMP | ||
| 21 | * @amp_gain: Option GPIO to control AMP gain | ||
| 22 | */ | ||
| 23 | struct s3c24xx_audio_simtec_pdata { | ||
| 24 | unsigned int use_mpllin:1; | ||
| 25 | unsigned int output_cdclk:1; | ||
| 26 | |||
| 27 | unsigned int have_mic:1; | ||
| 28 | unsigned int have_lout:1; | ||
| 29 | |||
| 30 | int amp_gpio; | ||
| 31 | int amp_gain[2]; | ||
| 32 | |||
| 33 | void (*startup)(void); | ||
| 34 | }; | ||
| 35 | |||
| 36 | extern int simtec_audio_add(const char *codec_name, | ||
| 37 | struct s3c24xx_audio_simtec_pdata *pdata); | ||
diff --git a/arch/arm/plat-s3c/include/plat/cpu-freq.h b/arch/arm/plat-s3c/include/plat/cpu-freq.h index c86a13307e90..7b982b7f28cd 100644 --- a/arch/arm/plat-s3c/include/plat/cpu-freq.h +++ b/arch/arm/plat-s3c/include/plat/cpu-freq.h | |||
| @@ -17,6 +17,21 @@ struct s3c_cpufreq_info; | |||
| 17 | struct s3c_cpufreq_board; | 17 | struct s3c_cpufreq_board; |
| 18 | struct s3c_iotimings; | 18 | struct s3c_iotimings; |
| 19 | 19 | ||
| 20 | /** | ||
| 21 | * struct s3c_freq - frequency information (mainly for core drivers) | ||
| 22 | * @fclk: The FCLK frequency in Hz. | ||
| 23 | * @armclk: The ARMCLK frequency in Hz. | ||
| 24 | * @hclk_tns: HCLK cycle time in 10ths of nano-seconds. | ||
| 25 | * @hclk: The HCLK frequency in Hz. | ||
| 26 | * @pclk: The PCLK frequency in Hz. | ||
| 27 | * | ||
| 28 | * This contains the frequency information about the current configuration | ||
| 29 | * mainly for the core drivers to ensure we do not end up passing about | ||
| 30 | * a large number of parameters. | ||
| 31 | * | ||
| 32 | * The @hclk_tns field is a useful cache for the parts of the drivers that | ||
| 33 | * need to calculate IO timings and suchlike. | ||
| 34 | */ | ||
| 20 | struct s3c_freq { | 35 | struct s3c_freq { |
| 21 | unsigned long fclk; | 36 | unsigned long fclk; |
| 22 | unsigned long armclk; | 37 | unsigned long armclk; |
| @@ -25,48 +40,84 @@ struct s3c_freq { | |||
| 25 | unsigned long pclk; | 40 | unsigned long pclk; |
| 26 | }; | 41 | }; |
| 27 | 42 | ||
| 28 | /* wrapper 'struct cpufreq_freqs' so that any drivers receiving the | 43 | /** |
| 44 | * struct s3c_cpufreq_freqs - s3c cpufreq notification information. | ||
| 45 | * @freqs: The cpufreq setting information. | ||
| 46 | * @old: The old clock settings. | ||
| 47 | * @new: The new clock settings. | ||
| 48 | * @pll_changing: Set if the PLL is changing. | ||
| 49 | * | ||
| 50 | * Wrapper 'struct cpufreq_freqs' so that any drivers receiving the | ||
| 29 | * notification can use this information that is not provided by just | 51 | * notification can use this information that is not provided by just |
| 30 | * having the core frequency alone. | 52 | * having the core frequency alone. |
| 53 | * | ||
| 54 | * The pll_changing flag is used to indicate if the PLL itself is | ||
| 55 | * being set during this change. This is important as the clocks | ||
| 56 | * will temporarily be set to the XTAL clock during this time, so | ||
| 57 | * drivers may want to close down their output during this time. | ||
| 58 | * | ||
| 59 | * Note, this is not being used by any current drivers and therefore | ||
| 60 | * may be removed in the future. | ||
| 31 | */ | 61 | */ |
| 32 | |||
| 33 | struct s3c_cpufreq_freqs { | 62 | struct s3c_cpufreq_freqs { |
| 34 | struct cpufreq_freqs freqs; | 63 | struct cpufreq_freqs freqs; |
| 35 | struct s3c_freq old; | 64 | struct s3c_freq old; |
| 36 | struct s3c_freq new; | 65 | struct s3c_freq new; |
| 66 | |||
| 67 | unsigned int pll_changing:1; | ||
| 37 | }; | 68 | }; |
| 38 | 69 | ||
| 39 | #define to_s3c_cpufreq(_cf) container_of(_cf, struct s3c_cpufreq_freqs, freqs) | 70 | #define to_s3c_cpufreq(_cf) container_of(_cf, struct s3c_cpufreq_freqs, freqs) |
| 40 | 71 | ||
| 72 | /** | ||
| 73 | * struct s3c_clkdivs - clock divisor information | ||
| 74 | * @p_divisor: Divisor from FCLK to PCLK. | ||
| 75 | * @h_divisor: Divisor from FCLK to HCLK. | ||
| 76 | * @arm_divisor: Divisor from FCLK to ARMCLK (not all CPUs). | ||
| 77 | * @dvs: Non-zero if using DVS mode for ARMCLK. | ||
| 78 | * | ||
| 79 | * Divisor settings for the core clocks. | ||
| 80 | */ | ||
| 41 | struct s3c_clkdivs { | 81 | struct s3c_clkdivs { |
| 42 | int p_divisor; /* fclk / pclk */ | 82 | int p_divisor; |
| 43 | int h_divisor; /* fclk / hclk */ | 83 | int h_divisor; |
| 44 | int arm_divisor; /* not all cpus have this. */ | 84 | int arm_divisor; |
| 45 | unsigned char dvs; /* using dvs mode to arm. */ | 85 | unsigned char dvs; |
| 46 | }; | 86 | }; |
| 47 | 87 | ||
| 48 | #define PLLVAL(_m, _p, _s) (((_m) << 12) | ((_p) << 4) | (_s)) | 88 | #define PLLVAL(_m, _p, _s) (((_m) << 12) | ((_p) << 4) | (_s)) |
| 49 | 89 | ||
| 90 | /** | ||
| 91 | * struct s3c_pllval - PLL value entry. | ||
| 92 | * @freq: The frequency for this entry in Hz. | ||
| 93 | * @pll_reg: The PLL register setting for this PLL value. | ||
| 94 | */ | ||
| 50 | struct s3c_pllval { | 95 | struct s3c_pllval { |
| 51 | unsigned long freq; | 96 | unsigned long freq; |
| 52 | unsigned long pll_reg; | 97 | unsigned long pll_reg; |
| 53 | }; | 98 | }; |
| 54 | 99 | ||
| 55 | struct s3c_cpufreq_config { | 100 | /** |
| 56 | struct s3c_freq freq; | 101 | * struct s3c_cpufreq_board - per-board cpu frequency informatin |
| 57 | struct s3c_pllval pll; | 102 | * @refresh: The SDRAM refresh period in nanoseconds. |
| 58 | struct s3c_clkdivs divs; | 103 | * @auto_io: Set if the IO timing settings should be generated from the |
| 59 | struct s3c_cpufreq_info *info; /* for core, not drivers */ | 104 | * initialisation time hardware registers. |
| 60 | struct s3c_cpufreq_board *board; | 105 | * @need_io: Set if the board has external IO on any of the chipselect |
| 61 | }; | 106 | * lines that will require the hardware timing registers to be |
| 62 | 107 | * updated on a clock change. | |
| 63 | /* s3c_cpufreq_board | 108 | * @max: The maxium frequency limits for the system. Any field that |
| 109 | * is left at zero will use the CPU's settings. | ||
| 110 | * | ||
| 111 | * This contains the board specific settings that affect how the CPU | ||
| 112 | * drivers chose settings. These include the memory refresh and IO | ||
| 113 | * timing information. | ||
| 64 | * | 114 | * |
| 65 | * per-board configuraton information, such as memory refresh and | 115 | * Registration depends on the driver being used, the ARMCLK only |
| 66 | * how to initialise IO timings. | 116 | * implementation does not currently need this but the older style |
| 117 | * driver requires this to be available. | ||
| 67 | */ | 118 | */ |
| 68 | struct s3c_cpufreq_board { | 119 | struct s3c_cpufreq_board { |
| 69 | unsigned int refresh; /* refresh period in ns */ | 120 | unsigned int refresh; |
| 70 | unsigned int auto_io:1; /* automatically init io timings. */ | 121 | unsigned int auto_io:1; /* automatically init io timings. */ |
| 71 | unsigned int need_io:1; /* set if needs io timing support. */ | 122 | unsigned int need_io:1; /* set if needs io timing support. */ |
| 72 | 123 | ||
diff --git a/arch/arm/plat-s3c/include/plat/cpu.h b/arch/arm/plat-s3c/include/plat/cpu.h index be541cbba070..fbc3d498e02e 100644 --- a/arch/arm/plat-s3c/include/plat/cpu.h +++ b/arch/arm/plat-s3c/include/plat/cpu.h | |||
| @@ -65,6 +65,7 @@ extern struct sys_timer s3c24xx_timer; | |||
| 65 | /* system device classes */ | 65 | /* system device classes */ |
| 66 | 66 | ||
| 67 | extern struct sysdev_class s3c2410_sysclass; | 67 | extern struct sysdev_class s3c2410_sysclass; |
| 68 | extern struct sysdev_class s3c2410a_sysclass; | ||
| 68 | extern struct sysdev_class s3c2412_sysclass; | 69 | extern struct sysdev_class s3c2412_sysclass; |
| 69 | extern struct sysdev_class s3c2440_sysclass; | 70 | extern struct sysdev_class s3c2440_sysclass; |
| 70 | extern struct sysdev_class s3c2442_sysclass; | 71 | extern struct sysdev_class s3c2442_sysclass; |
diff --git a/arch/arm/plat-s3c/include/plat/devs.h b/arch/arm/plat-s3c/include/plat/devs.h index 2e170827e0b0..0f540ea1e999 100644 --- a/arch/arm/plat-s3c/include/plat/devs.h +++ b/arch/arm/plat-s3c/include/plat/devs.h | |||
| @@ -46,6 +46,8 @@ extern struct platform_device s3c_device_hsmmc2; | |||
| 46 | extern struct platform_device s3c_device_spi0; | 46 | extern struct platform_device s3c_device_spi0; |
| 47 | extern struct platform_device s3c_device_spi1; | 47 | extern struct platform_device s3c_device_spi1; |
| 48 | 48 | ||
| 49 | extern struct platform_device s3c_device_hwmon; | ||
| 50 | |||
| 49 | extern struct platform_device s3c_device_nand; | 51 | extern struct platform_device s3c_device_nand; |
| 50 | 52 | ||
| 51 | extern struct platform_device s3c_device_usbgadget; | 53 | extern struct platform_device s3c_device_usbgadget; |
| @@ -56,5 +58,6 @@ extern struct platform_device s3c_device_usb_hsotg; | |||
| 56 | #ifdef CONFIG_CPU_S3C2440 | 58 | #ifdef CONFIG_CPU_S3C2440 |
| 57 | 59 | ||
| 58 | extern struct platform_device s3c_device_camif; | 60 | extern struct platform_device s3c_device_camif; |
| 61 | extern struct platform_device s3c_device_ac97; | ||
| 59 | 62 | ||
| 60 | #endif | 63 | #endif |
diff --git a/arch/arm/plat-s3c/include/plat/hwmon.h b/arch/arm/plat-s3c/include/plat/hwmon.h new file mode 100644 index 000000000000..1ba88ea0aa31 --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/hwmon.h | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c/include/plat/hwmon.h | ||
| 2 | * | ||
| 3 | * Copyright 2005 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * http://armlinux.simtec.co.uk/ | ||
| 6 | * | ||
| 7 | * S3C - HWMon interface for ADC | ||
| 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 | #ifndef __ASM_ARCH_ADC_HWMON_H | ||
| 15 | #define __ASM_ARCH_ADC_HWMON_H __FILE__ | ||
| 16 | |||
| 17 | /** | ||
| 18 | * s3c_hwmon_chcfg - channel configuration | ||
| 19 | * @name: The name to give this channel. | ||
| 20 | * @mult: Multiply the ADC value read by this. | ||
| 21 | * @div: Divide the value from the ADC by this. | ||
| 22 | * | ||
| 23 | * The value read from the ADC is converted to a value that | ||
| 24 | * hwmon expects (mV) by result = (value_read * @mult) / @div. | ||
| 25 | */ | ||
| 26 | struct s3c_hwmon_chcfg { | ||
| 27 | const char *name; | ||
| 28 | unsigned int mult; | ||
| 29 | unsigned int div; | ||
| 30 | }; | ||
| 31 | |||
| 32 | /** | ||
| 33 | * s3c_hwmon_pdata - HWMON platform data | ||
| 34 | * @in: One configuration for each possible channel used. | ||
| 35 | */ | ||
| 36 | struct s3c_hwmon_pdata { | ||
| 37 | struct s3c_hwmon_chcfg *in[8]; | ||
| 38 | }; | ||
| 39 | |||
| 40 | #endif /* __ASM_ARCH_ADC_HWMON_H */ | ||
| 41 | |||
diff --git a/arch/arm/plat-s3c/include/plat/map-base.h b/arch/arm/plat-s3c/include/plat/map-base.h index b84289d32a54..250be311c85b 100644 --- a/arch/arm/plat-s3c/include/plat/map-base.h +++ b/arch/arm/plat-s3c/include/plat/map-base.h | |||
| @@ -32,9 +32,15 @@ | |||
| 32 | 32 | ||
| 33 | #define S3C_VA_IRQ S3C_ADDR(0x00000000) /* irq controller(s) */ | 33 | #define S3C_VA_IRQ S3C_ADDR(0x00000000) /* irq controller(s) */ |
| 34 | #define S3C_VA_SYS S3C_ADDR(0x00100000) /* system control */ | 34 | #define S3C_VA_SYS S3C_ADDR(0x00100000) /* system control */ |
| 35 | #define S3C_VA_MEM S3C_ADDR(0x00200000) /* system control */ | 35 | #define S3C_VA_MEM S3C_ADDR(0x00200000) /* memory control */ |
| 36 | #define S3C_VA_TIMER S3C_ADDR(0x00300000) /* timer block */ | 36 | #define S3C_VA_TIMER S3C_ADDR(0x00300000) /* timer block */ |
| 37 | #define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */ | 37 | #define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */ |
| 38 | #define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */ | 38 | #define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */ |
| 39 | 39 | ||
| 40 | /* This is used for the CPU specific mappings that may be needed, so that | ||
| 41 | * they do not need to directly used S3C_ADDR() and thus make it easier to | ||
| 42 | * modify the space for mapping. | ||
| 43 | */ | ||
| 44 | #define S3C_ADDR_CPU(x) S3C_ADDR(0x00500000 + (x)) | ||
| 45 | |||
| 40 | #endif /* __ASM_PLAT_MAP_H */ | 46 | #endif /* __ASM_PLAT_MAP_H */ |
diff --git a/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h b/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h index 0fad7571030e..07659dad1748 100644 --- a/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h +++ b/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h | |||
| @@ -33,6 +33,11 @@ | |||
| 33 | #define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) | 33 | #define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) |
| 34 | #define S3C2412_IISCON_IIS_ACTIVE (1 << 0) | 34 | #define S3C2412_IISCON_IIS_ACTIVE (1 << 0) |
| 35 | 35 | ||
| 36 | #define S3C64XX_IISMOD_BLC_16BIT (0 << 13) | ||
| 37 | #define S3C64XX_IISMOD_BLC_8BIT (1 << 13) | ||
| 38 | #define S3C64XX_IISMOD_BLC_24BIT (2 << 13) | ||
| 39 | #define S3C64XX_IISMOD_BLC_MASK (3 << 13) | ||
| 40 | |||
| 36 | #define S3C64XX_IISMOD_IMS_PCLK (0 << 10) | 41 | #define S3C64XX_IISMOD_IMS_PCLK (0 << 10) |
| 37 | #define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10) | 42 | #define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10) |
| 38 | 43 | ||
diff --git a/arch/arm/plat-s3c24xx/pwm.c b/arch/arm/plat-s3c/pwm.c index 82a6d4de02a3..4fdc5b307fd2 100644 --- a/arch/arm/plat-s3c24xx/pwm.c +++ b/arch/arm/plat-s3c/pwm.c | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | /* arch/arm/plat-s3c24xx/pwm.c | 1 | /* arch/arm/plat-s3c/pwm.c |
| 2 | * | 2 | * |
| 3 | * Copyright (c) 2007 Ben Dooks | 3 | * Copyright (c) 2007 Ben Dooks |
| 4 | * Copyright (c) 2008 Simtec Electronics | 4 | * Copyright (c) 2008 Simtec Electronics |
| 5 | * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org> | 5 | * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org> |
| 6 | * | 6 | * |
| 7 | * S3C24XX PWM device core | 7 | * S3C series PWM device core |
| 8 | * | 8 | * |
| 9 | * 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 |
| 10 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/pwm.h> | 20 | #include <linux/pwm.h> |
| 21 | 21 | ||
| 22 | #include <mach/irqs.h> | 22 | #include <mach/irqs.h> |
| 23 | #include <mach/map.h> | ||
| 23 | 24 | ||
| 24 | #include <plat/devs.h> | 25 | #include <plat/devs.h> |
| 25 | #include <plat/regs-timer.h> | 26 | #include <plat/regs-timer.h> |
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index 5b0bc914f58e..9c7aca489643 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig | |||
| @@ -10,6 +10,7 @@ config PLAT_S3C24XX | |||
| 10 | default y | 10 | default y |
| 11 | select NO_IOPORT | 11 | select NO_IOPORT |
| 12 | select ARCH_REQUIRE_GPIOLIB | 12 | select ARCH_REQUIRE_GPIOLIB |
| 13 | select S3C_DEVICE_NAND | ||
| 13 | help | 14 | help |
| 14 | Base platform code for any Samsung S3C24XX device | 15 | Base platform code for any Samsung S3C24XX device |
| 15 | 16 | ||
| @@ -34,6 +35,40 @@ config CPU_S3C244X | |||
| 34 | help | 35 | help |
| 35 | Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems. | 36 | Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems. |
| 36 | 37 | ||
| 38 | config S3C2440_CPUFREQ | ||
| 39 | bool "S3C2440/S3C2442 CPU Frequency scaling support" | ||
| 40 | depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442) | ||
| 41 | select S3C2410_CPUFREQ_UTILS | ||
| 42 | default y | ||
| 43 | help | ||
| 44 | CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs. | ||
| 45 | |||
| 46 | config S3C2440_XTAL_12000000 | ||
| 47 | bool | ||
| 48 | help | ||
| 49 | Indicate that the build needs to support 12MHz system | ||
| 50 | crystal. | ||
| 51 | |||
| 52 | config S3C2440_XTAL_16934400 | ||
| 53 | bool | ||
| 54 | help | ||
| 55 | Indicate that the build needs to support 16.9344MHz system | ||
| 56 | crystal. | ||
| 57 | |||
| 58 | config S3C2440_PLL_12000000 | ||
| 59 | bool | ||
| 60 | depends on S3C2440_CPUFREQ && S3C2440_XTAL_12000000 | ||
| 61 | default y if CPU_FREQ_S3C24XX_PLL | ||
| 62 | help | ||
| 63 | PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals. | ||
| 64 | |||
| 65 | config S3C2440_PLL_16934400 | ||
| 66 | bool | ||
| 67 | depends on S3C2440_CPUFREQ && S3C2440_XTAL_16934400 | ||
| 68 | default y if CPU_FREQ_S3C24XX_PLL | ||
| 69 | help | ||
| 70 | PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals. | ||
| 71 | |||
| 37 | config S3C24XX_PWM | 72 | config S3C24XX_PWM |
| 38 | bool "PWM device support" | 73 | bool "PWM device support" |
| 39 | select HAVE_PWM | 74 | select HAVE_PWM |
| @@ -105,8 +140,39 @@ config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7 | |||
| 105 | SPI GPIO configuration code for BUS 1 when connected to | 140 | SPI GPIO configuration code for BUS 1 when connected to |
| 106 | GPG5, GPG6 and GPG7. | 141 | GPG5, GPG6 and GPG7. |
| 107 | 142 | ||
| 143 | config S3C24XX_SPI_BUS1_GPD8_GPD9_GPD10 | ||
| 144 | bool | ||
| 145 | help | ||
| 146 | SPI GPIO configuration code for BUS 1 when connected to | ||
| 147 | GPD8, GPD9 and GPD10. | ||
| 148 | |||
| 108 | # common code for s3c24xx based machines, such as the SMDKs. | 149 | # common code for s3c24xx based machines, such as the SMDKs. |
| 109 | 150 | ||
| 151 | # cpu frequency items common between s3c2410 and s3c2440/s3c2442 | ||
| 152 | |||
| 153 | config S3C2410_IOTIMING | ||
| 154 | bool | ||
| 155 | depends on CPU_FREQ_S3C24XX | ||
| 156 | help | ||
| 157 | Internal node to select io timing code that is common to the s3c2410 | ||
| 158 | and s3c2440/s3c2442 cpu frequency support. | ||
| 159 | |||
| 160 | config S3C2410_CPUFREQ_UTILS | ||
| 161 | bool | ||
| 162 | depends on CPU_FREQ_S3C24XX | ||
| 163 | help | ||
| 164 | Internal node to select timing code that is common to the s3c2410 | ||
| 165 | and s3c2440/s3c244 cpu frequency support. | ||
| 166 | |||
| 167 | # cpu frequency support common to s3c2412, s3c2413 and s3c2442 | ||
| 168 | |||
| 169 | config S3C2412_IOTIMING | ||
| 170 | bool | ||
| 171 | depends on CPU_FREQ_S3C24XX && (CPU_S3C2412 || CPU_S3C2443) | ||
| 172 | help | ||
| 173 | Intel node to select io timing code that is common to the s3c2412 | ||
| 174 | and the s3c2443. | ||
| 175 | |||
| 110 | config MACH_SMDK | 176 | config MACH_SMDK |
| 111 | bool | 177 | bool |
| 112 | help | 178 | help |
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index 579a165c2827..7780d2dd833a 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile | |||
| @@ -20,19 +20,28 @@ obj-y += gpiolib.o | |||
| 20 | obj-y += clock.o | 20 | obj-y += clock.o |
| 21 | obj-$(CONFIG_S3C24XX_DCLK) += clock-dclk.o | 21 | obj-$(CONFIG_S3C24XX_DCLK) += clock-dclk.o |
| 22 | 22 | ||
| 23 | obj-$(CONFIG_CPU_FREQ_S3C24XX) += cpu-freq.o | ||
| 24 | obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpu-freq-debugfs.o | ||
| 25 | |||
| 23 | # Architecture dependant builds | 26 | # Architecture dependant builds |
| 24 | 27 | ||
| 25 | obj-$(CONFIG_CPU_S3C244X) += s3c244x.o | 28 | obj-$(CONFIG_CPU_S3C244X) += s3c244x.o |
| 26 | obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o | 29 | obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o |
| 27 | obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o | 30 | obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o |
| 31 | obj-$(CONFIG_S3C2440_CPUFREQ) += s3c2440-cpufreq.o | ||
| 32 | obj-$(CONFIG_S3C2440_PLL_12000000) += s3c2440-pll-12000000.o | ||
| 33 | obj-$(CONFIG_S3C2440_PLL_16934400) += s3c2440-pll-16934400.o | ||
| 34 | |||
| 28 | obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o | 35 | obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o |
| 29 | obj-$(CONFIG_PM) += pm.o | 36 | obj-$(CONFIG_PM) += pm.o |
| 30 | obj-$(CONFIG_PM) += irq-pm.o | 37 | obj-$(CONFIG_PM) += irq-pm.o |
| 31 | obj-$(CONFIG_PM) += sleep.o | 38 | obj-$(CONFIG_PM) += sleep.o |
| 32 | obj-$(CONFIG_S3C24XX_PWM) += pwm.o | ||
| 33 | obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o | 39 | obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o |
| 34 | obj-$(CONFIG_S3C2410_DMA) += dma.o | 40 | obj-$(CONFIG_S3C2410_DMA) += dma.o |
| 35 | obj-$(CONFIG_S3C24XX_ADC) += adc.o | 41 | obj-$(CONFIG_S3C24XX_ADC) += adc.o |
| 42 | obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o | ||
| 43 | obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o | ||
| 44 | obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += s3c2410-cpufreq-utils.o | ||
| 36 | 45 | ||
| 37 | # device specific setup and/or initialisation | 46 | # device specific setup and/or initialisation |
| 38 | obj-$(CONFIG_ARCH_S3C2410) += setup-i2c.o | 47 | obj-$(CONFIG_ARCH_S3C2410) += setup-i2c.o |
| @@ -41,6 +50,7 @@ obj-$(CONFIG_ARCH_S3C2410) += setup-i2c.o | |||
| 41 | 50 | ||
| 42 | obj-$(CONFIG_S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13) += spi-bus0-gpe11_12_13.o | 51 | obj-$(CONFIG_S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13) += spi-bus0-gpe11_12_13.o |
| 43 | obj-$(CONFIG_S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7) += spi-bus1-gpg5_6_7.o | 52 | obj-$(CONFIG_S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7) += spi-bus1-gpg5_6_7.o |
| 53 | obj-$(CONFIG_S3C24XX_SPI_BUS1_GPD8_GPD9_GPD10) += spi-bus1-gpd8_9_10.o | ||
| 44 | 54 | ||
| 45 | # machine common support | 55 | # machine common support |
| 46 | 56 | ||
diff --git a/arch/arm/plat-s3c24xx/adc.c b/arch/arm/plat-s3c24xx/adc.c index ee1baf11ad9e..11117a7ba911 100644 --- a/arch/arm/plat-s3c24xx/adc.c +++ b/arch/arm/plat-s3c24xx/adc.c | |||
| @@ -39,13 +39,16 @@ | |||
| 39 | struct s3c_adc_client { | 39 | struct s3c_adc_client { |
| 40 | struct platform_device *pdev; | 40 | struct platform_device *pdev; |
| 41 | struct list_head pend; | 41 | struct list_head pend; |
| 42 | wait_queue_head_t *wait; | ||
| 42 | 43 | ||
| 43 | unsigned int nr_samples; | 44 | unsigned int nr_samples; |
| 45 | int result; | ||
| 44 | unsigned char is_ts; | 46 | unsigned char is_ts; |
| 45 | unsigned char channel; | 47 | unsigned char channel; |
| 46 | 48 | ||
| 47 | void (*select_cb)(unsigned selected); | 49 | void (*select_cb)(struct s3c_adc_client *c, unsigned selected); |
| 48 | void (*convert_cb)(unsigned val1, unsigned val2, | 50 | void (*convert_cb)(struct s3c_adc_client *c, |
| 51 | unsigned val1, unsigned val2, | ||
| 49 | unsigned *samples_left); | 52 | unsigned *samples_left); |
| 50 | }; | 53 | }; |
| 51 | 54 | ||
| @@ -81,7 +84,7 @@ static inline void s3c_adc_select(struct adc_device *adc, | |||
| 81 | { | 84 | { |
| 82 | unsigned con = readl(adc->regs + S3C2410_ADCCON); | 85 | unsigned con = readl(adc->regs + S3C2410_ADCCON); |
| 83 | 86 | ||
| 84 | client->select_cb(1); | 87 | client->select_cb(client, 1); |
| 85 | 88 | ||
| 86 | con &= ~S3C2410_ADCCON_MUXMASK; | 89 | con &= ~S3C2410_ADCCON_MUXMASK; |
| 87 | con &= ~S3C2410_ADCCON_STDBM; | 90 | con &= ~S3C2410_ADCCON_STDBM; |
| @@ -153,25 +156,61 @@ int s3c_adc_start(struct s3c_adc_client *client, | |||
| 153 | } | 156 | } |
| 154 | EXPORT_SYMBOL_GPL(s3c_adc_start); | 157 | EXPORT_SYMBOL_GPL(s3c_adc_start); |
| 155 | 158 | ||
| 156 | static void s3c_adc_default_select(unsigned select) | 159 | static void s3c_convert_done(struct s3c_adc_client *client, |
| 160 | unsigned v, unsigned u, unsigned *left) | ||
| 161 | { | ||
| 162 | client->result = v; | ||
| 163 | wake_up(client->wait); | ||
| 164 | } | ||
| 165 | |||
| 166 | int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch) | ||
| 167 | { | ||
| 168 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake); | ||
| 169 | int ret; | ||
| 170 | |||
| 171 | client->convert_cb = s3c_convert_done; | ||
| 172 | client->wait = &wake; | ||
| 173 | client->result = -1; | ||
| 174 | |||
| 175 | ret = s3c_adc_start(client, ch, 1); | ||
| 176 | if (ret < 0) | ||
| 177 | goto err; | ||
| 178 | |||
| 179 | ret = wait_event_timeout(wake, client->result >= 0, HZ / 2); | ||
| 180 | if (client->result < 0) { | ||
| 181 | ret = -ETIMEDOUT; | ||
| 182 | goto err; | ||
| 183 | } | ||
| 184 | |||
| 185 | client->convert_cb = NULL; | ||
| 186 | return client->result; | ||
| 187 | |||
| 188 | err: | ||
| 189 | return ret; | ||
| 190 | } | ||
| 191 | EXPORT_SYMBOL_GPL(s3c_adc_convert); | ||
| 192 | |||
| 193 | static void s3c_adc_default_select(struct s3c_adc_client *client, | ||
| 194 | unsigned select) | ||
| 157 | { | 195 | { |
| 158 | } | 196 | } |
| 159 | 197 | ||
| 160 | struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev, | 198 | struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev, |
| 161 | void (*select)(unsigned int selected), | 199 | void (*select)(struct s3c_adc_client *client, |
| 162 | void (*conv)(unsigned d0, unsigned d1, | 200 | unsigned int selected), |
| 201 | void (*conv)(struct s3c_adc_client *client, | ||
| 202 | unsigned d0, unsigned d1, | ||
| 163 | unsigned *samples_left), | 203 | unsigned *samples_left), |
| 164 | unsigned int is_ts) | 204 | unsigned int is_ts) |
| 165 | { | 205 | { |
| 166 | struct s3c_adc_client *client; | 206 | struct s3c_adc_client *client; |
| 167 | 207 | ||
| 168 | WARN_ON(!pdev); | 208 | WARN_ON(!pdev); |
| 169 | WARN_ON(!conv); | ||
| 170 | 209 | ||
| 171 | if (!select) | 210 | if (!select) |
| 172 | select = s3c_adc_default_select; | 211 | select = s3c_adc_default_select; |
| 173 | 212 | ||
| 174 | if (!conv || !pdev) | 213 | if (!pdev) |
| 175 | return ERR_PTR(-EINVAL); | 214 | return ERR_PTR(-EINVAL); |
| 176 | 215 | ||
| 177 | client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL); | 216 | client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL); |
| @@ -230,16 +269,19 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) | |||
| 230 | adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1); | 269 | adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1); |
| 231 | 270 | ||
| 232 | client->nr_samples--; | 271 | client->nr_samples--; |
| 233 | (client->convert_cb)(data0 & 0x3ff, data1 & 0x3ff, &client->nr_samples); | 272 | |
| 273 | if (client->convert_cb) | ||
| 274 | (client->convert_cb)(client, data0 & 0x3ff, data1 & 0x3ff, | ||
| 275 | &client->nr_samples); | ||
| 234 | 276 | ||
| 235 | if (client->nr_samples > 0) { | 277 | if (client->nr_samples > 0) { |
| 236 | /* fire another conversion for this */ | 278 | /* fire another conversion for this */ |
| 237 | 279 | ||
| 238 | client->select_cb(1); | 280 | client->select_cb(client, 1); |
| 239 | s3c_adc_convert(adc); | 281 | s3c_adc_convert(adc); |
| 240 | } else { | 282 | } else { |
| 241 | local_irq_save(flags); | 283 | local_irq_save(flags); |
| 242 | (client->select_cb)(0); | 284 | (client->select_cb)(client, 0); |
| 243 | adc->cur = NULL; | 285 | adc->cur = NULL; |
| 244 | 286 | ||
| 245 | s3c_adc_try(adc); | 287 | s3c_adc_try(adc); |
diff --git a/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c b/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c new file mode 100644 index 000000000000..a9276667c2fb --- /dev/null +++ b/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c | |||
| @@ -0,0 +1,199 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2009 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * | ||
| 7 | * S3C24XX CPU Frequency scaling - debugfs status support | ||
| 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 | #include <linux/init.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/ioport.h> | ||
| 18 | #include <linux/cpufreq.h> | ||
| 19 | #include <linux/debugfs.h> | ||
| 20 | #include <linux/seq_file.h> | ||
| 21 | #include <linux/err.h> | ||
| 22 | |||
| 23 | #include <plat/cpu-freq-core.h> | ||
| 24 | |||
| 25 | static struct dentry *dbgfs_root; | ||
| 26 | static struct dentry *dbgfs_file_io; | ||
| 27 | static struct dentry *dbgfs_file_info; | ||
| 28 | static struct dentry *dbgfs_file_board; | ||
| 29 | |||
| 30 | #define print_ns(x) ((x) / 10), ((x) % 10) | ||
| 31 | |||
| 32 | static void show_max(struct seq_file *seq, struct s3c_freq *f) | ||
| 33 | { | ||
| 34 | seq_printf(seq, "MAX: F=%lu, H=%lu, P=%lu, A=%lu\n", | ||
| 35 | f->fclk, f->hclk, f->pclk, f->armclk); | ||
| 36 | } | ||
| 37 | |||
| 38 | static int board_show(struct seq_file *seq, void *p) | ||
| 39 | { | ||
| 40 | struct s3c_cpufreq_config *cfg; | ||
| 41 | struct s3c_cpufreq_board *brd; | ||
| 42 | |||
| 43 | cfg = s3c_cpufreq_getconfig(); | ||
| 44 | if (!cfg) { | ||
| 45 | seq_printf(seq, "no configuration registered\n"); | ||
| 46 | return 0; | ||
| 47 | } | ||
| 48 | |||
| 49 | brd = cfg->board; | ||
| 50 | if (!brd) { | ||
| 51 | seq_printf(seq, "no board definition set?\n"); | ||
| 52 | return 0; | ||
| 53 | } | ||
| 54 | |||
| 55 | seq_printf(seq, "SDRAM refresh %u ns\n", brd->refresh); | ||
| 56 | seq_printf(seq, "auto_io=%u\n", brd->auto_io); | ||
| 57 | seq_printf(seq, "need_io=%u\n", brd->need_io); | ||
| 58 | |||
| 59 | show_max(seq, &brd->max); | ||
| 60 | |||
| 61 | |||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | static int fops_board_open(struct inode *inode, struct file *file) | ||
| 66 | { | ||
| 67 | return single_open(file, board_show, NULL); | ||
| 68 | } | ||
| 69 | |||
| 70 | static const struct file_operations fops_board = { | ||
| 71 | .open = fops_board_open, | ||
| 72 | .read = seq_read, | ||
| 73 | .llseek = seq_lseek, | ||
| 74 | .release = single_release, | ||
| 75 | .owner = THIS_MODULE, | ||
| 76 | }; | ||
| 77 | |||
| 78 | static int info_show(struct seq_file *seq, void *p) | ||
| 79 | { | ||
| 80 | struct s3c_cpufreq_config *cfg; | ||
| 81 | |||
| 82 | cfg = s3c_cpufreq_getconfig(); | ||
| 83 | if (!cfg) { | ||
| 84 | seq_printf(seq, "no configuration registered\n"); | ||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | |||
| 88 | seq_printf(seq, " FCLK %ld Hz\n", cfg->freq.fclk); | ||
| 89 | seq_printf(seq, " HCLK %ld Hz (%lu.%lu ns)\n", | ||
| 90 | cfg->freq.hclk, print_ns(cfg->freq.hclk_tns)); | ||
| 91 | seq_printf(seq, " PCLK %ld Hz\n", cfg->freq.hclk); | ||
| 92 | seq_printf(seq, "ARMCLK %ld Hz\n", cfg->freq.armclk); | ||
| 93 | seq_printf(seq, "\n"); | ||
| 94 | |||
| 95 | show_max(seq, &cfg->max); | ||
| 96 | |||
| 97 | seq_printf(seq, "Divisors: P=%d, H=%d, A=%d, dvs=%s\n", | ||
| 98 | cfg->divs.h_divisor, cfg->divs.p_divisor, | ||
| 99 | cfg->divs.arm_divisor, cfg->divs.dvs ? "on" : "off"); | ||
| 100 | seq_printf(seq, "\n"); | ||
| 101 | |||
| 102 | seq_printf(seq, "lock_pll=%u\n", cfg->lock_pll); | ||
| 103 | |||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | static int fops_info_open(struct inode *inode, struct file *file) | ||
| 108 | { | ||
| 109 | return single_open(file, info_show, NULL); | ||
| 110 | } | ||
| 111 | |||
| 112 | static const struct file_operations fops_info = { | ||
| 113 | .open = fops_info_open, | ||
| 114 | .read = seq_read, | ||
| 115 | .llseek = seq_lseek, | ||
| 116 | .release = single_release, | ||
| 117 | .owner = THIS_MODULE, | ||
| 118 | }; | ||
| 119 | |||
| 120 | static int io_show(struct seq_file *seq, void *p) | ||
| 121 | { | ||
| 122 | void (*show_bank)(struct seq_file *, struct s3c_cpufreq_config *, union s3c_iobank *); | ||
| 123 | struct s3c_cpufreq_config *cfg; | ||
| 124 | struct s3c_iotimings *iot; | ||
| 125 | union s3c_iobank *iob; | ||
| 126 | int bank; | ||
| 127 | |||
| 128 | cfg = s3c_cpufreq_getconfig(); | ||
| 129 | if (!cfg) { | ||
| 130 | seq_printf(seq, "no configuration registered\n"); | ||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 134 | show_bank = cfg->info->debug_io_show; | ||
| 135 | if (!show_bank) { | ||
| 136 | seq_printf(seq, "no code to show bank timing\n"); | ||
| 137 | return 0; | ||
| 138 | } | ||
| 139 | |||
| 140 | iot = s3c_cpufreq_getiotimings(); | ||
| 141 | if (!iot) { | ||
| 142 | seq_printf(seq, "no io timings registered\n"); | ||
| 143 | return 0; | ||
| 144 | } | ||
| 145 | |||
| 146 | seq_printf(seq, "hclk period is %lu.%lu ns\n", print_ns(cfg->freq.hclk_tns)); | ||
| 147 | |||
| 148 | for (bank = 0; bank < MAX_BANKS; bank++) { | ||
| 149 | iob = &iot->bank[bank]; | ||
| 150 | |||
| 151 | seq_printf(seq, "bank %d: ", bank); | ||
| 152 | |||
| 153 | if (!iob->io_2410) { | ||
| 154 | seq_printf(seq, "nothing set\n"); | ||
| 155 | continue; | ||
| 156 | } | ||
| 157 | |||
| 158 | show_bank(seq, cfg, iob); | ||
| 159 | } | ||
| 160 | |||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | |||
| 164 | static int fops_io_open(struct inode *inode, struct file *file) | ||
| 165 | { | ||
| 166 | return single_open(file, io_show, NULL); | ||
| 167 | } | ||
| 168 | |||
| 169 | static const struct file_operations fops_io = { | ||
| 170 | .open = fops_io_open, | ||
| 171 | .read = seq_read, | ||
| 172 | .llseek = seq_lseek, | ||
| 173 | .release = single_release, | ||
| 174 | .owner = THIS_MODULE, | ||
| 175 | }; | ||
| 176 | |||
| 177 | |||
| 178 | static int __init s3c_freq_debugfs_init(void) | ||
| 179 | { | ||
| 180 | dbgfs_root = debugfs_create_dir("s3c-cpufreq", NULL); | ||
| 181 | if (IS_ERR(dbgfs_root)) { | ||
| 182 | printk(KERN_ERR "%s: error creating debugfs root\n", __func__); | ||
| 183 | return PTR_ERR(dbgfs_root); | ||
| 184 | } | ||
| 185 | |||
| 186 | dbgfs_file_io = debugfs_create_file("io-timing", S_IRUGO, dbgfs_root, | ||
| 187 | NULL, &fops_io); | ||
| 188 | |||
| 189 | dbgfs_file_info = debugfs_create_file("info", S_IRUGO, dbgfs_root, | ||
| 190 | NULL, &fops_info); | ||
| 191 | |||
| 192 | dbgfs_file_board = debugfs_create_file("board", S_IRUGO, dbgfs_root, | ||
| 193 | NULL, &fops_board); | ||
| 194 | |||
| 195 | return 0; | ||
| 196 | } | ||
| 197 | |||
| 198 | late_initcall(s3c_freq_debugfs_init); | ||
| 199 | |||
diff --git a/arch/arm/plat-s3c24xx/cpu-freq.c b/arch/arm/plat-s3c24xx/cpu-freq.c new file mode 100644 index 000000000000..4f1b789a1173 --- /dev/null +++ b/arch/arm/plat-s3c24xx/cpu-freq.c | |||
| @@ -0,0 +1,716 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c24xx/cpu-freq.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2006,2007,2008 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * | ||
| 7 | * S3C24XX CPU Frequency scaling | ||
| 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 | #include <linux/init.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/ioport.h> | ||
| 18 | #include <linux/cpufreq.h> | ||
| 19 | #include <linux/cpu.h> | ||
| 20 | #include <linux/clk.h> | ||
| 21 | #include <linux/err.h> | ||
| 22 | #include <linux/io.h> | ||
| 23 | #include <linux/sysdev.h> | ||
| 24 | #include <linux/kobject.h> | ||
| 25 | #include <linux/sysfs.h> | ||
| 26 | |||
| 27 | #include <asm/mach/arch.h> | ||
| 28 | #include <asm/mach/map.h> | ||
| 29 | |||
| 30 | #include <plat/cpu.h> | ||
| 31 | #include <plat/clock.h> | ||
| 32 | #include <plat/cpu-freq-core.h> | ||
| 33 | |||
| 34 | #include <mach/regs-clock.h> | ||
| 35 | |||
| 36 | /* note, cpufreq support deals in kHz, no Hz */ | ||
| 37 | |||
| 38 | static struct cpufreq_driver s3c24xx_driver; | ||
| 39 | static struct s3c_cpufreq_config cpu_cur; | ||
| 40 | static struct s3c_iotimings s3c24xx_iotiming; | ||
| 41 | static struct cpufreq_frequency_table *pll_reg; | ||
| 42 | static unsigned int last_target = ~0; | ||
| 43 | static unsigned int ftab_size; | ||
| 44 | static struct cpufreq_frequency_table *ftab; | ||
| 45 | |||
| 46 | static struct clk *_clk_mpll; | ||
| 47 | static struct clk *_clk_xtal; | ||
| 48 | static struct clk *clk_fclk; | ||
| 49 | static struct clk *clk_hclk; | ||
| 50 | static struct clk *clk_pclk; | ||
| 51 | static struct clk *clk_arm; | ||
| 52 | |||
| 53 | #ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS | ||
| 54 | struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void) | ||
| 55 | { | ||
| 56 | return &cpu_cur; | ||
| 57 | } | ||
| 58 | |||
| 59 | struct s3c_iotimings *s3c_cpufreq_getiotimings(void) | ||
| 60 | { | ||
| 61 | return &s3c24xx_iotiming; | ||
| 62 | } | ||
| 63 | #endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUGFS */ | ||
| 64 | |||
| 65 | static void s3c_cpufreq_getcur(struct s3c_cpufreq_config *cfg) | ||
| 66 | { | ||
| 67 | unsigned long fclk, pclk, hclk, armclk; | ||
| 68 | |||
| 69 | cfg->freq.fclk = fclk = clk_get_rate(clk_fclk); | ||
| 70 | cfg->freq.hclk = hclk = clk_get_rate(clk_hclk); | ||
| 71 | cfg->freq.pclk = pclk = clk_get_rate(clk_pclk); | ||
| 72 | cfg->freq.armclk = armclk = clk_get_rate(clk_arm); | ||
| 73 | |||
| 74 | cfg->pll.index = __raw_readl(S3C2410_MPLLCON); | ||
| 75 | cfg->pll.frequency = fclk; | ||
| 76 | |||
| 77 | cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10); | ||
| 78 | |||
| 79 | cfg->divs.h_divisor = fclk / hclk; | ||
| 80 | cfg->divs.p_divisor = fclk / pclk; | ||
| 81 | } | ||
| 82 | |||
| 83 | static inline void s3c_cpufreq_calc(struct s3c_cpufreq_config *cfg) | ||
| 84 | { | ||
| 85 | unsigned long pll = cfg->pll.frequency; | ||
| 86 | |||
| 87 | cfg->freq.fclk = pll; | ||
| 88 | cfg->freq.hclk = pll / cfg->divs.h_divisor; | ||
| 89 | cfg->freq.pclk = pll / cfg->divs.p_divisor; | ||
| 90 | |||
| 91 | /* convert hclk into 10ths of nanoseconds for io calcs */ | ||
| 92 | cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10); | ||
| 93 | } | ||
| 94 | |||
| 95 | static inline int closer(unsigned int target, unsigned int n, unsigned int c) | ||
| 96 | { | ||
| 97 | int diff_cur = abs(target - c); | ||
| 98 | int diff_new = abs(target - n); | ||
| 99 | |||
| 100 | return (diff_new < diff_cur); | ||
| 101 | } | ||
| 102 | |||
| 103 | static void s3c_cpufreq_show(const char *pfx, | ||
| 104 | struct s3c_cpufreq_config *cfg) | ||
| 105 | { | ||
| 106 | s3c_freq_dbg("%s: Fvco=%u, F=%lu, A=%lu, H=%lu (%u), P=%lu (%u)\n", | ||
| 107 | pfx, cfg->pll.frequency, cfg->freq.fclk, cfg->freq.armclk, | ||
| 108 | cfg->freq.hclk, cfg->divs.h_divisor, | ||
| 109 | cfg->freq.pclk, cfg->divs.p_divisor); | ||
| 110 | } | ||
| 111 | |||
| 112 | /* functions to wrapper the driver info calls to do the cpu specific work */ | ||
| 113 | |||
| 114 | static void s3c_cpufreq_setio(struct s3c_cpufreq_config *cfg) | ||
| 115 | { | ||
| 116 | if (cfg->info->set_iotiming) | ||
| 117 | (cfg->info->set_iotiming)(cfg, &s3c24xx_iotiming); | ||
| 118 | } | ||
| 119 | |||
| 120 | static int s3c_cpufreq_calcio(struct s3c_cpufreq_config *cfg) | ||
| 121 | { | ||
| 122 | if (cfg->info->calc_iotiming) | ||
| 123 | return (cfg->info->calc_iotiming)(cfg, &s3c24xx_iotiming); | ||
| 124 | |||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | |||
| 128 | static void s3c_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg) | ||
| 129 | { | ||
| 130 | (cfg->info->set_refresh)(cfg); | ||
| 131 | } | ||
| 132 | |||
| 133 | static void s3c_cpufreq_setdivs(struct s3c_cpufreq_config *cfg) | ||
| 134 | { | ||
| 135 | (cfg->info->set_divs)(cfg); | ||
| 136 | } | ||
| 137 | |||
| 138 | static int s3c_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg) | ||
| 139 | { | ||
| 140 | return (cfg->info->calc_divs)(cfg); | ||
| 141 | } | ||
| 142 | |||
| 143 | static void s3c_cpufreq_setfvco(struct s3c_cpufreq_config *cfg) | ||
| 144 | { | ||
| 145 | (cfg->info->set_fvco)(cfg); | ||
| 146 | } | ||
| 147 | |||
| 148 | static inline void s3c_cpufreq_resume_clocks(void) | ||
| 149 | { | ||
| 150 | cpu_cur.info->resume_clocks(); | ||
| 151 | } | ||
| 152 | |||
| 153 | static inline void s3c_cpufreq_updateclk(struct clk *clk, | ||
| 154 | unsigned int freq) | ||
| 155 | { | ||
| 156 | clk_set_rate(clk, freq); | ||
| 157 | } | ||
| 158 | |||
| 159 | static int s3c_cpufreq_settarget(struct cpufreq_policy *policy, | ||
| 160 | unsigned int target_freq, | ||
| 161 | struct cpufreq_frequency_table *pll) | ||
| 162 | { | ||
| 163 | struct s3c_cpufreq_freqs freqs; | ||
| 164 | struct s3c_cpufreq_config cpu_new; | ||
| 165 | unsigned long flags; | ||
| 166 | |||
| 167 | cpu_new = cpu_cur; /* copy new from current */ | ||
| 168 | |||
| 169 | s3c_cpufreq_show("cur", &cpu_cur); | ||
| 170 | |||
| 171 | /* TODO - check for DMA currently outstanding */ | ||
| 172 | |||
| 173 | cpu_new.pll = pll ? *pll : cpu_cur.pll; | ||
| 174 | |||
| 175 | if (pll) | ||
| 176 | freqs.pll_changing = 1; | ||
| 177 | |||
| 178 | /* update our frequencies */ | ||
| 179 | |||
| 180 | cpu_new.freq.armclk = target_freq; | ||
| 181 | cpu_new.freq.fclk = cpu_new.pll.frequency; | ||
| 182 | |||
| 183 | if (s3c_cpufreq_calcdivs(&cpu_new) < 0) { | ||
| 184 | printk(KERN_ERR "no divisors for %d\n", target_freq); | ||
| 185 | goto err_notpossible; | ||
| 186 | } | ||
| 187 | |||
| 188 | s3c_freq_dbg("%s: got divs\n", __func__); | ||
| 189 | |||
| 190 | s3c_cpufreq_calc(&cpu_new); | ||
| 191 | |||
| 192 | s3c_freq_dbg("%s: calculated frequencies for new\n", __func__); | ||
| 193 | |||
| 194 | if (cpu_new.freq.hclk != cpu_cur.freq.hclk) { | ||
| 195 | if (s3c_cpufreq_calcio(&cpu_new) < 0) { | ||
| 196 | printk(KERN_ERR "%s: no IO timings\n", __func__); | ||
| 197 | goto err_notpossible; | ||
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 | s3c_cpufreq_show("new", &cpu_new); | ||
| 202 | |||
| 203 | /* setup our cpufreq parameters */ | ||
| 204 | |||
| 205 | freqs.old = cpu_cur.freq; | ||
| 206 | freqs.new = cpu_new.freq; | ||
| 207 | |||
| 208 | freqs.freqs.cpu = 0; | ||
| 209 | freqs.freqs.old = cpu_cur.freq.armclk / 1000; | ||
| 210 | freqs.freqs.new = cpu_new.freq.armclk / 1000; | ||
| 211 | |||
| 212 | /* update f/h/p clock settings before we issue the change | ||
| 213 | * notification, so that drivers do not need to do anything | ||
| 214 | * special if they want to recalculate on CPUFREQ_PRECHANGE. */ | ||
| 215 | |||
| 216 | s3c_cpufreq_updateclk(_clk_mpll, cpu_new.pll.frequency); | ||
| 217 | s3c_cpufreq_updateclk(clk_fclk, cpu_new.freq.fclk); | ||
| 218 | s3c_cpufreq_updateclk(clk_hclk, cpu_new.freq.hclk); | ||
| 219 | s3c_cpufreq_updateclk(clk_pclk, cpu_new.freq.pclk); | ||
| 220 | |||
| 221 | /* start the frequency change */ | ||
| 222 | |||
| 223 | if (policy) | ||
| 224 | cpufreq_notify_transition(&freqs.freqs, CPUFREQ_PRECHANGE); | ||
| 225 | |||
| 226 | /* If hclk is staying the same, then we do not need to | ||
| 227 | * re-write the IO or the refresh timings whilst we are changing | ||
| 228 | * speed. */ | ||
| 229 | |||
| 230 | local_irq_save(flags); | ||
| 231 | |||
| 232 | /* is our memory clock slowing down? */ | ||
| 233 | if (cpu_new.freq.hclk < cpu_cur.freq.hclk) { | ||
| 234 | s3c_cpufreq_setrefresh(&cpu_new); | ||
| 235 | s3c_cpufreq_setio(&cpu_new); | ||
| 236 | } | ||
| 237 | |||
| 238 | if (cpu_new.freq.fclk == cpu_cur.freq.fclk) { | ||
| 239 | /* not changing PLL, just set the divisors */ | ||
| 240 | |||
| 241 | s3c_cpufreq_setdivs(&cpu_new); | ||
| 242 | } else { | ||
| 243 | if (cpu_new.freq.fclk < cpu_cur.freq.fclk) { | ||
| 244 | /* slow the cpu down, then set divisors */ | ||
| 245 | |||
| 246 | s3c_cpufreq_setfvco(&cpu_new); | ||
| 247 | s3c_cpufreq_setdivs(&cpu_new); | ||
| 248 | } else { | ||
| 249 | /* set the divisors, then speed up */ | ||
| 250 | |||
| 251 | s3c_cpufreq_setdivs(&cpu_new); | ||
| 252 | s3c_cpufreq_setfvco(&cpu_new); | ||
| 253 | } | ||
| 254 | } | ||
| 255 | |||
| 256 | /* did our memory clock speed up */ | ||
| 257 | if (cpu_new.freq.hclk > cpu_cur.freq.hclk) { | ||
| 258 | s3c_cpufreq_setrefresh(&cpu_new); | ||
| 259 | s3c_cpufreq_setio(&cpu_new); | ||
| 260 | } | ||
| 261 | |||
| 262 | /* update our current settings */ | ||
| 263 | cpu_cur = cpu_new; | ||
| 264 | |||
| 265 | local_irq_restore(flags); | ||
| 266 | |||
| 267 | /* notify everyone we've done this */ | ||
| 268 | if (policy) | ||
| 269 | cpufreq_notify_transition(&freqs.freqs, CPUFREQ_POSTCHANGE); | ||
| 270 | |||
| 271 | s3c_freq_dbg("%s: finished\n", __func__); | ||
| 272 | return 0; | ||
| 273 | |||
| 274 | err_notpossible: | ||
| 275 | printk(KERN_ERR "no compatible settings for %d\n", target_freq); | ||
| 276 | return -EINVAL; | ||
| 277 | } | ||
| 278 | |||
| 279 | /* s3c_cpufreq_target | ||
| 280 | * | ||
| 281 | * called by the cpufreq core to adjust the frequency that the CPU | ||
| 282 | * is currently running at. | ||
| 283 | */ | ||
| 284 | |||
| 285 | static int s3c_cpufreq_target(struct cpufreq_policy *policy, | ||
| 286 | unsigned int target_freq, | ||
| 287 | unsigned int relation) | ||
| 288 | { | ||
| 289 | struct cpufreq_frequency_table *pll; | ||
| 290 | unsigned int index; | ||
| 291 | |||
| 292 | /* avoid repeated calls which cause a needless amout of duplicated | ||
| 293 | * logging output (and CPU time as the calculation process is | ||
| 294 | * done) */ | ||
| 295 | if (target_freq == last_target) | ||
| 296 | return 0; | ||
| 297 | |||
| 298 | last_target = target_freq; | ||
| 299 | |||
| 300 | s3c_freq_dbg("%s: policy %p, target %u, relation %u\n", | ||
| 301 | __func__, policy, target_freq, relation); | ||
| 302 | |||
| 303 | if (ftab) { | ||
| 304 | if (cpufreq_frequency_table_target(policy, ftab, | ||
| 305 | target_freq, relation, | ||
| 306 | &index)) { | ||
| 307 | s3c_freq_dbg("%s: table failed\n", __func__); | ||
| 308 | return -EINVAL; | ||
| 309 | } | ||
| 310 | |||
| 311 | s3c_freq_dbg("%s: adjust %d to entry %d (%u)\n", __func__, | ||
| 312 | target_freq, index, ftab[index].frequency); | ||
| 313 | target_freq = ftab[index].frequency; | ||
| 314 | } | ||
| 315 | |||
| 316 | target_freq *= 1000; /* convert target to Hz */ | ||
| 317 | |||
| 318 | /* find the settings for our new frequency */ | ||
| 319 | |||
| 320 | if (!pll_reg || cpu_cur.lock_pll) { | ||
| 321 | /* either we've not got any PLL values, or we've locked | ||
| 322 | * to the current one. */ | ||
| 323 | pll = NULL; | ||
| 324 | } else { | ||
| 325 | struct cpufreq_policy tmp_policy; | ||
| 326 | int ret; | ||
| 327 | |||
| 328 | /* we keep the cpu pll table in Hz, to ensure we get an | ||
| 329 | * accurate value for the PLL output. */ | ||
| 330 | |||
| 331 | tmp_policy.min = policy->min * 1000; | ||
| 332 | tmp_policy.max = policy->max * 1000; | ||
| 333 | tmp_policy.cpu = policy->cpu; | ||
| 334 | |||
| 335 | /* cpufreq_frequency_table_target uses a pointer to 'index' | ||
| 336 | * which is the number of the table entry, not the value of | ||
| 337 | * the table entry's index field. */ | ||
| 338 | |||
| 339 | ret = cpufreq_frequency_table_target(&tmp_policy, pll_reg, | ||
| 340 | target_freq, relation, | ||
| 341 | &index); | ||
| 342 | |||
| 343 | if (ret < 0) { | ||
| 344 | printk(KERN_ERR "%s: no PLL available\n", __func__); | ||
| 345 | goto err_notpossible; | ||
| 346 | } | ||
| 347 | |||
| 348 | pll = pll_reg + index; | ||
| 349 | |||
| 350 | s3c_freq_dbg("%s: target %u => %u\n", | ||
| 351 | __func__, target_freq, pll->frequency); | ||
| 352 | |||
| 353 | target_freq = pll->frequency; | ||
| 354 | } | ||
| 355 | |||
| 356 | return s3c_cpufreq_settarget(policy, target_freq, pll); | ||
| 357 | |||
| 358 | err_notpossible: | ||
| 359 | printk(KERN_ERR "no compatible settings for %d\n", target_freq); | ||
| 360 | return -EINVAL; | ||
| 361 | } | ||
| 362 | |||
| 363 | static unsigned int s3c_cpufreq_get(unsigned int cpu) | ||
| 364 | { | ||
| 365 | return clk_get_rate(clk_arm) / 1000; | ||
| 366 | } | ||
| 367 | |||
| 368 | struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) | ||
| 369 | { | ||
| 370 | struct clk *clk; | ||
| 371 | |||
| 372 | clk = clk_get(dev, name); | ||
| 373 | if (IS_ERR(clk)) | ||
| 374 | printk(KERN_ERR "cpufreq: failed to get clock '%s'\n", name); | ||
| 375 | |||
| 376 | return clk; | ||
| 377 | } | ||
| 378 | |||
| 379 | static int s3c_cpufreq_init(struct cpufreq_policy *policy) | ||
| 380 | { | ||
| 381 | printk(KERN_INFO "%s: initialising policy %p\n", __func__, policy); | ||
| 382 | |||
| 383 | if (policy->cpu != 0) | ||
| 384 | return -EINVAL; | ||
| 385 | |||
| 386 | policy->cur = s3c_cpufreq_get(0); | ||
| 387 | policy->min = policy->cpuinfo.min_freq = 0; | ||
| 388 | policy->max = policy->cpuinfo.max_freq = cpu_cur.info->max.fclk / 1000; | ||
| 389 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
| 390 | |||
| 391 | /* feed the latency information from the cpu driver */ | ||
| 392 | policy->cpuinfo.transition_latency = cpu_cur.info->latency; | ||
| 393 | |||
| 394 | if (ftab) | ||
| 395 | cpufreq_frequency_table_cpuinfo(policy, ftab); | ||
| 396 | |||
| 397 | return 0; | ||
| 398 | } | ||
| 399 | |||
| 400 | static __init int s3c_cpufreq_initclks(void) | ||
| 401 | { | ||
| 402 | _clk_mpll = s3c_cpufreq_clk_get(NULL, "mpll"); | ||
| 403 | _clk_xtal = s3c_cpufreq_clk_get(NULL, "xtal"); | ||
| 404 | clk_fclk = s3c_cpufreq_clk_get(NULL, "fclk"); | ||
| 405 | clk_hclk = s3c_cpufreq_clk_get(NULL, "hclk"); | ||
| 406 | clk_pclk = s3c_cpufreq_clk_get(NULL, "pclk"); | ||
| 407 | clk_arm = s3c_cpufreq_clk_get(NULL, "armclk"); | ||
| 408 | |||
| 409 | if (IS_ERR(clk_fclk) || IS_ERR(clk_hclk) || IS_ERR(clk_pclk) || | ||
| 410 | IS_ERR(_clk_mpll) || IS_ERR(clk_arm) || IS_ERR(_clk_xtal)) { | ||
| 411 | printk(KERN_ERR "%s: could not get clock(s)\n", __func__); | ||
| 412 | return -ENOENT; | ||
| 413 | } | ||
| 414 | |||
| 415 | printk(KERN_INFO "%s: clocks f=%lu,h=%lu,p=%lu,a=%lu\n", __func__, | ||
| 416 | clk_get_rate(clk_fclk) / 1000, | ||
| 417 | clk_get_rate(clk_hclk) / 1000, | ||
| 418 | clk_get_rate(clk_pclk) / 1000, | ||
| 419 | clk_get_rate(clk_arm) / 1000); | ||
| 420 | |||
| 421 | return 0; | ||
| 422 | } | ||
| 423 | |||
| 424 | static int s3c_cpufreq_verify(struct cpufreq_policy *policy) | ||
| 425 | { | ||
| 426 | if (policy->cpu != 0) | ||
| 427 | return -EINVAL; | ||
| 428 | |||
| 429 | return 0; | ||
| 430 | } | ||
| 431 | |||
| 432 | #ifdef CONFIG_PM | ||
| 433 | static struct cpufreq_frequency_table suspend_pll; | ||
| 434 | static unsigned int suspend_freq; | ||
| 435 | |||
| 436 | static int s3c_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg) | ||
| 437 | { | ||
| 438 | suspend_pll.frequency = clk_get_rate(_clk_mpll); | ||
| 439 | suspend_pll.index = __raw_readl(S3C2410_MPLLCON); | ||
| 440 | suspend_freq = s3c_cpufreq_get(0) * 1000; | ||
| 441 | |||
| 442 | return 0; | ||
| 443 | } | ||
| 444 | |||
| 445 | static int s3c_cpufreq_resume(struct cpufreq_policy *policy) | ||
| 446 | { | ||
| 447 | int ret; | ||
| 448 | |||
| 449 | s3c_freq_dbg("%s: resuming with policy %p\n", __func__, policy); | ||
| 450 | |||
| 451 | last_target = ~0; /* invalidate last_target setting */ | ||
| 452 | |||
| 453 | /* first, find out what speed we resumed at. */ | ||
| 454 | s3c_cpufreq_resume_clocks(); | ||
| 455 | |||
| 456 | /* whilst we will be called later on, we try and re-set the | ||
| 457 | * cpu frequencies as soon as possible so that we do not end | ||
| 458 | * up resuming devices and then immediatley having to re-set | ||
| 459 | * a number of settings once these devices have restarted. | ||
| 460 | * | ||
| 461 | * as a note, it is expected devices are not used until they | ||
| 462 | * have been un-suspended and at that time they should have | ||
| 463 | * used the updated clock settings. | ||
| 464 | */ | ||
| 465 | |||
| 466 | ret = s3c_cpufreq_settarget(NULL, suspend_freq, &suspend_pll); | ||
| 467 | if (ret) { | ||
| 468 | printk(KERN_ERR "%s: failed to reset pll/freq\n", __func__); | ||
| 469 | return ret; | ||
| 470 | } | ||
| 471 | |||
| 472 | return 0; | ||
| 473 | } | ||
| 474 | #else | ||
| 475 | #define s3c_cpufreq_resume NULL | ||
| 476 | #define s3c_cpufreq_suspend NULL | ||
| 477 | #endif | ||
| 478 | |||
| 479 | static struct cpufreq_driver s3c24xx_driver = { | ||
| 480 | .flags = CPUFREQ_STICKY, | ||
| 481 | .verify = s3c_cpufreq_verify, | ||
| 482 | .target = s3c_cpufreq_target, | ||
| 483 | .get = s3c_cpufreq_get, | ||
| 484 | .init = s3c_cpufreq_init, | ||
| 485 | .suspend = s3c_cpufreq_suspend, | ||
| 486 | .resume = s3c_cpufreq_resume, | ||
| 487 | .name = "s3c24xx", | ||
| 488 | }; | ||
| 489 | |||
| 490 | |||
| 491 | int __init s3c_cpufreq_register(struct s3c_cpufreq_info *info) | ||
| 492 | { | ||
| 493 | if (!info || !info->name) { | ||
| 494 | printk(KERN_ERR "%s: failed to pass valid information\n", | ||
| 495 | __func__); | ||
| 496 | return -EINVAL; | ||
| 497 | } | ||
| 498 | |||
| 499 | printk(KERN_INFO "S3C24XX CPU Frequency driver, %s cpu support\n", | ||
| 500 | info->name); | ||
| 501 | |||
| 502 | /* check our driver info has valid data */ | ||
| 503 | |||
| 504 | BUG_ON(info->set_refresh == NULL); | ||
| 505 | BUG_ON(info->set_divs == NULL); | ||
| 506 | BUG_ON(info->calc_divs == NULL); | ||
| 507 | |||
| 508 | /* info->set_fvco is optional, depending on whether there | ||
| 509 | * is a need to set the clock code. */ | ||
| 510 | |||
| 511 | cpu_cur.info = info; | ||
| 512 | |||
| 513 | /* Note, driver registering should probably update locktime */ | ||
| 514 | |||
| 515 | return 0; | ||
| 516 | } | ||
| 517 | |||
| 518 | int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board) | ||
| 519 | { | ||
| 520 | struct s3c_cpufreq_board *ours; | ||
| 521 | |||
| 522 | if (!board) { | ||
| 523 | printk(KERN_INFO "%s: no board data\n", __func__); | ||
| 524 | return -EINVAL; | ||
| 525 | } | ||
| 526 | |||
| 527 | /* Copy the board information so that each board can make this | ||
| 528 | * initdata. */ | ||
| 529 | |||
| 530 | ours = kzalloc(sizeof(struct s3c_cpufreq_board), GFP_KERNEL); | ||
| 531 | if (ours == NULL) { | ||
| 532 | printk(KERN_ERR "%s: no memory\n", __func__); | ||
| 533 | return -ENOMEM; | ||
| 534 | } | ||
| 535 | |||
| 536 | *ours = *board; | ||
| 537 | cpu_cur.board = ours; | ||
| 538 | |||
| 539 | return 0; | ||
| 540 | } | ||
| 541 | |||
| 542 | int __init s3c_cpufreq_auto_io(void) | ||
| 543 | { | ||
| 544 | int ret; | ||
| 545 | |||
| 546 | if (!cpu_cur.info->get_iotiming) { | ||
| 547 | printk(KERN_ERR "%s: get_iotiming undefined\n", __func__); | ||
| 548 | return -ENOENT; | ||
| 549 | } | ||
| 550 | |||
| 551 | printk(KERN_INFO "%s: working out IO settings\n", __func__); | ||
| 552 | |||
| 553 | ret = (cpu_cur.info->get_iotiming)(&cpu_cur, &s3c24xx_iotiming); | ||
| 554 | if (ret) | ||
| 555 | printk(KERN_ERR "%s: failed to get timings\n", __func__); | ||
| 556 | |||
| 557 | return ret; | ||
| 558 | } | ||
| 559 | |||
| 560 | /* if one or is zero, then return the other, otherwise return the min */ | ||
| 561 | #define do_min(_a, _b) ((_a) == 0 ? (_b) : (_b) == 0 ? (_a) : min(_a, _b)) | ||
| 562 | |||
| 563 | /** | ||
| 564 | * s3c_cpufreq_freq_min - find the minimum settings for the given freq. | ||
| 565 | * @dst: The destination structure | ||
| 566 | * @a: One argument. | ||
| 567 | * @b: The other argument. | ||
| 568 | * | ||
| 569 | * Create a minimum of each frequency entry in the 'struct s3c_freq', | ||
| 570 | * unless the entry is zero when it is ignored and the non-zero argument | ||
| 571 | * used. | ||
| 572 | */ | ||
| 573 | static void s3c_cpufreq_freq_min(struct s3c_freq *dst, | ||
| 574 | struct s3c_freq *a, struct s3c_freq *b) | ||
| 575 | { | ||
| 576 | dst->fclk = do_min(a->fclk, b->fclk); | ||
| 577 | dst->hclk = do_min(a->hclk, b->hclk); | ||
| 578 | dst->pclk = do_min(a->pclk, b->pclk); | ||
| 579 | dst->armclk = do_min(a->armclk, b->armclk); | ||
| 580 | } | ||
| 581 | |||
| 582 | static inline u32 calc_locktime(u32 freq, u32 time_us) | ||
| 583 | { | ||
| 584 | u32 result; | ||
| 585 | |||
| 586 | result = freq * time_us; | ||
| 587 | result = DIV_ROUND_UP(result, 1000 * 1000); | ||
| 588 | |||
| 589 | return result; | ||
| 590 | } | ||
| 591 | |||
| 592 | static void s3c_cpufreq_update_loctkime(void) | ||
| 593 | { | ||
| 594 | unsigned int bits = cpu_cur.info->locktime_bits; | ||
| 595 | u32 rate = (u32)clk_get_rate(_clk_xtal); | ||
| 596 | u32 val; | ||
| 597 | |||
| 598 | if (bits == 0) { | ||
| 599 | WARN_ON(1); | ||
| 600 | return; | ||
| 601 | } | ||
| 602 | |||
| 603 | val = calc_locktime(rate, cpu_cur.info->locktime_u) << bits; | ||
| 604 | val |= calc_locktime(rate, cpu_cur.info->locktime_m); | ||
| 605 | |||
| 606 | printk(KERN_INFO "%s: new locktime is 0x%08x\n", __func__, val); | ||
| 607 | __raw_writel(val, S3C2410_LOCKTIME); | ||
| 608 | } | ||
| 609 | |||
| 610 | static int s3c_cpufreq_build_freq(void) | ||
| 611 | { | ||
| 612 | int size, ret; | ||
| 613 | |||
| 614 | if (!cpu_cur.info->calc_freqtable) | ||
| 615 | return -EINVAL; | ||
| 616 | |||
| 617 | kfree(ftab); | ||
| 618 | ftab = NULL; | ||
| 619 | |||
| 620 | size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0); | ||
| 621 | size++; | ||
| 622 | |||
| 623 | ftab = kmalloc(sizeof(struct cpufreq_frequency_table) * size, GFP_KERNEL); | ||
| 624 | if (!ftab) { | ||
| 625 | printk(KERN_ERR "%s: no memory for tables\n", __func__); | ||
| 626 | return -ENOMEM; | ||
| 627 | } | ||
| 628 | |||
| 629 | ftab_size = size; | ||
| 630 | |||
| 631 | ret = cpu_cur.info->calc_freqtable(&cpu_cur, ftab, size); | ||
| 632 | s3c_cpufreq_addfreq(ftab, ret, size, CPUFREQ_TABLE_END); | ||
| 633 | |||
| 634 | return 0; | ||
| 635 | } | ||
| 636 | |||
| 637 | static int __init s3c_cpufreq_initcall(void) | ||
| 638 | { | ||
| 639 | int ret = 0; | ||
| 640 | |||
| 641 | if (cpu_cur.info && cpu_cur.board) { | ||
| 642 | ret = s3c_cpufreq_initclks(); | ||
| 643 | if (ret) | ||
| 644 | goto out; | ||
| 645 | |||
| 646 | /* get current settings */ | ||
| 647 | s3c_cpufreq_getcur(&cpu_cur); | ||
| 648 | s3c_cpufreq_show("cur", &cpu_cur); | ||
| 649 | |||
| 650 | if (cpu_cur.board->auto_io) { | ||
| 651 | ret = s3c_cpufreq_auto_io(); | ||
| 652 | if (ret) { | ||
| 653 | printk(KERN_ERR "%s: failed to get io timing\n", | ||
| 654 | __func__); | ||
| 655 | goto out; | ||
| 656 | } | ||
| 657 | } | ||
| 658 | |||
| 659 | if (cpu_cur.board->need_io && !cpu_cur.info->set_iotiming) { | ||
| 660 | printk(KERN_ERR "%s: no IO support registered\n", | ||
| 661 | __func__); | ||
| 662 | ret = -EINVAL; | ||
| 663 | goto out; | ||
| 664 | } | ||
| 665 | |||
| 666 | if (!cpu_cur.info->need_pll) | ||
| 667 | cpu_cur.lock_pll = 1; | ||
| 668 | |||
| 669 | s3c_cpufreq_update_loctkime(); | ||
| 670 | |||
| 671 | s3c_cpufreq_freq_min(&cpu_cur.max, &cpu_cur.board->max, | ||
| 672 | &cpu_cur.info->max); | ||
| 673 | |||
| 674 | if (cpu_cur.info->calc_freqtable) | ||
| 675 | s3c_cpufreq_build_freq(); | ||
| 676 | |||
| 677 | ret = cpufreq_register_driver(&s3c24xx_driver); | ||
| 678 | } | ||
| 679 | |||
| 680 | out: | ||
| 681 | return ret; | ||
| 682 | } | ||
| 683 | |||
| 684 | late_initcall(s3c_cpufreq_initcall); | ||
| 685 | |||
| 686 | /** | ||
| 687 | * s3c_plltab_register - register CPU PLL table. | ||
| 688 | * @plls: The list of PLL entries. | ||
| 689 | * @plls_no: The size of the PLL entries @plls. | ||
| 690 | * | ||
| 691 | * Register the given set of PLLs with the system. | ||
| 692 | */ | ||
| 693 | int __init s3c_plltab_register(struct cpufreq_frequency_table *plls, | ||
| 694 | unsigned int plls_no) | ||
| 695 | { | ||
| 696 | struct cpufreq_frequency_table *vals; | ||
| 697 | unsigned int size; | ||
| 698 | |||
| 699 | size = sizeof(struct cpufreq_frequency_table) * (plls_no + 1); | ||
| 700 | |||
| 701 | vals = kmalloc(size, GFP_KERNEL); | ||
| 702 | if (vals) { | ||
| 703 | memcpy(vals, plls, size); | ||
| 704 | pll_reg = vals; | ||
| 705 | |||
| 706 | /* write a terminating entry, we don't store it in the | ||
| 707 | * table that is stored in the kernel */ | ||
| 708 | vals += plls_no; | ||
| 709 | vals->frequency = CPUFREQ_TABLE_END; | ||
| 710 | |||
| 711 | printk(KERN_INFO "cpufreq: %d PLL entries\n", plls_no); | ||
| 712 | } else | ||
| 713 | printk(KERN_ERR "cpufreq: no memory for PLL tables\n"); | ||
| 714 | |||
| 715 | return vals ? 0 : -ENOMEM; | ||
| 716 | } | ||
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 1932b7e0da15..5447e60f3936 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c | |||
| @@ -81,7 +81,7 @@ static struct cpu_table cpu_ids[] __initdata = { | |||
| 81 | .map_io = s3c2410_map_io, | 81 | .map_io = s3c2410_map_io, |
| 82 | .init_clocks = s3c2410_init_clocks, | 82 | .init_clocks = s3c2410_init_clocks, |
| 83 | .init_uarts = s3c2410_init_uarts, | 83 | .init_uarts = s3c2410_init_uarts, |
| 84 | .init = s3c2410_init, | 84 | .init = s3c2410a_init, |
| 85 | .name = name_s3c2410a | 85 | .name = name_s3c2410a |
| 86 | }, | 86 | }, |
| 87 | { | 87 | { |
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index 4eb378c89a39..f52a92ce8dda 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c | |||
| @@ -26,6 +26,8 @@ | |||
| 26 | #include <asm/mach/irq.h> | 26 | #include <asm/mach/irq.h> |
| 27 | #include <mach/fb.h> | 27 | #include <mach/fb.h> |
| 28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
| 29 | #include <mach/dma.h> | ||
| 30 | #include <mach/irqs.h> | ||
| 29 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
| 30 | 32 | ||
| 31 | #include <plat/regs-serial.h> | 33 | #include <plat/regs-serial.h> |
| @@ -180,25 +182,6 @@ void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd) | |||
| 180 | } | 182 | } |
| 181 | } | 183 | } |
| 182 | 184 | ||
| 183 | /* NAND Controller */ | ||
| 184 | |||
| 185 | static struct resource s3c_nand_resource[] = { | ||
| 186 | [0] = { | ||
| 187 | .start = S3C24XX_PA_NAND, | ||
| 188 | .end = S3C24XX_PA_NAND + S3C24XX_SZ_NAND - 1, | ||
| 189 | .flags = IORESOURCE_MEM, | ||
| 190 | } | ||
| 191 | }; | ||
| 192 | |||
| 193 | struct platform_device s3c_device_nand = { | ||
| 194 | .name = "s3c2410-nand", | ||
| 195 | .id = -1, | ||
| 196 | .num_resources = ARRAY_SIZE(s3c_nand_resource), | ||
| 197 | .resource = s3c_nand_resource, | ||
| 198 | }; | ||
| 199 | |||
| 200 | EXPORT_SYMBOL(s3c_device_nand); | ||
| 201 | |||
| 202 | /* USB Device (Gadget)*/ | 185 | /* USB Device (Gadget)*/ |
| 203 | 186 | ||
| 204 | static struct resource s3c_usbgadget_resource[] = { | 187 | static struct resource s3c_usbgadget_resource[] = { |
| @@ -348,7 +331,7 @@ struct platform_device s3c_device_adc = { | |||
| 348 | /* HWMON */ | 331 | /* HWMON */ |
| 349 | 332 | ||
| 350 | struct platform_device s3c_device_hwmon = { | 333 | struct platform_device s3c_device_hwmon = { |
| 351 | .name = "s3c24xx-hwmon", | 334 | .name = "s3c-hwmon", |
| 352 | .id = -1, | 335 | .id = -1, |
| 353 | .dev.parent = &s3c_device_adc.dev, | 336 | .dev.parent = &s3c_device_adc.dev, |
| 354 | }; | 337 | }; |
| @@ -473,4 +456,52 @@ struct platform_device s3c_device_camif = { | |||
| 473 | 456 | ||
| 474 | EXPORT_SYMBOL(s3c_device_camif); | 457 | EXPORT_SYMBOL(s3c_device_camif); |
| 475 | 458 | ||
| 459 | /* AC97 */ | ||
| 460 | |||
| 461 | static struct resource s3c_ac97_resource[] = { | ||
| 462 | [0] = { | ||
| 463 | .start = S3C2440_PA_AC97, | ||
| 464 | .end = S3C2440_PA_AC97 + S3C2440_SZ_AC97 -1, | ||
| 465 | .flags = IORESOURCE_MEM, | ||
| 466 | }, | ||
| 467 | [1] = { | ||
| 468 | .start = IRQ_S3C244x_AC97, | ||
| 469 | .end = IRQ_S3C244x_AC97, | ||
| 470 | .flags = IORESOURCE_IRQ, | ||
| 471 | }, | ||
| 472 | [2] = { | ||
| 473 | .name = "PCM out", | ||
| 474 | .start = DMACH_PCM_OUT, | ||
| 475 | .end = DMACH_PCM_OUT, | ||
| 476 | .flags = IORESOURCE_DMA, | ||
| 477 | }, | ||
| 478 | [3] = { | ||
| 479 | .name = "PCM in", | ||
| 480 | .start = DMACH_PCM_IN, | ||
| 481 | .end = DMACH_PCM_IN, | ||
| 482 | .flags = IORESOURCE_DMA, | ||
| 483 | }, | ||
| 484 | [4] = { | ||
| 485 | .name = "Mic in", | ||
| 486 | .start = DMACH_MIC_IN, | ||
| 487 | .end = DMACH_MIC_IN, | ||
| 488 | .flags = IORESOURCE_DMA, | ||
| 489 | }, | ||
| 490 | }; | ||
| 491 | |||
| 492 | static u64 s3c_device_ac97_dmamask = 0xffffffffUL; | ||
| 493 | |||
| 494 | struct platform_device s3c_device_ac97 = { | ||
| 495 | .name = "s3c-ac97", | ||
| 496 | .id = -1, | ||
| 497 | .num_resources = ARRAY_SIZE(s3c_ac97_resource), | ||
| 498 | .resource = s3c_ac97_resource, | ||
| 499 | .dev = { | ||
| 500 | .dma_mask = &s3c_device_ac97_dmamask, | ||
| 501 | .coherent_dma_mask = 0xffffffffUL | ||
| 502 | } | ||
| 503 | }; | ||
| 504 | |||
| 505 | EXPORT_SYMBOL(s3c_device_ac97); | ||
| 506 | |||
| 476 | #endif // CONFIG_CPU_S32440 | 507 | #endif // CONFIG_CPU_S32440 |
diff --git a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h new file mode 100644 index 000000000000..efeb025affc7 --- /dev/null +++ b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h | |||
| @@ -0,0 +1,282 @@ | |||
| 1 | /* arch/arm/plat-s3c/include/plat/cpu-freq.h | ||
| 2 | * | ||
| 3 | * Copyright (c) 2006,2007,2009 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * | ||
| 7 | * S3C CPU frequency scaling support - core support | ||
| 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 | #include <plat/cpu-freq.h> | ||
| 15 | |||
| 16 | struct seq_file; | ||
| 17 | |||
| 18 | #define MAX_BANKS (8) | ||
| 19 | #define S3C2412_MAX_IO (8) | ||
| 20 | |||
| 21 | /** | ||
| 22 | * struct s3c2410_iobank_timing - IO bank timings for S3C2410 style timings | ||
| 23 | * @bankcon: The cached version of settings in this structure. | ||
| 24 | * @tacp: | ||
| 25 | * @tacs: Time from address valid to nCS asserted. | ||
| 26 | * @tcos: Time from nCS asserted to nOE or nWE asserted. | ||
| 27 | * @tacc: Time that nOE or nWE is asserted. | ||
| 28 | * @tcoh: Time nCS is held after nOE or nWE are released. | ||
| 29 | * @tcah: Time address is held for after | ||
| 30 | * @nwait_en: Whether nWAIT is enabled for this bank. | ||
| 31 | * | ||
| 32 | * This structure represents the IO timings for a S3C2410 style IO bank | ||
| 33 | * used by the CPU frequency support if it needs to change the settings | ||
| 34 | * of the IO. | ||
| 35 | */ | ||
| 36 | struct s3c2410_iobank_timing { | ||
| 37 | unsigned long bankcon; | ||
| 38 | unsigned int tacp; | ||
| 39 | unsigned int tacs; | ||
| 40 | unsigned int tcos; | ||
| 41 | unsigned int tacc; | ||
| 42 | unsigned int tcoh; /* nCS hold afrer nOE/nWE */ | ||
| 43 | unsigned int tcah; /* Address hold after nCS */ | ||
| 44 | unsigned char nwait_en; /* nWait enabled for bank. */ | ||
| 45 | }; | ||
| 46 | |||
| 47 | /** | ||
| 48 | * struct s3c2412_iobank_timing - io timings for PL092 (S3C2412) style IO | ||
| 49 | * @idcy: The idle cycle time between transactions. | ||
| 50 | * @wstrd: nCS release to end of read cycle. | ||
| 51 | * @wstwr: nCS release to end of write cycle. | ||
| 52 | * @wstoen: nCS assertion to nOE assertion time. | ||
| 53 | * @wstwen: nCS assertion to nWE assertion time. | ||
| 54 | * @wstbrd: Burst ready delay. | ||
| 55 | * @smbidcyr: Register cache for smbidcyr value. | ||
| 56 | * @smbwstrd: Register cache for smbwstrd value. | ||
| 57 | * @smbwstwr: Register cache for smbwstwr value. | ||
| 58 | * @smbwstoen: Register cache for smbwstoen value. | ||
| 59 | * @smbwstwen: Register cache for smbwstwen value. | ||
| 60 | * @smbwstbrd: Register cache for smbwstbrd value. | ||
| 61 | * | ||
| 62 | * Timing information for a IO bank on an S3C2412 or similar system which | ||
| 63 | * uses a PL093 block. | ||
| 64 | */ | ||
| 65 | struct s3c2412_iobank_timing { | ||
| 66 | unsigned int idcy; | ||
| 67 | unsigned int wstrd; | ||
| 68 | unsigned int wstwr; | ||
| 69 | unsigned int wstoen; | ||
| 70 | unsigned int wstwen; | ||
| 71 | unsigned int wstbrd; | ||
| 72 | |||
| 73 | /* register cache */ | ||
| 74 | unsigned char smbidcyr; | ||
| 75 | unsigned char smbwstrd; | ||
| 76 | unsigned char smbwstwr; | ||
| 77 | unsigned char smbwstoen; | ||
| 78 | unsigned char smbwstwen; | ||
| 79 | unsigned char smbwstbrd; | ||
| 80 | }; | ||
| 81 | |||
| 82 | union s3c_iobank { | ||
| 83 | struct s3c2410_iobank_timing *io_2410; | ||
| 84 | struct s3c2412_iobank_timing *io_2412; | ||
| 85 | }; | ||
| 86 | |||
| 87 | /** | ||
| 88 | * struct s3c_iotimings - Chip IO timings holder | ||
| 89 | * @bank: The timings for each IO bank. | ||
| 90 | */ | ||
| 91 | struct s3c_iotimings { | ||
| 92 | union s3c_iobank bank[MAX_BANKS]; | ||
| 93 | }; | ||
| 94 | |||
| 95 | /** | ||
| 96 | * struct s3c_plltab - PLL table information. | ||
| 97 | * @vals: List of PLL values. | ||
| 98 | * @size: Size of the PLL table @vals. | ||
| 99 | */ | ||
| 100 | struct s3c_plltab { | ||
| 101 | struct s3c_pllval *vals; | ||
| 102 | int size; | ||
| 103 | }; | ||
| 104 | |||
| 105 | /** | ||
| 106 | * struct s3c_cpufreq_config - current cpu frequency configuration | ||
| 107 | * @freq: The current settings for the core clocks. | ||
| 108 | * @max: Maxium settings, derived from core, board and user settings. | ||
| 109 | * @pll: The PLL table entry for the current PLL settings. | ||
| 110 | * @divs: The divisor settings for the core clocks. | ||
| 111 | * @info: The current core driver information. | ||
| 112 | * @board: The information for the board we are running on. | ||
| 113 | * @lock_pll: Set if the PLL settings cannot be changed. | ||
| 114 | * | ||
| 115 | * This is for the core drivers that need to know information about | ||
| 116 | * the current settings and values. It should not be needed by any | ||
| 117 | * device drivers. | ||
| 118 | */ | ||
| 119 | struct s3c_cpufreq_config { | ||
| 120 | struct s3c_freq freq; | ||
| 121 | struct s3c_freq max; | ||
| 122 | struct cpufreq_frequency_table pll; | ||
| 123 | struct s3c_clkdivs divs; | ||
| 124 | struct s3c_cpufreq_info *info; /* for core, not drivers */ | ||
| 125 | struct s3c_cpufreq_board *board; | ||
| 126 | |||
| 127 | unsigned int lock_pll:1; | ||
| 128 | }; | ||
| 129 | |||
| 130 | /** | ||
| 131 | * struct s3c_cpufreq_info - Information for the CPU frequency driver. | ||
| 132 | * @name: The name of this implementation. | ||
| 133 | * @max: The maximum frequencies for the system. | ||
| 134 | * @latency: Transition latency to give to cpufreq. | ||
| 135 | * @locktime_m: The lock-time in uS for the MPLL. | ||
| 136 | * @locktime_u: The lock-time in uS for the UPLL. | ||
| 137 | * @locttime_bits: The number of bits each LOCKTIME field. | ||
| 138 | * @need_pll: Set if this driver needs to change the PLL values to acheive | ||
| 139 | * any frequency changes. This is really only need by devices like the | ||
| 140 | * S3C2410 where there is no or limited divider between the PLL and the | ||
| 141 | * ARMCLK. | ||
| 142 | * @resume_clocks: Update the clocks on resume. | ||
| 143 | * @get_iotiming: Get the current IO timing data, mainly for use at start. | ||
| 144 | * @set_iotiming: Update the IO timings from the cached copies calculated | ||
| 145 | * from the @calc_iotiming entry when changing the frequency. | ||
| 146 | * @calc_iotiming: Calculate and update the cached copies of the IO timings | ||
| 147 | * from the newly calculated frequencies. | ||
| 148 | * @calc_freqtable: Calculate (fill in) the given frequency table from the | ||
| 149 | * current frequency configuration. If the table passed in is NULL, | ||
| 150 | * then the return is the number of elements to be filled for allocation | ||
| 151 | * of the table. | ||
| 152 | * @set_refresh: Set the memory refresh configuration. | ||
| 153 | * @set_fvco: Set the PLL frequencies. | ||
| 154 | * @set_divs: Update the clock divisors. | ||
| 155 | * @calc_divs: Calculate the clock divisors. | ||
| 156 | */ | ||
| 157 | struct s3c_cpufreq_info { | ||
| 158 | const char *name; | ||
| 159 | struct s3c_freq max; | ||
| 160 | |||
| 161 | unsigned int latency; | ||
| 162 | |||
| 163 | unsigned int locktime_m; | ||
| 164 | unsigned int locktime_u; | ||
| 165 | unsigned char locktime_bits; | ||
| 166 | |||
| 167 | unsigned int need_pll:1; | ||
| 168 | |||
| 169 | /* driver routines */ | ||
| 170 | |||
| 171 | void (*resume_clocks)(void); | ||
| 172 | |||
| 173 | int (*get_iotiming)(struct s3c_cpufreq_config *cfg, | ||
| 174 | struct s3c_iotimings *timings); | ||
| 175 | |||
| 176 | void (*set_iotiming)(struct s3c_cpufreq_config *cfg, | ||
| 177 | struct s3c_iotimings *timings); | ||
| 178 | |||
| 179 | int (*calc_iotiming)(struct s3c_cpufreq_config *cfg, | ||
| 180 | struct s3c_iotimings *timings); | ||
| 181 | |||
| 182 | int (*calc_freqtable)(struct s3c_cpufreq_config *cfg, | ||
| 183 | struct cpufreq_frequency_table *t, | ||
| 184 | size_t table_size); | ||
| 185 | |||
| 186 | void (*debug_io_show)(struct seq_file *seq, | ||
| 187 | struct s3c_cpufreq_config *cfg, | ||
| 188 | union s3c_iobank *iob); | ||
| 189 | |||
| 190 | void (*set_refresh)(struct s3c_cpufreq_config *cfg); | ||
| 191 | void (*set_fvco)(struct s3c_cpufreq_config *cfg); | ||
| 192 | void (*set_divs)(struct s3c_cpufreq_config *cfg); | ||
| 193 | int (*calc_divs)(struct s3c_cpufreq_config *cfg); | ||
| 194 | }; | ||
| 195 | |||
| 196 | extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info); | ||
| 197 | |||
| 198 | extern int s3c_plltab_register(struct cpufreq_frequency_table *plls, unsigned int plls_no); | ||
| 199 | |||
| 200 | /* exports and utilities for debugfs */ | ||
| 201 | extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void); | ||
| 202 | extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void); | ||
| 203 | |||
| 204 | extern void s3c2410_iotiming_debugfs(struct seq_file *seq, | ||
| 205 | struct s3c_cpufreq_config *cfg, | ||
| 206 | union s3c_iobank *iob); | ||
| 207 | |||
| 208 | extern void s3c2412_iotiming_debugfs(struct seq_file *seq, | ||
| 209 | struct s3c_cpufreq_config *cfg, | ||
| 210 | union s3c_iobank *iob); | ||
| 211 | |||
| 212 | #ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS | ||
| 213 | #define s3c_cpufreq_debugfs_call(x) x | ||
| 214 | #else | ||
| 215 | #define s3c_cpufreq_debugfs_call(x) NULL | ||
| 216 | #endif | ||
| 217 | |||
| 218 | /* Useful utility functions. */ | ||
| 219 | |||
| 220 | extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *); | ||
| 221 | |||
| 222 | /* S3C2410 and compatible exported functions */ | ||
| 223 | |||
| 224 | extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg); | ||
| 225 | |||
| 226 | extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg, | ||
| 227 | struct s3c_iotimings *iot); | ||
| 228 | |||
| 229 | extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg, | ||
| 230 | struct s3c_iotimings *timings); | ||
| 231 | |||
| 232 | extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg, | ||
| 233 | struct s3c_iotimings *iot); | ||
| 234 | |||
| 235 | extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg); | ||
| 236 | |||
| 237 | /* S3C2412 compatible routines */ | ||
| 238 | |||
| 239 | extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg, | ||
| 240 | struct s3c_iotimings *timings); | ||
| 241 | |||
| 242 | extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg, | ||
| 243 | struct s3c_iotimings *timings); | ||
| 244 | |||
| 245 | extern int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg, | ||
| 246 | struct s3c_iotimings *iot); | ||
| 247 | |||
| 248 | extern void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg, | ||
| 249 | struct s3c_iotimings *iot); | ||
| 250 | |||
| 251 | #ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUG | ||
| 252 | #define s3c_freq_dbg(x...) printk(KERN_INFO x) | ||
| 253 | #else | ||
| 254 | #define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0) | ||
| 255 | #endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUG */ | ||
| 256 | |||
| 257 | #ifdef CONFIG_CPU_FREQ_S3C24XX_IODEBUG | ||
| 258 | #define s3c_freq_iodbg(x...) printk(KERN_INFO x) | ||
| 259 | #else | ||
| 260 | #define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0) | ||
| 261 | #endif /* CONFIG_CPU_FREQ_S3C24XX_IODEBUG */ | ||
| 262 | |||
| 263 | static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table, | ||
| 264 | int index, size_t table_size, | ||
| 265 | unsigned int freq) | ||
| 266 | { | ||
| 267 | if (index < 0) | ||
| 268 | return index; | ||
| 269 | |||
| 270 | if (table) { | ||
| 271 | if (index >= table_size) | ||
| 272 | return -ENOMEM; | ||
| 273 | |||
| 274 | s3c_freq_dbg("%s: { %d = %u kHz }\n", | ||
| 275 | __func__, index, freq); | ||
| 276 | |||
| 277 | table[index].index = index; | ||
| 278 | table[index].frequency = freq; | ||
| 279 | } | ||
| 280 | |||
| 281 | return index + 1; | ||
| 282 | } | ||
diff --git a/arch/arm/plat-s3c24xx/include/plat/fiq.h b/arch/arm/plat-s3c24xx/include/plat/fiq.h new file mode 100644 index 000000000000..8521b8372c5f --- /dev/null +++ b/arch/arm/plat-s3c24xx/include/plat/fiq.h | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | /* linux/include/asm-arm/plat-s3c24xx/fiq.h | ||
| 2 | * | ||
| 3 | * Copyright (c) 2009 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * | ||
| 6 | * Header file for S3C24XX CPU FIQ support | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | extern int s3c24xx_set_fiq(unsigned int irq, bool on); | ||
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h index a9ac9e29759e..b6deeef8f663 100644 --- a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h +++ b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #ifdef CONFIG_CPU_S3C2410 | 14 | #ifdef CONFIG_CPU_S3C2410 |
| 15 | 15 | ||
| 16 | extern int s3c2410_init(void); | 16 | extern int s3c2410_init(void); |
| 17 | extern int s3c2410a_init(void); | ||
| 17 | 18 | ||
| 18 | extern void s3c2410_map_io(void); | 19 | extern void s3c2410_map_io(void); |
| 19 | 20 | ||
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c index 958737775ad2..d02f5f02045e 100644 --- a/arch/arm/plat-s3c24xx/irq.c +++ b/arch/arm/plat-s3c24xx/irq.c | |||
| @@ -493,6 +493,38 @@ s3c_irq_demux_extint4t7(unsigned int irq, | |||
| 493 | } | 493 | } |
| 494 | } | 494 | } |
| 495 | 495 | ||
| 496 | #ifdef CONFIG_FIQ | ||
| 497 | /** | ||
| 498 | * s3c24xx_set_fiq - set the FIQ routing | ||
| 499 | * @irq: IRQ number to route to FIQ on processor. | ||
| 500 | * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing. | ||
| 501 | * | ||
| 502 | * Change the state of the IRQ to FIQ routing depending on @irq and @on. If | ||
| 503 | * @on is true, the @irq is checked to see if it can be routed and the | ||
| 504 | * interrupt controller updated to route the IRQ. If @on is false, the FIQ | ||
| 505 | * routing is cleared, regardless of which @irq is specified. | ||
| 506 | */ | ||
| 507 | int s3c24xx_set_fiq(unsigned int irq, bool on) | ||
| 508 | { | ||
| 509 | u32 intmod; | ||
| 510 | unsigned offs; | ||
| 511 | |||
| 512 | if (on) { | ||
| 513 | offs = irq - FIQ_START; | ||
| 514 | if (offs > 31) | ||
| 515 | return -EINVAL; | ||
| 516 | |||
| 517 | intmod = 1 << offs; | ||
| 518 | } else { | ||
| 519 | intmod = 0; | ||
| 520 | } | ||
| 521 | |||
| 522 | __raw_writel(intmod, S3C2410_INTMOD); | ||
| 523 | return 0; | ||
| 524 | } | ||
| 525 | #endif | ||
| 526 | |||
| 527 | |||
| 496 | /* s3c24xx_init_irq | 528 | /* s3c24xx_init_irq |
| 497 | * | 529 | * |
| 498 | * Initialise S3C2410 IRQ system | 530 | * Initialise S3C2410 IRQ system |
| @@ -505,6 +537,10 @@ void __init s3c24xx_init_irq(void) | |||
| 505 | int irqno; | 537 | int irqno; |
| 506 | int i; | 538 | int i; |
| 507 | 539 | ||
| 540 | #ifdef CONFIG_FIQ | ||
| 541 | init_FIQ(); | ||
| 542 | #endif | ||
| 543 | |||
| 508 | irqdbf("s3c2410_init_irq: clearing interrupt status flags\n"); | 544 | irqdbf("s3c2410_init_irq: clearing interrupt status flags\n"); |
| 509 | 545 | ||
| 510 | /* first, clear all interrupts pending... */ | 546 | /* first, clear all interrupts pending... */ |
diff --git a/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c b/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c new file mode 100644 index 000000000000..43ea80190d87 --- /dev/null +++ b/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2009 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * | ||
| 7 | * S3C24XX CPU Frequency scaling - utils for S3C2410/S3C2440/S3C2442 | ||
| 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 | #include <linux/kernel.h> | ||
| 15 | #include <linux/errno.h> | ||
| 16 | #include <linux/cpufreq.h> | ||
| 17 | #include <linux/io.h> | ||
| 18 | |||
| 19 | #include <mach/map.h> | ||
| 20 | #include <mach/regs-mem.h> | ||
| 21 | #include <mach/regs-clock.h> | ||
| 22 | |||
| 23 | #include <plat/cpu-freq-core.h> | ||
| 24 | |||
| 25 | /** | ||
| 26 | * s3c2410_cpufreq_setrefresh - set SDRAM refresh value | ||
| 27 | * @cfg: The frequency configuration | ||
| 28 | * | ||
| 29 | * Set the SDRAM refresh value appropriately for the configured | ||
| 30 | * frequency. | ||
| 31 | */ | ||
| 32 | void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg) | ||
| 33 | { | ||
| 34 | struct s3c_cpufreq_board *board = cfg->board; | ||
| 35 | unsigned long refresh; | ||
| 36 | unsigned long refval; | ||
| 37 | |||
| 38 | /* Reduce both the refresh time (in ns) and the frequency (in MHz) | ||
| 39 | * down to ensure that we do not overflow 32 bit numbers. | ||
| 40 | * | ||
| 41 | * This should work for HCLK up to 133MHz and refresh period up | ||
| 42 | * to 30usec. | ||
| 43 | */ | ||
| 44 | |||
| 45 | refresh = (cfg->freq.hclk / 100) * (board->refresh / 10); | ||
| 46 | refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale */ | ||
| 47 | refresh = (1 << 11) + 1 - refresh; | ||
| 48 | |||
| 49 | s3c_freq_dbg("%s: refresh value %lu\n", __func__, refresh); | ||
| 50 | |||
| 51 | refval = __raw_readl(S3C2410_REFRESH); | ||
| 52 | refval &= ~((1 << 12) - 1); | ||
| 53 | refval |= refresh; | ||
| 54 | __raw_writel(refval, S3C2410_REFRESH); | ||
| 55 | } | ||
| 56 | |||
| 57 | /** | ||
| 58 | * s3c2410_set_fvco - set the PLL value | ||
| 59 | * @cfg: The frequency configuration | ||
| 60 | */ | ||
| 61 | void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg) | ||
| 62 | { | ||
| 63 | __raw_writel(cfg->pll.index, S3C2410_MPLLCON); | ||
| 64 | } | ||
diff --git a/arch/arm/plat-s3c24xx/s3c2410-iotiming.c b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c new file mode 100644 index 000000000000..d0a3a145cd4d --- /dev/null +++ b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c | |||
| @@ -0,0 +1,477 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c24xx/s3c2410-iotiming.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2006,2008,2009 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * | ||
| 7 | * S3C24XX CPU Frequency scaling - IO timing for S3C2410/S3C2440/S3C2442 | ||
| 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 | #include <linux/init.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/errno.h> | ||
| 17 | #include <linux/cpufreq.h> | ||
| 18 | #include <linux/seq_file.h> | ||
| 19 | #include <linux/io.h> | ||
| 20 | |||
| 21 | #include <mach/map.h> | ||
| 22 | #include <mach/regs-mem.h> | ||
| 23 | #include <mach/regs-clock.h> | ||
| 24 | |||
| 25 | #include <plat/cpu-freq-core.h> | ||
| 26 | |||
| 27 | #define print_ns(x) ((x) / 10), ((x) % 10) | ||
| 28 | |||
| 29 | /** | ||
| 30 | * s3c2410_print_timing - print bank timing data for debug purposes | ||
| 31 | * @pfx: The prefix to put on the output | ||
| 32 | * @timings: The timing inforamtion to print. | ||
| 33 | */ | ||
| 34 | static void s3c2410_print_timing(const char *pfx, | ||
| 35 | struct s3c_iotimings *timings) | ||
| 36 | { | ||
| 37 | struct s3c2410_iobank_timing *bt; | ||
| 38 | int bank; | ||
| 39 | |||
| 40 | for (bank = 0; bank < MAX_BANKS; bank++) { | ||
| 41 | bt = timings->bank[bank].io_2410; | ||
| 42 | if (!bt) | ||
| 43 | continue; | ||
| 44 | |||
| 45 | printk(KERN_DEBUG "%s %d: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, " | ||
| 46 | "Tcoh=%d.%d, Tcah=%d.%d\n", pfx, bank, | ||
| 47 | print_ns(bt->tacs), | ||
| 48 | print_ns(bt->tcos), | ||
| 49 | print_ns(bt->tacc), | ||
| 50 | print_ns(bt->tcoh), | ||
| 51 | print_ns(bt->tcah)); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | /** | ||
| 56 | * bank_reg - convert bank number to pointer to the control register. | ||
| 57 | * @bank: The IO bank number. | ||
| 58 | */ | ||
| 59 | static inline void __iomem *bank_reg(unsigned int bank) | ||
| 60 | { | ||
| 61 | return S3C2410_BANKCON0 + (bank << 2); | ||
| 62 | } | ||
| 63 | |||
| 64 | /** | ||
| 65 | * bank_is_io - test whether bank is used for IO | ||
| 66 | * @bankcon: The bank control register. | ||
| 67 | * | ||
| 68 | * This is a simplistic test to see if any BANKCON[x] is not an IO | ||
| 69 | * bank. It currently does not take into account whether BWSCON has | ||
| 70 | * an illegal width-setting in it, or if the pin connected to nCS[x] | ||
| 71 | * is actually being handled as a chip-select. | ||
| 72 | */ | ||
| 73 | static inline int bank_is_io(unsigned long bankcon) | ||
| 74 | { | ||
| 75 | return !(bankcon & S3C2410_BANKCON_SDRAM); | ||
| 76 | } | ||
| 77 | |||
| 78 | /** | ||
| 79 | * to_div - convert cycle time to divisor | ||
| 80 | * @cyc: The cycle time, in 10ths of nanoseconds. | ||
| 81 | * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds. | ||
| 82 | * | ||
| 83 | * Convert the given cycle time into the divisor to use to obtain it from | ||
| 84 | * HCLK. | ||
| 85 | */ | ||
| 86 | static inline unsigned int to_div(unsigned int cyc, unsigned int hclk_tns) | ||
| 87 | { | ||
| 88 | if (cyc == 0) | ||
| 89 | return 0; | ||
| 90 | |||
| 91 | return DIV_ROUND_UP(cyc, hclk_tns); | ||
| 92 | } | ||
| 93 | |||
| 94 | /** | ||
| 95 | * calc_0124 - calculate divisor control for divisors that do /0, /1. /2 and /4 | ||
| 96 | * @cyc: The cycle time, in 10ths of nanoseconds. | ||
| 97 | * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds. | ||
| 98 | * @v: Pointer to register to alter. | ||
| 99 | * @shift: The shift to get to the control bits. | ||
| 100 | * | ||
| 101 | * Calculate the divisor, and turn it into the correct control bits to | ||
| 102 | * set in the result, @v. | ||
| 103 | */ | ||
| 104 | static unsigned int calc_0124(unsigned int cyc, unsigned long hclk_tns, | ||
| 105 | unsigned long *v, int shift) | ||
| 106 | { | ||
| 107 | unsigned int div = to_div(cyc, hclk_tns); | ||
| 108 | unsigned long val; | ||
| 109 | |||
| 110 | s3c_freq_iodbg("%s: cyc=%d, hclk=%lu, shift=%d => div %d\n", | ||
| 111 | __func__, cyc, hclk_tns, shift, div); | ||
| 112 | |||
| 113 | switch (div) { | ||
| 114 | case 0: | ||
| 115 | val = 0; | ||
| 116 | break; | ||
| 117 | case 1: | ||
| 118 | val = 1; | ||
| 119 | break; | ||
| 120 | case 2: | ||
| 121 | val = 2; | ||
| 122 | break; | ||
| 123 | case 3: | ||
| 124 | case 4: | ||
| 125 | val = 3; | ||
| 126 | break; | ||
| 127 | default: | ||
| 128 | return -1; | ||
| 129 | } | ||
| 130 | |||
| 131 | *v |= val << shift; | ||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | int calc_tacp(unsigned int cyc, unsigned long hclk, unsigned long *v) | ||
| 136 | { | ||
| 137 | /* Currently no support for Tacp calculations. */ | ||
| 138 | return 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | /** | ||
| 142 | * calc_tacc - calculate divisor control for tacc. | ||
| 143 | * @cyc: The cycle time, in 10ths of nanoseconds. | ||
| 144 | * @nwait_en: IS nWAIT enabled for this bank. | ||
| 145 | * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds. | ||
| 146 | * @v: Pointer to register to alter. | ||
| 147 | * | ||
| 148 | * Calculate the divisor control for tACC, taking into account whether | ||
| 149 | * the bank has nWAIT enabled. The result is used to modify the value | ||
| 150 | * pointed to by @v. | ||
| 151 | */ | ||
| 152 | static int calc_tacc(unsigned int cyc, int nwait_en, | ||
| 153 | unsigned long hclk_tns, unsigned long *v) | ||
| 154 | { | ||
| 155 | unsigned int div = to_div(cyc, hclk_tns); | ||
| 156 | unsigned long val; | ||
| 157 | |||
| 158 | s3c_freq_iodbg("%s: cyc=%u, nwait=%d, hclk=%lu => div=%u\n", | ||
| 159 | __func__, cyc, nwait_en, hclk_tns, div); | ||
| 160 | |||
| 161 | /* if nWait enabled on an bank, Tacc must be at-least 4 cycles. */ | ||
| 162 | if (nwait_en && div < 4) | ||
| 163 | div = 4; | ||
| 164 | |||
| 165 | switch (div) { | ||
| 166 | case 0: | ||
| 167 | val = 0; | ||
| 168 | break; | ||
| 169 | |||
| 170 | case 1: | ||
| 171 | case 2: | ||
| 172 | case 3: | ||
| 173 | case 4: | ||
| 174 | val = div - 1; | ||
| 175 | break; | ||
| 176 | |||
| 177 | case 5: | ||
| 178 | case 6: | ||
| 179 | val = 4; | ||
| 180 | break; | ||
| 181 | |||
| 182 | case 7: | ||
| 183 | case 8: | ||
| 184 | val = 5; | ||
| 185 | break; | ||
| 186 | |||
| 187 | case 9: | ||
| 188 | case 10: | ||
| 189 | val = 6; | ||
| 190 | break; | ||
| 191 | |||
| 192 | case 11: | ||
| 193 | case 12: | ||
| 194 | case 13: | ||
| 195 | case 14: | ||
| 196 | val = 7; | ||
| 197 | break; | ||
| 198 | |||
| 199 | default: | ||
| 200 | return -1; | ||
| 201 | } | ||
| 202 | |||
| 203 | *v |= val << 8; | ||
| 204 | return 0; | ||
| 205 | } | ||
| 206 | |||
| 207 | /** | ||
| 208 | * s3c2410_calc_bank - calculate bank timing infromation | ||
| 209 | * @cfg: The configuration we need to calculate for. | ||
| 210 | * @bt: The bank timing information. | ||
| 211 | * | ||
| 212 | * Given the cycle timine for a bank @bt, calculate the new BANKCON | ||
| 213 | * setting for the @cfg timing. This updates the timing information | ||
| 214 | * ready for the cpu frequency change. | ||
| 215 | */ | ||
| 216 | static int s3c2410_calc_bank(struct s3c_cpufreq_config *cfg, | ||
| 217 | struct s3c2410_iobank_timing *bt) | ||
| 218 | { | ||
| 219 | unsigned long hclk = cfg->freq.hclk_tns; | ||
| 220 | unsigned long res; | ||
| 221 | int ret; | ||
| 222 | |||
| 223 | res = bt->bankcon; | ||
| 224 | res &= (S3C2410_BANKCON_SDRAM | S3C2410_BANKCON_PMC16); | ||
| 225 | |||
| 226 | /* tacp: 2,3,4,5 */ | ||
| 227 | /* tcah: 0,1,2,4 */ | ||
| 228 | /* tcoh: 0,1,2,4 */ | ||
| 229 | /* tacc: 1,2,3,4,6,7,10,14 (>4 for nwait) */ | ||
| 230 | /* tcos: 0,1,2,4 */ | ||
| 231 | /* tacs: 0,1,2,4 */ | ||
| 232 | |||
| 233 | ret = calc_0124(bt->tacs, hclk, &res, S3C2410_BANKCON_Tacs_SHIFT); | ||
| 234 | ret |= calc_0124(bt->tcos, hclk, &res, S3C2410_BANKCON_Tcos_SHIFT); | ||
| 235 | ret |= calc_0124(bt->tcah, hclk, &res, S3C2410_BANKCON_Tcah_SHIFT); | ||
| 236 | ret |= calc_0124(bt->tcoh, hclk, &res, S3C2410_BANKCON_Tcoh_SHIFT); | ||
| 237 | |||
| 238 | if (ret) | ||
| 239 | return -EINVAL; | ||
| 240 | |||
| 241 | ret |= calc_tacp(bt->tacp, hclk, &res); | ||
| 242 | ret |= calc_tacc(bt->tacc, bt->nwait_en, hclk, &res); | ||
| 243 | |||
| 244 | if (ret) | ||
| 245 | return -EINVAL; | ||
| 246 | |||
| 247 | bt->bankcon = res; | ||
| 248 | return 0; | ||
| 249 | } | ||
| 250 | |||
| 251 | static unsigned int tacc_tab[] = { | ||
| 252 | [0] = 1, | ||
| 253 | [1] = 2, | ||
| 254 | [2] = 3, | ||
| 255 | [3] = 4, | ||
| 256 | [4] = 6, | ||
| 257 | [5] = 9, | ||
| 258 | [6] = 10, | ||
| 259 | [7] = 14, | ||
| 260 | }; | ||
| 261 | |||
| 262 | /** | ||
| 263 | * get_tacc - turn tACC value into cycle time | ||
| 264 | * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds. | ||
| 265 | * @val: The bank timing register value, shifed down. | ||
| 266 | */ | ||
| 267 | static unsigned int get_tacc(unsigned long hclk_tns, | ||
| 268 | unsigned long val) | ||
| 269 | { | ||
| 270 | val &= 7; | ||
| 271 | return hclk_tns * tacc_tab[val]; | ||
| 272 | } | ||
| 273 | |||
| 274 | /** | ||
| 275 | * get_0124 - turn 0/1/2/4 divider into cycle time | ||
| 276 | * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds. | ||
| 277 | * @val: The bank timing register value, shifed down. | ||
| 278 | */ | ||
| 279 | static unsigned int get_0124(unsigned long hclk_tns, | ||
| 280 | unsigned long val) | ||
| 281 | { | ||
| 282 | val &= 3; | ||
| 283 | return hclk_tns * ((val == 3) ? 4 : val); | ||
| 284 | } | ||
| 285 | |||
| 286 | /** | ||
| 287 | * s3c2410_iotiming_getbank - turn BANKCON into cycle time information | ||
| 288 | * @cfg: The frequency configuration | ||
| 289 | * @bt: The bank timing to fill in (uses cached BANKCON) | ||
| 290 | * | ||
| 291 | * Given the BANKCON setting in @bt and the current frequency settings | ||
| 292 | * in @cfg, update the cycle timing information. | ||
| 293 | */ | ||
| 294 | void s3c2410_iotiming_getbank(struct s3c_cpufreq_config *cfg, | ||
| 295 | struct s3c2410_iobank_timing *bt) | ||
| 296 | { | ||
| 297 | unsigned long bankcon = bt->bankcon; | ||
| 298 | unsigned long hclk = cfg->freq.hclk_tns; | ||
| 299 | |||
| 300 | bt->tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT); | ||
| 301 | bt->tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT); | ||
| 302 | bt->tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT); | ||
| 303 | bt->tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT); | ||
| 304 | bt->tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT); | ||
| 305 | } | ||
| 306 | |||
| 307 | /** | ||
| 308 | * s3c2410_iotiming_debugfs - debugfs show io bank timing information | ||
| 309 | * @seq: The seq_file to write output to using seq_printf(). | ||
| 310 | * @cfg: The current configuration. | ||
| 311 | * @iob: The IO bank information to decode. | ||
| 312 | */ | ||
| 313 | void s3c2410_iotiming_debugfs(struct seq_file *seq, | ||
| 314 | struct s3c_cpufreq_config *cfg, | ||
| 315 | union s3c_iobank *iob) | ||
| 316 | { | ||
| 317 | struct s3c2410_iobank_timing *bt = iob->io_2410; | ||
| 318 | unsigned long bankcon = bt->bankcon; | ||
| 319 | unsigned long hclk = cfg->freq.hclk_tns; | ||
| 320 | unsigned int tacs; | ||
| 321 | unsigned int tcos; | ||
| 322 | unsigned int tacc; | ||
| 323 | unsigned int tcoh; | ||
| 324 | unsigned int tcah; | ||
| 325 | |||
| 326 | seq_printf(seq, "BANKCON=0x%08lx\n", bankcon); | ||
| 327 | |||
| 328 | tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT); | ||
| 329 | tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT); | ||
| 330 | tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT); | ||
| 331 | tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT); | ||
| 332 | tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT); | ||
| 333 | |||
| 334 | seq_printf(seq, | ||
| 335 | "\tRead: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n", | ||
| 336 | print_ns(bt->tacs), | ||
| 337 | print_ns(bt->tcos), | ||
| 338 | print_ns(bt->tacc), | ||
| 339 | print_ns(bt->tcoh), | ||
| 340 | print_ns(bt->tcah)); | ||
| 341 | |||
| 342 | seq_printf(seq, | ||
| 343 | "\t Set: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n", | ||
| 344 | print_ns(tacs), | ||
| 345 | print_ns(tcos), | ||
| 346 | print_ns(tacc), | ||
| 347 | print_ns(tcoh), | ||
| 348 | print_ns(tcah)); | ||
| 349 | } | ||
| 350 | |||
| 351 | /** | ||
| 352 | * s3c2410_iotiming_calc - Calculate bank timing for frequency change. | ||
| 353 | * @cfg: The frequency configuration | ||
| 354 | * @iot: The IO timing information to fill out. | ||
| 355 | * | ||
| 356 | * Calculate the new values for the banks in @iot based on the new | ||
| 357 | * frequency information in @cfg. This is then used by s3c2410_iotiming_set() | ||
| 358 | * to update the timing when necessary. | ||
| 359 | */ | ||
| 360 | int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg, | ||
| 361 | struct s3c_iotimings *iot) | ||
| 362 | { | ||
| 363 | struct s3c2410_iobank_timing *bt; | ||
| 364 | unsigned long bankcon; | ||
| 365 | int bank; | ||
| 366 | int ret; | ||
| 367 | |||
| 368 | for (bank = 0; bank < MAX_BANKS; bank++) { | ||
| 369 | bankcon = __raw_readl(bank_reg(bank)); | ||
| 370 | bt = iot->bank[bank].io_2410; | ||
| 371 | |||
| 372 | if (!bt) | ||
| 373 | continue; | ||
| 374 | |||
| 375 | bt->bankcon = bankcon; | ||
| 376 | |||
| 377 | ret = s3c2410_calc_bank(cfg, bt); | ||
| 378 | if (ret) { | ||
| 379 | printk(KERN_ERR "%s: cannot calculate bank %d io\n", | ||
| 380 | __func__, bank); | ||
| 381 | goto err; | ||
| 382 | } | ||
| 383 | |||
| 384 | s3c_freq_iodbg("%s: bank %d: con=%08lx\n", | ||
| 385 | __func__, bank, bt->bankcon); | ||
| 386 | } | ||
| 387 | |||
| 388 | return 0; | ||
| 389 | err: | ||
| 390 | return ret; | ||
| 391 | } | ||
| 392 | |||
| 393 | /** | ||
| 394 | * s3c2410_iotiming_set - set the IO timings from the given setup. | ||
| 395 | * @cfg: The frequency configuration | ||
| 396 | * @iot: The IO timing information to use. | ||
| 397 | * | ||
| 398 | * Set all the currently used IO bank timing information generated | ||
| 399 | * by s3c2410_iotiming_calc() once the core has validated that all | ||
| 400 | * the new values are within permitted bounds. | ||
| 401 | */ | ||
| 402 | void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg, | ||
| 403 | struct s3c_iotimings *iot) | ||
| 404 | { | ||
| 405 | struct s3c2410_iobank_timing *bt; | ||
| 406 | int bank; | ||
| 407 | |||
| 408 | /* set the io timings from the specifier */ | ||
| 409 | |||
| 410 | for (bank = 0; bank < MAX_BANKS; bank++) { | ||
| 411 | bt = iot->bank[bank].io_2410; | ||
| 412 | if (!bt) | ||
| 413 | continue; | ||
| 414 | |||
| 415 | __raw_writel(bt->bankcon, bank_reg(bank)); | ||
| 416 | } | ||
| 417 | } | ||
| 418 | |||
| 419 | /** | ||
| 420 | * s3c2410_iotiming_get - Get the timing information from current registers. | ||
| 421 | * @cfg: The frequency configuration | ||
| 422 | * @timings: The IO timing information to fill out. | ||
| 423 | * | ||
| 424 | * Calculate the @timings timing information from the current frequency | ||
| 425 | * information in @cfg, and the new frequency configur | ||
| 426 | * through all the IO banks, reading the state and then updating @iot | ||
| 427 | * as necessary. | ||
| 428 | * | ||
| 429 | * This is used at the moment on initialisation to get the current | ||
| 430 | * configuration so that boards do not have to carry their own setup | ||
| 431 | * if the timings are correct on initialisation. | ||
| 432 | */ | ||
| 433 | |||
| 434 | int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg, | ||
| 435 | struct s3c_iotimings *timings) | ||
| 436 | { | ||
| 437 | struct s3c2410_iobank_timing *bt; | ||
| 438 | unsigned long bankcon; | ||
| 439 | unsigned long bwscon; | ||
| 440 | int bank; | ||
| 441 | |||
| 442 | bwscon = __raw_readl(S3C2410_BWSCON); | ||
| 443 | |||
| 444 | /* look through all banks to see what is currently set. */ | ||
| 445 | |||
| 446 | for (bank = 0; bank < MAX_BANKS; bank++) { | ||
| 447 | bankcon = __raw_readl(bank_reg(bank)); | ||
| 448 | |||
| 449 | if (!bank_is_io(bankcon)) | ||
| 450 | continue; | ||
| 451 | |||
| 452 | s3c_freq_iodbg("%s: bank %d: con %08lx\n", | ||
| 453 | __func__, bank, bankcon); | ||
| 454 | |||
| 455 | bt = kzalloc(sizeof(struct s3c2410_iobank_timing), GFP_KERNEL); | ||
| 456 | if (!bt) { | ||
| 457 | printk(KERN_ERR "%s: no memory for bank\n", __func__); | ||
| 458 | return -ENOMEM; | ||
| 459 | } | ||
| 460 | |||
| 461 | /* find out in nWait is enabled for bank. */ | ||
| 462 | |||
| 463 | if (bank != 0) { | ||
| 464 | unsigned long tmp = S3C2410_BWSCON_GET(bwscon, bank); | ||
| 465 | if (tmp & S3C2410_BWSCON_WS) | ||
| 466 | bt->nwait_en = 1; | ||
| 467 | } | ||
| 468 | |||
| 469 | timings->bank[bank].io_2410 = bt; | ||
| 470 | bt->bankcon = bankcon; | ||
| 471 | |||
| 472 | s3c2410_iotiming_getbank(cfg, bt); | ||
| 473 | } | ||
| 474 | |||
| 475 | s3c2410_print_timing("get", timings); | ||
| 476 | return 0; | ||
| 477 | } | ||
diff --git a/arch/arm/plat-s3c24xx/s3c2412-iotiming.c b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c new file mode 100644 index 000000000000..fd45e47facbc --- /dev/null +++ b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c | |||
| @@ -0,0 +1,285 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c24xx/s3c2412-iotiming.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2006,2008 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * | ||
| 7 | * S3C2412/S3C2443 (PL093 based) IO timing support | ||
| 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 | #include <linux/init.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/ioport.h> | ||
| 18 | #include <linux/cpufreq.h> | ||
| 19 | #include <linux/seq_file.h> | ||
| 20 | #include <linux/sysdev.h> | ||
| 21 | #include <linux/delay.h> | ||
| 22 | #include <linux/clk.h> | ||
| 23 | #include <linux/err.h> | ||
| 24 | |||
| 25 | #include <linux/amba/pl093.h> | ||
| 26 | |||
| 27 | #include <asm/mach/arch.h> | ||
| 28 | #include <asm/mach/map.h> | ||
| 29 | |||
| 30 | #include <mach/regs-s3c2412-mem.h> | ||
| 31 | |||
| 32 | #include <plat/cpu.h> | ||
| 33 | #include <plat/cpu-freq-core.h> | ||
| 34 | #include <plat/clock.h> | ||
| 35 | |||
| 36 | #define print_ns(x) ((x) / 10), ((x) % 10) | ||
| 37 | |||
| 38 | /** | ||
| 39 | * s3c2412_print_timing - print timing infromation via printk. | ||
| 40 | * @pfx: The prefix to print each line with. | ||
| 41 | * @iot: The IO timing information | ||
| 42 | */ | ||
| 43 | static void s3c2412_print_timing(const char *pfx, struct s3c_iotimings *iot) | ||
| 44 | { | ||
| 45 | struct s3c2412_iobank_timing *bt; | ||
| 46 | unsigned int bank; | ||
| 47 | |||
| 48 | for (bank = 0; bank < MAX_BANKS; bank++) { | ||
| 49 | bt = iot->bank[bank].io_2412; | ||
| 50 | if (!bt) | ||
| 51 | continue; | ||
| 52 | |||
| 53 | printk(KERN_DEBUG "%s: %d: idcy=%d.%d wstrd=%d.%d wstwr=%d,%d" | ||
| 54 | "wstoen=%d.%d wstwen=%d.%d wstbrd=%d.%d\n", pfx, bank, | ||
| 55 | print_ns(bt->idcy), | ||
| 56 | print_ns(bt->wstrd), | ||
| 57 | print_ns(bt->wstwr), | ||
| 58 | print_ns(bt->wstoen), | ||
| 59 | print_ns(bt->wstwen), | ||
| 60 | print_ns(bt->wstbrd)); | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | /** | ||
| 65 | * to_div - turn a cycle length into a divisor setting. | ||
| 66 | * @cyc_tns: The cycle time in 10ths of nanoseconds. | ||
| 67 | * @clk_tns: The clock period in 10ths of nanoseconds. | ||
| 68 | */ | ||
| 69 | static inline unsigned int to_div(unsigned int cyc_tns, unsigned int clk_tns) | ||
| 70 | { | ||
| 71 | return cyc_tns ? DIV_ROUND_UP(cyc_tns, clk_tns) : 0; | ||
| 72 | } | ||
| 73 | |||
| 74 | /** | ||
| 75 | * calc_timing - calculate timing divisor value and check in range. | ||
| 76 | * @hwtm: The hardware timing in 10ths of nanoseconds. | ||
| 77 | * @clk_tns: The clock period in 10ths of nanoseconds. | ||
| 78 | * @err: Pointer to err variable to update in event of failure. | ||
| 79 | */ | ||
| 80 | static unsigned int calc_timing(unsigned int hwtm, unsigned int clk_tns, | ||
| 81 | unsigned int *err) | ||
| 82 | { | ||
| 83 | unsigned int ret = to_div(hwtm, clk_tns); | ||
| 84 | |||
| 85 | if (ret > 0xf) | ||
| 86 | *err = -EINVAL; | ||
| 87 | |||
| 88 | return ret; | ||
| 89 | } | ||
| 90 | |||
| 91 | /** | ||
| 92 | * s3c2412_calc_bank - calculate the bank divisor settings. | ||
| 93 | * @cfg: The current frequency configuration. | ||
| 94 | * @bt: The bank timing. | ||
| 95 | */ | ||
| 96 | static int s3c2412_calc_bank(struct s3c_cpufreq_config *cfg, | ||
| 97 | struct s3c2412_iobank_timing *bt) | ||
| 98 | { | ||
| 99 | unsigned int hclk = cfg->freq.hclk_tns; | ||
| 100 | int err = 0; | ||
| 101 | |||
| 102 | bt->smbidcyr = calc_timing(bt->idcy, hclk, &err); | ||
| 103 | bt->smbwstrd = calc_timing(bt->wstrd, hclk, &err); | ||
| 104 | bt->smbwstwr = calc_timing(bt->wstwr, hclk, &err); | ||
| 105 | bt->smbwstoen = calc_timing(bt->wstoen, hclk, &err); | ||
| 106 | bt->smbwstwen = calc_timing(bt->wstwen, hclk, &err); | ||
| 107 | bt->smbwstbrd = calc_timing(bt->wstbrd, hclk, &err); | ||
| 108 | |||
| 109 | return err; | ||
| 110 | } | ||
| 111 | |||
| 112 | /** | ||
| 113 | * s3c2412_iotiming_debugfs - debugfs show io bank timing information | ||
| 114 | * @seq: The seq_file to write output to using seq_printf(). | ||
| 115 | * @cfg: The current configuration. | ||
| 116 | * @iob: The IO bank information to decode. | ||
| 117 | */ | ||
| 118 | void s3c2412_iotiming_debugfs(struct seq_file *seq, | ||
| 119 | struct s3c_cpufreq_config *cfg, | ||
| 120 | union s3c_iobank *iob) | ||
| 121 | { | ||
| 122 | struct s3c2412_iobank_timing *bt = iob->io_2412; | ||
| 123 | |||
| 124 | seq_printf(seq, | ||
| 125 | "\tRead: idcy=%d.%d wstrd=%d.%d wstwr=%d,%d" | ||
| 126 | "wstoen=%d.%d wstwen=%d.%d wstbrd=%d.%d\n", | ||
| 127 | print_ns(bt->idcy), | ||
| 128 | print_ns(bt->wstrd), | ||
| 129 | print_ns(bt->wstwr), | ||
| 130 | print_ns(bt->wstoen), | ||
| 131 | print_ns(bt->wstwen), | ||
| 132 | print_ns(bt->wstbrd)); | ||
| 133 | } | ||
| 134 | |||
| 135 | /** | ||
| 136 | * s3c2412_iotiming_calc - calculate all the bank divisor settings. | ||
| 137 | * @cfg: The current frequency configuration. | ||
| 138 | * @iot: The bank timing information. | ||
| 139 | * | ||
| 140 | * Calculate the timing information for all the banks that are | ||
| 141 | * configured as IO, using s3c2412_calc_bank(). | ||
| 142 | */ | ||
| 143 | int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg, | ||
| 144 | struct s3c_iotimings *iot) | ||
| 145 | { | ||
| 146 | struct s3c2412_iobank_timing *bt; | ||
| 147 | int bank; | ||
| 148 | int ret; | ||
| 149 | |||
| 150 | for (bank = 0; bank < MAX_BANKS; bank++) { | ||
| 151 | bt = iot->bank[bank].io_2412; | ||
| 152 | if (!bt) | ||
| 153 | continue; | ||
| 154 | |||
| 155 | ret = s3c2412_calc_bank(cfg, bt); | ||
| 156 | if (ret) { | ||
| 157 | printk(KERN_ERR "%s: cannot calculate bank %d io\n", | ||
| 158 | __func__, bank); | ||
| 159 | goto err; | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | return 0; | ||
| 164 | err: | ||
| 165 | return ret; | ||
| 166 | } | ||
| 167 | |||
| 168 | /** | ||
| 169 | * s3c2412_iotiming_set - set the timing information | ||
| 170 | * @cfg: The current frequency configuration. | ||
| 171 | * @iot: The bank timing information. | ||
| 172 | * | ||
| 173 | * Set the IO bank information from the details calculated earlier from | ||
| 174 | * calling s3c2412_iotiming_calc(). | ||
| 175 | */ | ||
| 176 | void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg, | ||
| 177 | struct s3c_iotimings *iot) | ||
| 178 | { | ||
| 179 | struct s3c2412_iobank_timing *bt; | ||
| 180 | void __iomem *regs; | ||
| 181 | int bank; | ||
| 182 | |||
| 183 | /* set the io timings from the specifier */ | ||
| 184 | |||
| 185 | for (bank = 0; bank < MAX_BANKS; bank++) { | ||
| 186 | bt = iot->bank[bank].io_2412; | ||
| 187 | if (!bt) | ||
| 188 | continue; | ||
| 189 | |||
| 190 | regs = S3C2412_SSMC_BANK(bank); | ||
| 191 | |||
| 192 | __raw_writel(bt->smbidcyr, regs + SMBIDCYR); | ||
| 193 | __raw_writel(bt->smbwstrd, regs + SMBWSTRDR); | ||
| 194 | __raw_writel(bt->smbwstwr, regs + SMBWSTWRR); | ||
| 195 | __raw_writel(bt->smbwstoen, regs + SMBWSTOENR); | ||
| 196 | __raw_writel(bt->smbwstwen, regs + SMBWSTWENR); | ||
| 197 | __raw_writel(bt->smbwstbrd, regs + SMBWSTBRDR); | ||
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 | static inline unsigned int s3c2412_decode_timing(unsigned int clock, u32 reg) | ||
| 202 | { | ||
| 203 | return (reg & 0xf) * clock; | ||
| 204 | } | ||
| 205 | |||
| 206 | static void s3c2412_iotiming_getbank(struct s3c_cpufreq_config *cfg, | ||
| 207 | struct s3c2412_iobank_timing *bt, | ||
| 208 | unsigned int bank) | ||
| 209 | { | ||
| 210 | unsigned long clk = cfg->freq.hclk_tns; /* ssmc clock??? */ | ||
| 211 | void __iomem *regs = S3C2412_SSMC_BANK(bank); | ||
| 212 | |||
| 213 | bt->idcy = s3c2412_decode_timing(clk, __raw_readl(regs + SMBIDCYR)); | ||
| 214 | bt->wstrd = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTRDR)); | ||
| 215 | bt->wstoen = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTOENR)); | ||
| 216 | bt->wstwen = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTWENR)); | ||
| 217 | bt->wstbrd = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTBRDR)); | ||
| 218 | } | ||
| 219 | |||
| 220 | /** | ||
| 221 | * bank_is_io - return true if bank is (possibly) IO. | ||
| 222 | * @bank: The bank number. | ||
| 223 | * @bankcfg: The value of S3C2412_EBI_BANKCFG. | ||
| 224 | */ | ||
| 225 | static inline bool bank_is_io(unsigned int bank, u32 bankcfg) | ||
| 226 | { | ||
| 227 | if (bank < 2) | ||
| 228 | return true; | ||
| 229 | |||
| 230 | return !(bankcfg & (1 << bank)); | ||
| 231 | } | ||
| 232 | |||
| 233 | int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg, | ||
| 234 | struct s3c_iotimings *timings) | ||
| 235 | { | ||
| 236 | struct s3c2412_iobank_timing *bt; | ||
| 237 | u32 bankcfg = __raw_readl(S3C2412_EBI_BANKCFG); | ||
| 238 | unsigned int bank; | ||
| 239 | |||
| 240 | /* look through all banks to see what is currently set. */ | ||
| 241 | |||
| 242 | for (bank = 0; bank < MAX_BANKS; bank++) { | ||
| 243 | if (!bank_is_io(bank, bankcfg)) | ||
| 244 | continue; | ||
| 245 | |||
| 246 | bt = kzalloc(sizeof(struct s3c2412_iobank_timing), GFP_KERNEL); | ||
| 247 | if (!bt) { | ||
| 248 | printk(KERN_ERR "%s: no memory for bank\n", __func__); | ||
| 249 | return -ENOMEM; | ||
| 250 | } | ||
| 251 | |||
| 252 | timings->bank[bank].io_2412 = bt; | ||
| 253 | s3c2412_iotiming_getbank(cfg, bt, bank); | ||
| 254 | } | ||
| 255 | |||
| 256 | s3c2412_print_timing("get", timings); | ||
| 257 | return 0; | ||
| 258 | } | ||
| 259 | |||
| 260 | /* this is in here as it is so small, it doesn't currently warrant a file | ||
| 261 | * to itself. We expect that any s3c24xx needing this is going to also | ||
| 262 | * need the iotiming support. | ||
| 263 | */ | ||
| 264 | void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg) | ||
| 265 | { | ||
| 266 | struct s3c_cpufreq_board *board = cfg->board; | ||
| 267 | u32 refresh; | ||
| 268 | |||
| 269 | WARN_ON(board == NULL); | ||
| 270 | |||
| 271 | /* Reduce both the refresh time (in ns) and the frequency (in MHz) | ||
| 272 | * down to ensure that we do not overflow 32 bit numbers. | ||
| 273 | * | ||
| 274 | * This should work for HCLK up to 133MHz and refresh period up | ||
| 275 | * to 30usec. | ||
| 276 | */ | ||
| 277 | |||
| 278 | refresh = (cfg->freq.hclk / 100) * (board->refresh / 10); | ||
| 279 | refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale */ | ||
| 280 | refresh &= ((1 << 16) - 1); | ||
| 281 | |||
| 282 | s3c_freq_dbg("%s: refresh value %u\n", __func__, (unsigned int)refresh); | ||
| 283 | |||
| 284 | __raw_writel(refresh, S3C2412_REFRESH); | ||
| 285 | } | ||
diff --git a/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c b/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c new file mode 100644 index 000000000000..ae2e6c604f27 --- /dev/null +++ b/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c | |||
| @@ -0,0 +1,311 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2006,2008,2009 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * Vincent Sanders <vince@simtec.co.uk> | ||
| 7 | * | ||
| 8 | * S3C2440/S3C2442 CPU Frequency scaling | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/ioport.h> | ||
| 19 | #include <linux/cpufreq.h> | ||
| 20 | #include <linux/sysdev.h> | ||
| 21 | #include <linux/delay.h> | ||
| 22 | #include <linux/clk.h> | ||
| 23 | #include <linux/err.h> | ||
| 24 | #include <linux/io.h> | ||
| 25 | |||
| 26 | #include <mach/hardware.h> | ||
| 27 | |||
| 28 | #include <asm/mach/arch.h> | ||
| 29 | #include <asm/mach/map.h> | ||
| 30 | |||
| 31 | #include <mach/regs-clock.h> | ||
| 32 | |||
| 33 | #include <plat/cpu.h> | ||
| 34 | #include <plat/cpu-freq-core.h> | ||
| 35 | #include <plat/clock.h> | ||
| 36 | |||
| 37 | static struct clk *xtal; | ||
| 38 | static struct clk *fclk; | ||
| 39 | static struct clk *hclk; | ||
| 40 | static struct clk *armclk; | ||
| 41 | |||
| 42 | /* HDIV: 1, 2, 3, 4, 6, 8 */ | ||
| 43 | |||
| 44 | static inline int within_khz(unsigned long a, unsigned long b) | ||
| 45 | { | ||
| 46 | long diff = a - b; | ||
| 47 | |||
| 48 | return (diff >= -1000 && diff <= 1000); | ||
| 49 | } | ||
| 50 | |||
| 51 | /** | ||
| 52 | * s3c2440_cpufreq_calcdivs - calculate divider settings | ||
| 53 | * @cfg: The cpu frequency settings. | ||
| 54 | * | ||
| 55 | * Calcualte the divider values for the given frequency settings | ||
| 56 | * specified in @cfg. The values are stored in @cfg for later use | ||
| 57 | * by the relevant set routine if the request settings can be reached. | ||
| 58 | */ | ||
| 59 | int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg) | ||
| 60 | { | ||
| 61 | unsigned int hdiv, pdiv; | ||
| 62 | unsigned long hclk, fclk, armclk; | ||
| 63 | unsigned long hclk_max; | ||
| 64 | |||
| 65 | fclk = cfg->freq.fclk; | ||
| 66 | armclk = cfg->freq.armclk; | ||
| 67 | hclk_max = cfg->max.hclk; | ||
| 68 | |||
| 69 | s3c_freq_dbg("%s: fclk is %lu, armclk %lu, max hclk %lu\n", | ||
| 70 | __func__, fclk, armclk, hclk_max); | ||
| 71 | |||
| 72 | if (armclk > fclk) { | ||
| 73 | printk(KERN_WARNING "%s: armclk > fclk\n", __func__); | ||
| 74 | armclk = fclk; | ||
| 75 | } | ||
| 76 | |||
| 77 | /* if we are in DVS, we need HCLK to be <= ARMCLK */ | ||
| 78 | if (armclk < fclk && armclk < hclk_max) | ||
| 79 | hclk_max = armclk; | ||
| 80 | |||
| 81 | for (hdiv = 1; hdiv < 9; hdiv++) { | ||
| 82 | if (hdiv == 5 || hdiv == 7) | ||
| 83 | hdiv++; | ||
| 84 | |||
| 85 | hclk = (fclk / hdiv); | ||
| 86 | if (hclk <= hclk_max || within_khz(hclk, hclk_max)) | ||
| 87 | break; | ||
| 88 | } | ||
| 89 | |||
| 90 | s3c_freq_dbg("%s: hclk %lu, div %d\n", __func__, hclk, hdiv); | ||
| 91 | |||
| 92 | if (hdiv > 8) | ||
| 93 | goto invalid; | ||
| 94 | |||
| 95 | pdiv = (hclk > cfg->max.pclk) ? 2 : 1; | ||
| 96 | |||
| 97 | if ((hclk / pdiv) > cfg->max.pclk) | ||
| 98 | pdiv++; | ||
| 99 | |||
| 100 | s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv); | ||
| 101 | |||
| 102 | if (pdiv > 2) | ||
| 103 | goto invalid; | ||
| 104 | |||
| 105 | pdiv *= hdiv; | ||
| 106 | |||
| 107 | /* calculate a valid armclk */ | ||
| 108 | |||
| 109 | if (armclk < hclk) | ||
| 110 | armclk = hclk; | ||
| 111 | |||
| 112 | /* if we're running armclk lower than fclk, this really means | ||
| 113 | * that the system should go into dvs mode, which means that | ||
| 114 | * armclk is connected to hclk. */ | ||
| 115 | if (armclk < fclk) { | ||
| 116 | cfg->divs.dvs = 1; | ||
| 117 | armclk = hclk; | ||
| 118 | } else | ||
| 119 | cfg->divs.dvs = 0; | ||
| 120 | |||
| 121 | cfg->freq.armclk = armclk; | ||
| 122 | |||
| 123 | /* store the result, and then return */ | ||
| 124 | |||
| 125 | cfg->divs.h_divisor = hdiv; | ||
| 126 | cfg->divs.p_divisor = pdiv; | ||
| 127 | |||
| 128 | return 0; | ||
| 129 | |||
| 130 | invalid: | ||
| 131 | return -EINVAL; | ||
| 132 | } | ||
| 133 | |||
| 134 | #define CAMDIVN_HCLK_HALF (S3C2440_CAMDIVN_HCLK3_HALF | \ | ||
| 135 | S3C2440_CAMDIVN_HCLK4_HALF) | ||
| 136 | |||
| 137 | /** | ||
| 138 | * s3c2440_cpufreq_setdivs - set the cpu frequency divider settings | ||
| 139 | * @cfg: The cpu frequency settings. | ||
| 140 | * | ||
| 141 | * Set the divisors from the settings in @cfg, which where generated | ||
| 142 | * during the calculation phase by s3c2440_cpufreq_calcdivs(). | ||
| 143 | */ | ||
| 144 | static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg) | ||
| 145 | { | ||
| 146 | unsigned long clkdiv, camdiv; | ||
| 147 | |||
| 148 | s3c_freq_dbg("%s: divsiors: h=%d, p=%d\n", __func__, | ||
| 149 | cfg->divs.h_divisor, cfg->divs.p_divisor); | ||
| 150 | |||
| 151 | clkdiv = __raw_readl(S3C2410_CLKDIVN); | ||
| 152 | camdiv = __raw_readl(S3C2440_CAMDIVN); | ||
| 153 | |||
| 154 | clkdiv &= ~(S3C2440_CLKDIVN_HDIVN_MASK | S3C2440_CLKDIVN_PDIVN); | ||
| 155 | camdiv &= ~CAMDIVN_HCLK_HALF; | ||
| 156 | |||
| 157 | switch (cfg->divs.h_divisor) { | ||
| 158 | case 1: | ||
| 159 | clkdiv |= S3C2440_CLKDIVN_HDIVN_1; | ||
| 160 | break; | ||
| 161 | |||
| 162 | case 2: | ||
| 163 | clkdiv |= S3C2440_CLKDIVN_HDIVN_2; | ||
| 164 | break; | ||
| 165 | |||
| 166 | case 6: | ||
| 167 | camdiv |= S3C2440_CAMDIVN_HCLK3_HALF; | ||
| 168 | case 3: | ||
| 169 | clkdiv |= S3C2440_CLKDIVN_HDIVN_3_6; | ||
| 170 | break; | ||
| 171 | |||
| 172 | case 8: | ||
| 173 | camdiv |= S3C2440_CAMDIVN_HCLK4_HALF; | ||
| 174 | case 4: | ||
| 175 | clkdiv |= S3C2440_CLKDIVN_HDIVN_4_8; | ||
| 176 | break; | ||
| 177 | |||
| 178 | default: | ||
| 179 | BUG(); /* we don't expect to get here. */ | ||
| 180 | } | ||
| 181 | |||
| 182 | if (cfg->divs.p_divisor != cfg->divs.h_divisor) | ||
| 183 | clkdiv |= S3C2440_CLKDIVN_PDIVN; | ||
| 184 | |||
| 185 | /* todo - set pclk. */ | ||
| 186 | |||
| 187 | /* Write the divisors first with hclk intentionally halved so that | ||
| 188 | * when we write clkdiv we will under-frequency instead of over. We | ||
| 189 | * then make a short delay and remove the hclk halving if necessary. | ||
| 190 | */ | ||
| 191 | |||
| 192 | __raw_writel(camdiv | CAMDIVN_HCLK_HALF, S3C2440_CAMDIVN); | ||
| 193 | __raw_writel(clkdiv, S3C2410_CLKDIVN); | ||
| 194 | |||
| 195 | ndelay(20); | ||
| 196 | __raw_writel(camdiv, S3C2440_CAMDIVN); | ||
| 197 | |||
| 198 | clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk); | ||
| 199 | } | ||
| 200 | |||
| 201 | static int run_freq_for(unsigned long max_hclk, unsigned long fclk, | ||
| 202 | int *divs, | ||
| 203 | struct cpufreq_frequency_table *table, | ||
| 204 | size_t table_size) | ||
| 205 | { | ||
| 206 | unsigned long freq; | ||
| 207 | int index = 0; | ||
| 208 | int div; | ||
| 209 | |||
| 210 | for (div = *divs; div > 0; div = *divs++) { | ||
| 211 | freq = fclk / div; | ||
| 212 | |||
| 213 | if (freq > max_hclk && div != 1) | ||
| 214 | continue; | ||
| 215 | |||
| 216 | freq /= 1000; /* table is in kHz */ | ||
| 217 | index = s3c_cpufreq_addfreq(table, index, table_size, freq); | ||
| 218 | if (index < 0) | ||
| 219 | break; | ||
| 220 | } | ||
| 221 | |||
| 222 | return index; | ||
| 223 | } | ||
| 224 | |||
| 225 | static int hclk_divs[] = { 1, 2, 3, 4, 6, 8, -1 }; | ||
| 226 | |||
| 227 | static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg, | ||
| 228 | struct cpufreq_frequency_table *table, | ||
| 229 | size_t table_size) | ||
| 230 | { | ||
| 231 | int ret; | ||
| 232 | |||
| 233 | WARN_ON(cfg->info == NULL); | ||
| 234 | WARN_ON(cfg->board == NULL); | ||
| 235 | |||
| 236 | ret = run_freq_for(cfg->info->max.hclk, | ||
| 237 | cfg->info->max.fclk, | ||
| 238 | hclk_divs, | ||
| 239 | table, table_size); | ||
| 240 | |||
| 241 | s3c_freq_dbg("%s: returning %d\n", __func__, ret); | ||
| 242 | |||
| 243 | return ret; | ||
| 244 | } | ||
| 245 | |||
| 246 | struct s3c_cpufreq_info s3c2440_cpufreq_info = { | ||
| 247 | .max = { | ||
| 248 | .fclk = 400000000, | ||
| 249 | .hclk = 133333333, | ||
| 250 | .pclk = 66666666, | ||
| 251 | }, | ||
| 252 | |||
| 253 | .locktime_m = 300, | ||
| 254 | .locktime_u = 300, | ||
| 255 | .locktime_bits = 16, | ||
| 256 | |||
| 257 | .name = "s3c244x", | ||
| 258 | .calc_iotiming = s3c2410_iotiming_calc, | ||
| 259 | .set_iotiming = s3c2410_iotiming_set, | ||
| 260 | .get_iotiming = s3c2410_iotiming_get, | ||
| 261 | .set_fvco = s3c2410_set_fvco, | ||
| 262 | |||
| 263 | .set_refresh = s3c2410_cpufreq_setrefresh, | ||
| 264 | .set_divs = s3c2440_cpufreq_setdivs, | ||
| 265 | .calc_divs = s3c2440_cpufreq_calcdivs, | ||
| 266 | .calc_freqtable = s3c2440_cpufreq_calctable, | ||
| 267 | |||
| 268 | .resume_clocks = s3c244x_setup_clocks, | ||
| 269 | |||
| 270 | .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs), | ||
| 271 | }; | ||
| 272 | |||
| 273 | static int s3c2440_cpufreq_add(struct sys_device *sysdev) | ||
| 274 | { | ||
| 275 | xtal = s3c_cpufreq_clk_get(NULL, "xtal"); | ||
| 276 | hclk = s3c_cpufreq_clk_get(NULL, "hclk"); | ||
| 277 | fclk = s3c_cpufreq_clk_get(NULL, "fclk"); | ||
| 278 | armclk = s3c_cpufreq_clk_get(NULL, "armclk"); | ||
| 279 | |||
| 280 | if (IS_ERR(xtal) || IS_ERR(hclk) || IS_ERR(fclk) || IS_ERR(armclk)) { | ||
| 281 | printk(KERN_ERR "%s: failed to get clocks\n", __func__); | ||
| 282 | return -ENOENT; | ||
| 283 | } | ||
| 284 | |||
| 285 | return s3c_cpufreq_register(&s3c2440_cpufreq_info); | ||
| 286 | } | ||
| 287 | |||
| 288 | static struct sysdev_driver s3c2440_cpufreq_driver = { | ||
| 289 | .add = s3c2440_cpufreq_add, | ||
| 290 | }; | ||
| 291 | |||
| 292 | static int s3c2440_cpufreq_init(void) | ||
| 293 | { | ||
| 294 | return sysdev_driver_register(&s3c2440_sysclass, | ||
| 295 | &s3c2440_cpufreq_driver); | ||
| 296 | } | ||
| 297 | |||
| 298 | /* arch_initcall adds the clocks we need, so use subsys_initcall. */ | ||
| 299 | subsys_initcall(s3c2440_cpufreq_init); | ||
| 300 | |||
| 301 | static struct sysdev_driver s3c2442_cpufreq_driver = { | ||
| 302 | .add = s3c2440_cpufreq_add, | ||
| 303 | }; | ||
| 304 | |||
| 305 | static int s3c2442_cpufreq_init(void) | ||
| 306 | { | ||
| 307 | return sysdev_driver_register(&s3c2442_sysclass, | ||
| 308 | &s3c2442_cpufreq_driver); | ||
| 309 | } | ||
| 310 | |||
| 311 | subsys_initcall(s3c2442_cpufreq_init); | ||
diff --git a/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c b/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c new file mode 100644 index 000000000000..ff9443b233aa --- /dev/null +++ b/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | /* arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2006,2007 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * Vincent Sanders <vince@arm.linux.org.uk> | ||
| 7 | * | ||
| 8 | * S3C2440/S3C2442 CPU PLL tables (12MHz Crystal) | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/types.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/sysdev.h> | ||
| 18 | #include <linux/clk.h> | ||
| 19 | #include <linux/err.h> | ||
| 20 | |||
| 21 | #include <plat/cpu.h> | ||
| 22 | #include <plat/cpu-freq-core.h> | ||
| 23 | |||
| 24 | static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = { | ||
| 25 | { .frequency = 75000000, .index = PLLVAL(0x75, 3, 3), }, /* FVco 600.000000 */ | ||
| 26 | { .frequency = 80000000, .index = PLLVAL(0x98, 4, 3), }, /* FVco 640.000000 */ | ||
| 27 | { .frequency = 90000000, .index = PLLVAL(0x70, 2, 3), }, /* FVco 720.000000 */ | ||
| 28 | { .frequency = 100000000, .index = PLLVAL(0x5c, 1, 3), }, /* FVco 800.000000 */ | ||
| 29 | { .frequency = 110000000, .index = PLLVAL(0x66, 1, 3), }, /* FVco 880.000000 */ | ||
| 30 | { .frequency = 120000000, .index = PLLVAL(0x70, 1, 3), }, /* FVco 960.000000 */ | ||
| 31 | { .frequency = 150000000, .index = PLLVAL(0x75, 3, 2), }, /* FVco 600.000000 */ | ||
| 32 | { .frequency = 160000000, .index = PLLVAL(0x98, 4, 2), }, /* FVco 640.000000 */ | ||
| 33 | { .frequency = 170000000, .index = PLLVAL(0x4d, 1, 2), }, /* FVco 680.000000 */ | ||
| 34 | { .frequency = 180000000, .index = PLLVAL(0x70, 2, 2), }, /* FVco 720.000000 */ | ||
| 35 | { .frequency = 190000000, .index = PLLVAL(0x57, 1, 2), }, /* FVco 760.000000 */ | ||
| 36 | { .frequency = 200000000, .index = PLLVAL(0x5c, 1, 2), }, /* FVco 800.000000 */ | ||
| 37 | { .frequency = 210000000, .index = PLLVAL(0x84, 2, 2), }, /* FVco 840.000000 */ | ||
| 38 | { .frequency = 220000000, .index = PLLVAL(0x66, 1, 2), }, /* FVco 880.000000 */ | ||
| 39 | { .frequency = 230000000, .index = PLLVAL(0x6b, 1, 2), }, /* FVco 920.000000 */ | ||
| 40 | { .frequency = 240000000, .index = PLLVAL(0x70, 1, 2), }, /* FVco 960.000000 */ | ||
| 41 | { .frequency = 300000000, .index = PLLVAL(0x75, 3, 1), }, /* FVco 600.000000 */ | ||
| 42 | { .frequency = 310000000, .index = PLLVAL(0x93, 4, 1), }, /* FVco 620.000000 */ | ||
| 43 | { .frequency = 320000000, .index = PLLVAL(0x98, 4, 1), }, /* FVco 640.000000 */ | ||
| 44 | { .frequency = 330000000, .index = PLLVAL(0x66, 2, 1), }, /* FVco 660.000000 */ | ||
| 45 | { .frequency = 340000000, .index = PLLVAL(0x4d, 1, 1), }, /* FVco 680.000000 */ | ||
| 46 | { .frequency = 350000000, .index = PLLVAL(0xa7, 4, 1), }, /* FVco 700.000000 */ | ||
| 47 | { .frequency = 360000000, .index = PLLVAL(0x70, 2, 1), }, /* FVco 720.000000 */ | ||
| 48 | { .frequency = 370000000, .index = PLLVAL(0xb1, 4, 1), }, /* FVco 740.000000 */ | ||
| 49 | { .frequency = 380000000, .index = PLLVAL(0x57, 1, 1), }, /* FVco 760.000000 */ | ||
| 50 | { .frequency = 390000000, .index = PLLVAL(0x7a, 2, 1), }, /* FVco 780.000000 */ | ||
| 51 | { .frequency = 400000000, .index = PLLVAL(0x5c, 1, 1), }, /* FVco 800.000000 */ | ||
| 52 | }; | ||
| 53 | |||
| 54 | static int s3c2440_plls12_add(struct sys_device *dev) | ||
| 55 | { | ||
| 56 | struct clk *xtal_clk; | ||
| 57 | unsigned long xtal; | ||
| 58 | |||
| 59 | xtal_clk = clk_get(NULL, "xtal"); | ||
| 60 | if (IS_ERR(xtal_clk)) | ||
| 61 | return PTR_ERR(xtal_clk); | ||
| 62 | |||
| 63 | xtal = clk_get_rate(xtal_clk); | ||
| 64 | clk_put(xtal_clk); | ||
| 65 | |||
| 66 | if (xtal == 12000000) { | ||
| 67 | printk(KERN_INFO "Using PLL table for 12MHz crystal\n"); | ||
| 68 | return s3c_plltab_register(s3c2440_plls_12, | ||
| 69 | ARRAY_SIZE(s3c2440_plls_12)); | ||
| 70 | } | ||
| 71 | |||
| 72 | return 0; | ||
| 73 | } | ||
| 74 | |||
| 75 | static struct sysdev_driver s3c2440_plls12_drv = { | ||
| 76 | .add = s3c2440_plls12_add, | ||
| 77 | }; | ||
| 78 | |||
| 79 | static int __init s3c2440_pll_12mhz(void) | ||
| 80 | { | ||
| 81 | return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_plls12_drv); | ||
| 82 | |||
| 83 | } | ||
| 84 | |||
| 85 | arch_initcall(s3c2440_pll_12mhz); | ||
| 86 | |||
| 87 | static struct sysdev_driver s3c2442_plls12_drv = { | ||
| 88 | .add = s3c2440_plls12_add, | ||
| 89 | }; | ||
| 90 | |||
| 91 | static int __init s3c2442_pll_12mhz(void) | ||
| 92 | { | ||
| 93 | return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_plls12_drv); | ||
| 94 | |||
| 95 | } | ||
| 96 | |||
| 97 | arch_initcall(s3c2442_pll_12mhz); | ||
diff --git a/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c b/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c new file mode 100644 index 000000000000..7679af13a94d --- /dev/null +++ b/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c | |||
| @@ -0,0 +1,127 @@ | |||
| 1 | /* arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2006-2008 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * Vincent Sanders <vince@arm.linux.org.uk> | ||
| 7 | * | ||
| 8 | * S3C2440/S3C2442 CPU PLL tables (16.93444MHz Crystal) | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/types.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/sysdev.h> | ||
| 18 | #include <linux/clk.h> | ||
| 19 | #include <linux/err.h> | ||
| 20 | |||
| 21 | #include <plat/cpu.h> | ||
| 22 | #include <plat/cpu-freq-core.h> | ||
| 23 | |||
| 24 | static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = { | ||
| 25 | { .frequency = 78019200, .index = PLLVAL(121, 5, 3), }, /* FVco 624.153600 */ | ||
| 26 | { .frequency = 84067200, .index = PLLVAL(131, 5, 3), }, /* FVco 672.537600 */ | ||
| 27 | { .frequency = 90115200, .index = PLLVAL(141, 5, 3), }, /* FVco 720.921600 */ | ||
| 28 | { .frequency = 96163200, .index = PLLVAL(151, 5, 3), }, /* FVco 769.305600 */ | ||
| 29 | { .frequency = 102135600, .index = PLLVAL(185, 6, 3), }, /* FVco 817.084800 */ | ||
| 30 | { .frequency = 108259200, .index = PLLVAL(171, 5, 3), }, /* FVco 866.073600 */ | ||
| 31 | { .frequency = 114307200, .index = PLLVAL(127, 3, 3), }, /* FVco 914.457600 */ | ||
| 32 | { .frequency = 120234240, .index = PLLVAL(134, 3, 3), }, /* FVco 961.873920 */ | ||
| 33 | { .frequency = 126161280, .index = PLLVAL(141, 3, 3), }, /* FVco 1009.290240 */ | ||
| 34 | { .frequency = 132088320, .index = PLLVAL(148, 3, 3), }, /* FVco 1056.706560 */ | ||
| 35 | { .frequency = 138015360, .index = PLLVAL(155, 3, 3), }, /* FVco 1104.122880 */ | ||
| 36 | { .frequency = 144789120, .index = PLLVAL(163, 3, 3), }, /* FVco 1158.312960 */ | ||
| 37 | { .frequency = 150100363, .index = PLLVAL(187, 9, 2), }, /* FVco 600.401454 */ | ||
| 38 | { .frequency = 156038400, .index = PLLVAL(121, 5, 2), }, /* FVco 624.153600 */ | ||
| 39 | { .frequency = 162086400, .index = PLLVAL(126, 5, 2), }, /* FVco 648.345600 */ | ||
| 40 | { .frequency = 168134400, .index = PLLVAL(131, 5, 2), }, /* FVco 672.537600 */ | ||
| 41 | { .frequency = 174048000, .index = PLLVAL(177, 7, 2), }, /* FVco 696.192000 */ | ||
| 42 | { .frequency = 180230400, .index = PLLVAL(141, 5, 2), }, /* FVco 720.921600 */ | ||
| 43 | { .frequency = 186278400, .index = PLLVAL(124, 4, 2), }, /* FVco 745.113600 */ | ||
| 44 | { .frequency = 192326400, .index = PLLVAL(151, 5, 2), }, /* FVco 769.305600 */ | ||
| 45 | { .frequency = 198132480, .index = PLLVAL(109, 3, 2), }, /* FVco 792.529920 */ | ||
| 46 | { .frequency = 204271200, .index = PLLVAL(185, 6, 2), }, /* FVco 817.084800 */ | ||
| 47 | { .frequency = 210268800, .index = PLLVAL(141, 4, 2), }, /* FVco 841.075200 */ | ||
| 48 | { .frequency = 216518400, .index = PLLVAL(171, 5, 2), }, /* FVco 866.073600 */ | ||
| 49 | { .frequency = 222264000, .index = PLLVAL(97, 2, 2), }, /* FVco 889.056000 */ | ||
| 50 | { .frequency = 228614400, .index = PLLVAL(127, 3, 2), }, /* FVco 914.457600 */ | ||
| 51 | { .frequency = 234259200, .index = PLLVAL(158, 4, 2), }, /* FVco 937.036800 */ | ||
| 52 | { .frequency = 240468480, .index = PLLVAL(134, 3, 2), }, /* FVco 961.873920 */ | ||
| 53 | { .frequency = 246960000, .index = PLLVAL(167, 4, 2), }, /* FVco 987.840000 */ | ||
| 54 | { .frequency = 252322560, .index = PLLVAL(141, 3, 2), }, /* FVco 1009.290240 */ | ||
| 55 | { .frequency = 258249600, .index = PLLVAL(114, 2, 2), }, /* FVco 1032.998400 */ | ||
| 56 | { .frequency = 264176640, .index = PLLVAL(148, 3, 2), }, /* FVco 1056.706560 */ | ||
| 57 | { .frequency = 270950400, .index = PLLVAL(120, 2, 2), }, /* FVco 1083.801600 */ | ||
| 58 | { .frequency = 276030720, .index = PLLVAL(155, 3, 2), }, /* FVco 1104.122880 */ | ||
| 59 | { .frequency = 282240000, .index = PLLVAL(92, 1, 2), }, /* FVco 1128.960000 */ | ||
| 60 | { .frequency = 289578240, .index = PLLVAL(163, 3, 2), }, /* FVco 1158.312960 */ | ||
| 61 | { .frequency = 294235200, .index = PLLVAL(131, 2, 2), }, /* FVco 1176.940800 */ | ||
| 62 | { .frequency = 300200727, .index = PLLVAL(187, 9, 1), }, /* FVco 600.401454 */ | ||
| 63 | { .frequency = 306358690, .index = PLLVAL(191, 9, 1), }, /* FVco 612.717380 */ | ||
| 64 | { .frequency = 312076800, .index = PLLVAL(121, 5, 1), }, /* FVco 624.153600 */ | ||
| 65 | { .frequency = 318366720, .index = PLLVAL(86, 3, 1), }, /* FVco 636.733440 */ | ||
| 66 | { .frequency = 324172800, .index = PLLVAL(126, 5, 1), }, /* FVco 648.345600 */ | ||
| 67 | { .frequency = 330220800, .index = PLLVAL(109, 4, 1), }, /* FVco 660.441600 */ | ||
| 68 | { .frequency = 336268800, .index = PLLVAL(131, 5, 1), }, /* FVco 672.537600 */ | ||
| 69 | { .frequency = 342074880, .index = PLLVAL(93, 3, 1), }, /* FVco 684.149760 */ | ||
| 70 | { .frequency = 348096000, .index = PLLVAL(177, 7, 1), }, /* FVco 696.192000 */ | ||
| 71 | { .frequency = 355622400, .index = PLLVAL(118, 4, 1), }, /* FVco 711.244800 */ | ||
| 72 | { .frequency = 360460800, .index = PLLVAL(141, 5, 1), }, /* FVco 720.921600 */ | ||
| 73 | { .frequency = 366206400, .index = PLLVAL(165, 6, 1), }, /* FVco 732.412800 */ | ||
| 74 | { .frequency = 372556800, .index = PLLVAL(124, 4, 1), }, /* FVco 745.113600 */ | ||
| 75 | { .frequency = 378201600, .index = PLLVAL(126, 4, 1), }, /* FVco 756.403200 */ | ||
| 76 | { .frequency = 384652800, .index = PLLVAL(151, 5, 1), }, /* FVco 769.305600 */ | ||
| 77 | { .frequency = 391608000, .index = PLLVAL(177, 6, 1), }, /* FVco 783.216000 */ | ||
| 78 | { .frequency = 396264960, .index = PLLVAL(109, 3, 1), }, /* FVco 792.529920 */ | ||
| 79 | { .frequency = 402192000, .index = PLLVAL(87, 2, 1), }, /* FVco 804.384000 */ | ||
| 80 | }; | ||
| 81 | |||
| 82 | static int s3c2440_plls169344_add(struct sys_device *dev) | ||
| 83 | { | ||
| 84 | struct clk *xtal_clk; | ||
| 85 | unsigned long xtal; | ||
| 86 | |||
| 87 | xtal_clk = clk_get(NULL, "xtal"); | ||
| 88 | if (IS_ERR(xtal_clk)) | ||
| 89 | return PTR_ERR(xtal_clk); | ||
| 90 | |||
| 91 | xtal = clk_get_rate(xtal_clk); | ||
| 92 | clk_put(xtal_clk); | ||
| 93 | |||
| 94 | if (xtal == 169344000) { | ||
| 95 | printk(KERN_INFO "Using PLL table for 16.9344MHz crystal\n"); | ||
| 96 | return s3c_plltab_register(s3c2440_plls_169344, | ||
| 97 | ARRAY_SIZE(s3c2440_plls_169344)); | ||
| 98 | } | ||
| 99 | |||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | |||
| 103 | static struct sysdev_driver s3c2440_plls169344_drv = { | ||
| 104 | .add = s3c2440_plls169344_add, | ||
| 105 | }; | ||
| 106 | |||
| 107 | static int __init s3c2440_pll_16934400(void) | ||
| 108 | { | ||
| 109 | return sysdev_driver_register(&s3c2440_sysclass, | ||
| 110 | &s3c2440_plls169344_drv); | ||
| 111 | |||
| 112 | } | ||
| 113 | |||
| 114 | arch_initcall(s3c2440_pll_16934400); | ||
| 115 | |||
| 116 | static struct sysdev_driver s3c2442_plls169344_drv = { | ||
| 117 | .add = s3c2440_plls169344_add, | ||
| 118 | }; | ||
| 119 | |||
| 120 | static int __init s3c2442_pll_16934400(void) | ||
| 121 | { | ||
| 122 | return sysdev_driver_register(&s3c2442_sysclass, | ||
| 123 | &s3c2442_plls169344_drv); | ||
| 124 | |||
| 125 | } | ||
| 126 | |||
| 127 | arch_initcall(s3c2442_pll_16934400); | ||
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c new file mode 100644 index 000000000000..89fcf5308cf6 --- /dev/null +++ b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c24xx/spi-bus0-gpd8_9_10.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2008 Simtec Electronics | ||
| 4 | * http://armlinux.simtec.co.uk/ | ||
| 5 | * Ben Dooks <ben@simtec.co.uk> | ||
| 6 | * | ||
| 7 | * S3C24XX SPI - gpio configuration for bus 1 on gpd8,9,10 | ||
| 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 as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/gpio.h> | ||
| 16 | |||
| 17 | #include <mach/spi.h> | ||
| 18 | #include <mach/regs-gpio.h> | ||
| 19 | |||
| 20 | void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi, | ||
| 21 | int enable) | ||
| 22 | { | ||
| 23 | |||
| 24 | printk(KERN_INFO "%s(%d)\n", __func__, enable); | ||
| 25 | if (enable) { | ||
| 26 | s3c2410_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1); | ||
| 27 | s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1); | ||
| 28 | s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1); | ||
| 29 | s3c2410_gpio_pullup(S3C2410_GPD(10), 0); | ||
| 30 | s3c2410_gpio_pullup(S3C2410_GPD(9), 0); | ||
| 31 | } else { | ||
| 32 | s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT); | ||
| 33 | s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT); | ||
| 34 | s3c2410_gpio_pullup(S3C2410_GPD(10), 1); | ||
| 35 | s3c2410_gpio_pullup(S3C2410_GPD(9), 1); | ||
| 36 | s3c2410_gpio_pullup(S3C2410_GPD(8), 1); | ||
| 37 | } | ||
| 38 | } | ||
diff --git a/arch/arm/plat-s3c64xx/Kconfig b/arch/arm/plat-s3c64xx/Kconfig index 5ebd8b425a54..bcfa778614d8 100644 --- a/arch/arm/plat-s3c64xx/Kconfig +++ b/arch/arm/plat-s3c64xx/Kconfig | |||
| @@ -19,6 +19,7 @@ config PLAT_S3C64XX | |||
| 19 | select S3C_GPIO_PULL_UPDOWN | 19 | select S3C_GPIO_PULL_UPDOWN |
| 20 | select S3C_GPIO_CFG_S3C24XX | 20 | select S3C_GPIO_CFG_S3C24XX |
| 21 | select S3C_GPIO_CFG_S3C64XX | 21 | select S3C_GPIO_CFG_S3C64XX |
| 22 | select S3C_DEV_NAND | ||
| 22 | select USB_ARCH_HAS_OHCI | 23 | select USB_ARCH_HAS_OHCI |
| 23 | help | 24 | help |
| 24 | Base platform code for any Samsung S3C64XX device | 25 | Base platform code for any Samsung S3C64XX device |
diff --git a/arch/arm/plat-s3c64xx/Makefile b/arch/arm/plat-s3c64xx/Makefile index 3c8882cd6268..b85b4359e935 100644 --- a/arch/arm/plat-s3c64xx/Makefile +++ b/arch/arm/plat-s3c64xx/Makefile | |||
| @@ -40,4 +40,5 @@ obj-$(CONFIG_S3C64XX_DMA) += dma.o | |||
| 40 | obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o | 40 | obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o |
| 41 | obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o | 41 | obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o |
| 42 | obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o | 42 | obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o |
| 43 | obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o \ No newline at end of file | 43 | obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o |
| 44 | obj-$(CONFIG_SND_S3C24XX_SOC) += dev-audio.o | ||
diff --git a/arch/arm/plat-s3c/dev-audio.c b/arch/arm/plat-s3c64xx/dev-audio.c index 1322beb40dd7..1322beb40dd7 100644 --- a/arch/arm/plat-s3c/dev-audio.c +++ b/arch/arm/plat-s3c64xx/dev-audio.c | |||
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig new file mode 100644 index 000000000000..a8a711c3c064 --- /dev/null +++ b/arch/arm/plat-s5pc1xx/Kconfig | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | # arch/arm/plat-s5pc1xx/Kconfig | ||
| 2 | # | ||
| 3 | # Copyright 2009 Samsung Electronics Co. | ||
| 4 | # Byungho Min <bhmin@samsung.com> | ||
| 5 | # | ||
| 6 | # Licensed under GPLv2 | ||
| 7 | |||
| 8 | config PLAT_S5PC1XX | ||
| 9 | bool | ||
| 10 | depends on ARCH_S5PC1XX | ||
| 11 | default y | ||
| 12 | select PLAT_S3C | ||
| 13 | select ARM_VIC | ||
| 14 | select NO_IOPORT | ||
| 15 | select ARCH_REQUIRE_GPIOLIB | ||
| 16 | select S3C_GPIO_TRACK | ||
| 17 | select S3C_GPIO_PULL_UPDOWN | ||
| 18 | help | ||
| 19 | Base platform code for any Samsung S5PC1XX device | ||
| 20 | |||
| 21 | if PLAT_S5PC1XX | ||
| 22 | |||
| 23 | # Configuration options shared by all S3C64XX implementations | ||
| 24 | |||
| 25 | config CPU_S5PC100_INIT | ||
| 26 | bool | ||
| 27 | help | ||
| 28 | Common initialisation code for the S5PC1XX | ||
| 29 | |||
| 30 | config CPU_S5PC100_CLOCK | ||
| 31 | bool | ||
| 32 | help | ||
| 33 | Common clock support code for the S5PC1XX | ||
| 34 | |||
| 35 | # platform specific device setup | ||
| 36 | |||
| 37 | config S5PC100_SETUP_I2C0 | ||
| 38 | bool | ||
| 39 | default y | ||
| 40 | help | ||
| 41 | Common setup code for i2c bus 0. | ||
| 42 | |||
| 43 | Note, currently since i2c0 is always compiled, this setup helper | ||
| 44 | is always compiled with it. | ||
| 45 | |||
| 46 | config S5PC100_SETUP_I2C1 | ||
| 47 | bool | ||
| 48 | help | ||
| 49 | Common setup code for i2c bus 1. | ||
| 50 | endif | ||
diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile new file mode 100644 index 000000000000..f1ecb2c37ee2 --- /dev/null +++ b/arch/arm/plat-s5pc1xx/Makefile | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | # arch/arm/plat-s5pc1xx/Makefile | ||
| 2 | # | ||
| 3 | # Copyright 2009 Samsung Electronics Co. | ||
| 4 | # | ||
| 5 | # Licensed under GPLv2 | ||
| 6 | |||
| 7 | obj-y := | ||
| 8 | obj-m := | ||
| 9 | obj-n := dummy.o | ||
| 10 | obj- := | ||
| 11 | |||
| 12 | # Core files | ||
| 13 | |||
| 14 | obj-y += dev-uart.o | ||
| 15 | obj-y += cpu.o | ||
| 16 | obj-y += irq.o | ||
| 17 | |||
| 18 | # CPU support | ||
| 19 | |||
| 20 | obj-$(CONFIG_CPU_S5PC100_INIT) += s5pc100-init.o | ||
| 21 | obj-$(CONFIG_CPU_S5PC100_CLOCK) += s5pc100-clock.o | ||
| 22 | |||
| 23 | # Device setup | ||
| 24 | |||
| 25 | obj-$(CONFIG_S5PC100_SETUP_I2C0) += setup-i2c0.o | ||
| 26 | obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o | ||
diff --git a/arch/arm/plat-s5pc1xx/cpu.c b/arch/arm/plat-s5pc1xx/cpu.c new file mode 100644 index 000000000000..715a7330794d --- /dev/null +++ b/arch/arm/plat-s5pc1xx/cpu.c | |||
| @@ -0,0 +1,112 @@ | |||
| 1 | /* linux/arch/arm/plat-s5pc1xx/cpu.c | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC1XX CPU Support | ||
| 7 | * | ||
| 8 | * Based on plat-s3c64xx/cpu.c | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/ioport.h> | ||
| 19 | #include <linux/serial_core.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | |||
| 23 | #include <mach/hardware.h> | ||
| 24 | #include <mach/map.h> | ||
| 25 | |||
| 26 | #include <asm/mach/map.h> | ||
| 27 | |||
| 28 | #include <plat/regs-serial.h> | ||
| 29 | |||
| 30 | #include <plat/cpu.h> | ||
| 31 | #include <plat/devs.h> | ||
| 32 | #include <plat/clock.h> | ||
| 33 | |||
| 34 | #include <plat/s5pc100.h> | ||
| 35 | |||
| 36 | /* table of supported CPUs */ | ||
| 37 | |||
| 38 | static const char name_s5pc100[] = "S5PC100"; | ||
| 39 | |||
| 40 | static struct cpu_table cpu_ids[] __initdata = { | ||
| 41 | { | ||
| 42 | .idcode = 0x43100000, | ||
| 43 | .idmask = 0xfffff000, | ||
| 44 | .map_io = s5pc100_map_io, | ||
| 45 | .init_clocks = s5pc100_init_clocks, | ||
| 46 | .init_uarts = s5pc100_init_uarts, | ||
| 47 | .init = s5pc100_init, | ||
| 48 | .name = name_s5pc100, | ||
| 49 | }, | ||
| 50 | }; | ||
| 51 | /* minimal IO mapping */ | ||
| 52 | |||
| 53 | /* see notes on uart map in arch/arm/mach-s5pc100/include/mach/debug-macro.S */ | ||
| 54 | #define UART_OFFS (S3C_PA_UART & 0xffff) | ||
| 55 | |||
| 56 | static struct map_desc s5pc1xx_iodesc[] __initdata = { | ||
| 57 | { | ||
| 58 | .virtual = (unsigned long)S5PC1XX_VA_CHIPID, | ||
| 59 | .pfn = __phys_to_pfn(S5PC1XX_PA_CHIPID), | ||
| 60 | .length = SZ_16, | ||
| 61 | .type = MT_DEVICE, | ||
| 62 | }, { | ||
| 63 | .virtual = (unsigned long)S5PC1XX_VA_CLK, | ||
| 64 | .pfn = __phys_to_pfn(S5PC1XX_PA_CLK), | ||
| 65 | .length = SZ_4K, | ||
| 66 | .type = MT_DEVICE, | ||
| 67 | }, { | ||
| 68 | .virtual = (unsigned long)S5PC1XX_VA_PWR, | ||
| 69 | .pfn = __phys_to_pfn(S5PC1XX_PA_PWR), | ||
| 70 | .length = SZ_4K, | ||
| 71 | .type = MT_DEVICE, | ||
| 72 | }, { | ||
| 73 | .virtual = (unsigned long)(S5PC1XX_VA_UART), | ||
| 74 | .pfn = __phys_to_pfn(S5PC1XX_PA_UART), | ||
| 75 | .length = SZ_4K, | ||
| 76 | .type = MT_DEVICE, | ||
| 77 | }, { | ||
| 78 | .virtual = (unsigned long)S5PC1XX_VA_VIC(0), | ||
| 79 | .pfn = __phys_to_pfn(S5PC1XX_PA_VIC(0)), | ||
| 80 | .length = SZ_4K, | ||
| 81 | .type = MT_DEVICE, | ||
| 82 | }, { | ||
| 83 | .virtual = (unsigned long)S5PC1XX_VA_VIC(1), | ||
| 84 | .pfn = __phys_to_pfn(S5PC1XX_PA_VIC(1)), | ||
| 85 | .length = SZ_4K, | ||
| 86 | .type = MT_DEVICE, | ||
| 87 | }, { | ||
| 88 | .virtual = (unsigned long)S5PC1XX_VA_VIC(2), | ||
| 89 | .pfn = __phys_to_pfn(S5PC1XX_PA_VIC(2)), | ||
| 90 | .length = SZ_4K, | ||
| 91 | .type = MT_DEVICE, | ||
| 92 | }, { | ||
| 93 | .virtual = (unsigned long)S5PC1XX_VA_TIMER, | ||
| 94 | .pfn = __phys_to_pfn(S5PC1XX_PA_TIMER), | ||
| 95 | .length = SZ_256, | ||
| 96 | .type = MT_DEVICE, | ||
| 97 | }, | ||
| 98 | }; | ||
| 99 | |||
| 100 | /* read cpu identification code */ | ||
| 101 | |||
| 102 | void __init s5pc1xx_init_io(struct map_desc *mach_desc, int size) | ||
| 103 | { | ||
| 104 | unsigned long idcode; | ||
| 105 | |||
| 106 | /* initialise the io descriptors we need for initialisation */ | ||
| 107 | iotable_init(s5pc1xx_iodesc, ARRAY_SIZE(s5pc1xx_iodesc)); | ||
| 108 | iotable_init(mach_desc, size); | ||
| 109 | |||
| 110 | idcode = __raw_readl(S5PC1XX_VA_CHIPID); | ||
| 111 | s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids)); | ||
| 112 | } | ||
diff --git a/arch/arm/plat-s5pc1xx/dev-uart.c b/arch/arm/plat-s5pc1xx/dev-uart.c new file mode 100644 index 000000000000..f749bc5407b5 --- /dev/null +++ b/arch/arm/plat-s5pc1xx/dev-uart.c | |||
| @@ -0,0 +1,174 @@ | |||
| 1 | /* linux/arch/arm/plat-s5pc1xx/dev-uart.c | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * Based on plat-s3c64xx/dev-uart.c | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/types.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/list.h> | ||
| 18 | #include <linux/platform_device.h> | ||
| 19 | |||
| 20 | #include <asm/mach/arch.h> | ||
| 21 | #include <asm/mach/irq.h> | ||
| 22 | #include <mach/hardware.h> | ||
| 23 | #include <mach/map.h> | ||
| 24 | |||
| 25 | #include <plat/devs.h> | ||
| 26 | |||
| 27 | /* Serial port registrations */ | ||
| 28 | |||
| 29 | /* 64xx uarts are closer together */ | ||
| 30 | |||
| 31 | static struct resource s5pc1xx_uart0_resource[] = { | ||
| 32 | [0] = { | ||
| 33 | .start = S3C_PA_UART0, | ||
| 34 | .end = S3C_PA_UART0 + 0x100, | ||
| 35 | .flags = IORESOURCE_MEM, | ||
| 36 | }, | ||
| 37 | [1] = { | ||
| 38 | .start = IRQ_S3CUART_RX0, | ||
| 39 | .end = IRQ_S3CUART_RX0, | ||
| 40 | .flags = IORESOURCE_IRQ, | ||
| 41 | }, | ||
| 42 | [2] = { | ||
| 43 | .start = IRQ_S3CUART_TX0, | ||
| 44 | .end = IRQ_S3CUART_TX0, | ||
| 45 | .flags = IORESOURCE_IRQ, | ||
| 46 | |||
| 47 | }, | ||
| 48 | [3] = { | ||
| 49 | .start = IRQ_S3CUART_ERR0, | ||
| 50 | .end = IRQ_S3CUART_ERR0, | ||
| 51 | .flags = IORESOURCE_IRQ, | ||
| 52 | } | ||
| 53 | }; | ||
| 54 | |||
| 55 | static struct resource s5pc1xx_uart1_resource[] = { | ||
| 56 | [0] = { | ||
| 57 | .start = S3C_PA_UART1, | ||
| 58 | .end = S3C_PA_UART1 + 0x100, | ||
| 59 | .flags = IORESOURCE_MEM, | ||
| 60 | }, | ||
| 61 | [1] = { | ||
| 62 | .start = IRQ_S3CUART_RX1, | ||
| 63 | .end = IRQ_S3CUART_RX1, | ||
| 64 | .flags = IORESOURCE_IRQ, | ||
| 65 | }, | ||
| 66 | [2] = { | ||
| 67 | .start = IRQ_S3CUART_TX1, | ||
| 68 | .end = IRQ_S3CUART_TX1, | ||
| 69 | .flags = IORESOURCE_IRQ, | ||
| 70 | |||
| 71 | }, | ||
| 72 | [3] = { | ||
| 73 | .start = IRQ_S3CUART_ERR1, | ||
| 74 | .end = IRQ_S3CUART_ERR1, | ||
| 75 | .flags = IORESOURCE_IRQ, | ||
| 76 | }, | ||
| 77 | }; | ||
| 78 | |||
| 79 | static struct resource s5pc1xx_uart2_resource[] = { | ||
| 80 | [0] = { | ||
| 81 | .start = S3C_PA_UART2, | ||
| 82 | .end = S3C_PA_UART2 + 0x100, | ||
| 83 | .flags = IORESOURCE_MEM, | ||
| 84 | }, | ||
| 85 | [1] = { | ||
| 86 | .start = IRQ_S3CUART_RX2, | ||
| 87 | .end = IRQ_S3CUART_RX2, | ||
| 88 | .flags = IORESOURCE_IRQ, | ||
| 89 | }, | ||
| 90 | [2] = { | ||
| 91 | .start = IRQ_S3CUART_TX2, | ||
| 92 | .end = IRQ_S3CUART_TX2, | ||
| 93 | .flags = IORESOURCE_IRQ, | ||
| 94 | |||
| 95 | }, | ||
| 96 | [3] = { | ||
| 97 | .start = IRQ_S3CUART_ERR2, | ||
| 98 | .end = IRQ_S3CUART_ERR2, | ||
| 99 | .flags = IORESOURCE_IRQ, | ||
| 100 | }, | ||
| 101 | }; | ||
| 102 | |||
| 103 | static struct resource s5pc1xx_uart3_resource[] = { | ||
| 104 | [0] = { | ||
| 105 | .start = S3C_PA_UART3, | ||
| 106 | .end = S3C_PA_UART3 + 0x100, | ||
| 107 | .flags = IORESOURCE_MEM, | ||
| 108 | }, | ||
| 109 | [1] = { | ||
| 110 | .start = IRQ_S3CUART_RX3, | ||
| 111 | .end = IRQ_S3CUART_RX3, | ||
| 112 | .flags = IORESOURCE_IRQ, | ||
| 113 | }, | ||
| 114 | [2] = { | ||
| 115 | .start = IRQ_S3CUART_TX3, | ||
| 116 | .end = IRQ_S3CUART_TX3, | ||
| 117 | .flags = IORESOURCE_IRQ, | ||
| 118 | |||
| 119 | }, | ||
| 120 | [3] = { | ||
| 121 | .start = IRQ_S3CUART_ERR3, | ||
| 122 | .end = IRQ_S3CUART_ERR3, | ||
| 123 | .flags = IORESOURCE_IRQ, | ||
| 124 | }, | ||
| 125 | }; | ||
| 126 | |||
| 127 | |||
| 128 | struct s3c24xx_uart_resources s5pc1xx_uart_resources[] __initdata = { | ||
| 129 | [0] = { | ||
| 130 | .resources = s5pc1xx_uart0_resource, | ||
| 131 | .nr_resources = ARRAY_SIZE(s5pc1xx_uart0_resource), | ||
| 132 | }, | ||
| 133 | [1] = { | ||
| 134 | .resources = s5pc1xx_uart1_resource, | ||
| 135 | .nr_resources = ARRAY_SIZE(s5pc1xx_uart1_resource), | ||
| 136 | }, | ||
| 137 | [2] = { | ||
| 138 | .resources = s5pc1xx_uart2_resource, | ||
| 139 | .nr_resources = ARRAY_SIZE(s5pc1xx_uart2_resource), | ||
| 140 | }, | ||
| 141 | [3] = { | ||
| 142 | .resources = s5pc1xx_uart3_resource, | ||
| 143 | .nr_resources = ARRAY_SIZE(s5pc1xx_uart3_resource), | ||
| 144 | }, | ||
| 145 | }; | ||
| 146 | |||
| 147 | /* uart devices */ | ||
| 148 | |||
| 149 | static struct platform_device s3c24xx_uart_device0 = { | ||
| 150 | .id = 0, | ||
| 151 | }; | ||
| 152 | |||
| 153 | static struct platform_device s3c24xx_uart_device1 = { | ||
| 154 | .id = 1, | ||
| 155 | }; | ||
| 156 | |||
| 157 | static struct platform_device s3c24xx_uart_device2 = { | ||
| 158 | .id = 2, | ||
| 159 | }; | ||
| 160 | |||
| 161 | static struct platform_device s3c24xx_uart_device3 = { | ||
| 162 | .id = 3, | ||
| 163 | }; | ||
| 164 | |||
| 165 | struct platform_device *s3c24xx_uart_src[4] = { | ||
| 166 | &s3c24xx_uart_device0, | ||
| 167 | &s3c24xx_uart_device1, | ||
| 168 | &s3c24xx_uart_device2, | ||
| 169 | &s3c24xx_uart_device3, | ||
| 170 | }; | ||
| 171 | |||
| 172 | struct platform_device *s3c24xx_uart_devs[4] = { | ||
| 173 | }; | ||
| 174 | |||
diff --git a/arch/arm/plat-s5pc1xx/include/plat/irqs.h b/arch/arm/plat-s5pc1xx/include/plat/irqs.h new file mode 100644 index 000000000000..f07d8c3b25d6 --- /dev/null +++ b/arch/arm/plat-s5pc1xx/include/plat/irqs.h | |||
| @@ -0,0 +1,182 @@ | |||
| 1 | /* linux/arch/arm/plat-s5pc1xx/include/plat/irqs.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC1XX - Common IRQ support | ||
| 7 | * | ||
| 8 | * Based on plat-s3c64xx/include/plat/irqs.h | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef __ASM_PLAT_S5PC1XX_IRQS_H | ||
| 12 | #define __ASM_PLAT_S5PC1XX_IRQS_H __FILE__ | ||
| 13 | |||
| 14 | /* we keep the first set of CPU IRQs out of the range of | ||
| 15 | * the ISA space, so that the PC104 has them to itself | ||
| 16 | * and we don't end up having to do horrible things to the | ||
| 17 | * standard ISA drivers.... | ||
| 18 | * | ||
| 19 | * note, since we're using the VICs, our start must be a | ||
| 20 | * mulitple of 32 to allow the common code to work | ||
| 21 | */ | ||
| 22 | |||
| 23 | #define S3C_IRQ_OFFSET (32) | ||
| 24 | |||
| 25 | #define S3C_IRQ(x) ((x) + S3C_IRQ_OFFSET) | ||
| 26 | |||
| 27 | #define S3C_VIC0_BASE S3C_IRQ(0) | ||
| 28 | #define S3C_VIC1_BASE S3C_IRQ(32) | ||
| 29 | #define S3C_VIC2_BASE S3C_IRQ(64) | ||
| 30 | |||
| 31 | /* UART interrupts, each UART has 4 intterupts per channel so | ||
| 32 | * use the space between the ISA and S3C main interrupts. Note, these | ||
| 33 | * are not in the same order as the S3C24XX series! */ | ||
| 34 | |||
| 35 | #define IRQ_S3CUART_BASE0 (16) | ||
| 36 | #define IRQ_S3CUART_BASE1 (20) | ||
| 37 | #define IRQ_S3CUART_BASE2 (24) | ||
| 38 | #define IRQ_S3CUART_BASE3 (28) | ||
| 39 | |||
| 40 | #define UART_IRQ_RXD (0) | ||
| 41 | #define UART_IRQ_ERR (1) | ||
| 42 | #define UART_IRQ_TXD (2) | ||
| 43 | #define UART_IRQ_MODEM (3) | ||
| 44 | |||
| 45 | #define IRQ_S3CUART_RX0 (IRQ_S3CUART_BASE0 + UART_IRQ_RXD) | ||
| 46 | #define IRQ_S3CUART_TX0 (IRQ_S3CUART_BASE0 + UART_IRQ_TXD) | ||
| 47 | #define IRQ_S3CUART_ERR0 (IRQ_S3CUART_BASE0 + UART_IRQ_ERR) | ||
| 48 | |||
| 49 | #define IRQ_S3CUART_RX1 (IRQ_S3CUART_BASE1 + UART_IRQ_RXD) | ||
| 50 | #define IRQ_S3CUART_TX1 (IRQ_S3CUART_BASE1 + UART_IRQ_TXD) | ||
| 51 | #define IRQ_S3CUART_ERR1 (IRQ_S3CUART_BASE1 + UART_IRQ_ERR) | ||
| 52 | |||
| 53 | #define IRQ_S3CUART_RX2 (IRQ_S3CUART_BASE2 + UART_IRQ_RXD) | ||
| 54 | #define IRQ_S3CUART_TX2 (IRQ_S3CUART_BASE2 + UART_IRQ_TXD) | ||
| 55 | #define IRQ_S3CUART_ERR2 (IRQ_S3CUART_BASE2 + UART_IRQ_ERR) | ||
| 56 | |||
| 57 | #define IRQ_S3CUART_RX3 (IRQ_S3CUART_BASE3 + UART_IRQ_RXD) | ||
| 58 | #define IRQ_S3CUART_TX3 (IRQ_S3CUART_BASE3 + UART_IRQ_TXD) | ||
| 59 | #define IRQ_S3CUART_ERR3 (IRQ_S3CUART_BASE3 + UART_IRQ_ERR) | ||
| 60 | |||
| 61 | /* VIC based IRQs */ | ||
| 62 | |||
| 63 | #define S5PC1XX_IRQ_VIC0(x) (S3C_VIC0_BASE + (x)) | ||
| 64 | #define S5PC1XX_IRQ_VIC1(x) (S3C_VIC1_BASE + (x)) | ||
| 65 | #define S5PC1XX_IRQ_VIC2(x) (S3C_VIC2_BASE + (x)) | ||
| 66 | |||
| 67 | /* | ||
| 68 | * VIC0: system, DMA, timer | ||
| 69 | */ | ||
| 70 | #define IRQ_EINT0 S5PC1XX_IRQ_VIC0(0) | ||
| 71 | #define IRQ_EINT1 S5PC1XX_IRQ_VIC0(1) | ||
| 72 | #define IRQ_EINT2 S5PC1XX_IRQ_VIC0(2) | ||
| 73 | #define IRQ_EINT3 S5PC1XX_IRQ_VIC0(3) | ||
| 74 | #define IRQ_EINT4 S5PC1XX_IRQ_VIC0(4) | ||
| 75 | #define IRQ_EINT5 S5PC1XX_IRQ_VIC0(5) | ||
| 76 | #define IRQ_EINT6 S5PC1XX_IRQ_VIC0(6) | ||
| 77 | #define IRQ_EINT7 S5PC1XX_IRQ_VIC0(7) | ||
| 78 | #define IRQ_EINT8 S5PC1XX_IRQ_VIC0(8) | ||
| 79 | #define IRQ_EINT9 S5PC1XX_IRQ_VIC0(9) | ||
| 80 | #define IRQ_EINT10 S5PC1XX_IRQ_VIC0(10) | ||
| 81 | #define IRQ_EINT11 S5PC1XX_IRQ_VIC0(11) | ||
| 82 | #define IRQ_EINT12 S5PC1XX_IRQ_VIC0(12) | ||
| 83 | #define IRQ_EINT13 S5PC1XX_IRQ_VIC0(13) | ||
| 84 | #define IRQ_EINT14 S5PC1XX_IRQ_VIC0(14) | ||
| 85 | #define IRQ_EINT15 S5PC1XX_IRQ_VIC0(15) | ||
| 86 | #define IRQ_EINT16_31 S5PC1XX_IRQ_VIC0(16) | ||
| 87 | #define IRQ_BATF S5PC1XX_IRQ_VIC0(17) | ||
| 88 | #define IRQ_MDMA S5PC1XX_IRQ_VIC0(18) | ||
| 89 | #define IRQ_PDMA0 S5PC1XX_IRQ_VIC0(19) | ||
| 90 | #define IRQ_PDMA1 S5PC1XX_IRQ_VIC0(20) | ||
| 91 | #define IRQ_TIMER0 S5PC1XX_IRQ_VIC0(21) | ||
| 92 | #define IRQ_TIMER1 S5PC1XX_IRQ_VIC0(22) | ||
| 93 | #define IRQ_TIMER2 S5PC1XX_IRQ_VIC0(23) | ||
| 94 | #define IRQ_TIMER3 S5PC1XX_IRQ_VIC0(24) | ||
| 95 | #define IRQ_TIMER4 S5PC1XX_IRQ_VIC0(25) | ||
| 96 | #define IRQ_SYSTIMER S5PC1XX_IRQ_VIC0(26) | ||
| 97 | #define IRQ_WDT S5PC1XX_IRQ_VIC0(27) | ||
| 98 | #define IRQ_RTC_ALARM S5PC1XX_IRQ_VIC0(28) | ||
| 99 | #define IRQ_RTC_TIC S5PC1XX_IRQ_VIC0(29) | ||
| 100 | #define IRQ_GPIOINT S5PC1XX_IRQ_VIC0(30) | ||
| 101 | |||
| 102 | /* | ||
| 103 | * VIC1: ARM, power, memory, connectivity | ||
| 104 | */ | ||
| 105 | #define IRQ_CORTEX0 S5PC1XX_IRQ_VIC1(0) | ||
| 106 | #define IRQ_CORTEX1 S5PC1XX_IRQ_VIC1(1) | ||
| 107 | #define IRQ_CORTEX2 S5PC1XX_IRQ_VIC1(2) | ||
| 108 | #define IRQ_CORTEX3 S5PC1XX_IRQ_VIC1(3) | ||
| 109 | #define IRQ_CORTEX4 S5PC1XX_IRQ_VIC1(4) | ||
| 110 | #define IRQ_IEMAPC S5PC1XX_IRQ_VIC1(5) | ||
| 111 | #define IRQ_IEMIEC S5PC1XX_IRQ_VIC1(6) | ||
| 112 | #define IRQ_ONENAND S5PC1XX_IRQ_VIC1(7) | ||
| 113 | #define IRQ_NFC S5PC1XX_IRQ_VIC1(8) | ||
| 114 | #define IRQ_CFC S5PC1XX_IRQ_VIC1(9) | ||
| 115 | #define IRQ_UART0 S5PC1XX_IRQ_VIC1(10) | ||
| 116 | #define IRQ_UART1 S5PC1XX_IRQ_VIC1(11) | ||
| 117 | #define IRQ_UART2 S5PC1XX_IRQ_VIC1(12) | ||
| 118 | #define IRQ_UART3 S5PC1XX_IRQ_VIC1(13) | ||
| 119 | #define IRQ_IIC S5PC1XX_IRQ_VIC1(14) | ||
| 120 | #define IRQ_SPI0 S5PC1XX_IRQ_VIC1(15) | ||
| 121 | #define IRQ_SPI1 S5PC1XX_IRQ_VIC1(16) | ||
| 122 | #define IRQ_SPI2 S5PC1XX_IRQ_VIC1(17) | ||
| 123 | #define IRQ_IRDA S5PC1XX_IRQ_VIC1(18) | ||
| 124 | #define IRQ_CAN0 S5PC1XX_IRQ_VIC1(19) | ||
| 125 | #define IRQ_CAN1 S5PC1XX_IRQ_VIC1(20) | ||
| 126 | #define IRQ_HSIRX S5PC1XX_IRQ_VIC1(21) | ||
| 127 | #define IRQ_HSITX S5PC1XX_IRQ_VIC1(22) | ||
| 128 | #define IRQ_UHOST S5PC1XX_IRQ_VIC1(23) | ||
| 129 | #define IRQ_OTG S5PC1XX_IRQ_VIC1(24) | ||
| 130 | #define IRQ_MSM S5PC1XX_IRQ_VIC1(25) | ||
| 131 | #define IRQ_HSMMC0 S5PC1XX_IRQ_VIC1(26) | ||
| 132 | #define IRQ_HSMMC1 S5PC1XX_IRQ_VIC1(27) | ||
| 133 | #define IRQ_HSMMC2 S5PC1XX_IRQ_VIC1(28) | ||
| 134 | #define IRQ_MIPICSI S5PC1XX_IRQ_VIC1(29) | ||
| 135 | #define IRQ_MIPIDSI S5PC1XX_IRQ_VIC1(30) | ||
| 136 | |||
| 137 | /* | ||
| 138 | * VIC2: multimedia, audio, security | ||
| 139 | */ | ||
| 140 | #define IRQ_LCD0 S5PC1XX_IRQ_VIC2(0) | ||
| 141 | #define IRQ_LCD1 S5PC1XX_IRQ_VIC2(1) | ||
| 142 | #define IRQ_LCD2 S5PC1XX_IRQ_VIC2(2) | ||
| 143 | #define IRQ_LCD3 S5PC1XX_IRQ_VIC2(3) | ||
| 144 | #define IRQ_ROTATOR S5PC1XX_IRQ_VIC2(4) | ||
| 145 | #define IRQ_FIMC0 S5PC1XX_IRQ_VIC2(5) | ||
| 146 | #define IRQ_FIMC1 S5PC1XX_IRQ_VIC2(6) | ||
| 147 | #define IRQ_FIMC2 S5PC1XX_IRQ_VIC2(7) | ||
| 148 | #define IRQ_JPEG S5PC1XX_IRQ_VIC2(8) | ||
| 149 | #define IRQ_2D S5PC1XX_IRQ_VIC2(9) | ||
| 150 | #define IRQ_3D S5PC1XX_IRQ_VIC2(10) | ||
| 151 | #define IRQ_MIXER S5PC1XX_IRQ_VIC2(11) | ||
| 152 | #define IRQ_HDMI S5PC1XX_IRQ_VIC2(12) | ||
| 153 | #define IRQ_IIC1 S5PC1XX_IRQ_VIC2(13) | ||
| 154 | #define IRQ_MFC S5PC1XX_IRQ_VIC2(14) | ||
| 155 | #define IRQ_TVENC S5PC1XX_IRQ_VIC2(15) | ||
| 156 | #define IRQ_I2S0 S5PC1XX_IRQ_VIC2(16) | ||
| 157 | #define IRQ_I2S1 S5PC1XX_IRQ_VIC2(17) | ||
| 158 | #define IRQ_I2S2 S5PC1XX_IRQ_VIC2(18) | ||
| 159 | #define IRQ_AC97 S5PC1XX_IRQ_VIC2(19) | ||
| 160 | #define IRQ_PCM0 S5PC1XX_IRQ_VIC2(20) | ||
| 161 | #define IRQ_PCM1 S5PC1XX_IRQ_VIC2(21) | ||
| 162 | #define IRQ_SPDIF S5PC1XX_IRQ_VIC2(22) | ||
| 163 | #define IRQ_ADC S5PC1XX_IRQ_VIC2(23) | ||
| 164 | #define IRQ_PENDN S5PC1XX_IRQ_VIC2(24) | ||
| 165 | #define IRQ_TC IRQ_PENDN | ||
| 166 | #define IRQ_KEYPAD S5PC1XX_IRQ_VIC2(25) | ||
| 167 | #define IRQ_CG S5PC1XX_IRQ_VIC2(26) | ||
| 168 | #define IRQ_SEC S5PC1XX_IRQ_VIC2(27) | ||
| 169 | #define IRQ_SECRX S5PC1XX_IRQ_VIC2(28) | ||
| 170 | #define IRQ_SECTX S5PC1XX_IRQ_VIC2(29) | ||
| 171 | #define IRQ_SDMIRQ S5PC1XX_IRQ_VIC2(30) | ||
| 172 | #define IRQ_SDMFIQ S5PC1XX_IRQ_VIC2(31) | ||
| 173 | |||
| 174 | #define S3C_IRQ_EINT_BASE (IRQ_SDMFIQ + 1) | ||
| 175 | |||
| 176 | #define S3C_EINT(x) ((x) + S3C_IRQ_EINT_BASE) | ||
| 177 | #define IRQ_EINT(x) S3C_EINT(x) | ||
| 178 | |||
| 179 | #define NR_IRQS (IRQ_EINT(31)+1) | ||
| 180 | |||
| 181 | #endif /* __ASM_PLAT_S5PC1XX_IRQS_H */ | ||
| 182 | |||
diff --git a/arch/arm/plat-s5pc1xx/include/plat/pll.h b/arch/arm/plat-s5pc1xx/include/plat/pll.h new file mode 100644 index 000000000000..21afef1573e7 --- /dev/null +++ b/arch/arm/plat-s5pc1xx/include/plat/pll.h | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /* arch/arm/plat-s5pc1xx/include/plat/pll.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC1XX PLL code | ||
| 7 | * | ||
| 8 | * Based on plat-s3c64xx/include/plat/pll.h | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #define S5P_PLL_MDIV_MASK ((1 << (25-16+1)) - 1) | ||
| 16 | #define S5P_PLL_PDIV_MASK ((1 << (13-8+1)) - 1) | ||
| 17 | #define S5P_PLL_SDIV_MASK ((1 << (2-0+1)) - 1) | ||
| 18 | #define S5P_PLL_MDIV_SHIFT (16) | ||
| 19 | #define S5P_PLL_PDIV_SHIFT (8) | ||
| 20 | #define S5P_PLL_SDIV_SHIFT (0) | ||
| 21 | |||
| 22 | #include <asm/div64.h> | ||
| 23 | |||
| 24 | static inline unsigned long s5pc1xx_get_pll(unsigned long baseclk, | ||
| 25 | u32 pllcon) | ||
| 26 | { | ||
| 27 | u32 mdiv, pdiv, sdiv; | ||
| 28 | u64 fvco = baseclk; | ||
| 29 | |||
| 30 | mdiv = (pllcon >> S5P_PLL_MDIV_SHIFT) & S5P_PLL_MDIV_MASK; | ||
| 31 | pdiv = (pllcon >> S5P_PLL_PDIV_SHIFT) & S5P_PLL_PDIV_MASK; | ||
| 32 | sdiv = (pllcon >> S5P_PLL_SDIV_SHIFT) & S5P_PLL_SDIV_MASK; | ||
| 33 | |||
| 34 | fvco *= mdiv; | ||
| 35 | do_div(fvco, (pdiv << sdiv)); | ||
| 36 | |||
| 37 | return (unsigned long)fvco; | ||
| 38 | } | ||
diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h new file mode 100644 index 000000000000..75c8390cb827 --- /dev/null +++ b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h | |||
| @@ -0,0 +1,421 @@ | |||
| 1 | /* arch/arm/plat-s5pc1xx/include/plat/regs-clock.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC1XX clock register definitions | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef __PLAT_REGS_CLOCK_H | ||
| 14 | #define __PLAT_REGS_CLOCK_H __FILE__ | ||
| 15 | |||
| 16 | #define S5PC1XX_CLKREG(x) (S5PC1XX_VA_CLK + (x)) | ||
| 17 | |||
| 18 | #define S5PC1XX_APLL_LOCK S5PC1XX_CLKREG(0x00) | ||
| 19 | #define S5PC1XX_MPLL_LOCK S5PC1XX_CLKREG(0x04) | ||
| 20 | #define S5PC1XX_EPLL_LOCK S5PC1XX_CLKREG(0x08) | ||
| 21 | #define S5PC100_HPLL_LOCK S5PC1XX_CLKREG(0x0C) | ||
| 22 | |||
| 23 | #define S5PC1XX_APLL_CON S5PC1XX_CLKREG(0x100) | ||
| 24 | #define S5PC1XX_MPLL_CON S5PC1XX_CLKREG(0x104) | ||
| 25 | #define S5PC1XX_EPLL_CON S5PC1XX_CLKREG(0x108) | ||
| 26 | #define S5PC100_HPLL_CON S5PC1XX_CLKREG(0x10C) | ||
| 27 | |||
| 28 | #define S5PC1XX_CLK_SRC0 S5PC1XX_CLKREG(0x200) | ||
| 29 | #define S5PC1XX_CLK_SRC1 S5PC1XX_CLKREG(0x204) | ||
| 30 | #define S5PC1XX_CLK_SRC2 S5PC1XX_CLKREG(0x208) | ||
| 31 | #define S5PC1XX_CLK_SRC3 S5PC1XX_CLKREG(0x20C) | ||
| 32 | |||
| 33 | #define S5PC1XX_CLK_DIV0 S5PC1XX_CLKREG(0x300) | ||
| 34 | #define S5PC1XX_CLK_DIV1 S5PC1XX_CLKREG(0x304) | ||
| 35 | #define S5PC1XX_CLK_DIV2 S5PC1XX_CLKREG(0x308) | ||
| 36 | #define S5PC1XX_CLK_DIV3 S5PC1XX_CLKREG(0x30C) | ||
| 37 | #define S5PC1XX_CLK_DIV4 S5PC1XX_CLKREG(0x310) | ||
| 38 | |||
| 39 | #define S5PC100_CLK_OUT S5PC1XX_CLKREG(0x400) | ||
| 40 | |||
| 41 | #define S5PC100_CLKGATE_D00 S5PC1XX_CLKREG(0x500) | ||
| 42 | #define S5PC100_CLKGATE_D01 S5PC1XX_CLKREG(0x504) | ||
| 43 | #define S5PC100_CLKGATE_D02 S5PC1XX_CLKREG(0x508) | ||
| 44 | |||
| 45 | #define S5PC100_CLKGATE_D10 S5PC1XX_CLKREG(0x520) | ||
| 46 | #define S5PC100_CLKGATE_D11 S5PC1XX_CLKREG(0x524) | ||
| 47 | #define S5PC100_CLKGATE_D12 S5PC1XX_CLKREG(0x528) | ||
| 48 | #define S5PC100_CLKGATE_D13 S5PC1XX_CLKREG(0x52C) | ||
| 49 | #define S5PC100_CLKGATE_D14 S5PC1XX_CLKREG(0x530) | ||
| 50 | #define S5PC100_CLKGATE_D15 S5PC1XX_CLKREG(0x534) | ||
| 51 | |||
| 52 | #define S5PC100_CLKGATE_D20 S5PC1XX_CLKREG(0x540) | ||
| 53 | |||
| 54 | #define S5PC100_SCLKGATE0 S5PC1XX_CLKREG(0x560) | ||
| 55 | #define S5PC100_SCLKGATE1 S5PC1XX_CLKREG(0x564) | ||
| 56 | |||
| 57 | #define S5PC100_OTHERS S5PC1XX_CLKREG(0x8200) | ||
| 58 | |||
| 59 | #define S5PC1XX_EPLL_EN (1<<31) | ||
| 60 | #define S5PC1XX_EPLL_MASK 0xffffffff | ||
| 61 | #define S5PC1XX_EPLLVAL(_m, _p, _s) ((_m) << 16 | ((_p) << 8) | ((_s))) | ||
| 62 | |||
| 63 | /* CLKSRC0 */ | ||
| 64 | #define S5PC1XX_CLKSRC0_APLL_MASK (0x1<<0) | ||
| 65 | #define S5PC1XX_CLKSRC0_APLL_SHIFT (0) | ||
| 66 | #define S5PC1XX_CLKSRC0_MPLL_MASK (0x1<<4) | ||
| 67 | #define S5PC1XX_CLKSRC0_MPLL_SHIFT (4) | ||
| 68 | #define S5PC1XX_CLKSRC0_EPLL_MASK (0x1<<8) | ||
| 69 | #define S5PC1XX_CLKSRC0_EPLL_SHIFT (8) | ||
| 70 | #define S5PC100_CLKSRC0_HPLL_MASK (0x1<<12) | ||
| 71 | #define S5PC100_CLKSRC0_HPLL_SHIFT (12) | ||
| 72 | #define S5PC100_CLKSRC0_AMMUX_MASK (0x1<<16) | ||
| 73 | #define S5PC100_CLKSRC0_AMMUX_SHIFT (16) | ||
| 74 | #define S5PC100_CLKSRC0_HREF_MASK (0x1<<20) | ||
| 75 | #define S5PC100_CLKSRC0_HREF_SHIFT (20) | ||
| 76 | #define S5PC1XX_CLKSRC0_ONENAND_MASK (0x1<<24) | ||
| 77 | #define S5PC1XX_CLKSRC0_ONENAND_SHIFT (24) | ||
| 78 | |||
| 79 | |||
| 80 | /* CLKSRC1 */ | ||
| 81 | #define S5PC100_CLKSRC1_UART_MASK (0x1<<0) | ||
| 82 | #define S5PC100_CLKSRC1_UART_SHIFT (0) | ||
| 83 | #define S5PC100_CLKSRC1_SPI0_MASK (0x3<<4) | ||
| 84 | #define S5PC100_CLKSRC1_SPI0_SHIFT (4) | ||
| 85 | #define S5PC100_CLKSRC1_SPI1_MASK (0x3<<8) | ||
| 86 | #define S5PC100_CLKSRC1_SPI1_SHIFT (8) | ||
| 87 | #define S5PC100_CLKSRC1_SPI2_MASK (0x3<<12) | ||
| 88 | #define S5PC100_CLKSRC1_SPI2_SHIFT (12) | ||
| 89 | #define S5PC100_CLKSRC1_IRDA_MASK (0x3<<16) | ||
| 90 | #define S5PC100_CLKSRC1_IRDA_SHIFT (16) | ||
| 91 | #define S5PC100_CLKSRC1_UHOST_MASK (0x3<<20) | ||
| 92 | #define S5PC100_CLKSRC1_UHOST_SHIFT (20) | ||
| 93 | #define S5PC100_CLKSRC1_CLK48M_MASK (0x1<<24) | ||
| 94 | #define S5PC100_CLKSRC1_CLK48M_SHIFT (24) | ||
| 95 | |||
| 96 | /* CLKSRC2 */ | ||
| 97 | #define S5PC100_CLKSRC2_MMC0_MASK (0x3<<0) | ||
| 98 | #define S5PC100_CLKSRC2_MMC0_SHIFT (0) | ||
| 99 | #define S5PC100_CLKSRC2_MMC1_MASK (0x3<<4) | ||
| 100 | #define S5PC100_CLKSRC2_MMC1_SHIFT (4) | ||
| 101 | #define S5PC100_CLKSRC2_MMC2_MASK (0x3<<8) | ||
| 102 | #define S5PC100_CLKSRC2_MMC2_SHIFT (8) | ||
| 103 | #define S5PC100_CLKSRC2_LCD_MASK (0x3<<12) | ||
| 104 | #define S5PC100_CLKSRC2_LCD_SHIFT (12) | ||
| 105 | #define S5PC100_CLKSRC2_FIMC0_MASK (0x3<<16) | ||
| 106 | #define S5PC100_CLKSRC2_FIMC0_SHIFT (16) | ||
| 107 | #define S5PC100_CLKSRC2_FIMC1_MASK (0x3<<20) | ||
| 108 | #define S5PC100_CLKSRC2_FIMC1_SHIFT (20) | ||
| 109 | #define S5PC100_CLKSRC2_FIMC2_MASK (0x3<<24) | ||
| 110 | #define S5PC100_CLKSRC2_FIMC2_SHIFT (24) | ||
| 111 | #define S5PC100_CLKSRC2_MIXER_MASK (0x3<<28) | ||
| 112 | #define S5PC100_CLKSRC2_MIXER_SHIFT (28) | ||
| 113 | |||
| 114 | /* CLKSRC3 */ | ||
| 115 | #define S5PC100_CLKSRC3_PWI_MASK (0x3<<0) | ||
| 116 | #define S5PC100_CLKSRC3_PWI_SHIFT (0) | ||
| 117 | #define S5PC100_CLKSRC3_HCLKD2_MASK (0x1<<4) | ||
| 118 | #define S5PC100_CLKSRC3_HCLKD2_SHIFT (4) | ||
| 119 | #define S5PC100_CLKSRC3_I2SD2_MASK (0x3<<8) | ||
| 120 | #define S5PC100_CLKSRC3_I2SD2_SHIFT (8) | ||
| 121 | #define S5PC100_CLKSRC3_AUDIO0_MASK (0x7<<12) | ||
| 122 | #define S5PC100_CLKSRC3_AUDIO0_SHIFT (12) | ||
| 123 | #define S5PC100_CLKSRC3_AUDIO1_MASK (0x7<<16) | ||
| 124 | #define S5PC100_CLKSRC3_AUDIO1_SHIFT (16) | ||
| 125 | #define S5PC100_CLKSRC3_AUDIO2_MASK (0x7<<20) | ||
| 126 | #define S5PC100_CLKSRC3_AUDIO2_SHIFT (20) | ||
| 127 | #define S5PC100_CLKSRC3_SPDIF_MASK (0x3<<24) | ||
| 128 | #define S5PC100_CLKSRC3_SPDIF_SHIFT (24) | ||
| 129 | |||
| 130 | |||
| 131 | /* CLKDIV0 */ | ||
| 132 | #define S5PC1XX_CLKDIV0_APLL_MASK (0x1<<0) | ||
| 133 | #define S5PC1XX_CLKDIV0_APLL_SHIFT (0) | ||
| 134 | #define S5PC100_CLKDIV0_ARM_MASK (0x7<<4) | ||
| 135 | #define S5PC100_CLKDIV0_ARM_SHIFT (4) | ||
| 136 | #define S5PC100_CLKDIV0_D0_MASK (0x7<<8) | ||
| 137 | #define S5PC100_CLKDIV0_D0_SHIFT (8) | ||
| 138 | #define S5PC100_CLKDIV0_PCLKD0_MASK (0x7<<12) | ||
| 139 | #define S5PC100_CLKDIV0_PCLKD0_SHIFT (12) | ||
| 140 | #define S5PC100_CLKDIV0_SECSS_MASK (0x7<<16) | ||
| 141 | #define S5PC100_CLKDIV0_SECSS_SHIFT (16) | ||
| 142 | |||
| 143 | /* CLKDIV1 */ | ||
| 144 | #define S5PC100_CLKDIV1_AM_MASK (0x7<<0) | ||
| 145 | #define S5PC100_CLKDIV1_AM_SHIFT (0) | ||
| 146 | #define S5PC100_CLKDIV1_MPLL_MASK (0x3<<4) | ||
| 147 | #define S5PC100_CLKDIV1_MPLL_SHIFT (4) | ||
| 148 | #define S5PC100_CLKDIV1_MPLL2_MASK (0x1<<8) | ||
| 149 | #define S5PC100_CLKDIV1_MPLL2_SHIFT (8) | ||
| 150 | #define S5PC100_CLKDIV1_D1_MASK (0x7<<12) | ||
| 151 | #define S5PC100_CLKDIV1_D1_SHIFT (12) | ||
| 152 | #define S5PC100_CLKDIV1_PCLKD1_MASK (0x7<<16) | ||
| 153 | #define S5PC100_CLKDIV1_PCLKD1_SHIFT (16) | ||
| 154 | #define S5PC100_CLKDIV1_ONENAND_MASK (0x3<<20) | ||
| 155 | #define S5PC100_CLKDIV1_ONENAND_SHIFT (20) | ||
| 156 | #define S5PC100_CLKDIV1_CAM_MASK (0x1F<<24) | ||
| 157 | #define S5PC100_CLKDIV1_CAM_SHIFT (24) | ||
| 158 | |||
| 159 | /* CLKDIV2 */ | ||
| 160 | #define S5PC100_CLKDIV2_UART_MASK (0x7<<0) | ||
| 161 | #define S5PC100_CLKDIV2_UART_SHIFT (0) | ||
| 162 | #define S5PC100_CLKDIV2_SPI0_MASK (0xf<<4) | ||
| 163 | #define S5PC100_CLKDIV2_SPI0_SHIFT (4) | ||
| 164 | #define S5PC100_CLKDIV2_SPI1_MASK (0xf<<8) | ||
| 165 | #define S5PC100_CLKDIV2_SPI1_SHIFT (8) | ||
| 166 | #define S5PC100_CLKDIV2_SPI2_MASK (0xf<<12) | ||
| 167 | #define S5PC100_CLKDIV2_SPI2_SHIFT (12) | ||
| 168 | #define S5PC100_CLKDIV2_IRDA_MASK (0xf<<16) | ||
| 169 | #define S5PC100_CLKDIV2_IRDA_SHIFT (16) | ||
| 170 | #define S5PC100_CLKDIV2_UHOST_MASK (0xf<<20) | ||
| 171 | #define S5PC100_CLKDIV2_UHOST_SHIFT (20) | ||
| 172 | |||
| 173 | /* CLKDIV3 */ | ||
| 174 | #define S5PC100_CLKDIV3_MMC0_MASK (0xf<<0) | ||
| 175 | #define S5PC100_CLKDIV3_MMC0_SHIFT (0) | ||
| 176 | #define S5PC100_CLKDIV3_MMC1_MASK (0xf<<4) | ||
| 177 | #define S5PC100_CLKDIV3_MMC1_SHIFT (4) | ||
| 178 | #define S5PC100_CLKDIV3_MMC2_MASK (0xf<<8) | ||
| 179 | #define S5PC100_CLKDIV3_MMC2_SHIFT (8) | ||
| 180 | #define S5PC100_CLKDIV3_LCD_MASK (0xf<<12) | ||
| 181 | #define S5PC100_CLKDIV3_LCD_SHIFT (12) | ||
| 182 | #define S5PC100_CLKDIV3_FIMC0_MASK (0xf<<16) | ||
| 183 | #define S5PC100_CLKDIV3_FIMC0_SHIFT (16) | ||
| 184 | #define S5PC100_CLKDIV3_FIMC1_MASK (0xf<<20) | ||
| 185 | #define S5PC100_CLKDIV3_FIMC1_SHIFT (20) | ||
| 186 | #define S5PC100_CLKDIV3_FIMC2_MASK (0xf<<24) | ||
| 187 | #define S5PC100_CLKDIV3_FIMC2_SHIFT (24) | ||
| 188 | #define S5PC100_CLKDIV3_HDMI_MASK (0xf<<28) | ||
| 189 | #define S5PC100_CLKDIV3_HDMI_SHIFT (28) | ||
| 190 | |||
| 191 | /* CLKDIV4 */ | ||
| 192 | #define S5PC100_CLKDIV4_PWI_MASK (0x7<<0) | ||
| 193 | #define S5PC100_CLKDIV4_PWI_SHIFT (0) | ||
| 194 | #define S5PC100_CLKDIV4_HCLKD2_MASK (0x7<<4) | ||
| 195 | #define S5PC100_CLKDIV4_HCLKD2_SHIFT (4) | ||
| 196 | #define S5PC100_CLKDIV4_I2SD2_MASK (0xf<<8) | ||
| 197 | #define S5PC100_CLKDIV4_I2SD2_SHIFT (8) | ||
| 198 | #define S5PC100_CLKDIV4_AUDIO0_MASK (0xf<<12) | ||
| 199 | #define S5PC100_CLKDIV4_AUDIO0_SHIFT (12) | ||
| 200 | #define S5PC100_CLKDIV4_AUDIO1_MASK (0xf<<16) | ||
| 201 | #define S5PC100_CLKDIV4_AUDIO1_SHIFT (16) | ||
| 202 | #define S5PC100_CLKDIV4_AUDIO2_MASK (0xf<<20) | ||
| 203 | #define S5PC100_CLKDIV4_AUDIO2_SHIFT (20) | ||
| 204 | |||
| 205 | |||
| 206 | /* HCLKD0/PCLKD0 Clock Gate 0 Registers */ | ||
| 207 | #define S5PC100_CLKGATE_D00_INTC (1<<0) | ||
| 208 | #define S5PC100_CLKGATE_D00_TZIC (1<<1) | ||
| 209 | #define S5PC100_CLKGATE_D00_CFCON (1<<2) | ||
| 210 | #define S5PC100_CLKGATE_D00_MDMA (1<<3) | ||
| 211 | #define S5PC100_CLKGATE_D00_G2D (1<<4) | ||
| 212 | #define S5PC100_CLKGATE_D00_SECSS (1<<5) | ||
| 213 | #define S5PC100_CLKGATE_D00_CSSYS (1<<6) | ||
| 214 | |||
| 215 | /* HCLKD0/PCLKD0 Clock Gate 1 Registers */ | ||
| 216 | #define S5PC100_CLKGATE_D01_DMC (1<<0) | ||
| 217 | #define S5PC100_CLKGATE_D01_SROMC (1<<1) | ||
| 218 | #define S5PC100_CLKGATE_D01_ONENAND (1<<2) | ||
| 219 | #define S5PC100_CLKGATE_D01_NFCON (1<<3) | ||
| 220 | #define S5PC100_CLKGATE_D01_INTMEM (1<<4) | ||
| 221 | #define S5PC100_CLKGATE_D01_EBI (1<<5) | ||
| 222 | |||
| 223 | /* PCLKD0 Clock Gate 2 Registers */ | ||
| 224 | #define S5PC100_CLKGATE_D02_SECKEY (1<<1) | ||
| 225 | #define S5PC100_CLKGATE_D02_SDM (1<<2) | ||
| 226 | |||
| 227 | /* HCLKD1/PCLKD1 Clock Gate 0 Registers */ | ||
| 228 | #define S5PC100_CLKGATE_D10_PDMA0 (1<<0) | ||
| 229 | #define S5PC100_CLKGATE_D10_PDMA1 (1<<1) | ||
| 230 | #define S5PC100_CLKGATE_D10_USBHOST (1<<2) | ||
| 231 | #define S5PC100_CLKGATE_D10_USBOTG (1<<3) | ||
| 232 | #define S5PC100_CLKGATE_D10_MODEMIF (1<<4) | ||
| 233 | #define S5PC100_CLKGATE_D10_HSMMC0 (1<<5) | ||
| 234 | #define S5PC100_CLKGATE_D10_HSMMC1 (1<<6) | ||
| 235 | #define S5PC100_CLKGATE_D10_HSMMC2 (1<<7) | ||
| 236 | |||
| 237 | /* HCLKD1/PCLKD1 Clock Gate 1 Registers */ | ||
| 238 | #define S5PC100_CLKGATE_D11_LCD (1<<0) | ||
| 239 | #define S5PC100_CLKGATE_D11_ROTATOR (1<<1) | ||
| 240 | #define S5PC100_CLKGATE_D11_FIMC0 (1<<2) | ||
| 241 | #define S5PC100_CLKGATE_D11_FIMC1 (1<<3) | ||
| 242 | #define S5PC100_CLKGATE_D11_FIMC2 (1<<4) | ||
| 243 | #define S5PC100_CLKGATE_D11_JPEG (1<<5) | ||
| 244 | #define S5PC100_CLKGATE_D11_DSI (1<<6) | ||
| 245 | #define S5PC100_CLKGATE_D11_CSI (1<<7) | ||
| 246 | #define S5PC100_CLKGATE_D11_G3D (1<<8) | ||
| 247 | |||
| 248 | /* HCLKD1/PCLKD1 Clock Gate 2 Registers */ | ||
| 249 | #define S5PC100_CLKGATE_D12_TV (1<<0) | ||
| 250 | #define S5PC100_CLKGATE_D12_VP (1<<1) | ||
| 251 | #define S5PC100_CLKGATE_D12_MIXER (1<<2) | ||
| 252 | #define S5PC100_CLKGATE_D12_HDMI (1<<3) | ||
| 253 | #define S5PC100_CLKGATE_D12_MFC (1<<4) | ||
| 254 | |||
| 255 | /* HCLKD1/PCLKD1 Clock Gate 3 Registers */ | ||
| 256 | #define S5PC100_CLKGATE_D13_CHIPID (1<<0) | ||
| 257 | #define S5PC100_CLKGATE_D13_GPIO (1<<1) | ||
| 258 | #define S5PC100_CLKGATE_D13_APC (1<<2) | ||
| 259 | #define S5PC100_CLKGATE_D13_IEC (1<<3) | ||
| 260 | #define S5PC100_CLKGATE_D13_PWM (1<<6) | ||
| 261 | #define S5PC100_CLKGATE_D13_SYSTIMER (1<<7) | ||
| 262 | #define S5PC100_CLKGATE_D13_WDT (1<<8) | ||
| 263 | #define S5PC100_CLKGATE_D13_RTC (1<<9) | ||
| 264 | |||
| 265 | /* HCLKD1/PCLKD1 Clock Gate 4 Registers */ | ||
| 266 | #define S5PC100_CLKGATE_D14_UART0 (1<<0) | ||
| 267 | #define S5PC100_CLKGATE_D14_UART1 (1<<1) | ||
| 268 | #define S5PC100_CLKGATE_D14_UART2 (1<<2) | ||
| 269 | #define S5PC100_CLKGATE_D14_UART3 (1<<3) | ||
| 270 | #define S5PC100_CLKGATE_D14_IIC (1<<4) | ||
| 271 | #define S5PC100_CLKGATE_D14_HDMI_IIC (1<<5) | ||
| 272 | #define S5PC100_CLKGATE_D14_SPI0 (1<<6) | ||
| 273 | #define S5PC100_CLKGATE_D14_SPI1 (1<<7) | ||
| 274 | #define S5PC100_CLKGATE_D14_SPI2 (1<<8) | ||
| 275 | #define S5PC100_CLKGATE_D14_IRDA (1<<9) | ||
| 276 | #define S5PC100_CLKGATE_D14_CCAN0 (1<<10) | ||
| 277 | #define S5PC100_CLKGATE_D14_CCAN1 (1<<11) | ||
| 278 | #define S5PC100_CLKGATE_D14_HSITX (1<<12) | ||
| 279 | #define S5PC100_CLKGATE_D14_HSIRX (1<<13) | ||
| 280 | |||
| 281 | /* HCLKD1/PCLKD1 Clock Gate 5 Registers */ | ||
| 282 | #define S5PC100_CLKGATE_D15_IIS0 (1<<0) | ||
| 283 | #define S5PC100_CLKGATE_D15_IIS1 (1<<1) | ||
| 284 | #define S5PC100_CLKGATE_D15_IIS2 (1<<2) | ||
| 285 | #define S5PC100_CLKGATE_D15_AC97 (1<<3) | ||
| 286 | #define S5PC100_CLKGATE_D15_PCM0 (1<<4) | ||
| 287 | #define S5PC100_CLKGATE_D15_PCM1 (1<<5) | ||
| 288 | #define S5PC100_CLKGATE_D15_SPDIF (1<<6) | ||
| 289 | #define S5PC100_CLKGATE_D15_TSADC (1<<7) | ||
| 290 | #define S5PC100_CLKGATE_D15_KEYIF (1<<8) | ||
| 291 | #define S5PC100_CLKGATE_D15_CG (1<<9) | ||
| 292 | |||
| 293 | /* HCLKD2 Clock Gate 0 Registers */ | ||
| 294 | #define S5PC100_CLKGATE_D20_HCLKD2 (1<<0) | ||
| 295 | #define S5PC100_CLKGATE_D20_I2SD2 (1<<1) | ||
| 296 | |||
| 297 | /* Special Clock Gate 0 Registers */ | ||
| 298 | #define S5PC1XX_CLKGATE_SCLK0_HPM (1<<0) | ||
| 299 | #define S5PC1XX_CLKGATE_SCLK0_PWI (1<<1) | ||
| 300 | #define S5PC100_CLKGATE_SCLK0_ONENAND (1<<2) | ||
| 301 | #define S5PC100_CLKGATE_SCLK0_UART (1<<3) | ||
| 302 | #define S5PC100_CLKGATE_SCLK0_SPI0 (1<<4) | ||
| 303 | #define S5PC100_CLKGATE_SCLK0_SPI1 (1<<5) | ||
| 304 | #define S5PC100_CLKGATE_SCLK0_SPI2 (1<<6) | ||
| 305 | #define S5PC100_CLKGATE_SCLK0_SPI0_48 (1<<7) | ||
| 306 | #define S5PC100_CLKGATE_SCLK0_SPI1_48 (1<<8) | ||
| 307 | #define S5PC100_CLKGATE_SCLK0_SPI2_48 (1<<9) | ||
| 308 | #define S5PC100_CLKGATE_SCLK0_IRDA (1<<10) | ||
| 309 | #define S5PC100_CLKGATE_SCLK0_USBHOST (1<<11) | ||
| 310 | #define S5PC100_CLKGATE_SCLK0_MMC0 (1<<12) | ||
| 311 | #define S5PC100_CLKGATE_SCLK0_MMC1 (1<<13) | ||
| 312 | #define S5PC100_CLKGATE_SCLK0_MMC2 (1<<14) | ||
| 313 | #define S5PC100_CLKGATE_SCLK0_MMC0_48 (1<<15) | ||
| 314 | #define S5PC100_CLKGATE_SCLK0_MMC1_48 (1<<16) | ||
| 315 | #define S5PC100_CLKGATE_SCLK0_MMC2_48 (1<<17) | ||
| 316 | |||
| 317 | /* Special Clock Gate 1 Registers */ | ||
| 318 | #define S5PC100_CLKGATE_SCLK1_LCD (1<<0) | ||
| 319 | #define S5PC100_CLKGATE_SCLK1_FIMC0 (1<<1) | ||
| 320 | #define S5PC100_CLKGATE_SCLK1_FIMC1 (1<<2) | ||
| 321 | #define S5PC100_CLKGATE_SCLK1_FIMC2 (1<<3) | ||
| 322 | #define S5PC100_CLKGATE_SCLK1_TV54 (1<<4) | ||
| 323 | #define S5PC100_CLKGATE_SCLK1_VDAC54 (1<<5) | ||
| 324 | #define S5PC100_CLKGATE_SCLK1_MIXER (1<<6) | ||
| 325 | #define S5PC100_CLKGATE_SCLK1_HDMI (1<<7) | ||
| 326 | #define S5PC100_CLKGATE_SCLK1_AUDIO0 (1<<8) | ||
| 327 | #define S5PC100_CLKGATE_SCLK1_AUDIO1 (1<<9) | ||
| 328 | #define S5PC100_CLKGATE_SCLK1_AUDIO2 (1<<10) | ||
| 329 | #define S5PC100_CLKGATE_SCLK1_SPDIF (1<<11) | ||
| 330 | #define S5PC100_CLKGATE_SCLK1_CAM (1<<12) | ||
| 331 | |||
| 332 | /* register for power management */ | ||
| 333 | #define S5PC100_PWR_CFG S5PC1XX_CLKREG(0x8000) | ||
| 334 | #define S5PC100_EINT_WAKEUP_MASK S5PC1XX_CLKREG(0x8004) | ||
| 335 | #define S5PC100_NORMAL_CFG S5PC1XX_CLKREG(0x8010) | ||
| 336 | #define S5PC100_STOP_CFG S5PC1XX_CLKREG(0x8014) | ||
| 337 | #define S5PC100_SLEEP_CFG S5PC1XX_CLKREG(0x8018) | ||
| 338 | #define S5PC100_STOP_MEM_CFG S5PC1XX_CLKREG(0x801C) | ||
| 339 | #define S5PC100_OSC_FREQ S5PC1XX_CLKREG(0x8100) | ||
| 340 | #define S5PC100_OSC_STABLE S5PC1XX_CLKREG(0x8104) | ||
| 341 | #define S5PC100_PWR_STABLE S5PC1XX_CLKREG(0x8108) | ||
| 342 | #define S5PC100_MTC_STABLE S5PC1XX_CLKREG(0x8110) | ||
| 343 | #define S5PC100_CLAMP_STABLE S5PC1XX_CLKREG(0x8114) | ||
| 344 | #define S5PC100_OTHERS S5PC1XX_CLKREG(0x8200) | ||
| 345 | #define S5PC100_RST_STAT S5PC1XX_CLKREG(0x8300) | ||
| 346 | #define S5PC100_WAKEUP_STAT S5PC1XX_CLKREG(0x8304) | ||
| 347 | #define S5PC100_BLK_PWR_STAT S5PC1XX_CLKREG(0x8308) | ||
| 348 | #define S5PC100_INFORM0 S5PC1XX_CLKREG(0x8400) | ||
| 349 | #define S5PC100_INFORM1 S5PC1XX_CLKREG(0x8404) | ||
| 350 | #define S5PC100_INFORM2 S5PC1XX_CLKREG(0x8408) | ||
| 351 | #define S5PC100_INFORM3 S5PC1XX_CLKREG(0x840C) | ||
| 352 | #define S5PC100_INFORM4 S5PC1XX_CLKREG(0x8410) | ||
| 353 | #define S5PC100_INFORM5 S5PC1XX_CLKREG(0x8414) | ||
| 354 | #define S5PC100_INFORM6 S5PC1XX_CLKREG(0x8418) | ||
| 355 | #define S5PC100_INFORM7 S5PC1XX_CLKREG(0x841C) | ||
| 356 | #define S5PC100_DCGIDX_MAP0 S5PC1XX_CLKREG(0x8500) | ||
| 357 | #define S5PC100_DCGIDX_MAP1 S5PC1XX_CLKREG(0x8504) | ||
| 358 | #define S5PC100_DCGIDX_MAP2 S5PC1XX_CLKREG(0x8508) | ||
| 359 | #define S5PC100_DCGPERF_MAP0 S5PC1XX_CLKREG(0x850C) | ||
| 360 | #define S5PC100_DCGPERF_MAP1 S5PC1XX_CLKREG(0x8510) | ||
| 361 | #define S5PC100_DVCIDX_MAP S5PC1XX_CLKREG(0x8514) | ||
| 362 | #define S5PC100_FREQ_CPU S5PC1XX_CLKREG(0x8518) | ||
| 363 | #define S5PC100_FREQ_DPM S5PC1XX_CLKREG(0x851C) | ||
| 364 | #define S5PC100_DVSEMCLK_EN S5PC1XX_CLKREG(0x8520) | ||
| 365 | #define S5PC100_APLL_CON_L8 S5PC1XX_CLKREG(0x8600) | ||
| 366 | #define S5PC100_APLL_CON_L7 S5PC1XX_CLKREG(0x8604) | ||
| 367 | #define S5PC100_APLL_CON_L6 S5PC1XX_CLKREG(0x8608) | ||
| 368 | #define S5PC100_APLL_CON_L5 S5PC1XX_CLKREG(0x860C) | ||
| 369 | #define S5PC100_APLL_CON_L4 S5PC1XX_CLKREG(0x8610) | ||
| 370 | #define S5PC100_APLL_CON_L3 S5PC1XX_CLKREG(0x8614) | ||
| 371 | #define S5PC100_APLL_CON_L2 S5PC1XX_CLKREG(0x8618) | ||
| 372 | #define S5PC100_APLL_CON_L1 S5PC1XX_CLKREG(0x861C) | ||
| 373 | #define S5PC100_IEM_CONTROL S5PC1XX_CLKREG(0x8620) | ||
| 374 | #define S5PC100_CLKDIV_IEM_L8 S5PC1XX_CLKREG(0x8700) | ||
| 375 | #define S5PC100_CLKDIV_IEM_L7 S5PC1XX_CLKREG(0x8704) | ||
| 376 | #define S5PC100_CLKDIV_IEM_L6 S5PC1XX_CLKREG(0x8708) | ||
| 377 | #define S5PC100_CLKDIV_IEM_L5 S5PC1XX_CLKREG(0x870C) | ||
| 378 | #define S5PC100_CLKDIV_IEM_L4 S5PC1XX_CLKREG(0x8710) | ||
| 379 | #define S5PC100_CLKDIV_IEM_L3 S5PC1XX_CLKREG(0x8714) | ||
| 380 | #define S5PC100_CLKDIV_IEM_L2 S5PC1XX_CLKREG(0x8718) | ||
| 381 | #define S5PC100_CLKDIV_IEM_L1 S5PC1XX_CLKREG(0x871C) | ||
| 382 | #define S5PC100_IEM_HPMCLK_DIV S5PC1XX_CLKREG(0x8724) | ||
| 383 | |||
| 384 | #define S5PC100_SWRESET S5PC1XX_CLKREG(0x100000) | ||
| 385 | #define S5PC100_OND_SWRESET S5PC1XX_CLKREG(0x100008) | ||
| 386 | #define S5PC100_GEN_CTRL S5PC1XX_CLKREG(0x100100) | ||
| 387 | #define S5PC100_GEN_STATUS S5PC1XX_CLKREG(0x100104) | ||
| 388 | #define S5PC100_MEM_SYS_CFG S5PC1XX_CLKREG(0x100200) | ||
| 389 | #define S5PC100_CAM_MUX_SEL S5PC1XX_CLKREG(0x100300) | ||
| 390 | #define S5PC100_MIXER_OUT_SEL S5PC1XX_CLKREG(0x100304) | ||
| 391 | #define S5PC100_LPMP_MODE_SEL S5PC1XX_CLKREG(0x100308) | ||
| 392 | #define S5PC100_MIPI_PHY_CON0 S5PC1XX_CLKREG(0x100400) | ||
| 393 | #define S5PC100_MIPI_PHY_CON1 S5PC1XX_CLKREG(0x100414) | ||
| 394 | #define S5PC100_HDMI_PHY_CON0 S5PC1XX_CLKREG(0x100420) | ||
| 395 | |||
| 396 | #define S5PC100_CFG_WFI_CLEAN (~(3<<5)) | ||
| 397 | #define S5PC100_CFG_WFI_IDLE (1<<5) | ||
| 398 | #define S5PC100_CFG_WFI_STOP (2<<5) | ||
| 399 | #define S5PC100_CFG_WFI_SLEEP (3<<5) | ||
| 400 | |||
| 401 | #define S5PC100_OTHER_SYS_INT 24 | ||
| 402 | #define S5PC100_OTHER_STA_TYPE 23 | ||
| 403 | #define STA_TYPE_EXPON 0 | ||
| 404 | #define STA_TYPE_SFR 1 | ||
| 405 | |||
| 406 | #define S5PC100_PWR_STA_EXP_SCALE 0 | ||
| 407 | #define S5PC100_PWR_STA_CNT 4 | ||
| 408 | |||
| 409 | #define S5PC100_PWR_STABLE_COUNT 85500 | ||
| 410 | |||
| 411 | #define S5PC100_SLEEP_CFG_OSC_EN 0 | ||
| 412 | |||
| 413 | /* OTHERS Resgister */ | ||
| 414 | #define S5PC100_OTHERS_USB_SIG_MASK (1 << 16) | ||
| 415 | #define S5PC100_OTHERS_MIPI_DPHY_EN (1 << 28) | ||
| 416 | |||
| 417 | /* MIPI D-PHY Control Register 0 */ | ||
| 418 | #define S5PC100_MIPI_PHY_CON0_M_RESETN (1 << 1) | ||
| 419 | #define S5PC100_MIPI_PHY_CON0_S_RESETN (1 << 0) | ||
| 420 | |||
| 421 | #endif /* _PLAT_REGS_CLOCK_H */ | ||
diff --git a/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h b/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h new file mode 100644 index 000000000000..45e275131665 --- /dev/null +++ b/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | /* arch/arm/plat-s5pc1xx/include/plat/s5pc100.h | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * Header file for s5pc100 cpu support | ||
| 7 | * | ||
| 8 | * Based on plat-s3c64xx/include/plat/s3c6400.h | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | /* Common init code for S5PC100 related SoCs */ | ||
| 16 | extern int s5pc100_init(void); | ||
| 17 | extern void s5pc100_map_io(void); | ||
| 18 | extern void s5pc100_init_clocks(int xtal); | ||
| 19 | extern int s5pc100_register_baseclocks(unsigned long xtal); | ||
| 20 | extern void s5pc100_init_irq(void); | ||
| 21 | extern void s5pc100_init_io(struct map_desc *mach_desc, int size); | ||
| 22 | extern void s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no); | ||
| 23 | extern void s5pc100_register_clocks(void); | ||
| 24 | extern void s5pc100_setup_clocks(void); | ||
| 25 | extern struct sysdev_class s5pc100_sysclass; | ||
| 26 | |||
| 27 | #define s5pc100_init_uarts s5pc100_common_init_uarts | ||
| 28 | |||
| 29 | /* Some day, belows will be moved to plat-s5pc/include/plat/cpu.h */ | ||
| 30 | extern void s5pc1xx_init_irq(u32 *vic_valid, int num); | ||
| 31 | extern void s5pc1xx_init_io(struct map_desc *mach_desc, int size); | ||
| 32 | |||
| 33 | /* Some day, belows will be moved to plat-s5pc/include/plat/clock.h */ | ||
| 34 | extern struct clk clk_hpll; | ||
| 35 | extern struct clk clk_hd0; | ||
| 36 | extern struct clk clk_pd0; | ||
| 37 | extern struct clk clk_54m; | ||
| 38 | extern struct clk clk_dout_mpll2; | ||
| 39 | extern void s5pc1xx_register_clocks(void); | ||
| 40 | extern int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable); | ||
| 41 | extern int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable); | ||
| 42 | |||
| 43 | /* Some day, belows will be moved to plat-s5pc/include/plat/devs.h */ | ||
| 44 | extern struct s3c24xx_uart_resources s5pc1xx_uart_resources[]; | ||
| 45 | extern struct platform_device s3c_device_g2d; | ||
| 46 | extern struct platform_device s3c_device_g3d; | ||
| 47 | extern struct platform_device s3c_device_vpp; | ||
| 48 | extern struct platform_device s3c_device_tvenc; | ||
| 49 | extern struct platform_device s3c_device_tvscaler; | ||
| 50 | extern struct platform_device s3c_device_rotator; | ||
| 51 | extern struct platform_device s3c_device_jpeg; | ||
| 52 | extern struct platform_device s3c_device_onenand; | ||
| 53 | extern struct platform_device s3c_device_usb_otghcd; | ||
| 54 | extern struct platform_device s3c_device_keypad; | ||
| 55 | extern struct platform_device s3c_device_ts; | ||
| 56 | extern struct platform_device s3c_device_g3d; | ||
| 57 | extern struct platform_device s3c_device_smc911x; | ||
| 58 | extern struct platform_device s3c_device_fimc0; | ||
| 59 | extern struct platform_device s3c_device_fimc1; | ||
| 60 | extern struct platform_device s3c_device_mfc; | ||
| 61 | extern struct platform_device s3c_device_ac97; | ||
| 62 | extern struct platform_device s3c_device_fimc0; | ||
| 63 | extern struct platform_device s3c_device_fimc1; | ||
| 64 | extern struct platform_device s3c_device_fimc2; | ||
| 65 | |||
diff --git a/arch/arm/plat-s5pc1xx/irq.c b/arch/arm/plat-s5pc1xx/irq.c new file mode 100644 index 000000000000..80d6dd942cb8 --- /dev/null +++ b/arch/arm/plat-s5pc1xx/irq.c | |||
| @@ -0,0 +1,259 @@ | |||
| 1 | /* arch/arm/plat-s5pc1xx/irq.c | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC1XX - Interrupt handling | ||
| 7 | * | ||
| 8 | * Based on plat-s3c64xx/irq.c | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/irq.h> | ||
| 18 | #include <linux/io.h> | ||
| 19 | |||
| 20 | #include <asm/hardware/vic.h> | ||
| 21 | |||
| 22 | #include <mach/map.h> | ||
| 23 | #include <plat/regs-timer.h> | ||
| 24 | #include <plat/cpu.h> | ||
| 25 | |||
| 26 | /* Timer interrupt handling */ | ||
| 27 | |||
| 28 | static void s3c_irq_demux_timer(unsigned int base_irq, unsigned int sub_irq) | ||
| 29 | { | ||
| 30 | generic_handle_irq(sub_irq); | ||
| 31 | } | ||
| 32 | |||
| 33 | static void s3c_irq_demux_timer0(unsigned int irq, struct irq_desc *desc) | ||
| 34 | { | ||
| 35 | s3c_irq_demux_timer(irq, IRQ_TIMER0); | ||
| 36 | } | ||
| 37 | |||
| 38 | static void s3c_irq_demux_timer1(unsigned int irq, struct irq_desc *desc) | ||
| 39 | { | ||
| 40 | s3c_irq_demux_timer(irq, IRQ_TIMER1); | ||
| 41 | } | ||
| 42 | |||
| 43 | static void s3c_irq_demux_timer2(unsigned int irq, struct irq_desc *desc) | ||
| 44 | { | ||
| 45 | s3c_irq_demux_timer(irq, IRQ_TIMER2); | ||
| 46 | } | ||
| 47 | |||
| 48 | static void s3c_irq_demux_timer3(unsigned int irq, struct irq_desc *desc) | ||
| 49 | { | ||
| 50 | s3c_irq_demux_timer(irq, IRQ_TIMER3); | ||
| 51 | } | ||
| 52 | |||
| 53 | static void s3c_irq_demux_timer4(unsigned int irq, struct irq_desc *desc) | ||
| 54 | { | ||
| 55 | s3c_irq_demux_timer(irq, IRQ_TIMER4); | ||
| 56 | } | ||
| 57 | |||
| 58 | /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ | ||
| 59 | |||
| 60 | static void s3c_irq_timer_mask(unsigned int irq) | ||
| 61 | { | ||
| 62 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | ||
| 63 | |||
| 64 | reg &= 0x1f; /* mask out pending interrupts */ | ||
| 65 | reg &= ~(1 << (irq - IRQ_TIMER0)); | ||
| 66 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | ||
| 67 | } | ||
| 68 | |||
| 69 | static void s3c_irq_timer_unmask(unsigned int irq) | ||
| 70 | { | ||
| 71 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | ||
| 72 | |||
| 73 | reg &= 0x1f; /* mask out pending interrupts */ | ||
| 74 | reg |= 1 << (irq - IRQ_TIMER0); | ||
| 75 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | ||
| 76 | } | ||
| 77 | |||
| 78 | static void s3c_irq_timer_ack(unsigned int irq) | ||
| 79 | { | ||
| 80 | u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); | ||
| 81 | |||
| 82 | reg &= 0x1f; | ||
| 83 | reg |= (1 << 5) << (irq - IRQ_TIMER0); | ||
| 84 | __raw_writel(reg, S3C64XX_TINT_CSTAT); | ||
| 85 | } | ||
| 86 | |||
| 87 | static struct irq_chip s3c_irq_timer = { | ||
| 88 | .name = "s3c-timer", | ||
| 89 | .mask = s3c_irq_timer_mask, | ||
| 90 | .unmask = s3c_irq_timer_unmask, | ||
| 91 | .ack = s3c_irq_timer_ack, | ||
| 92 | }; | ||
| 93 | |||
| 94 | struct uart_irq { | ||
| 95 | void __iomem *regs; | ||
| 96 | unsigned int base_irq; | ||
| 97 | unsigned int parent_irq; | ||
| 98 | }; | ||
| 99 | |||
| 100 | /* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3] | ||
| 101 | * are consecutive when looking up the interrupt in the demux routines. | ||
| 102 | */ | ||
| 103 | static struct uart_irq uart_irqs[] = { | ||
| 104 | [0] = { | ||
| 105 | .regs = (void *)S3C_VA_UART0, | ||
| 106 | .base_irq = IRQ_S3CUART_BASE0, | ||
| 107 | .parent_irq = IRQ_UART0, | ||
| 108 | }, | ||
| 109 | [1] = { | ||
| 110 | .regs = (void *)S3C_VA_UART1, | ||
| 111 | .base_irq = IRQ_S3CUART_BASE1, | ||
| 112 | .parent_irq = IRQ_UART1, | ||
| 113 | }, | ||
| 114 | [2] = { | ||
| 115 | .regs = (void *)S3C_VA_UART2, | ||
| 116 | .base_irq = IRQ_S3CUART_BASE2, | ||
| 117 | .parent_irq = IRQ_UART2, | ||
| 118 | }, | ||
| 119 | [3] = { | ||
| 120 | .regs = (void *)S3C_VA_UART3, | ||
| 121 | .base_irq = IRQ_S3CUART_BASE3, | ||
| 122 | .parent_irq = IRQ_UART3, | ||
| 123 | }, | ||
| 124 | }; | ||
| 125 | |||
| 126 | static inline void __iomem *s3c_irq_uart_base(unsigned int irq) | ||
| 127 | { | ||
| 128 | struct uart_irq *uirq = get_irq_chip_data(irq); | ||
| 129 | return uirq->regs; | ||
| 130 | } | ||
| 131 | |||
| 132 | static inline unsigned int s3c_irq_uart_bit(unsigned int irq) | ||
| 133 | { | ||
| 134 | return irq & 3; | ||
| 135 | } | ||
| 136 | |||
| 137 | /* UART interrupt registers, not worth adding to seperate include header */ | ||
| 138 | #define S3C64XX_UINTP 0x30 | ||
| 139 | #define S3C64XX_UINTSP 0x34 | ||
| 140 | #define S3C64XX_UINTM 0x38 | ||
| 141 | |||
| 142 | static void s3c_irq_uart_mask(unsigned int irq) | ||
| 143 | { | ||
| 144 | void __iomem *regs = s3c_irq_uart_base(irq); | ||
| 145 | unsigned int bit = s3c_irq_uart_bit(irq); | ||
| 146 | u32 reg; | ||
| 147 | |||
| 148 | reg = __raw_readl(regs + S3C64XX_UINTM); | ||
| 149 | reg |= (1 << bit); | ||
| 150 | __raw_writel(reg, regs + S3C64XX_UINTM); | ||
| 151 | } | ||
| 152 | |||
| 153 | static void s3c_irq_uart_maskack(unsigned int irq) | ||
| 154 | { | ||
| 155 | void __iomem *regs = s3c_irq_uart_base(irq); | ||
| 156 | unsigned int bit = s3c_irq_uart_bit(irq); | ||
| 157 | u32 reg; | ||
| 158 | |||
| 159 | reg = __raw_readl(regs + S3C64XX_UINTM); | ||
| 160 | reg |= (1 << bit); | ||
| 161 | __raw_writel(reg, regs + S3C64XX_UINTM); | ||
| 162 | __raw_writel(1 << bit, regs + S3C64XX_UINTP); | ||
| 163 | } | ||
| 164 | |||
| 165 | static void s3c_irq_uart_unmask(unsigned int irq) | ||
| 166 | { | ||
| 167 | void __iomem *regs = s3c_irq_uart_base(irq); | ||
| 168 | unsigned int bit = s3c_irq_uart_bit(irq); | ||
| 169 | u32 reg; | ||
| 170 | |||
| 171 | reg = __raw_readl(regs + S3C64XX_UINTM); | ||
| 172 | reg &= ~(1 << bit); | ||
| 173 | __raw_writel(reg, regs + S3C64XX_UINTM); | ||
| 174 | } | ||
| 175 | |||
| 176 | static void s3c_irq_uart_ack(unsigned int irq) | ||
| 177 | { | ||
| 178 | void __iomem *regs = s3c_irq_uart_base(irq); | ||
| 179 | unsigned int bit = s3c_irq_uart_bit(irq); | ||
| 180 | |||
| 181 | __raw_writel(1 << bit, regs + S3C64XX_UINTP); | ||
| 182 | } | ||
| 183 | |||
| 184 | static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) | ||
| 185 | { | ||
| 186 | struct uart_irq *uirq = &uart_irqs[irq - IRQ_UART0]; | ||
| 187 | u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP); | ||
| 188 | int base = uirq->base_irq; | ||
| 189 | |||
| 190 | if (pend & (1 << 0)) | ||
| 191 | generic_handle_irq(base); | ||
| 192 | if (pend & (1 << 1)) | ||
| 193 | generic_handle_irq(base + 1); | ||
| 194 | if (pend & (1 << 2)) | ||
| 195 | generic_handle_irq(base + 2); | ||
| 196 | if (pend & (1 << 3)) | ||
| 197 | generic_handle_irq(base + 3); | ||
| 198 | } | ||
| 199 | |||
| 200 | static struct irq_chip s3c_irq_uart = { | ||
| 201 | .name = "s3c-uart", | ||
| 202 | .mask = s3c_irq_uart_mask, | ||
| 203 | .unmask = s3c_irq_uart_unmask, | ||
| 204 | .mask_ack = s3c_irq_uart_maskack, | ||
| 205 | .ack = s3c_irq_uart_ack, | ||
| 206 | }; | ||
| 207 | |||
| 208 | static void __init s5pc1xx_uart_irq(struct uart_irq *uirq) | ||
| 209 | { | ||
| 210 | void __iomem *reg_base = uirq->regs; | ||
| 211 | unsigned int irq; | ||
| 212 | int offs; | ||
| 213 | |||
| 214 | /* mask all interrupts at the start. */ | ||
| 215 | __raw_writel(0xf, reg_base + S3C64XX_UINTM); | ||
| 216 | |||
| 217 | for (offs = 0; offs < 3; offs++) { | ||
| 218 | irq = uirq->base_irq + offs; | ||
| 219 | |||
| 220 | set_irq_chip(irq, &s3c_irq_uart); | ||
| 221 | set_irq_chip_data(irq, uirq); | ||
| 222 | set_irq_handler(irq, handle_level_irq); | ||
| 223 | set_irq_flags(irq, IRQF_VALID); | ||
| 224 | } | ||
| 225 | |||
| 226 | set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart); | ||
| 227 | } | ||
| 228 | |||
| 229 | void __init s5pc1xx_init_irq(u32 *vic_valid, int num) | ||
| 230 | { | ||
| 231 | int i; | ||
| 232 | int uart, irq; | ||
| 233 | |||
| 234 | printk(KERN_DEBUG "%s: initialising interrupts\n", __func__); | ||
| 235 | |||
| 236 | /* initialise the pair of VICs */ | ||
| 237 | for (i = 0; i < num; i++) | ||
| 238 | vic_init((void *)S5PC1XX_VA_VIC(i), S3C_IRQ(i * S3C_IRQ_OFFSET), | ||
| 239 | vic_valid[i], 0); | ||
| 240 | |||
| 241 | /* add the timer sub-irqs */ | ||
| 242 | |||
| 243 | set_irq_chained_handler(IRQ_TIMER0, s3c_irq_demux_timer0); | ||
| 244 | set_irq_chained_handler(IRQ_TIMER1, s3c_irq_demux_timer1); | ||
| 245 | set_irq_chained_handler(IRQ_TIMER2, s3c_irq_demux_timer2); | ||
| 246 | set_irq_chained_handler(IRQ_TIMER3, s3c_irq_demux_timer3); | ||
| 247 | set_irq_chained_handler(IRQ_TIMER4, s3c_irq_demux_timer4); | ||
| 248 | |||
| 249 | for (irq = IRQ_TIMER0; irq <= IRQ_TIMER4; irq++) { | ||
| 250 | set_irq_chip(irq, &s3c_irq_timer); | ||
| 251 | set_irq_handler(irq, handle_level_irq); | ||
| 252 | set_irq_flags(irq, IRQF_VALID); | ||
| 253 | } | ||
| 254 | |||
| 255 | for (uart = 0; uart < ARRAY_SIZE(uart_irqs); uart++) | ||
| 256 | s5pc1xx_uart_irq(&uart_irqs[uart]); | ||
| 257 | } | ||
| 258 | |||
| 259 | |||
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-clock.c b/arch/arm/plat-s5pc1xx/s5pc100-clock.c new file mode 100644 index 000000000000..6b24035172fa --- /dev/null +++ b/arch/arm/plat-s5pc1xx/s5pc100-clock.c | |||
| @@ -0,0 +1,1139 @@ | |||
| 1 | /* linux/arch/arm/plat-s5pc1xx/s5pc100-clock.c | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics, Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC100 based common clock support | ||
| 7 | * | ||
| 8 | * Based on plat-s3c64xx/s3c6400-clock.c | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/list.h> | ||
| 19 | #include <linux/errno.h> | ||
| 20 | #include <linux/err.h> | ||
| 21 | #include <linux/clk.h> | ||
| 22 | #include <linux/sysdev.h> | ||
| 23 | #include <linux/io.h> | ||
| 24 | |||
| 25 | #include <mach/hardware.h> | ||
| 26 | #include <mach/map.h> | ||
| 27 | |||
| 28 | #include <plat/cpu-freq.h> | ||
| 29 | |||
| 30 | #include <plat/regs-clock.h> | ||
| 31 | #include <plat/clock.h> | ||
| 32 | #include <plat/cpu.h> | ||
| 33 | #include <plat/pll.h> | ||
| 34 | #include <plat/devs.h> | ||
| 35 | #include <plat/s5pc100.h> | ||
| 36 | |||
| 37 | /* fin_apll, fin_mpll and fin_epll are all the same clock, which we call | ||
| 38 | * ext_xtal_mux for want of an actual name from the manual. | ||
| 39 | */ | ||
| 40 | |||
| 41 | static struct clk clk_ext_xtal_mux = { | ||
| 42 | .name = "ext_xtal", | ||
| 43 | .id = -1, | ||
| 44 | }; | ||
| 45 | |||
| 46 | #define clk_fin_apll clk_ext_xtal_mux | ||
| 47 | #define clk_fin_mpll clk_ext_xtal_mux | ||
| 48 | #define clk_fin_epll clk_ext_xtal_mux | ||
| 49 | #define clk_fin_hpll clk_ext_xtal_mux | ||
| 50 | |||
| 51 | #define clk_fout_mpll clk_mpll | ||
| 52 | |||
| 53 | struct clk_sources { | ||
| 54 | unsigned int nr_sources; | ||
| 55 | struct clk **sources; | ||
| 56 | }; | ||
| 57 | |||
| 58 | struct clksrc_clk { | ||
| 59 | struct clk clk; | ||
| 60 | unsigned int mask; | ||
| 61 | unsigned int shift; | ||
| 62 | |||
| 63 | struct clk_sources *sources; | ||
| 64 | |||
| 65 | unsigned int divider_shift; | ||
| 66 | void __iomem *reg_divider; | ||
| 67 | void __iomem *reg_source; | ||
| 68 | }; | ||
| 69 | |||
| 70 | static int clk_default_setrate(struct clk *clk, unsigned long rate) | ||
| 71 | { | ||
| 72 | clk->rate = rate; | ||
| 73 | return 1; | ||
| 74 | } | ||
| 75 | |||
| 76 | struct clk clk_27m = { | ||
| 77 | .name = "clk_27m", | ||
| 78 | .id = -1, | ||
| 79 | .rate = 27000000, | ||
| 80 | }; | ||
| 81 | |||
| 82 | static int clk_48m_ctrl(struct clk *clk, int enable) | ||
| 83 | { | ||
| 84 | unsigned long flags; | ||
| 85 | u32 val; | ||
| 86 | |||
| 87 | /* can't rely on clock lock, this register has other usages */ | ||
| 88 | local_irq_save(flags); | ||
| 89 | |||
| 90 | val = __raw_readl(S5PC1XX_CLK_SRC1); | ||
| 91 | if (enable) | ||
| 92 | val |= S5PC100_CLKSRC1_CLK48M_MASK; | ||
| 93 | else | ||
| 94 | val &= ~S5PC100_CLKSRC1_CLK48M_MASK; | ||
| 95 | |||
| 96 | __raw_writel(val, S5PC1XX_CLK_SRC1); | ||
| 97 | local_irq_restore(flags); | ||
| 98 | |||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | |||
| 102 | struct clk clk_48m = { | ||
| 103 | .name = "clk_48m", | ||
| 104 | .id = -1, | ||
| 105 | .rate = 48000000, | ||
| 106 | .enable = clk_48m_ctrl, | ||
| 107 | }; | ||
| 108 | |||
| 109 | struct clk clk_54m = { | ||
| 110 | .name = "clk_54m", | ||
| 111 | .id = -1, | ||
| 112 | .rate = 54000000, | ||
| 113 | }; | ||
| 114 | |||
| 115 | struct clk clk_hpll = { | ||
| 116 | .name = "hpll", | ||
| 117 | .id = -1, | ||
| 118 | }; | ||
| 119 | |||
| 120 | struct clk clk_hd0 = { | ||
| 121 | .name = "hclkd0", | ||
| 122 | .id = -1, | ||
| 123 | .rate = 0, | ||
| 124 | .parent = NULL, | ||
| 125 | .ctrlbit = 0, | ||
| 126 | .set_rate = clk_default_setrate, | ||
| 127 | }; | ||
| 128 | |||
| 129 | struct clk clk_pd0 = { | ||
| 130 | .name = "pclkd0", | ||
| 131 | .id = -1, | ||
| 132 | .rate = 0, | ||
| 133 | .parent = NULL, | ||
| 134 | .ctrlbit = 0, | ||
| 135 | .set_rate = clk_default_setrate, | ||
| 136 | }; | ||
| 137 | |||
| 138 | static int s5pc1xx_clk_gate(void __iomem *reg, | ||
| 139 | struct clk *clk, | ||
| 140 | int enable) | ||
| 141 | { | ||
| 142 | unsigned int ctrlbit = clk->ctrlbit; | ||
| 143 | u32 con; | ||
| 144 | |||
| 145 | con = __raw_readl(reg); | ||
| 146 | |||
| 147 | if (enable) | ||
| 148 | con |= ctrlbit; | ||
| 149 | else | ||
| 150 | con &= ~ctrlbit; | ||
| 151 | |||
| 152 | __raw_writel(con, reg); | ||
| 153 | return 0; | ||
| 154 | } | ||
| 155 | |||
| 156 | static int s5pc1xx_clk_d00_ctrl(struct clk *clk, int enable) | ||
| 157 | { | ||
| 158 | return s5pc1xx_clk_gate(S5PC100_CLKGATE_D00, clk, enable); | ||
| 159 | } | ||
| 160 | |||
| 161 | static int s5pc1xx_clk_d01_ctrl(struct clk *clk, int enable) | ||
| 162 | { | ||
| 163 | return s5pc1xx_clk_gate(S5PC100_CLKGATE_D01, clk, enable); | ||
| 164 | } | ||
| 165 | |||
| 166 | static int s5pc1xx_clk_d02_ctrl(struct clk *clk, int enable) | ||
| 167 | { | ||
| 168 | return s5pc1xx_clk_gate(S5PC100_CLKGATE_D02, clk, enable); | ||
| 169 | } | ||
| 170 | |||
| 171 | static int s5pc1xx_clk_d10_ctrl(struct clk *clk, int enable) | ||
| 172 | { | ||
| 173 | return s5pc1xx_clk_gate(S5PC100_CLKGATE_D10, clk, enable); | ||
| 174 | } | ||
| 175 | |||
| 176 | static int s5pc1xx_clk_d11_ctrl(struct clk *clk, int enable) | ||
| 177 | { | ||
| 178 | return s5pc1xx_clk_gate(S5PC100_CLKGATE_D11, clk, enable); | ||
| 179 | } | ||
| 180 | |||
| 181 | static int s5pc1xx_clk_d12_ctrl(struct clk *clk, int enable) | ||
| 182 | { | ||
| 183 | return s5pc1xx_clk_gate(S5PC100_CLKGATE_D12, clk, enable); | ||
| 184 | } | ||
| 185 | |||
| 186 | static int s5pc1xx_clk_d13_ctrl(struct clk *clk, int enable) | ||
| 187 | { | ||
| 188 | return s5pc1xx_clk_gate(S5PC100_CLKGATE_D13, clk, enable); | ||
| 189 | } | ||
| 190 | |||
| 191 | static int s5pc1xx_clk_d14_ctrl(struct clk *clk, int enable) | ||
| 192 | { | ||
| 193 | return s5pc1xx_clk_gate(S5PC100_CLKGATE_D14, clk, enable); | ||
| 194 | } | ||
| 195 | |||
| 196 | static int s5pc1xx_clk_d15_ctrl(struct clk *clk, int enable) | ||
| 197 | { | ||
| 198 | return s5pc1xx_clk_gate(S5PC100_CLKGATE_D15, clk, enable); | ||
| 199 | } | ||
| 200 | |||
| 201 | static int s5pc1xx_clk_d20_ctrl(struct clk *clk, int enable) | ||
| 202 | { | ||
| 203 | return s5pc1xx_clk_gate(S5PC100_CLKGATE_D20, clk, enable); | ||
| 204 | } | ||
| 205 | |||
| 206 | int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable) | ||
| 207 | { | ||
| 208 | return s5pc1xx_clk_gate(S5PC100_SCLKGATE0, clk, enable); | ||
| 209 | } | ||
| 210 | |||
| 211 | int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable) | ||
| 212 | { | ||
| 213 | return s5pc1xx_clk_gate(S5PC100_SCLKGATE1, clk, enable); | ||
| 214 | } | ||
| 215 | |||
| 216 | static struct clk init_clocks_disable[] = { | ||
| 217 | { | ||
| 218 | .name = "dsi", | ||
| 219 | .id = -1, | ||
| 220 | .parent = &clk_p, | ||
| 221 | .enable = s5pc1xx_clk_d11_ctrl, | ||
| 222 | .ctrlbit = S5PC100_CLKGATE_D11_DSI, | ||
| 223 | }, { | ||
| 224 | .name = "csi", | ||
| 225 | .id = -1, | ||
| 226 | .parent = &clk_h, | ||
| 227 | .enable = s5pc1xx_clk_d11_ctrl, | ||
| 228 | .ctrlbit = S5PC100_CLKGATE_D11_CSI, | ||
| 229 | }, { | ||
| 230 | .name = "ccan0", | ||
| 231 | .id = 0, | ||
| 232 | .parent = &clk_p, | ||
| 233 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 234 | .ctrlbit = S5PC100_CLKGATE_D14_CCAN0, | ||
| 235 | }, { | ||
| 236 | .name = "ccan1", | ||
| 237 | .id = 1, | ||
| 238 | .parent = &clk_p, | ||
| 239 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 240 | .ctrlbit = S5PC100_CLKGATE_D14_CCAN1, | ||
| 241 | }, { | ||
| 242 | .name = "keypad", | ||
| 243 | .id = -1, | ||
| 244 | .parent = &clk_p, | ||
| 245 | .enable = s5pc1xx_clk_d15_ctrl, | ||
| 246 | .ctrlbit = S5PC100_CLKGATE_D15_KEYIF, | ||
| 247 | }, { | ||
| 248 | .name = "hclkd2", | ||
| 249 | .id = -1, | ||
| 250 | .parent = NULL, | ||
| 251 | .enable = s5pc1xx_clk_d20_ctrl, | ||
| 252 | .ctrlbit = S5PC100_CLKGATE_D20_HCLKD2, | ||
| 253 | }, { | ||
| 254 | .name = "iis-d2", | ||
| 255 | .id = -1, | ||
| 256 | .parent = NULL, | ||
| 257 | .enable = s5pc1xx_clk_d20_ctrl, | ||
| 258 | .ctrlbit = S5PC100_CLKGATE_D20_I2SD2, | ||
| 259 | }, { | ||
| 260 | .name = "otg", | ||
| 261 | .id = -1, | ||
| 262 | .parent = &clk_h, | ||
| 263 | .enable = s5pc1xx_clk_d10_ctrl, | ||
| 264 | .ctrlbit = S5PC100_CLKGATE_D10_USBOTG, | ||
| 265 | }, | ||
| 266 | }; | ||
| 267 | |||
| 268 | static struct clk init_clocks[] = { | ||
| 269 | /* System1 (D0_0) devices */ | ||
| 270 | { | ||
| 271 | .name = "intc", | ||
| 272 | .id = -1, | ||
| 273 | .parent = &clk_hd0, | ||
| 274 | .enable = s5pc1xx_clk_d00_ctrl, | ||
| 275 | .ctrlbit = S5PC100_CLKGATE_D00_INTC, | ||
| 276 | }, { | ||
| 277 | .name = "tzic", | ||
| 278 | .id = -1, | ||
| 279 | .parent = &clk_hd0, | ||
| 280 | .enable = s5pc1xx_clk_d00_ctrl, | ||
| 281 | .ctrlbit = S5PC100_CLKGATE_D00_TZIC, | ||
| 282 | }, { | ||
| 283 | .name = "cf-ata", | ||
| 284 | .id = -1, | ||
| 285 | .parent = &clk_hd0, | ||
| 286 | .enable = s5pc1xx_clk_d00_ctrl, | ||
| 287 | .ctrlbit = S5PC100_CLKGATE_D00_CFCON, | ||
| 288 | }, { | ||
| 289 | .name = "mdma", | ||
| 290 | .id = -1, | ||
| 291 | .parent = &clk_hd0, | ||
| 292 | .enable = s5pc1xx_clk_d00_ctrl, | ||
| 293 | .ctrlbit = S5PC100_CLKGATE_D00_MDMA, | ||
| 294 | }, { | ||
| 295 | .name = "g2d", | ||
| 296 | .id = -1, | ||
| 297 | .parent = &clk_hd0, | ||
| 298 | .enable = s5pc1xx_clk_d00_ctrl, | ||
| 299 | .ctrlbit = S5PC100_CLKGATE_D00_G2D, | ||
| 300 | }, { | ||
| 301 | .name = "secss", | ||
| 302 | .id = -1, | ||
| 303 | .parent = &clk_hd0, | ||
| 304 | .enable = s5pc1xx_clk_d00_ctrl, | ||
| 305 | .ctrlbit = S5PC100_CLKGATE_D00_SECSS, | ||
| 306 | }, { | ||
| 307 | .name = "cssys", | ||
| 308 | .id = -1, | ||
| 309 | .parent = &clk_hd0, | ||
| 310 | .enable = s5pc1xx_clk_d00_ctrl, | ||
| 311 | .ctrlbit = S5PC100_CLKGATE_D00_CSSYS, | ||
| 312 | }, | ||
| 313 | |||
| 314 | /* Memory (D0_1) devices */ | ||
| 315 | { | ||
| 316 | .name = "dmc", | ||
| 317 | .id = -1, | ||
| 318 | .parent = &clk_hd0, | ||
| 319 | .enable = s5pc1xx_clk_d01_ctrl, | ||
| 320 | .ctrlbit = S5PC100_CLKGATE_D01_DMC, | ||
| 321 | }, { | ||
| 322 | .name = "sromc", | ||
| 323 | .id = -1, | ||
| 324 | .parent = &clk_hd0, | ||
| 325 | .enable = s5pc1xx_clk_d01_ctrl, | ||
| 326 | .ctrlbit = S5PC100_CLKGATE_D01_SROMC, | ||
| 327 | }, { | ||
| 328 | .name = "onenand", | ||
| 329 | .id = -1, | ||
| 330 | .parent = &clk_hd0, | ||
| 331 | .enable = s5pc1xx_clk_d01_ctrl, | ||
| 332 | .ctrlbit = S5PC100_CLKGATE_D01_ONENAND, | ||
| 333 | }, { | ||
| 334 | .name = "nand", | ||
| 335 | .id = -1, | ||
| 336 | .parent = &clk_hd0, | ||
| 337 | .enable = s5pc1xx_clk_d01_ctrl, | ||
| 338 | .ctrlbit = S5PC100_CLKGATE_D01_NFCON, | ||
| 339 | }, { | ||
| 340 | .name = "intmem", | ||
| 341 | .id = -1, | ||
| 342 | .parent = &clk_hd0, | ||
| 343 | .enable = s5pc1xx_clk_d01_ctrl, | ||
| 344 | .ctrlbit = S5PC100_CLKGATE_D01_INTMEM, | ||
| 345 | }, { | ||
| 346 | .name = "ebi", | ||
| 347 | .id = -1, | ||
| 348 | .parent = &clk_hd0, | ||
| 349 | .enable = s5pc1xx_clk_d01_ctrl, | ||
| 350 | .ctrlbit = S5PC100_CLKGATE_D01_EBI, | ||
| 351 | }, | ||
| 352 | |||
| 353 | /* System2 (D0_2) devices */ | ||
| 354 | { | ||
| 355 | .name = "seckey", | ||
| 356 | .id = -1, | ||
| 357 | .parent = &clk_pd0, | ||
| 358 | .enable = s5pc1xx_clk_d02_ctrl, | ||
| 359 | .ctrlbit = S5PC100_CLKGATE_D02_SECKEY, | ||
| 360 | }, { | ||
| 361 | .name = "sdm", | ||
| 362 | .id = -1, | ||
| 363 | .parent = &clk_hd0, | ||
| 364 | .enable = s5pc1xx_clk_d02_ctrl, | ||
| 365 | .ctrlbit = S5PC100_CLKGATE_D02_SDM, | ||
| 366 | }, | ||
| 367 | |||
| 368 | /* File (D1_0) devices */ | ||
| 369 | { | ||
| 370 | .name = "pdma0", | ||
| 371 | .id = -1, | ||
| 372 | .parent = &clk_h, | ||
| 373 | .enable = s5pc1xx_clk_d10_ctrl, | ||
| 374 | .ctrlbit = S5PC100_CLKGATE_D10_PDMA0, | ||
| 375 | }, { | ||
| 376 | .name = "pdma1", | ||
| 377 | .id = -1, | ||
| 378 | .parent = &clk_h, | ||
| 379 | .enable = s5pc1xx_clk_d10_ctrl, | ||
| 380 | .ctrlbit = S5PC100_CLKGATE_D10_PDMA1, | ||
| 381 | }, { | ||
| 382 | .name = "usb-host", | ||
| 383 | .id = -1, | ||
| 384 | .parent = &clk_h, | ||
| 385 | .enable = s5pc1xx_clk_d10_ctrl, | ||
| 386 | .ctrlbit = S5PC100_CLKGATE_D10_USBHOST, | ||
| 387 | }, { | ||
| 388 | .name = "modem", | ||
| 389 | .id = -1, | ||
| 390 | .parent = &clk_h, | ||
| 391 | .enable = s5pc1xx_clk_d10_ctrl, | ||
| 392 | .ctrlbit = S5PC100_CLKGATE_D10_MODEMIF, | ||
| 393 | }, { | ||
| 394 | .name = "hsmmc", | ||
| 395 | .id = 0, | ||
| 396 | .parent = &clk_h, | ||
| 397 | .enable = s5pc1xx_clk_d10_ctrl, | ||
| 398 | .ctrlbit = S5PC100_CLKGATE_D10_HSMMC0, | ||
| 399 | }, { | ||
| 400 | .name = "hsmmc", | ||
| 401 | .id = 1, | ||
| 402 | .parent = &clk_h, | ||
| 403 | .enable = s5pc1xx_clk_d10_ctrl, | ||
| 404 | .ctrlbit = S5PC100_CLKGATE_D10_HSMMC1, | ||
| 405 | }, { | ||
| 406 | .name = "hsmmc", | ||
| 407 | .id = 2, | ||
| 408 | .parent = &clk_h, | ||
| 409 | .enable = s5pc1xx_clk_d10_ctrl, | ||
| 410 | .ctrlbit = S5PC100_CLKGATE_D10_HSMMC2, | ||
| 411 | }, | ||
| 412 | |||
| 413 | /* Multimedia1 (D1_1) devices */ | ||
| 414 | { | ||
| 415 | .name = "lcd", | ||
| 416 | .id = -1, | ||
| 417 | .parent = &clk_h, | ||
| 418 | .enable = s5pc1xx_clk_d11_ctrl, | ||
| 419 | .ctrlbit = S5PC100_CLKGATE_D11_LCD, | ||
| 420 | }, { | ||
| 421 | .name = "rotator", | ||
| 422 | .id = -1, | ||
| 423 | .parent = &clk_h, | ||
| 424 | .enable = s5pc1xx_clk_d11_ctrl, | ||
| 425 | .ctrlbit = S5PC100_CLKGATE_D11_ROTATOR, | ||
| 426 | }, { | ||
| 427 | .name = "fimc", | ||
| 428 | .id = 0, | ||
| 429 | .parent = &clk_h, | ||
| 430 | .enable = s5pc1xx_clk_d11_ctrl, | ||
| 431 | .ctrlbit = S5PC100_CLKGATE_D11_FIMC0, | ||
| 432 | }, { | ||
| 433 | .name = "fimc", | ||
| 434 | .id = 1, | ||
| 435 | .parent = &clk_h, | ||
| 436 | .enable = s5pc1xx_clk_d11_ctrl, | ||
| 437 | .ctrlbit = S5PC100_CLKGATE_D11_FIMC1, | ||
| 438 | }, { | ||
| 439 | .name = "fimc", | ||
| 440 | .id = 2, | ||
| 441 | .parent = &clk_h, | ||
| 442 | .enable = s5pc1xx_clk_d11_ctrl, | ||
| 443 | .ctrlbit = S5PC100_CLKGATE_D11_FIMC2, | ||
| 444 | }, { | ||
| 445 | .name = "jpeg", | ||
| 446 | .id = -1, | ||
| 447 | .parent = &clk_h, | ||
| 448 | .enable = s5pc1xx_clk_d11_ctrl, | ||
| 449 | .ctrlbit = S5PC100_CLKGATE_D11_JPEG, | ||
| 450 | }, { | ||
| 451 | .name = "g3d", | ||
| 452 | .id = -1, | ||
| 453 | .parent = &clk_h, | ||
| 454 | .enable = s5pc1xx_clk_d11_ctrl, | ||
| 455 | .ctrlbit = S5PC100_CLKGATE_D11_G3D, | ||
| 456 | }, | ||
| 457 | |||
| 458 | /* Multimedia2 (D1_2) devices */ | ||
| 459 | { | ||
| 460 | .name = "tv", | ||
| 461 | .id = -1, | ||
| 462 | .parent = &clk_h, | ||
| 463 | .enable = s5pc1xx_clk_d12_ctrl, | ||
| 464 | .ctrlbit = S5PC100_CLKGATE_D12_TV, | ||
| 465 | }, { | ||
| 466 | .name = "vp", | ||
| 467 | .id = -1, | ||
| 468 | .parent = &clk_h, | ||
| 469 | .enable = s5pc1xx_clk_d12_ctrl, | ||
| 470 | .ctrlbit = S5PC100_CLKGATE_D12_VP, | ||
| 471 | }, { | ||
| 472 | .name = "mixer", | ||
| 473 | .id = -1, | ||
| 474 | .parent = &clk_h, | ||
| 475 | .enable = s5pc1xx_clk_d12_ctrl, | ||
| 476 | .ctrlbit = S5PC100_CLKGATE_D12_MIXER, | ||
| 477 | }, { | ||
| 478 | .name = "hdmi", | ||
| 479 | .id = -1, | ||
| 480 | .parent = &clk_h, | ||
| 481 | .enable = s5pc1xx_clk_d12_ctrl, | ||
| 482 | .ctrlbit = S5PC100_CLKGATE_D12_HDMI, | ||
| 483 | }, { | ||
| 484 | .name = "mfc", | ||
| 485 | .id = -1, | ||
| 486 | .parent = &clk_h, | ||
| 487 | .enable = s5pc1xx_clk_d12_ctrl, | ||
| 488 | .ctrlbit = S5PC100_CLKGATE_D12_MFC, | ||
| 489 | }, | ||
| 490 | |||
| 491 | /* System (D1_3) devices */ | ||
| 492 | { | ||
| 493 | .name = "chipid", | ||
| 494 | .id = -1, | ||
| 495 | .parent = &clk_p, | ||
| 496 | .enable = s5pc1xx_clk_d13_ctrl, | ||
| 497 | .ctrlbit = S5PC100_CLKGATE_D13_CHIPID, | ||
| 498 | }, { | ||
| 499 | .name = "gpio", | ||
| 500 | .id = -1, | ||
| 501 | .parent = &clk_p, | ||
| 502 | .enable = s5pc1xx_clk_d13_ctrl, | ||
| 503 | .ctrlbit = S5PC100_CLKGATE_D13_GPIO, | ||
| 504 | }, { | ||
| 505 | .name = "apc", | ||
| 506 | .id = -1, | ||
| 507 | .parent = &clk_p, | ||
| 508 | .enable = s5pc1xx_clk_d13_ctrl, | ||
| 509 | .ctrlbit = S5PC100_CLKGATE_D13_APC, | ||
| 510 | }, { | ||
| 511 | .name = "iec", | ||
| 512 | .id = -1, | ||
| 513 | .parent = &clk_p, | ||
| 514 | .enable = s5pc1xx_clk_d13_ctrl, | ||
| 515 | .ctrlbit = S5PC100_CLKGATE_D13_IEC, | ||
| 516 | }, { | ||
| 517 | .name = "timers", | ||
| 518 | .id = -1, | ||
| 519 | .parent = &clk_p, | ||
| 520 | .enable = s5pc1xx_clk_d13_ctrl, | ||
| 521 | .ctrlbit = S5PC100_CLKGATE_D13_PWM, | ||
| 522 | }, { | ||
| 523 | .name = "systimer", | ||
| 524 | .id = -1, | ||
| 525 | .parent = &clk_p, | ||
| 526 | .enable = s5pc1xx_clk_d13_ctrl, | ||
| 527 | .ctrlbit = S5PC100_CLKGATE_D13_SYSTIMER, | ||
| 528 | }, { | ||
| 529 | .name = "watchdog", | ||
| 530 | .id = -1, | ||
| 531 | .parent = &clk_p, | ||
| 532 | .enable = s5pc1xx_clk_d13_ctrl, | ||
| 533 | .ctrlbit = S5PC100_CLKGATE_D13_WDT, | ||
| 534 | }, { | ||
| 535 | .name = "rtc", | ||
| 536 | .id = -1, | ||
| 537 | .parent = &clk_p, | ||
| 538 | .enable = s5pc1xx_clk_d13_ctrl, | ||
| 539 | .ctrlbit = S5PC100_CLKGATE_D13_RTC, | ||
| 540 | }, | ||
| 541 | |||
| 542 | /* Connectivity (D1_4) devices */ | ||
| 543 | { | ||
| 544 | .name = "uart", | ||
| 545 | .id = 0, | ||
| 546 | .parent = &clk_p, | ||
| 547 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 548 | .ctrlbit = S5PC100_CLKGATE_D14_UART0, | ||
| 549 | }, { | ||
| 550 | .name = "uart", | ||
| 551 | .id = 1, | ||
| 552 | .parent = &clk_p, | ||
| 553 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 554 | .ctrlbit = S5PC100_CLKGATE_D14_UART1, | ||
| 555 | }, { | ||
| 556 | .name = "uart", | ||
| 557 | .id = 2, | ||
| 558 | .parent = &clk_p, | ||
| 559 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 560 | .ctrlbit = S5PC100_CLKGATE_D14_UART2, | ||
| 561 | }, { | ||
| 562 | .name = "uart", | ||
| 563 | .id = 3, | ||
| 564 | .parent = &clk_p, | ||
| 565 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 566 | .ctrlbit = S5PC100_CLKGATE_D14_UART3, | ||
| 567 | }, { | ||
| 568 | .name = "i2c", | ||
| 569 | .id = -1, | ||
| 570 | .parent = &clk_p, | ||
| 571 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 572 | .ctrlbit = S5PC100_CLKGATE_D14_IIC, | ||
| 573 | }, { | ||
| 574 | .name = "hdmi-i2c", | ||
| 575 | .id = -1, | ||
| 576 | .parent = &clk_p, | ||
| 577 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 578 | .ctrlbit = S5PC100_CLKGATE_D14_HDMI_IIC, | ||
| 579 | }, { | ||
| 580 | .name = "spi", | ||
| 581 | .id = 0, | ||
| 582 | .parent = &clk_p, | ||
| 583 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 584 | .ctrlbit = S5PC100_CLKGATE_D14_SPI0, | ||
| 585 | }, { | ||
| 586 | .name = "spi", | ||
| 587 | .id = 1, | ||
| 588 | .parent = &clk_p, | ||
| 589 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 590 | .ctrlbit = S5PC100_CLKGATE_D14_SPI1, | ||
| 591 | }, { | ||
| 592 | .name = "spi", | ||
| 593 | .id = 2, | ||
| 594 | .parent = &clk_p, | ||
| 595 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 596 | .ctrlbit = S5PC100_CLKGATE_D14_SPI2, | ||
| 597 | }, { | ||
| 598 | .name = "irda", | ||
| 599 | .id = -1, | ||
| 600 | .parent = &clk_p, | ||
| 601 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 602 | .ctrlbit = S5PC100_CLKGATE_D14_IRDA, | ||
| 603 | }, { | ||
| 604 | .name = "hsitx", | ||
| 605 | .id = -1, | ||
| 606 | .parent = &clk_p, | ||
| 607 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 608 | .ctrlbit = S5PC100_CLKGATE_D14_HSITX, | ||
| 609 | }, { | ||
| 610 | .name = "hsirx", | ||
| 611 | .id = -1, | ||
| 612 | .parent = &clk_p, | ||
| 613 | .enable = s5pc1xx_clk_d14_ctrl, | ||
| 614 | .ctrlbit = S5PC100_CLKGATE_D14_HSIRX, | ||
| 615 | }, | ||
| 616 | |||
| 617 | /* Audio (D1_5) devices */ | ||
| 618 | { | ||
| 619 | .name = "iis", | ||
| 620 | .id = 0, | ||
| 621 | .parent = &clk_p, | ||
| 622 | .enable = s5pc1xx_clk_d15_ctrl, | ||
| 623 | .ctrlbit = S5PC100_CLKGATE_D15_IIS0, | ||
| 624 | }, { | ||
| 625 | .name = "iis", | ||
| 626 | .id = 1, | ||
| 627 | .parent = &clk_p, | ||
| 628 | .enable = s5pc1xx_clk_d15_ctrl, | ||
| 629 | .ctrlbit = S5PC100_CLKGATE_D15_IIS1, | ||
| 630 | }, { | ||
| 631 | .name = "iis", | ||
| 632 | .id = 2, | ||
| 633 | .parent = &clk_p, | ||
| 634 | .enable = s5pc1xx_clk_d15_ctrl, | ||
| 635 | .ctrlbit = S5PC100_CLKGATE_D15_IIS2, | ||
| 636 | }, { | ||
| 637 | .name = "ac97", | ||
| 638 | .id = -1, | ||
| 639 | .parent = &clk_p, | ||
| 640 | .enable = s5pc1xx_clk_d15_ctrl, | ||
| 641 | .ctrlbit = S5PC100_CLKGATE_D15_AC97, | ||
| 642 | }, { | ||
| 643 | .name = "pcm", | ||
| 644 | .id = 0, | ||
| 645 | .parent = &clk_p, | ||
| 646 | .enable = s5pc1xx_clk_d15_ctrl, | ||
| 647 | .ctrlbit = S5PC100_CLKGATE_D15_PCM0, | ||
| 648 | }, { | ||
| 649 | .name = "pcm", | ||
| 650 | .id = 1, | ||
| 651 | .parent = &clk_p, | ||
| 652 | .enable = s5pc1xx_clk_d15_ctrl, | ||
| 653 | .ctrlbit = S5PC100_CLKGATE_D15_PCM1, | ||
| 654 | }, { | ||
| 655 | .name = "spdif", | ||
| 656 | .id = -1, | ||
| 657 | .parent = &clk_p, | ||
| 658 | .enable = s5pc1xx_clk_d15_ctrl, | ||
| 659 | .ctrlbit = S5PC100_CLKGATE_D15_SPDIF, | ||
| 660 | }, { | ||
| 661 | .name = "adc", | ||
| 662 | .id = -1, | ||
| 663 | .parent = &clk_p, | ||
| 664 | .enable = s5pc1xx_clk_d15_ctrl, | ||
| 665 | .ctrlbit = S5PC100_CLKGATE_D15_TSADC, | ||
| 666 | }, { | ||
| 667 | .name = "keyif", | ||
| 668 | .id = -1, | ||
| 669 | .parent = &clk_p, | ||
| 670 | .enable = s5pc1xx_clk_d15_ctrl, | ||
| 671 | .ctrlbit = S5PC100_CLKGATE_D15_KEYIF, | ||
| 672 | }, { | ||
| 673 | .name = "cg", | ||
| 674 | .id = -1, | ||
| 675 | .parent = &clk_p, | ||
| 676 | .enable = s5pc1xx_clk_d15_ctrl, | ||
| 677 | .ctrlbit = S5PC100_CLKGATE_D15_CG, | ||
| 678 | }, | ||
| 679 | |||
| 680 | /* Audio (D2_0) devices: all disabled */ | ||
| 681 | |||
| 682 | /* Special Clocks 1 */ | ||
| 683 | { | ||
| 684 | .name = "sclk_hpm", | ||
| 685 | .id = -1, | ||
| 686 | .parent = NULL, | ||
| 687 | .enable = s5pc1xx_sclk0_ctrl, | ||
| 688 | .ctrlbit = S5PC1XX_CLKGATE_SCLK0_HPM, | ||
| 689 | }, { | ||
| 690 | .name = "sclk_onenand", | ||
| 691 | .id = -1, | ||
| 692 | .parent = NULL, | ||
| 693 | .enable = s5pc1xx_sclk0_ctrl, | ||
| 694 | .ctrlbit = S5PC100_CLKGATE_SCLK0_ONENAND, | ||
| 695 | }, { | ||
| 696 | .name = "sclk_spi_48", | ||
| 697 | .id = 0, | ||
| 698 | .parent = &clk_48m, | ||
| 699 | .enable = s5pc1xx_sclk0_ctrl, | ||
| 700 | .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI0_48, | ||
| 701 | }, { | ||
| 702 | .name = "sclk_spi_48", | ||
| 703 | .id = 1, | ||
| 704 | .parent = &clk_48m, | ||
| 705 | .enable = s5pc1xx_sclk0_ctrl, | ||
| 706 | .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI1_48, | ||
| 707 | }, { | ||
| 708 | .name = "sclk_spi_48", | ||
| 709 | .id = 2, | ||
| 710 | .parent = &clk_48m, | ||
| 711 | .enable = s5pc1xx_sclk0_ctrl, | ||
| 712 | .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI2_48, | ||
| 713 | }, { | ||
| 714 | .name = "sclk_mmc_48", | ||
| 715 | .id = 0, | ||
| 716 | .parent = &clk_48m, | ||
| 717 | .enable = s5pc1xx_sclk0_ctrl, | ||
| 718 | .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC0_48, | ||
| 719 | }, { | ||
| 720 | .name = "sclk_mmc_48", | ||
| 721 | .id = 1, | ||
| 722 | .parent = &clk_48m, | ||
| 723 | .enable = s5pc1xx_sclk0_ctrl, | ||
| 724 | .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC1_48, | ||
| 725 | }, { | ||
| 726 | .name = "sclk_mmc_48", | ||
| 727 | .id = 2, | ||
| 728 | .parent = &clk_48m, | ||
| 729 | .enable = s5pc1xx_sclk0_ctrl, | ||
| 730 | .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC2_48, | ||
| 731 | }, | ||
| 732 | |||
| 733 | /* Special Clocks 2 */ | ||
| 734 | { | ||
| 735 | .name = "sclk_tv_54", | ||
| 736 | .id = -1, | ||
| 737 | .parent = &clk_54m, | ||
| 738 | .enable = s5pc1xx_sclk1_ctrl, | ||
| 739 | .ctrlbit = S5PC100_CLKGATE_SCLK1_TV54, | ||
| 740 | }, { | ||
| 741 | .name = "sclk_vdac_54", | ||
| 742 | .id = -1, | ||
| 743 | .parent = &clk_54m, | ||
| 744 | .enable = s5pc1xx_sclk1_ctrl, | ||
| 745 | .ctrlbit = S5PC100_CLKGATE_SCLK1_VDAC54, | ||
| 746 | }, { | ||
| 747 | .name = "sclk_spdif", | ||
| 748 | .id = -1, | ||
| 749 | .parent = NULL, | ||
| 750 | .enable = s5pc1xx_sclk1_ctrl, | ||
| 751 | .ctrlbit = S5PC100_CLKGATE_SCLK1_SPDIF, | ||
| 752 | }, | ||
| 753 | }; | ||
| 754 | |||
| 755 | void __init s5pc1xx_register_clocks(void) | ||
| 756 | { | ||
| 757 | struct clk *clkp; | ||
| 758 | int ret; | ||
| 759 | int ptr; | ||
| 760 | |||
| 761 | clkp = init_clocks; | ||
| 762 | for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) { | ||
| 763 | ret = s3c24xx_register_clock(clkp); | ||
| 764 | if (ret < 0) { | ||
| 765 | printk(KERN_ERR "Failed to register clock %s (%d)\n", | ||
| 766 | clkp->name, ret); | ||
| 767 | } | ||
| 768 | } | ||
| 769 | |||
| 770 | clkp = init_clocks_disable; | ||
| 771 | for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) { | ||
| 772 | |||
| 773 | ret = s3c24xx_register_clock(clkp); | ||
| 774 | if (ret < 0) { | ||
| 775 | printk(KERN_ERR "Failed to register clock %s (%d)\n", | ||
| 776 | clkp->name, ret); | ||
| 777 | } | ||
| 778 | |||
| 779 | (clkp->enable)(clkp, 0); | ||
| 780 | } | ||
| 781 | |||
| 782 | s3c_pwmclk_init(); | ||
| 783 | } | ||
| 784 | static struct clk clk_fout_apll = { | ||
| 785 | .name = "fout_apll", | ||
| 786 | .id = -1, | ||
| 787 | }; | ||
| 788 | |||
| 789 | static struct clk *clk_src_apll_list[] = { | ||
| 790 | [0] = &clk_fin_apll, | ||
| 791 | [1] = &clk_fout_apll, | ||
| 792 | }; | ||
| 793 | |||
| 794 | static struct clk_sources clk_src_apll = { | ||
| 795 | .sources = clk_src_apll_list, | ||
| 796 | .nr_sources = ARRAY_SIZE(clk_src_apll_list), | ||
| 797 | }; | ||
| 798 | |||
| 799 | static struct clksrc_clk clk_mout_apll = { | ||
| 800 | .clk = { | ||
| 801 | .name = "mout_apll", | ||
| 802 | .id = -1, | ||
| 803 | }, | ||
| 804 | .shift = S5PC1XX_CLKSRC0_APLL_SHIFT, | ||
| 805 | .mask = S5PC1XX_CLKSRC0_APLL_MASK, | ||
| 806 | .sources = &clk_src_apll, | ||
| 807 | .reg_source = S5PC1XX_CLK_SRC0, | ||
| 808 | }; | ||
| 809 | |||
| 810 | static struct clk clk_fout_epll = { | ||
| 811 | .name = "fout_epll", | ||
| 812 | .id = -1, | ||
| 813 | }; | ||
| 814 | |||
| 815 | static struct clk *clk_src_epll_list[] = { | ||
| 816 | [0] = &clk_fin_epll, | ||
| 817 | [1] = &clk_fout_epll, | ||
| 818 | }; | ||
| 819 | |||
| 820 | static struct clk_sources clk_src_epll = { | ||
| 821 | .sources = clk_src_epll_list, | ||
| 822 | .nr_sources = ARRAY_SIZE(clk_src_epll_list), | ||
| 823 | }; | ||
| 824 | |||
| 825 | static struct clksrc_clk clk_mout_epll = { | ||
| 826 | .clk = { | ||
| 827 | .name = "mout_epll", | ||
| 828 | .id = -1, | ||
| 829 | }, | ||
| 830 | .shift = S5PC1XX_CLKSRC0_EPLL_SHIFT, | ||
| 831 | .mask = S5PC1XX_CLKSRC0_EPLL_MASK, | ||
| 832 | .sources = &clk_src_epll, | ||
| 833 | .reg_source = S5PC1XX_CLK_SRC0, | ||
| 834 | }; | ||
| 835 | |||
| 836 | static struct clk *clk_src_mpll_list[] = { | ||
| 837 | [0] = &clk_fin_mpll, | ||
| 838 | [1] = &clk_fout_mpll, | ||
| 839 | }; | ||
| 840 | |||
| 841 | static struct clk_sources clk_src_mpll = { | ||
| 842 | .sources = clk_src_mpll_list, | ||
| 843 | .nr_sources = ARRAY_SIZE(clk_src_mpll_list), | ||
| 844 | }; | ||
| 845 | |||
| 846 | static struct clksrc_clk clk_mout_mpll = { | ||
| 847 | .clk = { | ||
| 848 | .name = "mout_mpll", | ||
| 849 | .id = -1, | ||
| 850 | }, | ||
| 851 | .shift = S5PC1XX_CLKSRC0_MPLL_SHIFT, | ||
| 852 | .mask = S5PC1XX_CLKSRC0_MPLL_MASK, | ||
| 853 | .sources = &clk_src_mpll, | ||
| 854 | .reg_source = S5PC1XX_CLK_SRC0, | ||
| 855 | }; | ||
| 856 | |||
| 857 | static unsigned long s5pc1xx_clk_doutmpll_get_rate(struct clk *clk) | ||
| 858 | { | ||
| 859 | unsigned long rate = clk_get_rate(clk->parent); | ||
| 860 | unsigned long clkdiv; | ||
| 861 | |||
| 862 | printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate); | ||
| 863 | |||
| 864 | clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL_MASK; | ||
| 865 | rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL_SHIFT) + 1; | ||
| 866 | |||
| 867 | return rate; | ||
| 868 | } | ||
| 869 | |||
| 870 | static struct clk clk_dout_mpll = { | ||
| 871 | .name = "dout_mpll", | ||
| 872 | .id = -1, | ||
| 873 | .parent = &clk_mout_mpll.clk, | ||
| 874 | .get_rate = s5pc1xx_clk_doutmpll_get_rate, | ||
| 875 | }; | ||
| 876 | |||
| 877 | static unsigned long s5pc1xx_clk_doutmpll2_get_rate(struct clk *clk) | ||
| 878 | { | ||
| 879 | unsigned long rate = clk_get_rate(clk->parent); | ||
| 880 | unsigned long clkdiv; | ||
| 881 | |||
| 882 | printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate); | ||
| 883 | |||
| 884 | clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL2_MASK; | ||
| 885 | rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL2_SHIFT) + 1; | ||
| 886 | |||
| 887 | return rate; | ||
| 888 | } | ||
| 889 | |||
| 890 | struct clk clk_dout_mpll2 = { | ||
| 891 | .name = "dout_mpll2", | ||
| 892 | .id = -1, | ||
| 893 | .parent = &clk_mout_mpll.clk, | ||
| 894 | .get_rate = s5pc1xx_clk_doutmpll2_get_rate, | ||
| 895 | }; | ||
| 896 | |||
| 897 | static struct clk *clkset_uart_list[] = { | ||
| 898 | &clk_mout_epll.clk, | ||
| 899 | &clk_dout_mpll, | ||
| 900 | NULL, | ||
| 901 | NULL | ||
| 902 | }; | ||
| 903 | |||
| 904 | static struct clk_sources clkset_uart = { | ||
| 905 | .sources = clkset_uart_list, | ||
| 906 | .nr_sources = ARRAY_SIZE(clkset_uart_list), | ||
| 907 | }; | ||
| 908 | |||
| 909 | static inline struct clksrc_clk *to_clksrc(struct clk *clk) | ||
| 910 | { | ||
| 911 | return container_of(clk, struct clksrc_clk, clk); | ||
| 912 | } | ||
| 913 | |||
| 914 | static unsigned long s5pc1xx_getrate_clksrc(struct clk *clk) | ||
| 915 | { | ||
| 916 | struct clksrc_clk *sclk = to_clksrc(clk); | ||
| 917 | unsigned long rate = clk_get_rate(clk->parent); | ||
| 918 | u32 clkdiv = __raw_readl(sclk->reg_divider); | ||
| 919 | |||
| 920 | clkdiv >>= sclk->divider_shift; | ||
| 921 | clkdiv &= 0xf; | ||
| 922 | clkdiv++; | ||
| 923 | |||
| 924 | rate /= clkdiv; | ||
| 925 | return rate; | ||
| 926 | } | ||
| 927 | |||
| 928 | static int s5pc1xx_setrate_clksrc(struct clk *clk, unsigned long rate) | ||
| 929 | { | ||
| 930 | struct clksrc_clk *sclk = to_clksrc(clk); | ||
| 931 | void __iomem *reg = sclk->reg_divider; | ||
| 932 | unsigned int div; | ||
| 933 | u32 val; | ||
| 934 | |||
| 935 | rate = clk_round_rate(clk, rate); | ||
| 936 | div = clk_get_rate(clk->parent) / rate; | ||
| 937 | if (div > 16) | ||
| 938 | return -EINVAL; | ||
| 939 | |||
| 940 | val = __raw_readl(reg); | ||
| 941 | val &= ~(0xf << sclk->shift); | ||
| 942 | val |= (div - 1) << sclk->shift; | ||
| 943 | __raw_writel(val, reg); | ||
| 944 | |||
| 945 | return 0; | ||
| 946 | } | ||
| 947 | |||
| 948 | static int s5pc1xx_setparent_clksrc(struct clk *clk, struct clk *parent) | ||
| 949 | { | ||
| 950 | struct clksrc_clk *sclk = to_clksrc(clk); | ||
| 951 | struct clk_sources *srcs = sclk->sources; | ||
| 952 | u32 clksrc = __raw_readl(sclk->reg_source); | ||
| 953 | int src_nr = -1; | ||
| 954 | int ptr; | ||
| 955 | |||
| 956 | for (ptr = 0; ptr < srcs->nr_sources; ptr++) | ||
| 957 | if (srcs->sources[ptr] == parent) { | ||
| 958 | src_nr = ptr; | ||
| 959 | break; | ||
| 960 | } | ||
| 961 | |||
| 962 | if (src_nr >= 0) { | ||
| 963 | clksrc &= ~sclk->mask; | ||
| 964 | clksrc |= src_nr << sclk->shift; | ||
| 965 | |||
| 966 | __raw_writel(clksrc, sclk->reg_source); | ||
| 967 | return 0; | ||
| 968 | } | ||
| 969 | |||
| 970 | return -EINVAL; | ||
| 971 | } | ||
| 972 | |||
| 973 | static unsigned long s5pc1xx_roundrate_clksrc(struct clk *clk, | ||
| 974 | unsigned long rate) | ||
| 975 | { | ||
| 976 | unsigned long parent_rate = clk_get_rate(clk->parent); | ||
| 977 | int div; | ||
| 978 | |||
| 979 | if (rate > parent_rate) | ||
| 980 | rate = parent_rate; | ||
| 981 | else { | ||
| 982 | div = rate / parent_rate; | ||
| 983 | |||
| 984 | if (div == 0) | ||
| 985 | div = 1; | ||
| 986 | if (div > 16) | ||
| 987 | div = 16; | ||
| 988 | |||
| 989 | rate = parent_rate / div; | ||
| 990 | } | ||
| 991 | |||
| 992 | return rate; | ||
| 993 | } | ||
| 994 | |||
| 995 | static struct clksrc_clk clk_uart_uclk1 = { | ||
| 996 | .clk = { | ||
| 997 | .name = "uclk1", | ||
| 998 | .id = -1, | ||
| 999 | .ctrlbit = S5PC100_CLKGATE_SCLK0_UART, | ||
| 1000 | .enable = s5pc1xx_sclk0_ctrl, | ||
| 1001 | .set_parent = s5pc1xx_setparent_clksrc, | ||
| 1002 | .get_rate = s5pc1xx_getrate_clksrc, | ||
| 1003 | .set_rate = s5pc1xx_setrate_clksrc, | ||
| 1004 | .round_rate = s5pc1xx_roundrate_clksrc, | ||
| 1005 | }, | ||
| 1006 | .shift = S5PC100_CLKSRC1_UART_SHIFT, | ||
| 1007 | .mask = S5PC100_CLKSRC1_UART_MASK, | ||
| 1008 | .sources = &clkset_uart, | ||
| 1009 | .divider_shift = S5PC100_CLKDIV2_UART_SHIFT, | ||
| 1010 | .reg_divider = S5PC1XX_CLK_DIV2, | ||
| 1011 | .reg_source = S5PC1XX_CLK_SRC1, | ||
| 1012 | }; | ||
| 1013 | |||
| 1014 | /* Clock initialisation code */ | ||
| 1015 | |||
| 1016 | static struct clksrc_clk *init_parents[] = { | ||
| 1017 | &clk_mout_apll, | ||
| 1018 | &clk_mout_epll, | ||
| 1019 | &clk_mout_mpll, | ||
| 1020 | &clk_uart_uclk1, | ||
| 1021 | }; | ||
| 1022 | |||
| 1023 | static void __init_or_cpufreq s5pc1xx_set_clksrc(struct clksrc_clk *clk) | ||
| 1024 | { | ||
| 1025 | struct clk_sources *srcs = clk->sources; | ||
| 1026 | u32 clksrc = __raw_readl(clk->reg_source); | ||
| 1027 | |||
| 1028 | clksrc &= clk->mask; | ||
| 1029 | clksrc >>= clk->shift; | ||
| 1030 | |||
| 1031 | if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) { | ||
| 1032 | printk(KERN_ERR "%s: bad source %d\n", | ||
| 1033 | clk->clk.name, clksrc); | ||
| 1034 | return; | ||
| 1035 | } | ||
| 1036 | |||
| 1037 | clk->clk.parent = srcs->sources[clksrc]; | ||
| 1038 | |||
| 1039 | printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n", | ||
| 1040 | clk->clk.name, clk->clk.parent->name, clksrc, | ||
| 1041 | clk_get_rate(&clk->clk)); | ||
| 1042 | } | ||
| 1043 | |||
| 1044 | #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) | ||
| 1045 | |||
| 1046 | void __init_or_cpufreq s5pc100_setup_clocks(void) | ||
| 1047 | { | ||
| 1048 | struct clk *xtal_clk; | ||
| 1049 | unsigned long xtal; | ||
| 1050 | unsigned long armclk; | ||
| 1051 | unsigned long hclkd0; | ||
| 1052 | unsigned long hclk; | ||
| 1053 | unsigned long pclkd0; | ||
| 1054 | unsigned long pclk; | ||
| 1055 | unsigned long apll; | ||
| 1056 | unsigned long mpll; | ||
| 1057 | unsigned long hpll; | ||
| 1058 | unsigned long epll; | ||
| 1059 | unsigned int ptr; | ||
| 1060 | u32 clkdiv0, clkdiv1; | ||
| 1061 | |||
| 1062 | printk(KERN_DEBUG "%s: registering clocks\n", __func__); | ||
| 1063 | |||
| 1064 | clkdiv0 = __raw_readl(S5PC1XX_CLK_DIV0); | ||
| 1065 | clkdiv1 = __raw_readl(S5PC1XX_CLK_DIV1); | ||
| 1066 | |||
| 1067 | printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n", | ||
| 1068 | __func__, clkdiv0, clkdiv1); | ||
| 1069 | |||
| 1070 | xtal_clk = clk_get(NULL, "xtal"); | ||
| 1071 | BUG_ON(IS_ERR(xtal_clk)); | ||
| 1072 | |||
| 1073 | xtal = clk_get_rate(xtal_clk); | ||
| 1074 | clk_put(xtal_clk); | ||
| 1075 | |||
| 1076 | printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); | ||
| 1077 | |||
| 1078 | apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_APLL_CON)); | ||
| 1079 | mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_MPLL_CON)); | ||
| 1080 | epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_EPLL_CON)); | ||
| 1081 | hpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_HPLL_CON)); | ||
| 1082 | |||
| 1083 | printk(KERN_INFO "S5PC100: PLL settings, A=%ld, M=%ld, E=%ld, H=%ld\n", | ||
| 1084 | apll, mpll, epll, hpll); | ||
| 1085 | |||
| 1086 | armclk = apll / GET_DIV(clkdiv0, S5PC1XX_CLKDIV0_APLL); | ||
| 1087 | armclk = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_ARM); | ||
| 1088 | hclkd0 = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_D0); | ||
| 1089 | pclkd0 = hclkd0 / GET_DIV(clkdiv0, S5PC100_CLKDIV0_PCLKD0); | ||
| 1090 | hclk = mpll / GET_DIV(clkdiv1, S5PC100_CLKDIV1_D1); | ||
| 1091 | pclk = hclk / GET_DIV(clkdiv1, S5PC100_CLKDIV1_PCLKD1); | ||
| 1092 | |||
| 1093 | printk(KERN_INFO "S5PC100: ARMCLK=%ld, HCLKD0=%ld, PCLKD0=%ld, HCLK=%ld, PCLK=%ld\n", | ||
| 1094 | armclk, hclkd0, pclkd0, hclk, pclk); | ||
| 1095 | |||
| 1096 | clk_fout_apll.rate = apll; | ||
| 1097 | clk_fout_mpll.rate = mpll; | ||
| 1098 | clk_fout_epll.rate = epll; | ||
| 1099 | clk_fout_apll.rate = apll; | ||
| 1100 | |||
| 1101 | clk_h.rate = hclk; | ||
| 1102 | clk_p.rate = pclk; | ||
| 1103 | |||
| 1104 | for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++) | ||
| 1105 | s5pc1xx_set_clksrc(init_parents[ptr]); | ||
| 1106 | } | ||
| 1107 | |||
| 1108 | static struct clk *clks[] __initdata = { | ||
| 1109 | &clk_ext_xtal_mux, | ||
| 1110 | &clk_mout_epll.clk, | ||
| 1111 | &clk_fout_epll, | ||
| 1112 | &clk_mout_mpll.clk, | ||
| 1113 | &clk_dout_mpll, | ||
| 1114 | &clk_uart_uclk1.clk, | ||
| 1115 | &clk_ext, | ||
| 1116 | &clk_epll, | ||
| 1117 | &clk_27m, | ||
| 1118 | &clk_48m, | ||
| 1119 | &clk_54m, | ||
| 1120 | }; | ||
| 1121 | |||
| 1122 | void __init s5pc100_register_clocks(void) | ||
| 1123 | { | ||
| 1124 | struct clk *clkp; | ||
| 1125 | int ret; | ||
| 1126 | int ptr; | ||
| 1127 | |||
| 1128 | for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) { | ||
| 1129 | clkp = clks[ptr]; | ||
| 1130 | ret = s3c24xx_register_clock(clkp); | ||
| 1131 | if (ret < 0) { | ||
| 1132 | printk(KERN_ERR "Failed to register clock %s (%d)\n", | ||
| 1133 | clkp->name, ret); | ||
| 1134 | } | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | clk_mpll.parent = &clk_mout_mpll.clk; | ||
| 1138 | clk_epll.parent = &clk_mout_epll.clk; | ||
| 1139 | } | ||
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-init.c b/arch/arm/plat-s5pc1xx/s5pc100-init.c new file mode 100644 index 000000000000..c58710884ceb --- /dev/null +++ b/arch/arm/plat-s5pc1xx/s5pc100-init.c | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | /* linux/arch/arm/plat-s5pc1xx/s5pc100-init.c | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * S5PC100 - CPU initialisation (common with other S5PC1XX chips) | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/types.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | |||
| 17 | #include <plat/cpu.h> | ||
| 18 | #include <plat/devs.h> | ||
| 19 | #include <plat/s5pc100.h> | ||
| 20 | |||
| 21 | /* uart registration process */ | ||
| 22 | |||
| 23 | void __init s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) | ||
| 24 | { | ||
| 25 | /* The driver name is s3c6400-uart to reuse s3c6400_serial_drv */ | ||
| 26 | s3c24xx_init_uartdevs("s3c6400-uart", s5pc1xx_uart_resources, cfg, no); | ||
| 27 | } | ||
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c0.c b/arch/arm/plat-s5pc1xx/setup-i2c0.c new file mode 100644 index 000000000000..3d00c025fffb --- /dev/null +++ b/arch/arm/plat-s5pc1xx/setup-i2c0.c | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* linux/arch/arm/plat-s5pc1xx/setup-i2c0.c | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * Base S5PC1XX I2C bus 0 gpio configuration | ||
| 7 | * | ||
| 8 | * Based on plat-s3c64xx/setup-i2c0.c | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/types.h> | ||
| 17 | |||
| 18 | struct platform_device; /* don't need the contents */ | ||
| 19 | |||
| 20 | #include <plat/iic.h> | ||
| 21 | |||
| 22 | void s3c_i2c0_cfg_gpio(struct platform_device *dev) | ||
| 23 | { | ||
| 24 | /* Pin configuration would be needed */ | ||
| 25 | } | ||
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c1.c b/arch/arm/plat-s5pc1xx/setup-i2c1.c new file mode 100644 index 000000000000..c8f3ca42f51d --- /dev/null +++ b/arch/arm/plat-s5pc1xx/setup-i2c1.c | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | /* linux/arch/arm/plat-s3c64xx/setup-i2c1.c | ||
| 2 | * | ||
| 3 | * Copyright 2009 Samsung Electronics Co. | ||
| 4 | * Byungho Min <bhmin@samsung.com> | ||
| 5 | * | ||
| 6 | * Base S5PC1XX I2C bus 1 gpio configuration | ||
| 7 | * | ||
| 8 | * Based on plat-s3c64xx/setup-i2c1.c | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/types.h> | ||
| 17 | |||
| 18 | struct platform_device; /* don't need the contents */ | ||
| 19 | |||
| 20 | #include <plat/iic.h> | ||
| 21 | |||
| 22 | void s3c_i2c1_cfg_gpio(struct platform_device *dev) | ||
| 23 | { | ||
| 24 | /* Pin configuration would be needed */ | ||
| 25 | } | ||
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 33026eff2aa4..c8c55b469342 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | # | 12 | # |
| 13 | # http://www.arm.linux.org.uk/developer/machines/?action=new | 13 | # http://www.arm.linux.org.uk/developer/machines/?action=new |
| 14 | # | 14 | # |
| 15 | # Last update: Sat Jun 20 22:28:39 2009 | 15 | # Last update: Sat Sep 12 12:00:16 2009 |
| 16 | # | 16 | # |
| 17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number | 17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number |
| 18 | # | 18 | # |
| @@ -1769,7 +1769,7 @@ mx31cicada MACH_MX31CICADA MX31CICADA 1777 | |||
| 1769 | mi424wr MACH_MI424WR MI424WR 1778 | 1769 | mi424wr MACH_MI424WR MI424WR 1778 |
| 1770 | axs_ultrax MACH_AXS_ULTRAX AXS_ULTRAX 1779 | 1770 | axs_ultrax MACH_AXS_ULTRAX AXS_ULTRAX 1779 |
| 1771 | at572d940deb MACH_AT572D940DEB AT572D940DEB 1780 | 1771 | at572d940deb MACH_AT572D940DEB AT572D940DEB 1780 |
| 1772 | davinci_da8xx_evm MACH_DAVINCI_DA8XX_EVM DAVINCI_DA8XX_EVM 1781 | 1772 | davinci_da830_evm MACH_DAVINCI_DA830_EVM DAVINCI_DA830_EVM 1781 |
| 1773 | ep9302 MACH_EP9302 EP9302 1782 | 1773 | ep9302 MACH_EP9302 EP9302 1782 |
| 1774 | at572d940hfek MACH_AT572D940HFEB AT572D940HFEB 1783 | 1774 | at572d940hfek MACH_AT572D940HFEB AT572D940HFEB 1783 |
| 1775 | cybook3 MACH_CYBOOK3 CYBOOK3 1784 | 1775 | cybook3 MACH_CYBOOK3 CYBOOK3 1784 |
| @@ -1962,7 +1962,7 @@ ethernut5 MACH_ETHERNUT5 ETHERNUT5 1971 | |||
| 1962 | arm11 MACH_ARM11 ARM11 1972 | 1962 | arm11 MACH_ARM11 ARM11 1972 |
| 1963 | cpuat9260 MACH_CPUAT9260 CPUAT9260 1973 | 1963 | cpuat9260 MACH_CPUAT9260 CPUAT9260 1973 |
| 1964 | cpupxa255 MACH_CPUPXA255 CPUPXA255 1974 | 1964 | cpupxa255 MACH_CPUPXA255 CPUPXA255 1974 |
| 1965 | cpuimx27 MACH_CPUIMX27 CPUIMX27 1975 | 1965 | eukrea_cpuimx27 MACH_CPUIMX27 CPUIMX27 1975 |
| 1966 | cheflux MACH_CHEFLUX CHEFLUX 1976 | 1966 | cheflux MACH_CHEFLUX CHEFLUX 1976 |
| 1967 | eb_cpux9k2 MACH_EB_CPUX9K2 EB_CPUX9K2 1977 | 1967 | eb_cpux9k2 MACH_EB_CPUX9K2 EB_CPUX9K2 1977 |
| 1968 | opcotec MACH_OPCOTEC OPCOTEC 1978 | 1968 | opcotec MACH_OPCOTEC OPCOTEC 1978 |
| @@ -2249,14 +2249,14 @@ omap3_phrazer MACH_OMAP3_PHRAZER OMAP3_PHRAZER 2261 | |||
| 2249 | darwin MACH_DARWIN DARWIN 2262 | 2249 | darwin MACH_DARWIN DARWIN 2262 |
| 2250 | oratiscomu MACH_ORATISCOMU ORATISCOMU 2263 | 2250 | oratiscomu MACH_ORATISCOMU ORATISCOMU 2263 |
| 2251 | rtsbc20 MACH_RTSBC20 RTSBC20 2264 | 2251 | rtsbc20 MACH_RTSBC20 RTSBC20 2264 |
| 2252 | i780 MACH_I780 I780 2265 | 2252 | sgh_i780 MACH_I780 I780 2265 |
| 2253 | gemini324 MACH_GEMINI324 GEMINI324 2266 | 2253 | gemini324 MACH_GEMINI324 GEMINI324 2266 |
| 2254 | oratislan MACH_ORATISLAN ORATISLAN 2267 | 2254 | oratislan MACH_ORATISLAN ORATISLAN 2267 |
| 2255 | oratisalog MACH_ORATISALOG ORATISALOG 2268 | 2255 | oratisalog MACH_ORATISALOG ORATISALOG 2268 |
| 2256 | oratismadi MACH_ORATISMADI ORATISMADI 2269 | 2256 | oratismadi MACH_ORATISMADI ORATISMADI 2269 |
| 2257 | oratisot16 MACH_ORATISOT16 ORATISOT16 2270 | 2257 | oratisot16 MACH_ORATISOT16 ORATISOT16 2270 |
| 2258 | oratisdesk MACH_ORATISDESK ORATISDESK 2271 | 2258 | oratisdesk MACH_ORATISDESK ORATISDESK 2271 |
| 2259 | v2p_ca9 MACH_V2P_CA9 V2P_CA9 2272 | 2259 | v2_ca9 MACH_V2P_CA9 V2P_CA9 2272 |
| 2260 | sintexo MACH_SINTEXO SINTEXO 2273 | 2260 | sintexo MACH_SINTEXO SINTEXO 2273 |
| 2261 | cm3389 MACH_CM3389 CM3389 2274 | 2261 | cm3389 MACH_CM3389 CM3389 2274 |
| 2262 | omap3_cio MACH_OMAP3_CIO OMAP3_CIO 2275 | 2262 | omap3_cio MACH_OMAP3_CIO OMAP3_CIO 2275 |
| @@ -2280,3 +2280,132 @@ htcrhodium MACH_HTCRHODIUM HTCRHODIUM 2292 | |||
| 2280 | htctopaz MACH_HTCTOPAZ HTCTOPAZ 2293 | 2280 | htctopaz MACH_HTCTOPAZ HTCTOPAZ 2293 |
| 2281 | matrix504 MACH_MATRIX504 MATRIX504 2294 | 2281 | matrix504 MACH_MATRIX504 MATRIX504 2294 |
| 2282 | mrfsa MACH_MRFSA MRFSA 2295 | 2282 | mrfsa MACH_MRFSA MRFSA 2295 |
| 2283 | sc_p270 MACH_SC_P270 SC_P270 2296 | ||
| 2284 | atlas5_evb MACH_ATLAS5_EVB ATLAS5_EVB 2297 | ||
| 2285 | pelco_lobox MACH_PELCO_LOBOX PELCO_LOBOX 2298 | ||
| 2286 | dilax_pcu200 MACH_DILAX_PCU200 DILAX_PCU200 2299 | ||
| 2287 | leonardo MACH_LEONARDO LEONARDO 2300 | ||
| 2288 | zoran_approach7 MACH_ZORAN_APPROACH7 ZORAN_APPROACH7 2301 | ||
| 2289 | dp6xx MACH_DP6XX DP6XX 2302 | ||
| 2290 | bcm2153_vesper MACH_BCM2153_VESPER BCM2153_VESPER 2303 | ||
| 2291 | mahimahi MACH_MAHIMAHI MAHIMAHI 2304 | ||
| 2292 | clickc MACH_CLICKC CLICKC 2305 | ||
| 2293 | zb_gateway MACH_ZB_GATEWAY ZB_GATEWAY 2306 | ||
| 2294 | tazcard MACH_TAZCARD TAZCARD 2307 | ||
| 2295 | tazdev MACH_TAZDEV TAZDEV 2308 | ||
| 2296 | annax_cb_arm MACH_ANNAX_CB_ARM ANNAX_CB_ARM 2309 | ||
| 2297 | annax_dm3 MACH_ANNAX_DM3 ANNAX_DM3 2310 | ||
| 2298 | cerebric MACH_CEREBRIC CEREBRIC 2311 | ||
| 2299 | orca MACH_ORCA ORCA 2312 | ||
| 2300 | pc9260 MACH_PC9260 PC9260 2313 | ||
| 2301 | ems285a MACH_EMS285A EMS285A 2314 | ||
| 2302 | gec2410 MACH_GEC2410 GEC2410 2315 | ||
| 2303 | gec2440 MACH_GEC2440 GEC2440 2316 | ||
| 2304 | mw903 MACH_ARCH_MW903 ARCH_MW903 2317 | ||
| 2305 | mw2440 MACH_MW2440 MW2440 2318 | ||
| 2306 | ecac2378 MACH_ECAC2378 ECAC2378 2319 | ||
| 2307 | tazkiosk MACH_TAZKIOSK TAZKIOSK 2320 | ||
| 2308 | whiterabbit_mch MACH_WHITERABBIT_MCH WHITERABBIT_MCH 2321 | ||
| 2309 | sbox9263 MACH_SBOX9263 SBOX9263 2322 | ||
| 2310 | oreo MACH_OREO OREO 2323 | ||
| 2311 | smdk6442 MACH_SMDK6442 SMDK6442 2324 | ||
| 2312 | openrd_base MACH_OPENRD_BASE OPENRD_BASE 2325 | ||
| 2313 | incredible MACH_INCREDIBLE INCREDIBLE 2326 | ||
| 2314 | incrediblec MACH_INCREDIBLEC INCREDIBLEC 2327 | ||
| 2315 | heroct MACH_HEROCT HEROCT 2328 | ||
| 2316 | mmnet1000 MACH_MMNET1000 MMNET1000 2329 | ||
| 2317 | devkit8000 MACH_DEVKIT8000 DEVKIT8000 2330 | ||
| 2318 | devkit9000 MACH_DEVKIT9000 DEVKIT9000 2331 | ||
| 2319 | mx31txtr MACH_MX31TXTR MX31TXTR 2332 | ||
| 2320 | u380 MACH_U380 U380 2333 | ||
| 2321 | oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334 | ||
| 2322 | npcmx50 MACH_NPCMX50 NPCMX50 2335 | ||
| 2323 | mx51_lange51 MACH_MX51_LANGE51 MX51_LANGE51 2336 | ||
| 2324 | mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337 | ||
| 2325 | riom MACH_RIOM RIOM 2338 | ||
| 2326 | comcas MACH_COMCAS COMCAS 2339 | ||
| 2327 | wsi_mx27 MACH_WSI_MX27 WSI_MX27 2340 | ||
| 2328 | cm_t35 MACH_CM_T35 CM_T35 2341 | ||
| 2329 | net2big MACH_NET2BIG NET2BIG 2342 | ||
| 2330 | motorola_a1600 MACH_MOTOROLA_A1600 MOTOROLA_A1600 2343 | ||
| 2331 | igep0020 MACH_IGEP0020 IGEP0020 2344 | ||
| 2332 | igep0010 MACH_IGEP0010 IGEP0010 2345 | ||
| 2333 | mv6281gtwge2 MACH_MV6281GTWGE2 MV6281GTWGE2 2346 | ||
| 2334 | scat100 MACH_SCAT100 SCAT100 2347 | ||
| 2335 | sanmina MACH_SANMINA SANMINA 2348 | ||
| 2336 | momento MACH_MOMENTO MOMENTO 2349 | ||
| 2337 | nuc9xx MACH_NUC9XX NUC9XX 2350 | ||
| 2338 | nuc910evb MACH_NUC910EVB NUC910EVB 2351 | ||
| 2339 | nuc920evb MACH_NUC920EVB NUC920EVB 2352 | ||
| 2340 | nuc950evb MACH_NUC950EVB NUC950EVB 2353 | ||
| 2341 | nuc945evb MACH_NUC945EVB NUC945EVB 2354 | ||
| 2342 | nuc960evb MACH_NUC960EVB NUC960EVB 2355 | ||
| 2343 | nuc932evb MACH_NUC932EVB NUC932EVB 2356 | ||
| 2344 | nuc900 MACH_NUC900 NUC900 2357 | ||
| 2345 | sd1soc MACH_SD1SOC SD1SOC 2358 | ||
| 2346 | ln2440bc MACH_LN2440BC LN2440BC 2359 | ||
| 2347 | rsbc MACH_RSBC RSBC 2360 | ||
| 2348 | openrd_client MACH_OPENRD_CLIENT OPENRD_CLIENT 2361 | ||
| 2349 | hpipaq11x MACH_HPIPAQ11X HPIPAQ11X 2362 | ||
| 2350 | wayland MACH_WAYLAND WAYLAND 2363 | ||
| 2351 | acnbsx102 MACH_ACNBSX102 ACNBSX102 2364 | ||
| 2352 | hwat91 MACH_HWAT91 HWAT91 2365 | ||
| 2353 | at91sam9263cs MACH_AT91SAM9263CS AT91SAM9263CS 2366 | ||
| 2354 | csb732 MACH_CSB732 CSB732 2367 | ||
| 2355 | u8500 MACH_U8500 U8500 2368 | ||
| 2356 | huqiu MACH_HUQIU HUQIU 2369 | ||
| 2357 | mx51_kunlun MACH_MX51_KUNLUN MX51_KUNLUN 2370 | ||
| 2358 | pmt1g MACH_PMT1G PMT1G 2371 | ||
| 2359 | htcelf MACH_HTCELF HTCELF 2372 | ||
| 2360 | armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373 | ||
| 2361 | armadillo440 MACH_ARMADILLO440 ARMADILLO440 2374 | ||
| 2362 | u_chip_dual_arm MACH_U_CHIP_DUAL_ARM U_CHIP_DUAL_ARM 2375 | ||
| 2363 | csr_bdb3 MACH_CSR_BDB3 CSR_BDB3 2376 | ||
| 2364 | dolby_cat1018 MACH_DOLBY_CAT1018 DOLBY_CAT1018 2377 | ||
| 2365 | hy9307 MACH_HY9307 HY9307 2378 | ||
| 2366 | aspire_easystore MACH_A_ES A_ES 2379 | ||
| 2367 | davinci_irif MACH_DAVINCI_IRIF DAVINCI_IRIF 2380 | ||
| 2368 | agama9263 MACH_AGAMA9263 AGAMA9263 2381 | ||
| 2369 | marvell_jasper MACH_MARVELL_JASPER MARVELL_JASPER 2382 | ||
| 2370 | flint MACH_FLINT FLINT 2383 | ||
| 2371 | tavorevb3 MACH_TAVOREVB3 TAVOREVB3 2384 | ||
| 2372 | sch_m490 MACH_SCH_M490 SCH_M490 2386 | ||
| 2373 | rbl01 MACH_RBL01 RBL01 2387 | ||
| 2374 | omnifi MACH_OMNIFI OMNIFI 2388 | ||
| 2375 | otavalo MACH_OTAVALO OTAVALO 2389 | ||
| 2376 | sienna MACH_SIENNA SIENNA 2390 | ||
| 2377 | htc_excalibur_s620 MACH_HTC_EXCALIBUR_S620 HTC_EXCALIBUR_S620 2391 | ||
| 2378 | htc_opal MACH_HTC_OPAL HTC_OPAL 2392 | ||
| 2379 | touchbook MACH_TOUCHBOOK TOUCHBOOK 2393 | ||
| 2380 | latte MACH_LATTE LATTE 2394 | ||
| 2381 | xa200 MACH_XA200 XA200 2395 | ||
| 2382 | nimrod MACH_NIMROD NIMROD 2396 | ||
| 2383 | cc9p9215_3g MACH_CC9P9215_3G CC9P9215_3G 2397 | ||
| 2384 | cc9p9215_3gjs MACH_CC9P9215_3GJS CC9P9215_3GJS 2398 | ||
| 2385 | tk71 MACH_TK71 TK71 2399 | ||
| 2386 | comham3525 MACH_COMHAM3525 COMHAM3525 2400 | ||
| 2387 | mx31erebus MACH_MX31EREBUS MX31EREBUS 2401 | ||
| 2388 | mcardmx27 MACH_MCARDMX27 MCARDMX27 2402 | ||
| 2389 | paradise MACH_PARADISE PARADISE 2403 | ||
| 2390 | tide MACH_TIDE TIDE 2404 | ||
| 2391 | wzl2440 MACH_WZL2440 WZL2440 2405 | ||
| 2392 | sdrdemo MACH_SDRDEMO SDRDEMO 2406 | ||
| 2393 | ethercan2 MACH_ETHERCAN2 ETHERCAN2 2407 | ||
| 2394 | ecmimg20 MACH_ECMIMG20 ECMIMG20 2408 | ||
| 2395 | omap_dragon MACH_OMAP_DRAGON OMAP_DRAGON 2409 | ||
| 2396 | halo MACH_HALO HALO 2410 | ||
| 2397 | huangshan MACH_HUANGSHAN HUANGSHAN 2411 | ||
| 2398 | vl_ma2sc MACH_VL_MA2SC VL_MA2SC 2412 | ||
| 2399 | raumfeld_rc MACH_RAUMFELD_RC RAUMFELD_RC 2413 | ||
| 2400 | raumfeld_connector MACH_RAUMFELD_CONNECTOR RAUMFELD_CONNECTOR 2414 | ||
| 2401 | raumfeld_speaker MACH_RAUMFELD_SPEAKER RAUMFELD_SPEAKER 2415 | ||
| 2402 | multibus_master MACH_MULTIBUS_MASTER MULTIBUS_MASTER 2416 | ||
| 2403 | multibus_pbk MACH_MULTIBUS_PBK MULTIBUS_PBK 2417 | ||
| 2404 | tnetv107x MACH_TNETV107X TNETV107X 2418 | ||
| 2405 | snake MACH_SNAKE SNAKE 2419 | ||
| 2406 | cwmx27 MACH_CWMX27 CWMX27 2420 | ||
| 2407 | sch_m480 MACH_SCH_M480 SCH_M480 2421 | ||
| 2408 | platypus MACH_PLATYPUS PLATYPUS 2422 | ||
| 2409 | pss2 MACH_PSS2 PSS2 2423 | ||
| 2410 | davinci_apm150 MACH_DAVINCI_APM150 DAVINCI_APM150 2424 | ||
| 2411 | str9100 MACH_STR9100 STR9100 2425 | ||
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index a2bed62aec21..4fa9903b83cf 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S | |||
| @@ -42,6 +42,7 @@ ENTRY(vfp_null_entry) | |||
| 42 | mov pc, lr | 42 | mov pc, lr |
| 43 | ENDPROC(vfp_null_entry) | 43 | ENDPROC(vfp_null_entry) |
| 44 | 44 | ||
| 45 | .align 2 | ||
| 45 | .LCvfp: | 46 | .LCvfp: |
| 46 | .word vfp_vector | 47 | .word vfp_vector |
| 47 | 48 | ||
| @@ -61,6 +62,7 @@ ENTRY(vfp_testing_entry) | |||
| 61 | mov pc, r9 @ we have handled the fault | 62 | mov pc, r9 @ we have handled the fault |
| 62 | ENDPROC(vfp_testing_entry) | 63 | ENDPROC(vfp_testing_entry) |
| 63 | 64 | ||
| 65 | .align 2 | ||
| 64 | VFP_arch_address: | 66 | VFP_arch_address: |
| 65 | .word VFP_arch | 67 | .word VFP_arch |
| 66 | 68 | ||
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index 1aeae38725dd..66dc2d03b7fc 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S | |||
| @@ -209,40 +209,55 @@ ENDPROC(vfp_save_state) | |||
| 209 | last_VFP_context_address: | 209 | last_VFP_context_address: |
| 210 | .word last_VFP_context | 210 | .word last_VFP_context |
| 211 | 211 | ||
| 212 | ENTRY(vfp_get_float) | 212 | .macro tbl_branch, base, tmp, shift |
| 213 | add pc, pc, r0, lsl #3 | 213 | #ifdef CONFIG_THUMB2_KERNEL |
| 214 | adr \tmp, 1f | ||
| 215 | add \tmp, \tmp, \base, lsl \shift | ||
| 216 | mov pc, \tmp | ||
| 217 | #else | ||
| 218 | add pc, pc, \base, lsl \shift | ||
| 214 | mov r0, r0 | 219 | mov r0, r0 |
| 220 | #endif | ||
| 221 | 1: | ||
| 222 | .endm | ||
| 223 | |||
| 224 | ENTRY(vfp_get_float) | ||
| 225 | tbl_branch r0, r3, #3 | ||
| 215 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | 226 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
| 216 | mrc p10, 0, r0, c\dr, c0, 0 @ fmrs r0, s0 | 227 | 1: mrc p10, 0, r0, c\dr, c0, 0 @ fmrs r0, s0 |
| 217 | mov pc, lr | 228 | mov pc, lr |
| 218 | mrc p10, 0, r0, c\dr, c0, 4 @ fmrs r0, s1 | 229 | .org 1b + 8 |
| 230 | 1: mrc p10, 0, r0, c\dr, c0, 4 @ fmrs r0, s1 | ||
| 219 | mov pc, lr | 231 | mov pc, lr |
| 232 | .org 1b + 8 | ||
| 220 | .endr | 233 | .endr |
| 221 | ENDPROC(vfp_get_float) | 234 | ENDPROC(vfp_get_float) |
| 222 | 235 | ||
| 223 | ENTRY(vfp_put_float) | 236 | ENTRY(vfp_put_float) |
| 224 | add pc, pc, r1, lsl #3 | 237 | tbl_branch r1, r3, #3 |
| 225 | mov r0, r0 | ||
| 226 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | 238 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
| 227 | mcr p10, 0, r0, c\dr, c0, 0 @ fmsr r0, s0 | 239 | 1: mcr p10, 0, r0, c\dr, c0, 0 @ fmsr r0, s0 |
| 228 | mov pc, lr | 240 | mov pc, lr |
| 229 | mcr p10, 0, r0, c\dr, c0, 4 @ fmsr r0, s1 | 241 | .org 1b + 8 |
| 242 | 1: mcr p10, 0, r0, c\dr, c0, 4 @ fmsr r0, s1 | ||
| 230 | mov pc, lr | 243 | mov pc, lr |
| 244 | .org 1b + 8 | ||
| 231 | .endr | 245 | .endr |
| 232 | ENDPROC(vfp_put_float) | 246 | ENDPROC(vfp_put_float) |
| 233 | 247 | ||
| 234 | ENTRY(vfp_get_double) | 248 | ENTRY(vfp_get_double) |
| 235 | add pc, pc, r0, lsl #3 | 249 | tbl_branch r0, r3, #3 |
| 236 | mov r0, r0 | ||
| 237 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | 250 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
| 238 | fmrrd r0, r1, d\dr | 251 | 1: fmrrd r0, r1, d\dr |
| 239 | mov pc, lr | 252 | mov pc, lr |
| 253 | .org 1b + 8 | ||
| 240 | .endr | 254 | .endr |
| 241 | #ifdef CONFIG_VFPv3 | 255 | #ifdef CONFIG_VFPv3 |
| 242 | @ d16 - d31 registers | 256 | @ d16 - d31 registers |
| 243 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | 257 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
| 244 | mrrc p11, 3, r0, r1, c\dr @ fmrrd r0, r1, d\dr | 258 | 1: mrrc p11, 3, r0, r1, c\dr @ fmrrd r0, r1, d\dr |
| 245 | mov pc, lr | 259 | mov pc, lr |
| 260 | .org 1b + 8 | ||
| 246 | .endr | 261 | .endr |
| 247 | #endif | 262 | #endif |
| 248 | 263 | ||
| @@ -253,17 +268,18 @@ ENTRY(vfp_get_double) | |||
| 253 | ENDPROC(vfp_get_double) | 268 | ENDPROC(vfp_get_double) |
| 254 | 269 | ||
| 255 | ENTRY(vfp_put_double) | 270 | ENTRY(vfp_put_double) |
| 256 | add pc, pc, r2, lsl #3 | 271 | tbl_branch r2, r3, #3 |
| 257 | mov r0, r0 | ||
| 258 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | 272 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
| 259 | fmdrr d\dr, r0, r1 | 273 | 1: fmdrr d\dr, r0, r1 |
| 260 | mov pc, lr | 274 | mov pc, lr |
| 275 | .org 1b + 8 | ||
| 261 | .endr | 276 | .endr |
| 262 | #ifdef CONFIG_VFPv3 | 277 | #ifdef CONFIG_VFPv3 |
| 263 | @ d16 - d31 registers | 278 | @ d16 - d31 registers |
| 264 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | 279 | .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
| 265 | mcrr p11, 3, r1, r2, c\dr @ fmdrr r1, r2, d\dr | 280 | 1: mcrr p11, 3, r1, r2, c\dr @ fmdrr r1, r2, d\dr |
| 266 | mov pc, lr | 281 | mov pc, lr |
| 282 | .org 1b + 8 | ||
| 267 | .endr | 283 | .endr |
| 268 | #endif | 284 | #endif |
| 269 | ENDPROC(vfp_put_double) | 285 | ENDPROC(vfp_put_double) |
diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c index 46c9b0a224cf..75f19f47fb2f 100644 --- a/arch/avr32/boards/favr-32/setup.c +++ b/arch/avr32/boards/favr-32/setup.c | |||
| @@ -72,6 +72,10 @@ static struct ads7846_platform_data ads7843_data = { | |||
| 72 | .debounce_max = 20, | 72 | .debounce_max = 20, |
| 73 | .debounce_rep = 4, | 73 | .debounce_rep = 4, |
| 74 | .debounce_tol = 5, | 74 | .debounce_tol = 5, |
| 75 | |||
| 76 | .keep_vref_on = true, | ||
| 77 | .settle_delay_usecs = 500, | ||
| 78 | .penirq_recheck_delay_usecs = 100, | ||
| 75 | }; | 79 | }; |
| 76 | 80 | ||
| 77 | static struct spi_board_info __initdata spi1_board_info[] = { | 81 | static struct spi_board_info __initdata spi1_board_info[] = { |
diff --git a/arch/avr32/include/asm/socket.h b/arch/avr32/include/asm/socket.h index 04c860619700..fe863f9794d5 100644 --- a/arch/avr32/include/asm/socket.h +++ b/arch/avr32/include/asm/socket.h | |||
| @@ -57,4 +57,7 @@ | |||
| 57 | #define SO_TIMESTAMPING 37 | 57 | #define SO_TIMESTAMPING 37 |
| 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING | 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING |
| 59 | 59 | ||
| 60 | #define SO_PROTOCOL 38 | ||
| 61 | #define SO_DOMAIN 39 | ||
| 62 | |||
| 60 | #endif /* __ASM_AVR32_SOCKET_H */ | 63 | #endif /* __ASM_AVR32_SOCKET_H */ |
diff --git a/arch/avr32/include/asm/thread_info.h b/arch/avr32/include/asm/thread_info.h index fc42de5ca209..fd0c5d7e9337 100644 --- a/arch/avr32/include/asm/thread_info.h +++ b/arch/avr32/include/asm/thread_info.h | |||
| @@ -84,6 +84,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 84 | #define TIF_MEMDIE 6 | 84 | #define TIF_MEMDIE 6 |
| 85 | #define TIF_RESTORE_SIGMASK 7 /* restore signal mask in do_signal */ | 85 | #define TIF_RESTORE_SIGMASK 7 /* restore signal mask in do_signal */ |
| 86 | #define TIF_CPU_GOING_TO_SLEEP 8 /* CPU is entering sleep 0 mode */ | 86 | #define TIF_CPU_GOING_TO_SLEEP 8 /* CPU is entering sleep 0 mode */ |
| 87 | #define TIF_NOTIFY_RESUME 9 /* callback before returning to user */ | ||
| 87 | #define TIF_FREEZE 29 | 88 | #define TIF_FREEZE 29 |
| 88 | #define TIF_DEBUG 30 /* debugging enabled */ | 89 | #define TIF_DEBUG 30 /* debugging enabled */ |
| 89 | #define TIF_USERSPACE 31 /* true if FS sets userspace */ | 90 | #define TIF_USERSPACE 31 /* true if FS sets userspace */ |
| @@ -96,6 +97,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 96 | #define _TIF_MEMDIE (1 << TIF_MEMDIE) | 97 | #define _TIF_MEMDIE (1 << TIF_MEMDIE) |
| 97 | #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) | 98 | #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) |
| 98 | #define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP) | 99 | #define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP) |
| 100 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) | ||
| 99 | #define _TIF_FREEZE (1 << TIF_FREEZE) | 101 | #define _TIF_FREEZE (1 << TIF_FREEZE) |
| 100 | 102 | ||
| 101 | /* Note: The masks below must never span more than 16 bits! */ | 103 | /* Note: The masks below must never span more than 16 bits! */ |
| @@ -103,13 +105,15 @@ static inline struct thread_info *current_thread_info(void) | |||
| 103 | /* work to do on interrupt/exception return */ | 105 | /* work to do on interrupt/exception return */ |
| 104 | #define _TIF_WORK_MASK \ | 106 | #define _TIF_WORK_MASK \ |
| 105 | ((1 << TIF_SIGPENDING) \ | 107 | ((1 << TIF_SIGPENDING) \ |
| 108 | | _TIF_NOTIFY_RESUME \ | ||
| 106 | | (1 << TIF_NEED_RESCHED) \ | 109 | | (1 << TIF_NEED_RESCHED) \ |
| 107 | | (1 << TIF_POLLING_NRFLAG) \ | 110 | | (1 << TIF_POLLING_NRFLAG) \ |
| 108 | | (1 << TIF_BREAKPOINT) \ | 111 | | (1 << TIF_BREAKPOINT) \ |
| 109 | | (1 << TIF_RESTORE_SIGMASK)) | 112 | | (1 << TIF_RESTORE_SIGMASK)) |
| 110 | 113 | ||
| 111 | /* work to do on any return to userspace */ | 114 | /* work to do on any return to userspace */ |
| 112 | #define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | (1 << TIF_SYSCALL_TRACE)) | 115 | #define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | (1 << TIF_SYSCALL_TRACE) | \ |
| 116 | _TIF_NOTIFY_RESUME) | ||
| 113 | /* work to do on return from debug mode */ | 117 | /* work to do on return from debug mode */ |
| 114 | #define _TIF_DBGWORK_MASK (_TIF_WORK_MASK & ~(1 << TIF_BREAKPOINT)) | 118 | #define _TIF_DBGWORK_MASK (_TIF_WORK_MASK & ~(1 << TIF_BREAKPOINT)) |
| 115 | 119 | ||
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S index 009a80155d67..169268c40ae2 100644 --- a/arch/avr32/kernel/entry-avr32b.S +++ b/arch/avr32/kernel/entry-avr32b.S | |||
| @@ -281,7 +281,7 @@ syscall_exit_work: | |||
| 281 | ld.w r1, r0[TI_flags] | 281 | ld.w r1, r0[TI_flags] |
| 282 | rjmp 1b | 282 | rjmp 1b |
| 283 | 283 | ||
| 284 | 2: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | 284 | 2: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NOTIFY_RESUME |
| 285 | tst r1, r2 | 285 | tst r1, r2 |
| 286 | breq 3f | 286 | breq 3f |
| 287 | unmask_interrupts | 287 | unmask_interrupts |
diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c index 27227561bad6..64f886fac2ef 100644 --- a/arch/avr32/kernel/signal.c +++ b/arch/avr32/kernel/signal.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/ptrace.h> | 16 | #include <linux/ptrace.h> |
| 17 | #include <linux/unistd.h> | 17 | #include <linux/unistd.h> |
| 18 | #include <linux/freezer.h> | 18 | #include <linux/freezer.h> |
| 19 | #include <linux/tracehook.h> | ||
| 19 | 20 | ||
| 20 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
| 21 | #include <asm/ucontext.h> | 22 | #include <asm/ucontext.h> |
| @@ -322,4 +323,11 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti) | |||
| 322 | 323 | ||
| 323 | if (ti->flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 324 | if (ti->flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) |
| 324 | do_signal(regs, ¤t->blocked, syscall); | 325 | do_signal(regs, ¤t->blocked, syscall); |
| 326 | |||
| 327 | if (ti->flags & _TIF_NOTIFY_RESUME) { | ||
| 328 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
| 329 | tracehook_notify_resume(regs); | ||
| 330 | if (current->replacement_session_keyring) | ||
| 331 | key_replace_session_keyring(); | ||
| 332 | } | ||
| 325 | } | 333 | } |
diff --git a/arch/avr32/lib/memcpy.S b/arch/avr32/lib/memcpy.S index 0abb26142b64..c2ca49d705af 100644 --- a/arch/avr32/lib/memcpy.S +++ b/arch/avr32/lib/memcpy.S | |||
| @@ -24,8 +24,8 @@ memcpy: | |||
| 24 | brne 1f | 24 | brne 1f |
| 25 | 25 | ||
| 26 | /* At this point, "from" is word-aligned */ | 26 | /* At this point, "from" is word-aligned */ |
| 27 | 2: sub r10, 4 | 27 | 2: mov r9, r12 |
| 28 | mov r9, r12 | 28 | 5: sub r10, 4 |
| 29 | brlt 4f | 29 | brlt 4f |
| 30 | 30 | ||
| 31 | 3: ld.w r8, r11++ | 31 | 3: ld.w r8, r11++ |
| @@ -49,6 +49,7 @@ memcpy: | |||
| 49 | 49 | ||
| 50 | /* Handle unaligned "from" pointer */ | 50 | /* Handle unaligned "from" pointer */ |
| 51 | 1: sub r10, 4 | 51 | 1: sub r10, 4 |
| 52 | movlt r9, r12 | ||
| 52 | brlt 4b | 53 | brlt 4b |
| 53 | add r10, r9 | 54 | add r10, r9 |
| 54 | lsl r9, 2 | 55 | lsl r9, 2 |
| @@ -59,4 +60,13 @@ memcpy: | |||
| 59 | st.b r12++, r8 | 60 | st.b r12++, r8 |
| 60 | ld.ub r8, r11++ | 61 | ld.ub r8, r11++ |
| 61 | st.b r12++, r8 | 62 | st.b r12++, r8 |
| 62 | rjmp 2b | 63 | mov r8, r12 |
| 64 | add pc, pc, r9 | ||
| 65 | sub r8, 1 | ||
| 66 | nop | ||
| 67 | sub r8, 1 | ||
| 68 | nop | ||
| 69 | sub r8, 1 | ||
| 70 | nop | ||
| 71 | mov r9, r8 | ||
| 72 | rjmp 5b | ||
diff --git a/arch/cris/include/asm/socket.h b/arch/cris/include/asm/socket.h index d5cf74005408..45ec49bdb7b1 100644 --- a/arch/cris/include/asm/socket.h +++ b/arch/cris/include/asm/socket.h | |||
| @@ -59,6 +59,9 @@ | |||
| 59 | #define SO_TIMESTAMPING 37 | 59 | #define SO_TIMESTAMPING 37 |
| 60 | #define SCM_TIMESTAMPING SO_TIMESTAMPING | 60 | #define SCM_TIMESTAMPING SO_TIMESTAMPING |
| 61 | 61 | ||
| 62 | #define SO_PROTOCOL 38 | ||
| 63 | #define SO_DOMAIN 39 | ||
| 64 | |||
| 62 | #endif /* _ASM_SOCKET_H */ | 65 | #endif /* _ASM_SOCKET_H */ |
| 63 | 66 | ||
| 64 | 67 | ||
diff --git a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c index b326023baab2..48b0f3912632 100644 --- a/arch/cris/kernel/ptrace.c +++ b/arch/cris/kernel/ptrace.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
| 17 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
| 18 | #include <linux/user.h> | 18 | #include <linux/user.h> |
| 19 | #include <linux/tracehook.h> | ||
| 19 | 20 | ||
| 20 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
| 21 | #include <asm/page.h> | 22 | #include <asm/page.h> |
| @@ -36,4 +37,11 @@ void do_notify_resume(int canrestart, struct pt_regs *regs, | |||
| 36 | /* deal with pending signal delivery */ | 37 | /* deal with pending signal delivery */ |
| 37 | if (thread_info_flags & _TIF_SIGPENDING) | 38 | if (thread_info_flags & _TIF_SIGPENDING) |
| 38 | do_signal(canrestart,regs); | 39 | do_signal(canrestart,regs); |
| 40 | |||
| 41 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | ||
| 42 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
| 43 | tracehook_notify_resume(regs); | ||
| 44 | if (current->replacement_session_keyring) | ||
| 45 | key_replace_session_keyring(); | ||
| 46 | } | ||
| 39 | } | 47 | } |
diff --git a/arch/frv/include/asm/socket.h b/arch/frv/include/asm/socket.h index 57c3d4054e8b..2dea726095c2 100644 --- a/arch/frv/include/asm/socket.h +++ b/arch/frv/include/asm/socket.h | |||
| @@ -57,5 +57,8 @@ | |||
| 57 | #define SO_TIMESTAMPING 37 | 57 | #define SO_TIMESTAMPING 37 |
| 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING | 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING |
| 59 | 59 | ||
| 60 | #define SO_PROTOCOL 38 | ||
| 61 | #define SO_DOMAIN 39 | ||
| 62 | |||
| 60 | #endif /* _ASM_SOCKET_H */ | 63 | #endif /* _ASM_SOCKET_H */ |
| 61 | 64 | ||
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index 4a7a62c6e783..6b0a2b6fed6a 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c | |||
| @@ -572,6 +572,8 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags) | |||
| 572 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 572 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
| 573 | clear_thread_flag(TIF_NOTIFY_RESUME); | 573 | clear_thread_flag(TIF_NOTIFY_RESUME); |
| 574 | tracehook_notify_resume(__frame); | 574 | tracehook_notify_resume(__frame); |
| 575 | if (current->replacement_session_keyring) | ||
| 576 | key_replace_session_keyring(); | ||
| 575 | } | 577 | } |
| 576 | 578 | ||
| 577 | } /* end do_notify_resume() */ | 579 | } /* end do_notify_resume() */ |
diff --git a/arch/h8300/include/asm/socket.h b/arch/h8300/include/asm/socket.h index 602518a70a1a..1547f01c8e22 100644 --- a/arch/h8300/include/asm/socket.h +++ b/arch/h8300/include/asm/socket.h | |||
| @@ -57,4 +57,7 @@ | |||
| 57 | #define SO_TIMESTAMPING 37 | 57 | #define SO_TIMESTAMPING 37 |
| 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING | 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING |
| 59 | 59 | ||
| 60 | #define SO_PROTOCOL 38 | ||
| 61 | #define SO_DOMAIN 39 | ||
| 62 | |||
| 60 | #endif /* _ASM_SOCKET_H */ | 63 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h index 8bbc8b0ee45d..70e67e47d020 100644 --- a/arch/h8300/include/asm/thread_info.h +++ b/arch/h8300/include/asm/thread_info.h | |||
| @@ -89,6 +89,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 89 | TIF_NEED_RESCHED */ | 89 | TIF_NEED_RESCHED */ |
| 90 | #define TIF_MEMDIE 4 | 90 | #define TIF_MEMDIE 4 |
| 91 | #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ | 91 | #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ |
| 92 | #define TIF_NOTIFY_RESUME 6 /* callback before returning to user */ | ||
| 92 | #define TIF_FREEZE 16 /* is freezing for suspend */ | 93 | #define TIF_FREEZE 16 /* is freezing for suspend */ |
| 93 | 94 | ||
| 94 | /* as above, but as bit values */ | 95 | /* as above, but as bit values */ |
| @@ -97,6 +98,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 97 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | 98 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
| 98 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 99 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
| 99 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) | 100 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) |
| 101 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) | ||
| 100 | #define _TIF_FREEZE (1<<TIF_FREEZE) | 102 | #define _TIF_FREEZE (1<<TIF_FREEZE) |
| 101 | 103 | ||
| 102 | #define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ | 104 | #define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ |
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c index cf3472f7389b..af842c369d24 100644 --- a/arch/h8300/kernel/signal.c +++ b/arch/h8300/kernel/signal.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/tty.h> | 39 | #include <linux/tty.h> |
| 40 | #include <linux/binfmts.h> | 40 | #include <linux/binfmts.h> |
| 41 | #include <linux/freezer.h> | 41 | #include <linux/freezer.h> |
| 42 | #include <linux/tracehook.h> | ||
| 42 | 43 | ||
| 43 | #include <asm/setup.h> | 44 | #include <asm/setup.h> |
| 44 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
| @@ -552,4 +553,11 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) | |||
| 552 | { | 553 | { |
| 553 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 554 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) |
| 554 | do_signal(regs, NULL); | 555 | do_signal(regs, NULL); |
| 556 | |||
| 557 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | ||
| 558 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
| 559 | tracehook_notify_resume(regs); | ||
| 560 | if (current->replacement_session_keyring) | ||
| 561 | key_replace_session_keyring(); | ||
| 562 | } | ||
| 555 | } | 563 | } |
diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c index e4d8fde68103..7e81966ce481 100644 --- a/arch/ia64/hp/sim/simeth.c +++ b/arch/ia64/hp/sim/simeth.c | |||
| @@ -412,7 +412,7 @@ simeth_tx(struct sk_buff *skb, struct net_device *dev) | |||
| 412 | */ | 412 | */ |
| 413 | 413 | ||
| 414 | dev_kfree_skb(skb); | 414 | dev_kfree_skb(skb); |
| 415 | return 0; | 415 | return NETDEV_TX_OK; |
| 416 | } | 416 | } |
| 417 | 417 | ||
| 418 | static inline struct sk_buff * | 418 | static inline struct sk_buff * |
diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h index 5a61b5c2e18f..8d3c79cd81e7 100644 --- a/arch/ia64/include/asm/dma-mapping.h +++ b/arch/ia64/include/asm/dma-mapping.h | |||
| @@ -44,7 +44,6 @@ static inline void dma_free_coherent(struct device *dev, size_t size, | |||
| 44 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | 44 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) |
| 45 | 45 | ||
| 46 | #define get_dma_ops(dev) platform_dma_get_ops(dev) | 46 | #define get_dma_ops(dev) platform_dma_get_ops(dev) |
| 47 | #define flush_write_buffers() | ||
| 48 | 47 | ||
| 49 | #include <asm-generic/dma-mapping-common.h> | 48 | #include <asm-generic/dma-mapping-common.h> |
| 50 | 49 | ||
| @@ -69,6 +68,24 @@ dma_set_mask (struct device *dev, u64 mask) | |||
| 69 | return 0; | 68 | return 0; |
| 70 | } | 69 | } |
| 71 | 70 | ||
| 71 | static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) | ||
| 72 | { | ||
| 73 | if (!dev->dma_mask) | ||
| 74 | return 0; | ||
| 75 | |||
| 76 | return addr + size <= *dev->dma_mask; | ||
| 77 | } | ||
| 78 | |||
| 79 | static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) | ||
| 80 | { | ||
| 81 | return paddr; | ||
| 82 | } | ||
| 83 | |||
| 84 | static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) | ||
| 85 | { | ||
| 86 | return daddr; | ||
| 87 | } | ||
| 88 | |||
| 72 | extern int dma_get_cache_alignment(void); | 89 | extern int dma_get_cache_alignment(void); |
| 73 | 90 | ||
| 74 | static inline void | 91 | static inline void |
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h index 5f43697aed30..d9b6325a9328 100644 --- a/arch/ia64/include/asm/kvm_host.h +++ b/arch/ia64/include/asm/kvm_host.h | |||
| @@ -235,7 +235,8 @@ struct kvm_vm_data { | |||
| 235 | #define KVM_REQ_PTC_G 32 | 235 | #define KVM_REQ_PTC_G 32 |
| 236 | #define KVM_REQ_RESUME 33 | 236 | #define KVM_REQ_RESUME 33 |
| 237 | 237 | ||
| 238 | #define KVM_PAGES_PER_HPAGE 1 | 238 | #define KVM_NR_PAGE_SIZES 1 |
| 239 | #define KVM_PAGES_PER_HPAGE(x) 1 | ||
| 239 | 240 | ||
| 240 | struct kvm; | 241 | struct kvm; |
| 241 | struct kvm_vcpu; | 242 | struct kvm_vcpu; |
| @@ -465,7 +466,6 @@ struct kvm_arch { | |||
| 465 | unsigned long metaphysical_rr4; | 466 | unsigned long metaphysical_rr4; |
| 466 | unsigned long vmm_init_rr; | 467 | unsigned long vmm_init_rr; |
| 467 | 468 | ||
| 468 | int online_vcpus; | ||
| 469 | int is_sn2; | 469 | int is_sn2; |
| 470 | 470 | ||
| 471 | struct kvm_ioapic *vioapic; | 471 | struct kvm_ioapic *vioapic; |
diff --git a/arch/ia64/include/asm/kvm_para.h b/arch/ia64/include/asm/kvm_para.h index 0d6d8ca07b8c..1588aee781a2 100644 --- a/arch/ia64/include/asm/kvm_para.h +++ b/arch/ia64/include/asm/kvm_para.h | |||
| @@ -19,9 +19,13 @@ | |||
| 19 | * | 19 | * |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #ifdef __KERNEL__ | ||
| 23 | |||
| 22 | static inline unsigned int kvm_arch_para_features(void) | 24 | static inline unsigned int kvm_arch_para_features(void) |
| 23 | { | 25 | { |
| 24 | return 0; | 26 | return 0; |
| 25 | } | 27 | } |
| 26 | 28 | ||
| 27 | #endif | 29 | #endif |
| 30 | |||
| 31 | #endif | ||
diff --git a/arch/ia64/include/asm/socket.h b/arch/ia64/include/asm/socket.h index 745421225ec6..0b0d5ff062e5 100644 --- a/arch/ia64/include/asm/socket.h +++ b/arch/ia64/include/asm/socket.h | |||
| @@ -66,4 +66,7 @@ | |||
| 66 | #define SO_TIMESTAMPING 37 | 66 | #define SO_TIMESTAMPING 37 |
| 67 | #define SCM_TIMESTAMPING SO_TIMESTAMPING | 67 | #define SCM_TIMESTAMPING SO_TIMESTAMPING |
| 68 | 68 | ||
| 69 | #define SO_PROTOCOL 38 | ||
| 70 | #define SO_DOMAIN 39 | ||
| 71 | |||
| 69 | #endif /* _ASM_IA64_SOCKET_H */ | 72 | #endif /* _ASM_IA64_SOCKET_H */ |
diff --git a/arch/ia64/kernel/dma-mapping.c b/arch/ia64/kernel/dma-mapping.c index 39a3cd0a4173..f2c1600da097 100644 --- a/arch/ia64/kernel/dma-mapping.c +++ b/arch/ia64/kernel/dma-mapping.c | |||
| @@ -10,7 +10,9 @@ EXPORT_SYMBOL(dma_ops); | |||
| 10 | 10 | ||
| 11 | static int __init dma_init(void) | 11 | static int __init dma_init(void) |
| 12 | { | 12 | { |
| 13 | dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); | 13 | dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); |
| 14 | |||
| 15 | return 0; | ||
| 14 | } | 16 | } |
| 15 | fs_initcall(dma_init); | 17 | fs_initcall(dma_init); |
| 16 | 18 | ||
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index 23f846de62d5..e6c5c3d5e1f8 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <asm/mca_asm.h> | 34 | #include <asm/mca_asm.h> |
| 35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
| 36 | #include <linux/linkage.h> | 36 | #include <linux/linkage.h> |
| 37 | #include "head.h" | ||
| 37 | 38 | ||
| 38 | #ifdef CONFIG_HOTPLUG_CPU | 39 | #ifdef CONFIG_HOTPLUG_CPU |
| 39 | #define SAL_PSR_BITS_TO_SET \ | 40 | #define SAL_PSR_BITS_TO_SET \ |
diff --git a/arch/ia64/kernel/head.h b/arch/ia64/kernel/head.h new file mode 100644 index 000000000000..2e2ac6824e65 --- /dev/null +++ b/arch/ia64/kernel/head.h | |||
| @@ -0,0 +1 @@ | |||
| extern void console_print(const char *s); | |||
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 5d7c0e5b9e76..9bcec9945c12 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
| @@ -161,6 +161,13 @@ show_regs (struct pt_regs *regs) | |||
| 161 | show_stack(NULL, NULL); | 161 | show_stack(NULL, NULL); |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | /* local support for deprecated console_print */ | ||
| 165 | void | ||
| 166 | console_print(const char *s) | ||
| 167 | { | ||
| 168 | printk(KERN_EMERG "%s", s); | ||
| 169 | } | ||
| 170 | |||
| 164 | void | 171 | void |
| 165 | do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall) | 172 | do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall) |
| 166 | { | 173 | { |
| @@ -192,6 +199,8 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall) | |||
| 192 | if (test_thread_flag(TIF_NOTIFY_RESUME)) { | 199 | if (test_thread_flag(TIF_NOTIFY_RESUME)) { |
| 193 | clear_thread_flag(TIF_NOTIFY_RESUME); | 200 | clear_thread_flag(TIF_NOTIFY_RESUME); |
| 194 | tracehook_notify_resume(&scr->pt); | 201 | tracehook_notify_resume(&scr->pt); |
| 202 | if (current->replacement_session_keyring) | ||
| 203 | key_replace_session_keyring(); | ||
| 195 | } | 204 | } |
| 196 | 205 | ||
| 197 | /* copy user rbs to kernel rbs */ | 206 | /* copy user rbs to kernel rbs */ |
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig index 64d520937874..ef3e7be29caf 100644 --- a/arch/ia64/kvm/Kconfig +++ b/arch/ia64/kvm/Kconfig | |||
| @@ -1,12 +1,8 @@ | |||
| 1 | # | 1 | # |
| 2 | # KVM configuration | 2 | # KVM configuration |
| 3 | # | 3 | # |
| 4 | config HAVE_KVM | ||
| 5 | bool | ||
| 6 | 4 | ||
| 7 | config HAVE_KVM_IRQCHIP | 5 | source "virt/kvm/Kconfig" |
| 8 | bool | ||
| 9 | default y | ||
| 10 | 6 | ||
| 11 | menuconfig VIRTUALIZATION | 7 | menuconfig VIRTUALIZATION |
| 12 | bool "Virtualization" | 8 | bool "Virtualization" |
| @@ -28,6 +24,8 @@ config KVM | |||
| 28 | depends on PCI | 24 | depends on PCI |
| 29 | select PREEMPT_NOTIFIERS | 25 | select PREEMPT_NOTIFIERS |
| 30 | select ANON_INODES | 26 | select ANON_INODES |
| 27 | select HAVE_KVM_IRQCHIP | ||
| 28 | select KVM_APIC_ARCHITECTURE | ||
| 31 | ---help--- | 29 | ---help--- |
| 32 | Support hosting fully virtualized guest machines using hardware | 30 | Support hosting fully virtualized guest machines using hardware |
| 33 | virtualization extensions. You will need a fairly recent | 31 | virtualization extensions. You will need a fairly recent |
| @@ -49,9 +47,6 @@ config KVM_INTEL | |||
| 49 | Provides support for KVM on Itanium 2 processors equipped with the VT | 47 | Provides support for KVM on Itanium 2 processors equipped with the VT |
| 50 | extensions. | 48 | extensions. |
| 51 | 49 | ||
| 52 | config KVM_TRACE | ||
| 53 | bool | ||
| 54 | |||
| 55 | source drivers/virtio/Kconfig | 50 | source drivers/virtio/Kconfig |
| 56 | 51 | ||
| 57 | endif # VIRTUALIZATION | 52 | endif # VIRTUALIZATION |
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 80c57b0a21c4..0ad09f05efa9 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
| @@ -210,16 +210,6 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
| 210 | 210 | ||
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu, | ||
| 214 | gpa_t addr, int len, int is_write) | ||
| 215 | { | ||
| 216 | struct kvm_io_device *dev; | ||
| 217 | |||
| 218 | dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len, is_write); | ||
| 219 | |||
| 220 | return dev; | ||
| 221 | } | ||
| 222 | |||
| 223 | static int handle_vm_error(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 213 | static int handle_vm_error(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) |
| 224 | { | 214 | { |
| 225 | kvm_run->exit_reason = KVM_EXIT_UNKNOWN; | 215 | kvm_run->exit_reason = KVM_EXIT_UNKNOWN; |
| @@ -231,6 +221,7 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 231 | { | 221 | { |
| 232 | struct kvm_mmio_req *p; | 222 | struct kvm_mmio_req *p; |
| 233 | struct kvm_io_device *mmio_dev; | 223 | struct kvm_io_device *mmio_dev; |
| 224 | int r; | ||
| 234 | 225 | ||
| 235 | p = kvm_get_vcpu_ioreq(vcpu); | 226 | p = kvm_get_vcpu_ioreq(vcpu); |
| 236 | 227 | ||
| @@ -247,16 +238,13 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 247 | kvm_run->exit_reason = KVM_EXIT_MMIO; | 238 | kvm_run->exit_reason = KVM_EXIT_MMIO; |
| 248 | return 0; | 239 | return 0; |
| 249 | mmio: | 240 | mmio: |
| 250 | mmio_dev = vcpu_find_mmio_dev(vcpu, p->addr, p->size, !p->dir); | 241 | if (p->dir) |
| 251 | if (mmio_dev) { | 242 | r = kvm_io_bus_read(&vcpu->kvm->mmio_bus, p->addr, |
| 252 | if (!p->dir) | 243 | p->size, &p->data); |
| 253 | kvm_iodevice_write(mmio_dev, p->addr, p->size, | 244 | else |
| 254 | &p->data); | 245 | r = kvm_io_bus_write(&vcpu->kvm->mmio_bus, p->addr, |
| 255 | else | 246 | p->size, &p->data); |
| 256 | kvm_iodevice_read(mmio_dev, p->addr, p->size, | 247 | if (r) |
| 257 | &p->data); | ||
| 258 | |||
| 259 | } else | ||
| 260 | printk(KERN_ERR"kvm: No iodevice found! addr:%lx\n", p->addr); | 248 | printk(KERN_ERR"kvm: No iodevice found! addr:%lx\n", p->addr); |
| 261 | p->state = STATE_IORESP_READY; | 249 | p->state = STATE_IORESP_READY; |
| 262 | 250 | ||
| @@ -337,13 +325,12 @@ static struct kvm_vcpu *lid_to_vcpu(struct kvm *kvm, unsigned long id, | |||
| 337 | { | 325 | { |
| 338 | union ia64_lid lid; | 326 | union ia64_lid lid; |
| 339 | int i; | 327 | int i; |
| 328 | struct kvm_vcpu *vcpu; | ||
| 340 | 329 | ||
| 341 | for (i = 0; i < kvm->arch.online_vcpus; i++) { | 330 | kvm_for_each_vcpu(i, vcpu, kvm) { |
| 342 | if (kvm->vcpus[i]) { | 331 | lid.val = VCPU_LID(vcpu); |
| 343 | lid.val = VCPU_LID(kvm->vcpus[i]); | 332 | if (lid.id == id && lid.eid == eid) |
| 344 | if (lid.id == id && lid.eid == eid) | 333 | return vcpu; |
| 345 | return kvm->vcpus[i]; | ||
| 346 | } | ||
| 347 | } | 334 | } |
| 348 | 335 | ||
| 349 | return NULL; | 336 | return NULL; |
| @@ -409,21 +396,21 @@ static int handle_global_purge(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 409 | struct kvm *kvm = vcpu->kvm; | 396 | struct kvm *kvm = vcpu->kvm; |
| 410 | struct call_data call_data; | 397 | struct call_data call_data; |
| 411 | int i; | 398 | int i; |
| 399 | struct kvm_vcpu *vcpui; | ||
| 412 | 400 | ||
| 413 | call_data.ptc_g_data = p->u.ptc_g_data; | 401 | call_data.ptc_g_data = p->u.ptc_g_data; |
| 414 | 402 | ||
| 415 | for (i = 0; i < kvm->arch.online_vcpus; i++) { | 403 | kvm_for_each_vcpu(i, vcpui, kvm) { |
| 416 | if (!kvm->vcpus[i] || kvm->vcpus[i]->arch.mp_state == | 404 | if (vcpui->arch.mp_state == KVM_MP_STATE_UNINITIALIZED || |
| 417 | KVM_MP_STATE_UNINITIALIZED || | 405 | vcpu == vcpui) |
| 418 | vcpu == kvm->vcpus[i]) | ||
| 419 | continue; | 406 | continue; |
| 420 | 407 | ||
| 421 | if (waitqueue_active(&kvm->vcpus[i]->wq)) | 408 | if (waitqueue_active(&vcpui->wq)) |
| 422 | wake_up_interruptible(&kvm->vcpus[i]->wq); | 409 | wake_up_interruptible(&vcpui->wq); |
| 423 | 410 | ||
| 424 | if (kvm->vcpus[i]->cpu != -1) { | 411 | if (vcpui->cpu != -1) { |
| 425 | call_data.vcpu = kvm->vcpus[i]; | 412 | call_data.vcpu = vcpui; |
| 426 | smp_call_function_single(kvm->vcpus[i]->cpu, | 413 | smp_call_function_single(vcpui->cpu, |
| 427 | vcpu_global_purge, &call_data, 1); | 414 | vcpu_global_purge, &call_data, 1); |
| 428 | } else | 415 | } else |
| 429 | printk(KERN_WARNING"kvm: Uninit vcpu received ipi!\n"); | 416 | printk(KERN_WARNING"kvm: Uninit vcpu received ipi!\n"); |
| @@ -852,8 +839,6 @@ struct kvm *kvm_arch_create_vm(void) | |||
| 852 | 839 | ||
| 853 | kvm_init_vm(kvm); | 840 | kvm_init_vm(kvm); |
| 854 | 841 | ||
| 855 | kvm->arch.online_vcpus = 0; | ||
| 856 | |||
| 857 | return kvm; | 842 | return kvm; |
| 858 | 843 | ||
| 859 | } | 844 | } |
| @@ -1000,10 +985,10 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
| 1000 | goto out; | 985 | goto out; |
| 1001 | if (irqchip_in_kernel(kvm)) { | 986 | if (irqchip_in_kernel(kvm)) { |
| 1002 | __s32 status; | 987 | __s32 status; |
| 1003 | mutex_lock(&kvm->lock); | 988 | mutex_lock(&kvm->irq_lock); |
| 1004 | status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, | 989 | status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, |
| 1005 | irq_event.irq, irq_event.level); | 990 | irq_event.irq, irq_event.level); |
| 1006 | mutex_unlock(&kvm->lock); | 991 | mutex_unlock(&kvm->irq_lock); |
| 1007 | if (ioctl == KVM_IRQ_LINE_STATUS) { | 992 | if (ioctl == KVM_IRQ_LINE_STATUS) { |
| 1008 | irq_event.status = status; | 993 | irq_event.status = status; |
| 1009 | if (copy_to_user(argp, &irq_event, | 994 | if (copy_to_user(argp, &irq_event, |
| @@ -1216,7 +1201,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
| 1216 | if (IS_ERR(vmm_vcpu)) | 1201 | if (IS_ERR(vmm_vcpu)) |
| 1217 | return PTR_ERR(vmm_vcpu); | 1202 | return PTR_ERR(vmm_vcpu); |
| 1218 | 1203 | ||
| 1219 | if (vcpu->vcpu_id == 0) { | 1204 | if (kvm_vcpu_is_bsp(vcpu)) { |
| 1220 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; | 1205 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; |
| 1221 | 1206 | ||
| 1222 | /*Set entry address for first run.*/ | 1207 | /*Set entry address for first run.*/ |
| @@ -1224,7 +1209,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
| 1224 | 1209 | ||
| 1225 | /*Initialize itc offset for vcpus*/ | 1210 | /*Initialize itc offset for vcpus*/ |
| 1226 | itc_offset = 0UL - kvm_get_itc(vcpu); | 1211 | itc_offset = 0UL - kvm_get_itc(vcpu); |
| 1227 | for (i = 0; i < kvm->arch.online_vcpus; i++) { | 1212 | for (i = 0; i < KVM_MAX_VCPUS; i++) { |
| 1228 | v = (struct kvm_vcpu *)((char *)vcpu + | 1213 | v = (struct kvm_vcpu *)((char *)vcpu + |
| 1229 | sizeof(struct kvm_vcpu_data) * i); | 1214 | sizeof(struct kvm_vcpu_data) * i); |
| 1230 | v->arch.itc_offset = itc_offset; | 1215 | v->arch.itc_offset = itc_offset; |
| @@ -1356,8 +1341,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
| 1356 | goto fail; | 1341 | goto fail; |
| 1357 | } | 1342 | } |
| 1358 | 1343 | ||
| 1359 | kvm->arch.online_vcpus++; | ||
| 1360 | |||
| 1361 | return vcpu; | 1344 | return vcpu; |
| 1362 | fail: | 1345 | fail: |
| 1363 | return ERR_PTR(r); | 1346 | return ERR_PTR(r); |
| @@ -1952,19 +1935,6 @@ int kvm_highest_pending_irq(struct kvm_vcpu *vcpu) | |||
| 1952 | return find_highest_bits((int *)&vpd->irr[0]); | 1935 | return find_highest_bits((int *)&vpd->irr[0]); |
| 1953 | } | 1936 | } |
| 1954 | 1937 | ||
| 1955 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu) | ||
| 1956 | { | ||
| 1957 | if (kvm_highest_pending_irq(vcpu) != -1) | ||
| 1958 | return 1; | ||
| 1959 | return 0; | ||
| 1960 | } | ||
| 1961 | |||
| 1962 | int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu) | ||
| 1963 | { | ||
| 1964 | /* do real check here */ | ||
| 1965 | return 1; | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) | 1938 | int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) |
| 1969 | { | 1939 | { |
| 1970 | return vcpu->arch.timer_fired; | 1940 | return vcpu->arch.timer_fired; |
| @@ -1977,7 +1947,8 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) | |||
| 1977 | 1947 | ||
| 1978 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) | 1948 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) |
| 1979 | { | 1949 | { |
| 1980 | return vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE; | 1950 | return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE) || |
| 1951 | (kvm_highest_pending_irq(vcpu) != -1); | ||
| 1981 | } | 1952 | } |
| 1982 | 1953 | ||
| 1983 | int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, | 1954 | int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, |
diff --git a/arch/ia64/kvm/vcpu.c b/arch/ia64/kvm/vcpu.c index cc406d064a09..dce75b70cdd5 100644 --- a/arch/ia64/kvm/vcpu.c +++ b/arch/ia64/kvm/vcpu.c | |||
| @@ -830,8 +830,8 @@ static void vcpu_set_itc(struct kvm_vcpu *vcpu, u64 val) | |||
| 830 | 830 | ||
| 831 | kvm = (struct kvm *)KVM_VM_BASE; | 831 | kvm = (struct kvm *)KVM_VM_BASE; |
| 832 | 832 | ||
| 833 | if (vcpu->vcpu_id == 0) { | 833 | if (kvm_vcpu_is_bsp(vcpu)) { |
| 834 | for (i = 0; i < kvm->arch.online_vcpus; i++) { | 834 | for (i = 0; i < atomic_read(&kvm->online_vcpus); i++) { |
| 835 | v = (struct kvm_vcpu *)((char *)vcpu + | 835 | v = (struct kvm_vcpu *)((char *)vcpu + |
| 836 | sizeof(struct kvm_vcpu_data) * i); | 836 | sizeof(struct kvm_vcpu_data) * i); |
| 837 | VMX(v, itc_offset) = itc_offset; | 837 | VMX(v, itc_offset) = itc_offset; |
diff --git a/arch/ia64/lib/ip_fast_csum.S b/arch/ia64/lib/ip_fast_csum.S index 1f86aeb2c948..620d9dc5220f 100644 --- a/arch/ia64/lib/ip_fast_csum.S +++ b/arch/ia64/lib/ip_fast_csum.S | |||
| @@ -96,20 +96,22 @@ END(ip_fast_csum) | |||
| 96 | GLOBAL_ENTRY(csum_ipv6_magic) | 96 | GLOBAL_ENTRY(csum_ipv6_magic) |
| 97 | ld4 r20=[in0],4 | 97 | ld4 r20=[in0],4 |
| 98 | ld4 r21=[in1],4 | 98 | ld4 r21=[in1],4 |
| 99 | dep r15=in3,in2,32,16 | 99 | zxt4 in2=in2 |
| 100 | ;; | 100 | ;; |
| 101 | ld4 r22=[in0],4 | 101 | ld4 r22=[in0],4 |
| 102 | ld4 r23=[in1],4 | 102 | ld4 r23=[in1],4 |
| 103 | mux1 r15=r15,@rev | 103 | dep r15=in3,in2,32,16 |
| 104 | ;; | 104 | ;; |
| 105 | ld4 r24=[in0],4 | 105 | ld4 r24=[in0],4 |
| 106 | ld4 r25=[in1],4 | 106 | ld4 r25=[in1],4 |
| 107 | shr.u r15=r15,16 | 107 | mux1 r15=r15,@rev |
| 108 | add r16=r20,r21 | 108 | add r16=r20,r21 |
| 109 | add r17=r22,r23 | 109 | add r17=r22,r23 |
| 110 | zxt4 in4=in4 | ||
| 110 | ;; | 111 | ;; |
| 111 | ld4 r26=[in0],4 | 112 | ld4 r26=[in0],4 |
| 112 | ld4 r27=[in1],4 | 113 | ld4 r27=[in1],4 |
| 114 | shr.u r15=r15,16 | ||
| 113 | add r18=r24,r25 | 115 | add r18=r24,r25 |
| 114 | add r8=r16,r17 | 116 | add r8=r16,r17 |
| 115 | ;; | 117 | ;; |
diff --git a/arch/ia64/xen/time.c b/arch/ia64/xen/time.c index fb8332690179..dbeadb9c8e20 100644 --- a/arch/ia64/xen/time.c +++ b/arch/ia64/xen/time.c | |||
| @@ -133,8 +133,7 @@ consider_steal_time(unsigned long new_itm) | |||
| 133 | account_idle_ticks(blocked); | 133 | account_idle_ticks(blocked); |
| 134 | run_local_timers(); | 134 | run_local_timers(); |
| 135 | 135 | ||
| 136 | if (rcu_pending(cpu)) | 136 | rcu_check_callbacks(cpu, user_mode(get_irq_regs())); |
| 137 | rcu_check_callbacks(cpu, user_mode(get_irq_regs())); | ||
| 138 | 137 | ||
| 139 | scheduler_tick(); | 138 | scheduler_tick(); |
| 140 | run_posix_cpu_timers(p); | 139 | run_posix_cpu_timers(p); |
diff --git a/arch/m32r/include/asm/socket.h b/arch/m32r/include/asm/socket.h index be7ed589af5c..3390a864f224 100644 --- a/arch/m32r/include/asm/socket.h +++ b/arch/m32r/include/asm/socket.h | |||
| @@ -57,4 +57,7 @@ | |||
| 57 | #define SO_TIMESTAMPING 37 | 57 | #define SO_TIMESTAMPING 37 |
| 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING | 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING |
| 59 | 59 | ||
| 60 | #define SO_PROTOCOL 38 | ||
| 61 | #define SO_DOMAIN 39 | ||
| 62 | |||
| 60 | #endif /* _ASM_M32R_SOCKET_H */ | 63 | #endif /* _ASM_M32R_SOCKET_H */ |
diff --git a/arch/m32r/include/asm/thread_info.h b/arch/m32r/include/asm/thread_info.h index 07bb5bd00e2a..71578151a403 100644 --- a/arch/m32r/include/asm/thread_info.h +++ b/arch/m32r/include/asm/thread_info.h | |||
| @@ -149,6 +149,7 @@ static inline unsigned int get_thread_fault_code(void) | |||
| 149 | #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ | 149 | #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ |
| 150 | #define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */ | 150 | #define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */ |
| 151 | #define TIF_IRET 4 /* return with iret */ | 151 | #define TIF_IRET 4 /* return with iret */ |
| 152 | #define TIF_NOTIFY_RESUME 5 /* callback before returning to user */ | ||
| 152 | #define TIF_RESTORE_SIGMASK 8 /* restore signal mask in do_signal() */ | 153 | #define TIF_RESTORE_SIGMASK 8 /* restore signal mask in do_signal() */ |
| 153 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ | 154 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ |
| 154 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ | 155 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ |
| @@ -160,6 +161,7 @@ static inline unsigned int get_thread_fault_code(void) | |||
| 160 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | 161 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
| 161 | #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) | 162 | #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) |
| 162 | #define _TIF_IRET (1<<TIF_IRET) | 163 | #define _TIF_IRET (1<<TIF_IRET) |
| 164 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) | ||
| 163 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) | 165 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) |
| 164 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) | 166 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) |
| 165 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 167 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index 18124542a6eb..144b0f124fc7 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/stddef.h> | 21 | #include <linux/stddef.h> |
| 22 | #include <linux/personality.h> | 22 | #include <linux/personality.h> |
| 23 | #include <linux/freezer.h> | 23 | #include <linux/freezer.h> |
| 24 | #include <linux/tracehook.h> | ||
| 24 | #include <asm/cacheflush.h> | 25 | #include <asm/cacheflush.h> |
| 25 | #include <asm/ucontext.h> | 26 | #include <asm/ucontext.h> |
| 26 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
| @@ -408,5 +409,12 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, | |||
| 408 | if (thread_info_flags & _TIF_SIGPENDING) | 409 | if (thread_info_flags & _TIF_SIGPENDING) |
| 409 | do_signal(regs,oldset); | 410 | do_signal(regs,oldset); |
| 410 | 411 | ||
| 412 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | ||
| 413 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
| 414 | tracehook_notify_resume(regs); | ||
| 415 | if (current->replacement_session_keyring) | ||
| 416 | key_replace_session_keyring(); | ||
| 417 | } | ||
| 418 | |||
| 411 | clear_thread_flag(TIF_IRET); | 419 | clear_thread_flag(TIF_IRET); |
| 412 | } | 420 | } |
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index 6e562751ad51..6c74751c7b82 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c | |||
| @@ -574,10 +574,11 @@ static int a2000_hwclk(int op, struct rtc_time *t) | |||
| 574 | 574 | ||
| 575 | tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD; | 575 | tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD; |
| 576 | 576 | ||
| 577 | while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) { | 577 | while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt) { |
| 578 | tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; | 578 | tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; |
| 579 | udelay(70); | 579 | udelay(70); |
| 580 | tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; | 580 | tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; |
| 581 | --cnt; | ||
| 581 | } | 582 | } |
| 582 | 583 | ||
| 583 | if (!cnt) | 584 | if (!cnt) |
| @@ -649,10 +650,11 @@ static int amiga_set_clock_mmss(unsigned long nowtime) | |||
| 649 | 650 | ||
| 650 | tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; | 651 | tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; |
| 651 | 652 | ||
| 652 | while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) { | 653 | while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt) { |
| 653 | tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; | 654 | tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; |
| 654 | udelay(70); | 655 | udelay(70); |
| 655 | tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; | 656 | tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; |
| 657 | --cnt; | ||
| 656 | } | 658 | } |
| 657 | 659 | ||
| 658 | if (!cnt) | 660 | if (!cnt) |
diff --git a/arch/m68k/include/asm/entry_mm.h b/arch/m68k/include/asm/entry_mm.h index 5202f5a5b420..474125886218 100644 --- a/arch/m68k/include/asm/entry_mm.h +++ b/arch/m68k/include/asm/entry_mm.h | |||
| @@ -46,7 +46,6 @@ | |||
| 46 | #define curptr a2 | 46 | #define curptr a2 |
| 47 | 47 | ||
| 48 | LFLUSH_I_AND_D = 0x00000808 | 48 | LFLUSH_I_AND_D = 0x00000808 |
| 49 | LSIGTRAP = 5 | ||
| 50 | 49 | ||
| 51 | /* process bits for task_struct.ptrace */ | 50 | /* process bits for task_struct.ptrace */ |
| 52 | PT_TRACESYS_OFF = 3 | 51 | PT_TRACESYS_OFF = 3 |
| @@ -118,9 +117,6 @@ PT_DTRACE_BIT = 2 | |||
| 118 | #define STR(X) STR1(X) | 117 | #define STR(X) STR1(X) |
| 119 | #define STR1(X) #X | 118 | #define STR1(X) #X |
| 120 | 119 | ||
| 121 | #define PT_OFF_ORIG_D0 0x24 | ||
| 122 | #define PT_OFF_FORMATVEC 0x32 | ||
| 123 | #define PT_OFF_SR 0x2C | ||
| 124 | #define SAVE_ALL_INT \ | 120 | #define SAVE_ALL_INT \ |
| 125 | "clrl %%sp@-;" /* stk_adj */ \ | 121 | "clrl %%sp@-;" /* stk_adj */ \ |
| 126 | "pea -1:w;" /* orig d0 = -1 */ \ | 122 | "pea -1:w;" /* orig d0 = -1 */ \ |
diff --git a/arch/m68k/include/asm/entry_no.h b/arch/m68k/include/asm/entry_no.h index c2553d26273d..907ed03d792f 100644 --- a/arch/m68k/include/asm/entry_no.h +++ b/arch/m68k/include/asm/entry_no.h | |||
| @@ -72,8 +72,8 @@ LENOSYS = 38 | |||
| 72 | lea %sp@(-32),%sp /* space for 8 regs */ | 72 | lea %sp@(-32),%sp /* space for 8 regs */ |
| 73 | moveml %d1-%d5/%a0-%a2,%sp@ | 73 | moveml %d1-%d5/%a0-%a2,%sp@ |
| 74 | movel sw_usp,%a0 /* get usp */ | 74 | movel sw_usp,%a0 /* get usp */ |
| 75 | movel %a0@-,%sp@(PT_PC) /* copy exception program counter */ | 75 | movel %a0@-,%sp@(PT_OFF_PC) /* copy exception program counter */ |
| 76 | movel %a0@-,%sp@(PT_FORMATVEC)/* copy exception format/vector/sr */ | 76 | movel %a0@-,%sp@(PT_OFF_FORMATVEC)/*copy exception format/vector/sr */ |
| 77 | bra 7f | 77 | bra 7f |
| 78 | 6: | 78 | 6: |
| 79 | clrl %sp@- /* stkadj */ | 79 | clrl %sp@- /* stkadj */ |
| @@ -89,8 +89,8 @@ LENOSYS = 38 | |||
| 89 | bnes 8f /* no, skip */ | 89 | bnes 8f /* no, skip */ |
| 90 | move #0x2700,%sr /* disable intrs */ | 90 | move #0x2700,%sr /* disable intrs */ |
| 91 | movel sw_usp,%a0 /* get usp */ | 91 | movel sw_usp,%a0 /* get usp */ |
| 92 | movel %sp@(PT_PC),%a0@- /* copy exception program counter */ | 92 | movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */ |
| 93 | movel %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */ | 93 | movel %sp@(PT_OFF_FORMATVEC),%a0@-/*copy exception format/vector/sr */ |
| 94 | moveml %sp@,%d1-%d5/%a0-%a2 | 94 | moveml %sp@,%d1-%d5/%a0-%a2 |
| 95 | lea %sp@(32),%sp /* space for 8 regs */ | 95 | lea %sp@(32),%sp /* space for 8 regs */ |
| 96 | movel %sp@+,%d0 | 96 | movel %sp@+,%d0 |
diff --git a/arch/m68k/include/asm/math-emu.h b/arch/m68k/include/asm/math-emu.h index ddfab96403cb..5e9249b0014c 100644 --- a/arch/m68k/include/asm/math-emu.h +++ b/arch/m68k/include/asm/math-emu.h | |||
| @@ -145,16 +145,16 @@ extern unsigned int fp_debugprint; | |||
| 145 | * these are only used during instruction decoding | 145 | * these are only used during instruction decoding |
| 146 | * where we always know how deep we're on the stack. | 146 | * where we always know how deep we're on the stack. |
| 147 | */ | 147 | */ |
| 148 | #define FPS_DO (PT_D0) | 148 | #define FPS_DO (PT_OFF_D0) |
| 149 | #define FPS_D1 (PT_D1) | 149 | #define FPS_D1 (PT_OFF_D1) |
| 150 | #define FPS_D2 (PT_D2) | 150 | #define FPS_D2 (PT_OFF_D2) |
| 151 | #define FPS_A0 (PT_A0) | 151 | #define FPS_A0 (PT_OFF_A0) |
| 152 | #define FPS_A1 (PT_A1) | 152 | #define FPS_A1 (PT_OFF_A1) |
| 153 | #define FPS_A2 (PT_A2) | 153 | #define FPS_A2 (PT_OFF_A2) |
| 154 | #define FPS_SR (PT_SR) | 154 | #define FPS_SR (PT_OFF_SR) |
| 155 | #define FPS_PC (PT_PC) | 155 | #define FPS_PC (PT_OFF_PC) |
| 156 | #define FPS_EA (PT_PC+6) | 156 | #define FPS_EA (PT_OFF_PC+6) |
| 157 | #define FPS_PC2 (PT_PC+10) | 157 | #define FPS_PC2 (PT_OFF_PC+10) |
| 158 | 158 | ||
| 159 | .macro fp_get_fp_reg | 159 | .macro fp_get_fp_reg |
| 160 | lea (FPD_FPREG,FPDATA,%d0.w*4),%a0 | 160 | lea (FPD_FPREG,FPDATA,%d0.w*4),%a0 |
diff --git a/arch/m68k/include/asm/motorola_pgalloc.h b/arch/m68k/include/asm/motorola_pgalloc.h index 15ee4c74a9f0..2f02f264e694 100644 --- a/arch/m68k/include/asm/motorola_pgalloc.h +++ b/arch/m68k/include/asm/motorola_pgalloc.h | |||
| @@ -36,12 +36,10 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addres | |||
| 36 | return NULL; | 36 | return NULL; |
| 37 | 37 | ||
| 38 | pte = kmap(page); | 38 | pte = kmap(page); |
| 39 | if (pte) { | 39 | __flush_page_to_ram(pte); |
| 40 | __flush_page_to_ram(pte); | 40 | flush_tlb_kernel_page(pte); |
| 41 | flush_tlb_kernel_page(pte); | 41 | nocache_page(pte); |
| 42 | nocache_page(pte); | 42 | kunmap(page); |
| 43 | } | ||
| 44 | kunmap(pte); | ||
| 45 | pgtable_page_ctor(page); | 43 | pgtable_page_ctor(page); |
| 46 | return page; | 44 | return page; |
| 47 | } | 45 | } |
diff --git a/arch/m68k/include/asm/pgtable_mm.h b/arch/m68k/include/asm/pgtable_mm.h index 0b604f0f192d..fe60e1abaee8 100644 --- a/arch/m68k/include/asm/pgtable_mm.h +++ b/arch/m68k/include/asm/pgtable_mm.h | |||
| @@ -135,8 +135,6 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, | |||
| 135 | #endif | 135 | #endif |
| 136 | 136 | ||
| 137 | #ifndef __ASSEMBLY__ | 137 | #ifndef __ASSEMBLY__ |
| 138 | #include <asm-generic/pgtable.h> | ||
| 139 | |||
| 140 | /* | 138 | /* |
| 141 | * Macro to mark a page protection value as "uncacheable". | 139 | * Macro to mark a page protection value as "uncacheable". |
| 142 | */ | 140 | */ |
| @@ -154,6 +152,7 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, | |||
| 154 | ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \ | 152 | ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \ |
| 155 | : (prot))) | 153 | : (prot))) |
| 156 | 154 | ||
| 155 | #include <asm-generic/pgtable.h> | ||
| 157 | #endif /* !__ASSEMBLY__ */ | 156 | #endif /* !__ASSEMBLY__ */ |
| 158 | 157 | ||
| 159 | /* | 158 | /* |
diff --git a/arch/m68k/include/asm/socket.h b/arch/m68k/include/asm/socket.h index ca87f938b03f..eee01cce921b 100644 --- a/arch/m68k/include/asm/socket.h +++ b/arch/m68k/include/asm/socket.h | |||
| @@ -57,4 +57,7 @@ | |||
| 57 | #define SO_TIMESTAMPING 37 | 57 | #define SO_TIMESTAMPING 37 |
| 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING | 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING |
| 59 | 59 | ||
| 60 | #define SO_PROTOCOL 38 | ||
| 61 | #define SO_DOMAIN 39 | ||
| 62 | |||
| 60 | #endif /* _ASM_SOCKET_H */ | 63 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/m68k/include/asm/thread_info_mm.h b/arch/m68k/include/asm/thread_info_mm.h index 6ea5c33b3c56..b6da3882be9b 100644 --- a/arch/m68k/include/asm/thread_info_mm.h +++ b/arch/m68k/include/asm/thread_info_mm.h | |||
| @@ -1,6 +1,10 @@ | |||
| 1 | #ifndef _ASM_M68K_THREAD_INFO_H | 1 | #ifndef _ASM_M68K_THREAD_INFO_H |
| 2 | #define _ASM_M68K_THREAD_INFO_H | 2 | #define _ASM_M68K_THREAD_INFO_H |
| 3 | 3 | ||
| 4 | #ifndef ASM_OFFSETS_C | ||
| 5 | #include <asm/asm-offsets.h> | ||
| 6 | #endif | ||
| 7 | #include <asm/current.h> | ||
| 4 | #include <asm/types.h> | 8 | #include <asm/types.h> |
| 5 | #include <asm/page.h> | 9 | #include <asm/page.h> |
| 6 | 10 | ||
| @@ -31,7 +35,12 @@ struct thread_info { | |||
| 31 | #define init_thread_info (init_task.thread.info) | 35 | #define init_thread_info (init_task.thread.info) |
| 32 | #define init_stack (init_thread_union.stack) | 36 | #define init_stack (init_thread_union.stack) |
| 33 | 37 | ||
| 34 | #define task_thread_info(tsk) (&(tsk)->thread.info) | 38 | #ifdef ASM_OFFSETS_C |
| 39 | #define task_thread_info(tsk) ((struct thread_info *) NULL) | ||
| 40 | #else | ||
| 41 | #define task_thread_info(tsk) ((struct thread_info *)((char *)tsk+TASK_TINFO)) | ||
| 42 | #endif | ||
| 43 | |||
| 35 | #define task_stack_page(tsk) ((tsk)->stack) | 44 | #define task_stack_page(tsk) ((tsk)->stack) |
| 36 | #define current_thread_info() task_thread_info(current) | 45 | #define current_thread_info() task_thread_info(current) |
| 37 | 46 | ||
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index aa29a8640f74..946d8691f2b0 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h | |||
| @@ -334,10 +334,12 @@ | |||
| 334 | #define __NR_inotify_init1 328 | 334 | #define __NR_inotify_init1 328 |
| 335 | #define __NR_preadv 329 | 335 | #define __NR_preadv 329 |
| 336 | #define __NR_pwritev 330 | 336 | #define __NR_pwritev 330 |
| 337 | #define __NR_rt_tgsigqueueinfo 331 | ||
| 338 | #define __NR_perf_counter_open 332 | ||
| 337 | 339 | ||
| 338 | #ifdef __KERNEL__ | 340 | #ifdef __KERNEL__ |
| 339 | 341 | ||
| 340 | #define NR_syscalls 331 | 342 | #define NR_syscalls 333 |
| 341 | 343 | ||
| 342 | #define __ARCH_WANT_IPC_PARSE_VERSION | 344 | #define __ARCH_WANT_IPC_PARSE_VERSION |
| 343 | #define __ARCH_WANT_OLD_READDIR | 345 | #define __ARCH_WANT_OLD_READDIR |
diff --git a/arch/m68k/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets.c index b1f012f6c493..73e5e581245b 100644 --- a/arch/m68k/kernel/asm-offsets.c +++ b/arch/m68k/kernel/asm-offsets.c | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | * #defines from the assembly-language output. | 8 | * #defines from the assembly-language output. |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #define ASM_OFFSETS_C | ||
| 12 | |||
| 11 | #include <linux/stddef.h> | 13 | #include <linux/stddef.h> |
| 12 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
| 13 | #include <linux/kernel_stat.h> | 15 | #include <linux/kernel_stat.h> |
| @@ -27,6 +29,9 @@ int main(void) | |||
| 27 | DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info)); | 29 | DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info)); |
| 28 | DEFINE(TASK_MM, offsetof(struct task_struct, mm)); | 30 | DEFINE(TASK_MM, offsetof(struct task_struct, mm)); |
| 29 | DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); | 31 | DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); |
| 32 | #ifdef CONFIG_MMU | ||
| 33 | DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info)); | ||
| 34 | #endif | ||
| 30 | 35 | ||
| 31 | /* offsets into the thread struct */ | 36 | /* offsets into the thread struct */ |
| 32 | DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); | 37 | DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); |
| @@ -44,20 +49,20 @@ int main(void) | |||
| 44 | DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags)); | 49 | DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags)); |
| 45 | 50 | ||
| 46 | /* offsets into the pt_regs */ | 51 | /* offsets into the pt_regs */ |
| 47 | DEFINE(PT_D0, offsetof(struct pt_regs, d0)); | 52 | DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0)); |
| 48 | DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0)); | 53 | DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0)); |
| 49 | DEFINE(PT_D1, offsetof(struct pt_regs, d1)); | 54 | DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1)); |
| 50 | DEFINE(PT_D2, offsetof(struct pt_regs, d2)); | 55 | DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2)); |
| 51 | DEFINE(PT_D3, offsetof(struct pt_regs, d3)); | 56 | DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3)); |
| 52 | DEFINE(PT_D4, offsetof(struct pt_regs, d4)); | 57 | DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4)); |
| 53 | DEFINE(PT_D5, offsetof(struct pt_regs, d5)); | 58 | DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5)); |
| 54 | DEFINE(PT_A0, offsetof(struct pt_regs, a0)); | 59 | DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0)); |
| 55 | DEFINE(PT_A1, offsetof(struct pt_regs, a1)); | 60 | DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1)); |
| 56 | DEFINE(PT_A2, offsetof(struct pt_regs, a2)); | 61 | DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2)); |
| 57 | DEFINE(PT_PC, offsetof(struct pt_regs, pc)); | 62 | DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc)); |
| 58 | DEFINE(PT_SR, offsetof(struct pt_regs, sr)); | 63 | DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr)); |
| 59 | /* bitfields are a bit difficult */ | 64 | /* bitfields are a bit difficult */ |
| 60 | DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4); | 65 | DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4); |
| 61 | 66 | ||
| 62 | /* offsets into the irq_handler struct */ | 67 | /* offsets into the irq_handler struct */ |
| 63 | DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler)); | 68 | DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler)); |
| @@ -84,10 +89,10 @@ int main(void) | |||
| 84 | DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref)); | 89 | DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref)); |
| 85 | 90 | ||
| 86 | /* signal defines */ | 91 | /* signal defines */ |
| 87 | DEFINE(SIGSEGV, SIGSEGV); | 92 | DEFINE(LSIGSEGV, SIGSEGV); |
| 88 | DEFINE(SEGV_MAPERR, SEGV_MAPERR); | 93 | DEFINE(LSEGV_MAPERR, SEGV_MAPERR); |
| 89 | DEFINE(SIGTRAP, SIGTRAP); | 94 | DEFINE(LSIGTRAP, SIGTRAP); |
| 90 | DEFINE(TRAP_TRACE, TRAP_TRACE); | 95 | DEFINE(LTRAP_TRACE, TRAP_TRACE); |
| 91 | 96 | ||
| 92 | /* offsets into the custom struct */ | 97 | /* offsets into the custom struct */ |
| 93 | DEFINE(CUSTOMBASE, &amiga_custom); | 98 | DEFINE(CUSTOMBASE, &amiga_custom); |
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 8744f60c07a9..922f52e7ed1a 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S | |||
| @@ -77,17 +77,17 @@ ENTRY(ret_from_fork) | |||
| 77 | jra .Lret_from_exception | 77 | jra .Lret_from_exception |
| 78 | 78 | ||
| 79 | do_trace_entry: | 79 | do_trace_entry: |
| 80 | movel #-ENOSYS,%sp@(PT_D0) | needed for strace | 80 | movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace |
| 81 | subql #4,%sp | 81 | subql #4,%sp |
| 82 | SAVE_SWITCH_STACK | 82 | SAVE_SWITCH_STACK |
| 83 | jbsr syscall_trace | 83 | jbsr syscall_trace |
| 84 | RESTORE_SWITCH_STACK | 84 | RESTORE_SWITCH_STACK |
| 85 | addql #4,%sp | 85 | addql #4,%sp |
| 86 | movel %sp@(PT_ORIG_D0),%d0 | 86 | movel %sp@(PT_OFF_ORIG_D0),%d0 |
| 87 | cmpl #NR_syscalls,%d0 | 87 | cmpl #NR_syscalls,%d0 |
| 88 | jcs syscall | 88 | jcs syscall |
| 89 | badsys: | 89 | badsys: |
| 90 | movel #-ENOSYS,%sp@(PT_D0) | 90 | movel #-ENOSYS,%sp@(PT_OFF_D0) |
| 91 | jra ret_from_syscall | 91 | jra ret_from_syscall |
| 92 | 92 | ||
| 93 | do_trace_exit: | 93 | do_trace_exit: |
| @@ -103,7 +103,7 @@ ENTRY(ret_from_signal) | |||
| 103 | addql #4,%sp | 103 | addql #4,%sp |
| 104 | /* on 68040 complete pending writebacks if any */ | 104 | /* on 68040 complete pending writebacks if any */ |
| 105 | #ifdef CONFIG_M68040 | 105 | #ifdef CONFIG_M68040 |
| 106 | bfextu %sp@(PT_VECTOR){#0,#4},%d0 | 106 | bfextu %sp@(PT_OFF_FORMATVEC){#0,#4},%d0 |
| 107 | subql #7,%d0 | bus error frame ? | 107 | subql #7,%d0 | bus error frame ? |
| 108 | jbne 1f | 108 | jbne 1f |
| 109 | movel %sp,%sp@- | 109 | movel %sp,%sp@- |
| @@ -127,7 +127,7 @@ ENTRY(system_call) | |||
| 127 | jcc badsys | 127 | jcc badsys |
| 128 | syscall: | 128 | syscall: |
| 129 | jbsr @(sys_call_table,%d0:l:4)@(0) | 129 | jbsr @(sys_call_table,%d0:l:4)@(0) |
| 130 | movel %d0,%sp@(PT_D0) | save the return value | 130 | movel %d0,%sp@(PT_OFF_D0) | save the return value |
| 131 | ret_from_syscall: | 131 | ret_from_syscall: |
| 132 | |oriw #0x0700,%sr | 132 | |oriw #0x0700,%sr |
| 133 | movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0 | 133 | movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0 |
| @@ -135,7 +135,7 @@ ret_from_syscall: | |||
| 135 | 1: RESTORE_ALL | 135 | 1: RESTORE_ALL |
| 136 | 136 | ||
| 137 | syscall_exit_work: | 137 | syscall_exit_work: |
| 138 | btst #5,%sp@(PT_SR) | check if returning to kernel | 138 | btst #5,%sp@(PT_OFF_SR) | check if returning to kernel |
| 139 | bnes 1b | if so, skip resched, signals | 139 | bnes 1b | if so, skip resched, signals |
| 140 | lslw #1,%d0 | 140 | lslw #1,%d0 |
| 141 | jcs do_trace_exit | 141 | jcs do_trace_exit |
| @@ -148,7 +148,7 @@ syscall_exit_work: | |||
| 148 | 148 | ||
| 149 | ENTRY(ret_from_exception) | 149 | ENTRY(ret_from_exception) |
| 150 | .Lret_from_exception: | 150 | .Lret_from_exception: |
| 151 | btst #5,%sp@(PT_SR) | check if returning to kernel | 151 | btst #5,%sp@(PT_OFF_SR) | check if returning to kernel |
| 152 | bnes 1f | if so, skip resched, signals | 152 | bnes 1f | if so, skip resched, signals |
| 153 | | only allow interrupts when we are really the last one on the | 153 | | only allow interrupts when we are really the last one on the |
| 154 | | kernel stack, otherwise stack overflow can occur during | 154 | | kernel stack, otherwise stack overflow can occur during |
| @@ -182,7 +182,7 @@ do_signal_return: | |||
| 182 | jbra resume_userspace | 182 | jbra resume_userspace |
| 183 | 183 | ||
| 184 | do_delayed_trace: | 184 | do_delayed_trace: |
| 185 | bclr #7,%sp@(PT_SR) | clear trace bit in SR | 185 | bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR |
| 186 | pea 1 | send SIGTRAP | 186 | pea 1 | send SIGTRAP |
| 187 | movel %curptr,%sp@- | 187 | movel %curptr,%sp@- |
| 188 | pea LSIGTRAP | 188 | pea LSIGTRAP |
| @@ -199,7 +199,7 @@ ENTRY(auto_inthandler) | |||
| 199 | GET_CURRENT(%d0) | 199 | GET_CURRENT(%d0) |
| 200 | addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | 200 | addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) |
| 201 | | put exception # in d0 | 201 | | put exception # in d0 |
| 202 | bfextu %sp@(PT_VECTOR){#4,#10},%d0 | 202 | bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 |
| 203 | subw #VEC_SPUR,%d0 | 203 | subw #VEC_SPUR,%d0 |
| 204 | 204 | ||
| 205 | movel %sp,%sp@- | 205 | movel %sp,%sp@- |
| @@ -216,7 +216,7 @@ ret_from_interrupt: | |||
| 216 | ALIGN | 216 | ALIGN |
| 217 | ret_from_last_interrupt: | 217 | ret_from_last_interrupt: |
| 218 | moveq #(~ALLOWINT>>8)&0xff,%d0 | 218 | moveq #(~ALLOWINT>>8)&0xff,%d0 |
| 219 | andb %sp@(PT_SR),%d0 | 219 | andb %sp@(PT_OFF_SR),%d0 |
| 220 | jne 2b | 220 | jne 2b |
| 221 | 221 | ||
| 222 | /* check if we need to do software interrupts */ | 222 | /* check if we need to do software interrupts */ |
| @@ -232,7 +232,7 @@ ENTRY(user_inthandler) | |||
| 232 | GET_CURRENT(%d0) | 232 | GET_CURRENT(%d0) |
| 233 | addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) | 233 | addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) |
| 234 | | put exception # in d0 | 234 | | put exception # in d0 |
| 235 | bfextu %sp@(PT_VECTOR){#4,#10},%d0 | 235 | bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 |
| 236 | user_irqvec_fixup = . + 2 | 236 | user_irqvec_fixup = . + 2 |
| 237 | subw #VEC_USER,%d0 | 237 | subw #VEC_USER,%d0 |
| 238 | 238 | ||
| @@ -755,4 +755,6 @@ sys_call_table: | |||
| 755 | .long sys_inotify_init1 | 755 | .long sys_inotify_init1 |
| 756 | .long sys_preadv | 756 | .long sys_preadv |
| 757 | .long sys_pwritev /* 330 */ | 757 | .long sys_pwritev /* 330 */ |
| 758 | .long sys_rt_tgsigqueueinfo | ||
| 759 | .long sys_perf_counter_open | ||
| 758 | 760 | ||
diff --git a/arch/m68k/math-emu/fp_entry.S b/arch/m68k/math-emu/fp_entry.S index 954b4f304a7d..a3fe1f348dfe 100644 --- a/arch/m68k/math-emu/fp_entry.S +++ b/arch/m68k/math-emu/fp_entry.S | |||
| @@ -85,8 +85,8 @@ fp_err_ua2: | |||
| 85 | fp_err_ua1: | 85 | fp_err_ua1: |
| 86 | addq.l #4,%sp | 86 | addq.l #4,%sp |
| 87 | move.l %a0,-(%sp) | 87 | move.l %a0,-(%sp) |
| 88 | pea SEGV_MAPERR | 88 | pea LSEGV_MAPERR |
| 89 | pea SIGSEGV | 89 | pea LSIGSEGV |
| 90 | jsr fpemu_signal | 90 | jsr fpemu_signal |
| 91 | add.w #12,%sp | 91 | add.w #12,%sp |
| 92 | jra ret_from_exception | 92 | jra ret_from_exception |
| @@ -96,8 +96,8 @@ fp_err_ua1: | |||
| 96 | | it does not really belong here, but... | 96 | | it does not really belong here, but... |
| 97 | fp_sendtrace060: | 97 | fp_sendtrace060: |
| 98 | move.l (FPS_PC,%sp),-(%sp) | 98 | move.l (FPS_PC,%sp),-(%sp) |
| 99 | pea TRAP_TRACE | 99 | pea LTRAP_TRACE |
| 100 | pea SIGTRAP | 100 | pea LSIGTRAP |
| 101 | jsr fpemu_signal | 101 | jsr fpemu_signal |
| 102 | add.w #12,%sp | 102 | add.w #12,%sp |
| 103 | jra ret_from_exception | 103 | jra ret_from_exception |
| @@ -122,17 +122,17 @@ fp_get_data_reg: | |||
| 122 | .long fp_get_d6, fp_get_d7 | 122 | .long fp_get_d6, fp_get_d7 |
| 123 | 123 | ||
| 124 | fp_get_d0: | 124 | fp_get_d0: |
| 125 | move.l (PT_D0+8,%sp),%d0 | 125 | move.l (PT_OFF_D0+8,%sp),%d0 |
| 126 | printf PREGISTER,"{d0->%08x}",1,%d0 | 126 | printf PREGISTER,"{d0->%08x}",1,%d0 |
| 127 | rts | 127 | rts |
| 128 | 128 | ||
| 129 | fp_get_d1: | 129 | fp_get_d1: |
| 130 | move.l (PT_D1+8,%sp),%d0 | 130 | move.l (PT_OFF_D1+8,%sp),%d0 |
| 131 | printf PREGISTER,"{d1->%08x}",1,%d0 | 131 | printf PREGISTER,"{d1->%08x}",1,%d0 |
| 132 | rts | 132 | rts |
| 133 | 133 | ||
| 134 | fp_get_d2: | 134 | fp_get_d2: |
| 135 | move.l (PT_D2+8,%sp),%d0 | 135 | move.l (PT_OFF_D2+8,%sp),%d0 |
| 136 | printf PREGISTER,"{d2->%08x}",1,%d0 | 136 | printf PREGISTER,"{d2->%08x}",1,%d0 |
| 137 | rts | 137 | rts |
| 138 | 138 | ||
| @@ -173,35 +173,35 @@ fp_put_data_reg: | |||
| 173 | 173 | ||
| 174 | fp_put_d0: | 174 | fp_put_d0: |
| 175 | printf PREGISTER,"{d0<-%08x}",1,%d0 | 175 | printf PREGISTER,"{d0<-%08x}",1,%d0 |
| 176 | move.l %d0,(PT_D0+8,%sp) | 176 | move.l %d0,(PT_OFF_D0+8,%sp) |
| 177 | rts | 177 | rts |
| 178 | 178 | ||
| 179 | fp_put_d1: | 179 | fp_put_d1: |
| 180 | printf PREGISTER,"{d1<-%08x}",1,%d0 | 180 | printf PREGISTER,"{d1<-%08x}",1,%d0 |
| 181 | move.l %d0,(PT_D1+8,%sp) | 181 | move.l %d0,(PT_OFF_D1+8,%sp) |
| 182 | rts | 182 | rts |
| 183 | 183 | ||
| 184 | fp_put_d2: | 184 | fp_put_d2: |
| 185 | printf PREGISTER,"{d2<-%08x}",1,%d0 | 185 | printf PREGISTER,"{d2<-%08x}",1,%d0 |
| 186 | move.l %d0,(PT_D2+8,%sp) | 186 | move.l %d0,(PT_OFF_D2+8,%sp) |
| 187 | rts | 187 | rts |
| 188 | 188 | ||
| 189 | fp_put_d3: | 189 | fp_put_d3: |
| 190 | printf PREGISTER,"{d3<-%08x}",1,%d0 | 190 | printf PREGISTER,"{d3<-%08x}",1,%d0 |
| 191 | | move.l %d0,%d3 | 191 | | move.l %d0,%d3 |
| 192 | move.l %d0,(PT_D3+8,%sp) | 192 | move.l %d0,(PT_OFF_D3+8,%sp) |
| 193 | rts | 193 | rts |
| 194 | 194 | ||
| 195 | fp_put_d4: | 195 | fp_put_d4: |
| 196 | printf PREGISTER,"{d4<-%08x}",1,%d0 | 196 | printf PREGISTER,"{d4<-%08x}",1,%d0 |
| 197 | | move.l %d0,%d4 | 197 | | move.l %d0,%d4 |
| 198 | move.l %d0,(PT_D4+8,%sp) | 198 | move.l %d0,(PT_OFF_D4+8,%sp) |
| 199 | rts | 199 | rts |
| 200 | 200 | ||
| 201 | fp_put_d5: | 201 | fp_put_d5: |
| 202 | printf PREGISTER,"{d5<-%08x}",1,%d0 | 202 | printf PREGISTER,"{d5<-%08x}",1,%d0 |
| 203 | | move.l %d0,%d5 | 203 | | move.l %d0,%d5 |
| 204 | move.l %d0,(PT_D5+8,%sp) | 204 | move.l %d0,(PT_OFF_D5+8,%sp) |
| 205 | rts | 205 | rts |
| 206 | 206 | ||
| 207 | fp_put_d6: | 207 | fp_put_d6: |
| @@ -225,17 +225,17 @@ fp_get_addr_reg: | |||
| 225 | .long fp_get_a6, fp_get_a7 | 225 | .long fp_get_a6, fp_get_a7 |
| 226 | 226 | ||
| 227 | fp_get_a0: | 227 | fp_get_a0: |
| 228 | move.l (PT_A0+8,%sp),%a0 | 228 | move.l (PT_OFF_A0+8,%sp),%a0 |
| 229 | printf PREGISTER,"{a0->%08x}",1,%a0 | 229 | printf PREGISTER,"{a0->%08x}",1,%a0 |
| 230 | rts | 230 | rts |
| 231 | 231 | ||
| 232 | fp_get_a1: | 232 | fp_get_a1: |
| 233 | move.l (PT_A1+8,%sp),%a0 | 233 | move.l (PT_OFF_A1+8,%sp),%a0 |
| 234 | printf PREGISTER,"{a1->%08x}",1,%a0 | 234 | printf PREGISTER,"{a1->%08x}",1,%a0 |
| 235 | rts | 235 | rts |
| 236 | 236 | ||
| 237 | fp_get_a2: | 237 | fp_get_a2: |
| 238 | move.l (PT_A2+8,%sp),%a0 | 238 | move.l (PT_OFF_A2+8,%sp),%a0 |
| 239 | printf PREGISTER,"{a2->%08x}",1,%a0 | 239 | printf PREGISTER,"{a2->%08x}",1,%a0 |
| 240 | rts | 240 | rts |
| 241 | 241 | ||
| @@ -276,17 +276,17 @@ fp_put_addr_reg: | |||
| 276 | 276 | ||
| 277 | fp_put_a0: | 277 | fp_put_a0: |
| 278 | printf PREGISTER,"{a0<-%08x}",1,%a0 | 278 | printf PREGISTER,"{a0<-%08x}",1,%a0 |
| 279 | move.l %a0,(PT_A0+8,%sp) | 279 | move.l %a0,(PT_OFF_A0+8,%sp) |
| 280 | rts | 280 | rts |
| 281 | 281 | ||
| 282 | fp_put_a1: | 282 | fp_put_a1: |
| 283 | printf PREGISTER,"{a1<-%08x}",1,%a0 | 283 | printf PREGISTER,"{a1<-%08x}",1,%a0 |
| 284 | move.l %a0,(PT_A1+8,%sp) | 284 | move.l %a0,(PT_OFF_A1+8,%sp) |
| 285 | rts | 285 | rts |
| 286 | 286 | ||
| 287 | fp_put_a2: | 287 | fp_put_a2: |
| 288 | printf PREGISTER,"{a2<-%08x}",1,%a0 | 288 | printf PREGISTER,"{a2<-%08x}",1,%a0 |
| 289 | move.l %a0,(PT_A2+8,%sp) | 289 | move.l %a0,(PT_OFF_A2+8,%sp) |
| 290 | rts | 290 | rts |
| 291 | 291 | ||
| 292 | fp_put_a3: | 292 | fp_put_a3: |
diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S index c0b8782832fd..0ae123e08985 100644 --- a/arch/m68knommu/kernel/syscalltable.S +++ b/arch/m68knommu/kernel/syscalltable.S | |||
| @@ -349,6 +349,8 @@ ENTRY(sys_call_table) | |||
| 349 | .long sys_inotify_init1 | 349 | .long sys_inotify_init1 |
| 350 | .long sys_preadv | 350 | .long sys_preadv |
| 351 | .long sys_pwritev /* 330 */ | 351 | .long sys_pwritev /* 330 */ |
| 352 | .long sys_rt_tgsigqueueinfo | ||
| 353 | .long sys_perf_counter_open | ||
| 352 | 354 | ||
| 353 | .rept NR_syscalls-(.-sys_call_table)/4 | 355 | .rept NR_syscalls-(.-sys_call_table)/4 |
| 354 | .long sys_ni_syscall | 356 | .long sys_ni_syscall |
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 2ecab6155932..cf50fa29b198 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | #include <linux/leds.h> | 32 | #include <linux/leds.h> |
| 33 | #include <linux/string.h> | 33 | #include <linux/string.h> |
| 34 | #include <linux/etherdevice.h> | 34 | #include <linux/etherdevice.h> |
| 35 | #include <linux/phy.h> | ||
| 36 | #include <linux/phy_fixed.h> | ||
| 35 | 37 | ||
| 36 | #include <asm/addrspace.h> | 38 | #include <asm/addrspace.h> |
| 37 | #include <asm/mach-ar7/ar7.h> | 39 | #include <asm/mach-ar7/ar7.h> |
| @@ -208,6 +210,12 @@ static struct physmap_flash_data physmap_flash_data = { | |||
| 208 | .width = 2, | 210 | .width = 2, |
| 209 | }; | 211 | }; |
| 210 | 212 | ||
| 213 | static struct fixed_phy_status fixed_phy_status __initdata = { | ||
| 214 | .link = 1, | ||
| 215 | .speed = 100, | ||
| 216 | .duplex = 1, | ||
| 217 | }; | ||
| 218 | |||
| 211 | static struct plat_cpmac_data cpmac_low_data = { | 219 | static struct plat_cpmac_data cpmac_low_data = { |
| 212 | .reset_bit = 17, | 220 | .reset_bit = 17, |
| 213 | .power_bit = 20, | 221 | .power_bit = 20, |
| @@ -530,6 +538,9 @@ static int __init ar7_register_devices(void) | |||
| 530 | } | 538 | } |
| 531 | 539 | ||
| 532 | if (ar7_has_high_cpmac()) { | 540 | if (ar7_has_high_cpmac()) { |
| 541 | res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status); | ||
| 542 | if (res && res != -ENODEV) | ||
| 543 | return res; | ||
| 533 | cpmac_get_mac(1, cpmac_high_data.dev_addr); | 544 | cpmac_get_mac(1, cpmac_high_data.dev_addr); |
| 534 | res = platform_device_register(&cpmac_high); | 545 | res = platform_device_register(&cpmac_high); |
| 535 | if (res) | 546 | if (res) |
| @@ -538,6 +549,10 @@ static int __init ar7_register_devices(void) | |||
| 538 | cpmac_low_data.phy_mask = 0xffffffff; | 549 | cpmac_low_data.phy_mask = 0xffffffff; |
| 539 | } | 550 | } |
| 540 | 551 | ||
| 552 | res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status); | ||
| 553 | if (res && res != -ENODEV) | ||
| 554 | return res; | ||
| 555 | |||
| 541 | cpmac_get_mac(0, cpmac_low_data.dev_addr); | 556 | cpmac_get_mac(0, cpmac_low_data.dev_addr); |
| 542 | res = platform_device_register(&cpmac_low); | 557 | res = platform_device_register(&cpmac_low); |
| 543 | if (res) | 558 | if (res) |
diff --git a/arch/mips/include/asm/socket.h b/arch/mips/include/asm/socket.h index 2abca1780169..ae05accd9fe4 100644 --- a/arch/mips/include/asm/socket.h +++ b/arch/mips/include/asm/socket.h | |||
| @@ -42,6 +42,8 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */ | |||
| 42 | #define SO_SNDTIMEO 0x1005 /* send timeout */ | 42 | #define SO_SNDTIMEO 0x1005 /* send timeout */ |
| 43 | #define SO_RCVTIMEO 0x1006 /* receive timeout */ | 43 | #define SO_RCVTIMEO 0x1006 /* receive timeout */ |
| 44 | #define SO_ACCEPTCONN 0x1009 | 44 | #define SO_ACCEPTCONN 0x1009 |
| 45 | #define SO_PROTOCOL 0x1028 /* protocol type */ | ||
| 46 | #define SO_DOMAIN 0x1029 /* domain/socket family */ | ||
| 45 | 47 | ||
| 46 | /* linux-specific, might as well be the same as on i386 */ | 48 | /* linux-specific, might as well be the same as on i386 */ |
| 47 | #define SO_NO_CHECK 11 | 49 | #define SO_NO_CHECK 11 |
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index f9df720d2e40..01cc1630b66c 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h | |||
| @@ -115,6 +115,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); | |||
| 115 | #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ | 115 | #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ |
| 116 | #define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */ | 116 | #define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */ |
| 117 | #define TIF_SECCOMP 4 /* secure computing */ | 117 | #define TIF_SECCOMP 4 /* secure computing */ |
| 118 | #define TIF_NOTIFY_RESUME 5 /* callback before returning to user */ | ||
| 118 | #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ | 119 | #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ |
| 119 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ | 120 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ |
| 120 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ | 121 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ |
| @@ -139,6 +140,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); | |||
| 139 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | 140 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
| 140 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) | 141 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) |
| 141 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) | 142 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) |
| 143 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) | ||
| 142 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) | 144 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) |
| 143 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) | 145 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) |
| 144 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 146 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index e855b118a079..1a6ae124635b 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
| @@ -164,7 +164,7 @@ EXPORT(sysn32_call_table) | |||
| 164 | PTR sys_connect | 164 | PTR sys_connect |
| 165 | PTR sys_accept | 165 | PTR sys_accept |
| 166 | PTR sys_sendto | 166 | PTR sys_sendto |
| 167 | PTR sys_recvfrom | 167 | PTR compat_sys_recvfrom |
| 168 | PTR compat_sys_sendmsg /* 6045 */ | 168 | PTR compat_sys_sendmsg /* 6045 */ |
| 169 | PTR compat_sys_recvmsg | 169 | PTR compat_sys_recvmsg |
| 170 | PTR sys_shutdown | 170 | PTR sys_shutdown |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 0c49f1a660be..cd31087a651f 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
| @@ -378,8 +378,8 @@ sys_call_table: | |||
| 378 | PTR sys_getsockname | 378 | PTR sys_getsockname |
| 379 | PTR sys_getsockopt | 379 | PTR sys_getsockopt |
| 380 | PTR sys_listen | 380 | PTR sys_listen |
| 381 | PTR sys_recv /* 4175 */ | 381 | PTR compat_sys_recv /* 4175 */ |
| 382 | PTR sys_recvfrom | 382 | PTR compat_sys_recvfrom |
| 383 | PTR compat_sys_recvmsg | 383 | PTR compat_sys_recvmsg |
| 384 | PTR sys_send | 384 | PTR sys_send |
| 385 | PTR compat_sys_sendmsg | 385 | PTR compat_sys_sendmsg |
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 830c5ef9932b..6254041b942f 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/compiler.h> | 21 | #include <linux/compiler.h> |
| 22 | #include <linux/syscalls.h> | 22 | #include <linux/syscalls.h> |
| 23 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
| 24 | #include <linux/tracehook.h> | ||
| 24 | 25 | ||
| 25 | #include <asm/abi.h> | 26 | #include <asm/abi.h> |
| 26 | #include <asm/asm.h> | 27 | #include <asm/asm.h> |
| @@ -700,4 +701,11 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, | |||
| 700 | /* deal with pending signal delivery */ | 701 | /* deal with pending signal delivery */ |
| 701 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 702 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) |
| 702 | do_signal(regs); | 703 | do_signal(regs); |
| 704 | |||
| 705 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | ||
| 706 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
| 707 | tracehook_notify_resume(regs); | ||
| 708 | if (current->replacement_session_keyring) | ||
| 709 | key_replace_session_keyring(); | ||
| 710 | } | ||
| 703 | } | 711 | } |
diff --git a/arch/mn10300/include/asm/socket.h b/arch/mn10300/include/asm/socket.h index fb5daf438ec9..4df75af29d76 100644 --- a/arch/mn10300/include/asm/socket.h +++ b/arch/mn10300/include/asm/socket.h | |||
| @@ -57,4 +57,7 @@ | |||
| 57 | #define SO_TIMESTAMPING 37 | 57 | #define SO_TIMESTAMPING 37 |
| 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING | 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING |
| 59 | 59 | ||
| 60 | #define SO_PROTOCOL 38 | ||
| 61 | #define SO_DOMAIN 39 | ||
| 62 | |||
| 60 | #endif /* _ASM_SOCKET_H */ | 63 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c index feb2f2e810db..a21f43bc68e2 100644 --- a/arch/mn10300/kernel/signal.c +++ b/arch/mn10300/kernel/signal.c | |||
| @@ -568,5 +568,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) | |||
| 568 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 568 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
| 569 | clear_thread_flag(TIF_NOTIFY_RESUME); | 569 | clear_thread_flag(TIF_NOTIFY_RESUME); |
| 570 | tracehook_notify_resume(__frame); | 570 | tracehook_notify_resume(__frame); |
| 571 | if (current->replacement_session_keyring) | ||
| 572 | key_replace_session_keyring(); | ||
| 571 | } | 573 | } |
| 572 | } | 574 | } |
diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h index 885472bf7b78..960b1e5d8e16 100644 --- a/arch/parisc/include/asm/socket.h +++ b/arch/parisc/include/asm/socket.h | |||
| @@ -24,6 +24,8 @@ | |||
| 24 | #define SO_RCVTIMEO 0x1006 | 24 | #define SO_RCVTIMEO 0x1006 |
| 25 | #define SO_ERROR 0x1007 | 25 | #define SO_ERROR 0x1007 |
| 26 | #define SO_TYPE 0x1008 | 26 | #define SO_TYPE 0x1008 |
| 27 | #define SO_PROTOCOL 0x1028 | ||
| 28 | #define SO_DOMAIN 0x1029 | ||
| 27 | #define SO_PEERNAME 0x2000 | 29 | #define SO_PEERNAME 0x2000 |
| 28 | 30 | ||
| 29 | #define SO_NO_CHECK 0x400b | 31 | #define SO_NO_CHECK 0x400b |
diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h index 4ce0edfbe969..ac775a76bff7 100644 --- a/arch/parisc/include/asm/thread_info.h +++ b/arch/parisc/include/asm/thread_info.h | |||
| @@ -59,6 +59,7 @@ struct thread_info { | |||
| 59 | #define TIF_MEMDIE 5 | 59 | #define TIF_MEMDIE 5 |
| 60 | #define TIF_RESTORE_SIGMASK 6 /* restore saved signal mask */ | 60 | #define TIF_RESTORE_SIGMASK 6 /* restore saved signal mask */ |
| 61 | #define TIF_FREEZE 7 /* is freezing for suspend */ | 61 | #define TIF_FREEZE 7 /* is freezing for suspend */ |
| 62 | #define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ | ||
| 62 | 63 | ||
| 63 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) | 64 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) |
| 64 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) | 65 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) |
| @@ -67,8 +68,9 @@ struct thread_info { | |||
| 67 | #define _TIF_32BIT (1 << TIF_32BIT) | 68 | #define _TIF_32BIT (1 << TIF_32BIT) |
| 68 | #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) | 69 | #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) |
| 69 | #define _TIF_FREEZE (1 << TIF_FREEZE) | 70 | #define _TIF_FREEZE (1 << TIF_FREEZE) |
| 71 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) | ||
| 70 | 72 | ||
| 71 | #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | \ | 73 | #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \ |
| 72 | _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK) | 74 | _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK) |
| 73 | 75 | ||
| 74 | #endif /* __KERNEL__ */ | 76 | #endif /* __KERNEL__ */ |
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index e552e547cb93..8c4712b74dc1 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
| @@ -948,7 +948,7 @@ intr_check_sig: | |||
| 948 | /* As above */ | 948 | /* As above */ |
| 949 | mfctl %cr30,%r1 | 949 | mfctl %cr30,%r1 |
| 950 | LDREG TI_FLAGS(%r1),%r19 | 950 | LDREG TI_FLAGS(%r1),%r19 |
| 951 | ldi (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r20 | 951 | ldi (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NOTIFY_RESUME), %r20 |
| 952 | and,COND(<>) %r19, %r20, %r0 | 952 | and,COND(<>) %r19, %r20, %r0 |
| 953 | b,n intr_restore /* skip past if we've nothing to do */ | 953 | b,n intr_restore /* skip past if we've nothing to do */ |
| 954 | 954 | ||
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index f82544225e8e..8eb3c63c407a 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/stddef.h> | 25 | #include <linux/stddef.h> |
| 26 | #include <linux/compat.h> | 26 | #include <linux/compat.h> |
| 27 | #include <linux/elf.h> | 27 | #include <linux/elf.h> |
| 28 | #include <linux/tracehook.h> | ||
| 28 | #include <asm/ucontext.h> | 29 | #include <asm/ucontext.h> |
| 29 | #include <asm/rt_sigframe.h> | 30 | #include <asm/rt_sigframe.h> |
| 30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
| @@ -645,4 +646,11 @@ void do_notify_resume(struct pt_regs *regs, long in_syscall) | |||
| 645 | if (test_thread_flag(TIF_SIGPENDING) || | 646 | if (test_thread_flag(TIF_SIGPENDING) || |
| 646 | test_thread_flag(TIF_RESTORE_SIGMASK)) | 647 | test_thread_flag(TIF_RESTORE_SIGMASK)) |
| 647 | do_signal(regs, in_syscall); | 648 | do_signal(regs, in_syscall); |
| 649 | |||
| 650 | if (test_thread_flag(TIF_NOTIFY_RESUME)) { | ||
| 651 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
| 652 | tracehook_notify_resume(regs); | ||
| 653 | if (current->replacement_session_keyring) | ||
| 654 | key_replace_session_keyring(); | ||
| 655 | } | ||
| 648 | } | 656 | } |
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 528f0ff9b273..8b58bf0b7d5a 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c | |||
| @@ -532,7 +532,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs) | |||
| 532 | /* Kill the user process later */ | 532 | /* Kill the user process later */ |
| 533 | regs->iaoq[0] = 0 | 3; | 533 | regs->iaoq[0] = 0 | 3; |
| 534 | regs->iaoq[1] = regs->iaoq[0] + 4; | 534 | regs->iaoq[1] = regs->iaoq[0] + 4; |
| 535 | regs->iasq[0] = regs->iasq[0] = regs->sr[7]; | 535 | regs->iasq[0] = regs->iasq[1] = regs->sr[7]; |
| 536 | regs->gr[0] &= ~PSW_B; | 536 | regs->gr[0] &= ~PSW_B; |
| 537 | return; | 537 | return; |
| 538 | } | 538 | } |
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index e28e65e7a0e1..7de127e4ceef 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig | |||
| @@ -1,13 +1,14 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.30-rc5 | 3 | # Linux kernel version: 2.6.31-rc7 |
| 4 | # Fri May 15 10:37:00 2009 | 4 | # Mon Aug 24 17:38:50 2009 |
| 5 | # | 5 | # |
| 6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
| 7 | 7 | ||
| 8 | # | 8 | # |
| 9 | # Processor support | 9 | # Processor support |
| 10 | # | 10 | # |
| 11 | CONFIG_PPC_BOOK3S_64=y | ||
| 11 | CONFIG_PPC_BOOK3S=y | 12 | CONFIG_PPC_BOOK3S=y |
| 12 | # CONFIG_POWER4_ONLY is not set | 13 | # CONFIG_POWER4_ONLY is not set |
| 13 | CONFIG_POWER3=y | 14 | CONFIG_POWER3=y |
| @@ -20,6 +21,7 @@ CONFIG_PPC_STD_MMU=y | |||
| 20 | CONFIG_PPC_STD_MMU_64=y | 21 | CONFIG_PPC_STD_MMU_64=y |
| 21 | CONFIG_PPC_MM_SLICES=y | 22 | CONFIG_PPC_MM_SLICES=y |
| 22 | CONFIG_VIRT_CPU_ACCOUNTING=y | 23 | CONFIG_VIRT_CPU_ACCOUNTING=y |
| 24 | CONFIG_PPC_HAVE_PMU_SUPPORT=y | ||
| 23 | CONFIG_SMP=y | 25 | CONFIG_SMP=y |
| 24 | CONFIG_NR_CPUS=2 | 26 | CONFIG_NR_CPUS=2 |
| 25 | CONFIG_64BIT=y | 27 | CONFIG_64BIT=y |
| @@ -31,6 +33,7 @@ CONFIG_GENERIC_TIME=y | |||
| 31 | CONFIG_GENERIC_TIME_VSYSCALL=y | 33 | CONFIG_GENERIC_TIME_VSYSCALL=y |
| 32 | CONFIG_GENERIC_CLOCKEVENTS=y | 34 | CONFIG_GENERIC_CLOCKEVENTS=y |
| 33 | CONFIG_GENERIC_HARDIRQS=y | 35 | CONFIG_GENERIC_HARDIRQS=y |
| 36 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | ||
| 34 | CONFIG_HAVE_SETUP_PER_CPU_AREA=y | 37 | CONFIG_HAVE_SETUP_PER_CPU_AREA=y |
| 35 | CONFIG_IRQ_PER_CPU=y | 38 | CONFIG_IRQ_PER_CPU=y |
| 36 | CONFIG_STACKTRACE_SUPPORT=y | 39 | CONFIG_STACKTRACE_SUPPORT=y |
| @@ -41,7 +44,6 @@ CONFIG_RWSEM_XCHGADD_ALGORITHM=y | |||
| 41 | CONFIG_ARCH_HAS_ILOG2_U32=y | 44 | CONFIG_ARCH_HAS_ILOG2_U32=y |
| 42 | CONFIG_ARCH_HAS_ILOG2_U64=y | 45 | CONFIG_ARCH_HAS_ILOG2_U64=y |
| 43 | CONFIG_GENERIC_HWEIGHT=y | 46 | CONFIG_GENERIC_HWEIGHT=y |
| 44 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
| 45 | CONFIG_GENERIC_FIND_NEXT_BIT=y | 47 | CONFIG_GENERIC_FIND_NEXT_BIT=y |
| 46 | CONFIG_ARCH_NO_VIRT_TO_BUS=y | 48 | CONFIG_ARCH_NO_VIRT_TO_BUS=y |
| 47 | CONFIG_PPC=y | 49 | CONFIG_PPC=y |
| @@ -62,6 +64,7 @@ CONFIG_DTC=y | |||
| 62 | # CONFIG_PPC_DCR_MMIO is not set | 64 | # CONFIG_PPC_DCR_MMIO is not set |
| 63 | CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y | 65 | CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y |
| 64 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 66 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
| 67 | CONFIG_CONSTRUCTORS=y | ||
| 65 | 68 | ||
| 66 | # | 69 | # |
| 67 | # General setup | 70 | # General setup |
| @@ -113,7 +116,6 @@ CONFIG_SYSCTL_SYSCALL=y | |||
| 113 | CONFIG_KALLSYMS=y | 116 | CONFIG_KALLSYMS=y |
| 114 | CONFIG_KALLSYMS_ALL=y | 117 | CONFIG_KALLSYMS_ALL=y |
| 115 | CONFIG_KALLSYMS_EXTRA_PASS=y | 118 | CONFIG_KALLSYMS_EXTRA_PASS=y |
| 116 | # CONFIG_STRIP_ASM_SYMS is not set | ||
| 117 | CONFIG_HOTPLUG=y | 119 | CONFIG_HOTPLUG=y |
| 118 | CONFIG_PRINTK=y | 120 | CONFIG_PRINTK=y |
| 119 | CONFIG_BUG=y | 121 | CONFIG_BUG=y |
| @@ -126,7 +128,14 @@ CONFIG_TIMERFD=y | |||
| 126 | CONFIG_EVENTFD=y | 128 | CONFIG_EVENTFD=y |
| 127 | CONFIG_SHMEM=y | 129 | CONFIG_SHMEM=y |
| 128 | CONFIG_AIO=y | 130 | CONFIG_AIO=y |
| 131 | CONFIG_HAVE_PERF_COUNTERS=y | ||
| 132 | |||
| 133 | # | ||
| 134 | # Performance Counters | ||
| 135 | # | ||
| 136 | # CONFIG_PERF_COUNTERS is not set | ||
| 129 | CONFIG_VM_EVENT_COUNTERS=y | 137 | CONFIG_VM_EVENT_COUNTERS=y |
| 138 | # CONFIG_STRIP_ASM_SYMS is not set | ||
| 130 | # CONFIG_COMPAT_BRK is not set | 139 | # CONFIG_COMPAT_BRK is not set |
| 131 | CONFIG_SLAB=y | 140 | CONFIG_SLAB=y |
| 132 | # CONFIG_SLUB is not set | 141 | # CONFIG_SLUB is not set |
| @@ -145,6 +154,11 @@ CONFIG_HAVE_KRETPROBES=y | |||
| 145 | CONFIG_HAVE_ARCH_TRACEHOOK=y | 154 | CONFIG_HAVE_ARCH_TRACEHOOK=y |
| 146 | CONFIG_HAVE_DMA_ATTRS=y | 155 | CONFIG_HAVE_DMA_ATTRS=y |
| 147 | CONFIG_USE_GENERIC_SMP_HELPERS=y | 156 | CONFIG_USE_GENERIC_SMP_HELPERS=y |
| 157 | |||
| 158 | # | ||
| 159 | # GCOV-based kernel profiling | ||
| 160 | # | ||
| 161 | # CONFIG_GCOV_KERNEL is not set | ||
| 148 | # CONFIG_SLOW_WORK is not set | 162 | # CONFIG_SLOW_WORK is not set |
| 149 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set | 163 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set |
| 150 | CONFIG_SLABINFO=y | 164 | CONFIG_SLABINFO=y |
| @@ -210,7 +224,7 @@ CONFIG_PPC_CELL=y | |||
| 210 | # | 224 | # |
| 211 | # Cell Broadband Engine options | 225 | # Cell Broadband Engine options |
| 212 | # | 226 | # |
| 213 | CONFIG_SPU_FS=y | 227 | CONFIG_SPU_FS=m |
| 214 | CONFIG_SPU_FS_64K_LS=y | 228 | CONFIG_SPU_FS_64K_LS=y |
| 215 | # CONFIG_SPU_TRACE is not set | 229 | # CONFIG_SPU_TRACE is not set |
| 216 | CONFIG_SPU_BASE=y | 230 | CONFIG_SPU_BASE=y |
| @@ -255,6 +269,7 @@ CONFIG_BINFMT_MISC=y | |||
| 255 | CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y | 269 | CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y |
| 256 | # CONFIG_IOMMU_VMERGE is not set | 270 | # CONFIG_IOMMU_VMERGE is not set |
| 257 | CONFIG_IOMMU_HELPER=y | 271 | CONFIG_IOMMU_HELPER=y |
| 272 | # CONFIG_SWIOTLB is not set | ||
| 258 | CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y | 273 | CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y |
| 259 | CONFIG_ARCH_HAS_WALK_MEMORY=y | 274 | CONFIG_ARCH_HAS_WALK_MEMORY=y |
| 260 | CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y | 275 | CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y |
| @@ -285,9 +300,9 @@ CONFIG_MIGRATION=y | |||
| 285 | CONFIG_PHYS_ADDR_T_64BIT=y | 300 | CONFIG_PHYS_ADDR_T_64BIT=y |
| 286 | CONFIG_ZONE_DMA_FLAG=1 | 301 | CONFIG_ZONE_DMA_FLAG=1 |
| 287 | CONFIG_BOUNCE=y | 302 | CONFIG_BOUNCE=y |
| 288 | CONFIG_UNEVICTABLE_LRU=y | ||
| 289 | CONFIG_HAVE_MLOCK=y | 303 | CONFIG_HAVE_MLOCK=y |
| 290 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | 304 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y |
| 305 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
| 291 | CONFIG_ARCH_MEMORY_PROBE=y | 306 | CONFIG_ARCH_MEMORY_PROBE=y |
| 292 | CONFIG_PPC_HAS_HASH_64K=y | 307 | CONFIG_PPC_HAS_HASH_64K=y |
| 293 | CONFIG_PPC_4K_PAGES=y | 308 | CONFIG_PPC_4K_PAGES=y |
| @@ -399,6 +414,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y | |||
| 399 | # CONFIG_ECONET is not set | 414 | # CONFIG_ECONET is not set |
| 400 | # CONFIG_WAN_ROUTER is not set | 415 | # CONFIG_WAN_ROUTER is not set |
| 401 | # CONFIG_PHONET is not set | 416 | # CONFIG_PHONET is not set |
| 417 | # CONFIG_IEEE802154 is not set | ||
| 402 | # CONFIG_NET_SCHED is not set | 418 | # CONFIG_NET_SCHED is not set |
| 403 | # CONFIG_DCB is not set | 419 | # CONFIG_DCB is not set |
| 404 | 420 | ||
| @@ -433,11 +449,14 @@ CONFIG_BT_HCIBTUSB=m | |||
| 433 | CONFIG_WIRELESS=y | 449 | CONFIG_WIRELESS=y |
| 434 | CONFIG_CFG80211=m | 450 | CONFIG_CFG80211=m |
| 435 | # CONFIG_CFG80211_REG_DEBUG is not set | 451 | # CONFIG_CFG80211_REG_DEBUG is not set |
| 452 | # CONFIG_CFG80211_DEBUGFS is not set | ||
| 436 | # CONFIG_WIRELESS_OLD_REGULATORY is not set | 453 | # CONFIG_WIRELESS_OLD_REGULATORY is not set |
| 437 | CONFIG_WIRELESS_EXT=y | 454 | CONFIG_WIRELESS_EXT=y |
| 438 | # CONFIG_WIRELESS_EXT_SYSFS is not set | 455 | # CONFIG_WIRELESS_EXT_SYSFS is not set |
| 439 | # CONFIG_LIB80211 is not set | 456 | # CONFIG_LIB80211 is not set |
| 440 | CONFIG_MAC80211=m | 457 | CONFIG_MAC80211=m |
| 458 | CONFIG_MAC80211_DEFAULT_PS=y | ||
| 459 | CONFIG_MAC80211_DEFAULT_PS_VALUE=1 | ||
| 441 | 460 | ||
| 442 | # | 461 | # |
| 443 | # Rate control algorithm selection | 462 | # Rate control algorithm selection |
| @@ -447,7 +466,6 @@ CONFIG_MAC80211_RC_PID=y | |||
| 447 | CONFIG_MAC80211_RC_DEFAULT_PID=y | 466 | CONFIG_MAC80211_RC_DEFAULT_PID=y |
| 448 | # CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set | 467 | # CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set |
| 449 | CONFIG_MAC80211_RC_DEFAULT="pid" | 468 | CONFIG_MAC80211_RC_DEFAULT="pid" |
| 450 | # CONFIG_MAC80211_MESH is not set | ||
| 451 | # CONFIG_MAC80211_LEDS is not set | 469 | # CONFIG_MAC80211_LEDS is not set |
| 452 | # CONFIG_MAC80211_DEBUGFS is not set | 470 | # CONFIG_MAC80211_DEBUGFS is not set |
| 453 | # CONFIG_MAC80211_DEBUG_MENU is not set | 471 | # CONFIG_MAC80211_DEBUG_MENU is not set |
| @@ -472,77 +490,7 @@ CONFIG_EXTRA_FIRMWARE="" | |||
| 472 | # CONFIG_DEBUG_DEVRES is not set | 490 | # CONFIG_DEBUG_DEVRES is not set |
| 473 | # CONFIG_SYS_HYPERVISOR is not set | 491 | # CONFIG_SYS_HYPERVISOR is not set |
| 474 | # CONFIG_CONNECTOR is not set | 492 | # CONFIG_CONNECTOR is not set |
| 475 | CONFIG_MTD=y | 493 | # CONFIG_MTD is not set |
| 476 | CONFIG_MTD_DEBUG=y | ||
| 477 | CONFIG_MTD_DEBUG_VERBOSE=0 | ||
| 478 | # CONFIG_MTD_CONCAT is not set | ||
| 479 | # CONFIG_MTD_PARTITIONS is not set | ||
| 480 | # CONFIG_MTD_TESTS is not set | ||
| 481 | |||
| 482 | # | ||
| 483 | # User Modules And Translation Layers | ||
| 484 | # | ||
| 485 | # CONFIG_MTD_CHAR is not set | ||
| 486 | CONFIG_MTD_BLKDEVS=y | ||
| 487 | CONFIG_MTD_BLOCK=y | ||
| 488 | # CONFIG_FTL is not set | ||
| 489 | # CONFIG_NFTL is not set | ||
| 490 | # CONFIG_INFTL is not set | ||
| 491 | # CONFIG_RFD_FTL is not set | ||
| 492 | # CONFIG_SSFDC is not set | ||
| 493 | # CONFIG_MTD_OOPS is not set | ||
| 494 | |||
| 495 | # | ||
| 496 | # RAM/ROM/Flash chip drivers | ||
| 497 | # | ||
| 498 | # CONFIG_MTD_CFI is not set | ||
| 499 | # CONFIG_MTD_JEDECPROBE is not set | ||
| 500 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
| 501 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
| 502 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
| 503 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
| 504 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
| 505 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
| 506 | CONFIG_MTD_CFI_I1=y | ||
| 507 | CONFIG_MTD_CFI_I2=y | ||
| 508 | # CONFIG_MTD_CFI_I4 is not set | ||
| 509 | # CONFIG_MTD_CFI_I8 is not set | ||
| 510 | # CONFIG_MTD_RAM is not set | ||
| 511 | # CONFIG_MTD_ROM is not set | ||
| 512 | # CONFIG_MTD_ABSENT is not set | ||
| 513 | |||
| 514 | # | ||
| 515 | # Mapping drivers for chip access | ||
| 516 | # | ||
| 517 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
| 518 | # CONFIG_MTD_PLATRAM is not set | ||
| 519 | |||
| 520 | # | ||
| 521 | # Self-contained MTD device drivers | ||
| 522 | # | ||
| 523 | # CONFIG_MTD_SLRAM is not set | ||
| 524 | # CONFIG_MTD_PHRAM is not set | ||
| 525 | # CONFIG_MTD_MTDRAM is not set | ||
| 526 | # CONFIG_MTD_BLOCK2MTD is not set | ||
| 527 | |||
| 528 | # | ||
| 529 | # Disk-On-Chip Device Drivers | ||
| 530 | # | ||
| 531 | # CONFIG_MTD_DOC2000 is not set | ||
| 532 | # CONFIG_MTD_DOC2001 is not set | ||
| 533 | # CONFIG_MTD_DOC2001PLUS is not set | ||
| 534 | # CONFIG_MTD_NAND is not set | ||
| 535 | # CONFIG_MTD_ONENAND is not set | ||
| 536 | |||
| 537 | # | ||
| 538 | # LPDDR flash memory drivers | ||
| 539 | # | ||
| 540 | # CONFIG_MTD_LPDDR is not set | ||
| 541 | |||
| 542 | # | ||
| 543 | # UBI - Unsorted block images | ||
| 544 | # | ||
| 545 | # CONFIG_MTD_UBI is not set | ||
| 546 | CONFIG_OF_DEVICE=y | 494 | CONFIG_OF_DEVICE=y |
| 547 | # CONFIG_PARPORT is not set | 495 | # CONFIG_PARPORT is not set |
| 548 | CONFIG_BLK_DEV=y | 496 | CONFIG_BLK_DEV=y |
| @@ -590,10 +538,6 @@ CONFIG_BLK_DEV_SR=y | |||
| 590 | # CONFIG_BLK_DEV_SR_VENDOR is not set | 538 | # CONFIG_BLK_DEV_SR_VENDOR is not set |
| 591 | CONFIG_CHR_DEV_SG=m | 539 | CONFIG_CHR_DEV_SG=m |
| 592 | # CONFIG_CHR_DEV_SCH is not set | 540 | # CONFIG_CHR_DEV_SCH is not set |
| 593 | |||
| 594 | # | ||
| 595 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | ||
| 596 | # | ||
| 597 | CONFIG_SCSI_MULTI_LUN=y | 541 | CONFIG_SCSI_MULTI_LUN=y |
| 598 | # CONFIG_SCSI_CONSTANTS is not set | 542 | # CONFIG_SCSI_CONSTANTS is not set |
| 599 | # CONFIG_SCSI_LOGGING is not set | 543 | # CONFIG_SCSI_LOGGING is not set |
| @@ -626,7 +570,6 @@ CONFIG_BLK_DEV_DM=m | |||
| 626 | # CONFIG_DM_UEVENT is not set | 570 | # CONFIG_DM_UEVENT is not set |
| 627 | # CONFIG_MACINTOSH_DRIVERS is not set | 571 | # CONFIG_MACINTOSH_DRIVERS is not set |
| 628 | CONFIG_NETDEVICES=y | 572 | CONFIG_NETDEVICES=y |
| 629 | CONFIG_COMPAT_NET_DEV_OPS=y | ||
| 630 | # CONFIG_DUMMY is not set | 573 | # CONFIG_DUMMY is not set |
| 631 | # CONFIG_BONDING is not set | 574 | # CONFIG_BONDING is not set |
| 632 | # CONFIG_MACVLAN is not set | 575 | # CONFIG_MACVLAN is not set |
| @@ -646,10 +589,11 @@ CONFIG_MII=m | |||
| 646 | # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set | 589 | # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set |
| 647 | # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set | 590 | # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set |
| 648 | # CONFIG_B44 is not set | 591 | # CONFIG_B44 is not set |
| 592 | # CONFIG_KS8842 is not set | ||
| 649 | CONFIG_NETDEV_1000=y | 593 | CONFIG_NETDEV_1000=y |
| 650 | CONFIG_GELIC_NET=y | 594 | CONFIG_GELIC_NET=y |
| 651 | CONFIG_GELIC_WIRELESS=y | 595 | CONFIG_GELIC_WIRELESS=y |
| 652 | CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE=y | 596 | # CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE is not set |
| 653 | # CONFIG_NETDEV_10000 is not set | 597 | # CONFIG_NETDEV_10000 is not set |
| 654 | 598 | ||
| 655 | # | 599 | # |
| @@ -669,8 +613,7 @@ CONFIG_WLAN_80211=y | |||
| 669 | # CONFIG_HOSTAP is not set | 613 | # CONFIG_HOSTAP is not set |
| 670 | # CONFIG_B43 is not set | 614 | # CONFIG_B43 is not set |
| 671 | # CONFIG_B43LEGACY is not set | 615 | # CONFIG_B43LEGACY is not set |
| 672 | CONFIG_ZD1211RW=m | 616 | # CONFIG_ZD1211RW is not set |
| 673 | # CONFIG_ZD1211RW_DEBUG is not set | ||
| 674 | # CONFIG_RT2X00 is not set | 617 | # CONFIG_RT2X00 is not set |
| 675 | 618 | ||
| 676 | # | 619 | # |
| @@ -682,7 +625,7 @@ CONFIG_ZD1211RW=m | |||
| 682 | # | 625 | # |
| 683 | # CONFIG_USB_CATC is not set | 626 | # CONFIG_USB_CATC is not set |
| 684 | # CONFIG_USB_KAWETH is not set | 627 | # CONFIG_USB_KAWETH is not set |
| 685 | CONFIG_USB_PEGASUS=m | 628 | # CONFIG_USB_PEGASUS is not set |
| 686 | # CONFIG_USB_RTL8150 is not set | 629 | # CONFIG_USB_RTL8150 is not set |
| 687 | CONFIG_USB_USBNET=m | 630 | CONFIG_USB_USBNET=m |
| 688 | CONFIG_USB_NET_AX8817X=m | 631 | CONFIG_USB_NET_AX8817X=m |
| @@ -693,10 +636,11 @@ CONFIG_USB_NET_AX8817X=m | |||
| 693 | # CONFIG_USB_NET_GL620A is not set | 636 | # CONFIG_USB_NET_GL620A is not set |
| 694 | # CONFIG_USB_NET_NET1080 is not set | 637 | # CONFIG_USB_NET_NET1080 is not set |
| 695 | # CONFIG_USB_NET_PLUSB is not set | 638 | # CONFIG_USB_NET_PLUSB is not set |
| 696 | CONFIG_USB_NET_MCS7830=m | 639 | # CONFIG_USB_NET_MCS7830 is not set |
| 697 | # CONFIG_USB_NET_RNDIS_HOST is not set | 640 | # CONFIG_USB_NET_RNDIS_HOST is not set |
| 698 | # CONFIG_USB_NET_CDC_SUBSET is not set | 641 | # CONFIG_USB_NET_CDC_SUBSET is not set |
| 699 | # CONFIG_USB_NET_ZAURUS is not set | 642 | # CONFIG_USB_NET_ZAURUS is not set |
| 643 | # CONFIG_USB_NET_INT51X1 is not set | ||
| 700 | # CONFIG_WAN is not set | 644 | # CONFIG_WAN is not set |
| 701 | CONFIG_PPP=m | 645 | CONFIG_PPP=m |
| 702 | CONFIG_PPP_MULTILINK=y | 646 | CONFIG_PPP_MULTILINK=y |
| @@ -771,8 +715,7 @@ CONFIG_DEVKMEM=y | |||
| 771 | # | 715 | # |
| 772 | CONFIG_UNIX98_PTYS=y | 716 | CONFIG_UNIX98_PTYS=y |
| 773 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | 717 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set |
| 774 | CONFIG_LEGACY_PTYS=y | 718 | # CONFIG_LEGACY_PTYS is not set |
| 775 | CONFIG_LEGACY_PTY_COUNT=16 | ||
| 776 | # CONFIG_HVC_UDBG is not set | 719 | # CONFIG_HVC_UDBG is not set |
| 777 | # CONFIG_IPMI_HANDLER is not set | 720 | # CONFIG_IPMI_HANDLER is not set |
| 778 | # CONFIG_HW_RANDOM is not set | 721 | # CONFIG_HW_RANDOM is not set |
| @@ -782,6 +725,11 @@ CONFIG_LEGACY_PTY_COUNT=16 | |||
| 782 | # CONFIG_TCG_TPM is not set | 725 | # CONFIG_TCG_TPM is not set |
| 783 | # CONFIG_I2C is not set | 726 | # CONFIG_I2C is not set |
| 784 | # CONFIG_SPI is not set | 727 | # CONFIG_SPI is not set |
| 728 | |||
| 729 | # | ||
| 730 | # PPS support | ||
| 731 | # | ||
| 732 | # CONFIG_PPS is not set | ||
| 785 | CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y | 733 | CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y |
| 786 | # CONFIG_GPIOLIB is not set | 734 | # CONFIG_GPIOLIB is not set |
| 787 | # CONFIG_W1 is not set | 735 | # CONFIG_W1 is not set |
| @@ -805,22 +753,7 @@ CONFIG_SSB_POSSIBLE=y | |||
| 805 | # CONFIG_HTC_PASIC3 is not set | 753 | # CONFIG_HTC_PASIC3 is not set |
| 806 | # CONFIG_MFD_TMIO is not set | 754 | # CONFIG_MFD_TMIO is not set |
| 807 | # CONFIG_REGULATOR is not set | 755 | # CONFIG_REGULATOR is not set |
| 808 | 756 | # CONFIG_MEDIA_SUPPORT is not set | |
| 809 | # | ||
| 810 | # Multimedia devices | ||
| 811 | # | ||
| 812 | |||
| 813 | # | ||
| 814 | # Multimedia core support | ||
| 815 | # | ||
| 816 | # CONFIG_VIDEO_DEV is not set | ||
| 817 | # CONFIG_DVB_CORE is not set | ||
| 818 | # CONFIG_VIDEO_MEDIA is not set | ||
| 819 | |||
| 820 | # | ||
| 821 | # Multimedia drivers | ||
| 822 | # | ||
| 823 | # CONFIG_DAB is not set | ||
| 824 | 757 | ||
| 825 | # | 758 | # |
| 826 | # Graphics support | 759 | # Graphics support |
| @@ -898,6 +831,11 @@ CONFIG_SND_SUPPORT_OLD_API=y | |||
| 898 | CONFIG_SND_VERBOSE_PROCFS=y | 831 | CONFIG_SND_VERBOSE_PROCFS=y |
| 899 | # CONFIG_SND_VERBOSE_PRINTK is not set | 832 | # CONFIG_SND_VERBOSE_PRINTK is not set |
| 900 | # CONFIG_SND_DEBUG is not set | 833 | # CONFIG_SND_DEBUG is not set |
| 834 | # CONFIG_SND_RAWMIDI_SEQ is not set | ||
| 835 | # CONFIG_SND_OPL3_LIB_SEQ is not set | ||
| 836 | # CONFIG_SND_OPL4_LIB_SEQ is not set | ||
| 837 | # CONFIG_SND_SBAWE_SEQ is not set | ||
| 838 | # CONFIG_SND_EMU10K1_SEQ is not set | ||
| 901 | # CONFIG_SND_DRIVERS is not set | 839 | # CONFIG_SND_DRIVERS is not set |
| 902 | CONFIG_SND_PPC=y | 840 | CONFIG_SND_PPC=y |
| 903 | CONFIG_SND_PS3=m | 841 | CONFIG_SND_PS3=m |
| @@ -930,29 +868,34 @@ CONFIG_USB_HIDDEV=y | |||
| 930 | # Special HID drivers | 868 | # Special HID drivers |
| 931 | # | 869 | # |
| 932 | # CONFIG_HID_A4TECH is not set | 870 | # CONFIG_HID_A4TECH is not set |
| 933 | # CONFIG_HID_APPLE is not set | 871 | CONFIG_HID_APPLE=m |
| 934 | # CONFIG_HID_BELKIN is not set | 872 | CONFIG_HID_BELKIN=m |
| 935 | # CONFIG_HID_CHERRY is not set | 873 | CONFIG_HID_CHERRY=m |
| 936 | # CONFIG_HID_CHICONY is not set | 874 | # CONFIG_HID_CHICONY is not set |
| 937 | # CONFIG_HID_CYPRESS is not set | 875 | # CONFIG_HID_CYPRESS is not set |
| 938 | # CONFIG_DRAGONRISE_FF is not set | 876 | # CONFIG_HID_DRAGONRISE is not set |
| 939 | # CONFIG_HID_EZKEY is not set | 877 | CONFIG_HID_EZKEY=m |
| 940 | # CONFIG_HID_KYE is not set | 878 | # CONFIG_HID_KYE is not set |
| 941 | # CONFIG_HID_GYRATION is not set | 879 | # CONFIG_HID_GYRATION is not set |
| 942 | # CONFIG_HID_KENSINGTON is not set | 880 | # CONFIG_HID_KENSINGTON is not set |
| 943 | # CONFIG_HID_LOGITECH is not set | 881 | CONFIG_HID_LOGITECH=m |
| 944 | # CONFIG_HID_MICROSOFT is not set | 882 | # CONFIG_LOGITECH_FF is not set |
| 883 | # CONFIG_LOGIRUMBLEPAD2_FF is not set | ||
| 884 | CONFIG_HID_MICROSOFT=m | ||
| 945 | # CONFIG_HID_MONTEREY is not set | 885 | # CONFIG_HID_MONTEREY is not set |
| 946 | # CONFIG_HID_NTRIG is not set | 886 | # CONFIG_HID_NTRIG is not set |
| 947 | # CONFIG_HID_PANTHERLORD is not set | 887 | # CONFIG_HID_PANTHERLORD is not set |
| 948 | # CONFIG_HID_PETALYNX is not set | 888 | # CONFIG_HID_PETALYNX is not set |
| 949 | # CONFIG_HID_SAMSUNG is not set | 889 | # CONFIG_HID_SAMSUNG is not set |
| 950 | CONFIG_HID_SONY=m | 890 | CONFIG_HID_SONY=m |
| 951 | # CONFIG_HID_SUNPLUS is not set | 891 | CONFIG_HID_SUNPLUS=m |
| 952 | # CONFIG_GREENASIA_FF is not set | 892 | # CONFIG_HID_GREENASIA is not set |
| 893 | CONFIG_HID_SMARTJOYPLUS=m | ||
| 894 | # CONFIG_SMARTJOYPLUS_FF is not set | ||
| 953 | # CONFIG_HID_TOPSEED is not set | 895 | # CONFIG_HID_TOPSEED is not set |
| 954 | # CONFIG_THRUSTMASTER_FF is not set | 896 | # CONFIG_HID_THRUSTMASTER is not set |
| 955 | # CONFIG_ZEROPLUS_FF is not set | 897 | # CONFIG_HID_WACOM is not set |
| 898 | # CONFIG_HID_ZEROPLUS is not set | ||
| 956 | CONFIG_USB_SUPPORT=y | 899 | CONFIG_USB_SUPPORT=y |
| 957 | CONFIG_USB_ARCH_HAS_HCD=y | 900 | CONFIG_USB_ARCH_HAS_HCD=y |
| 958 | CONFIG_USB_ARCH_HAS_OHCI=y | 901 | CONFIG_USB_ARCH_HAS_OHCI=y |
| @@ -988,6 +931,8 @@ CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y | |||
| 988 | # CONFIG_USB_ISP116X_HCD is not set | 931 | # CONFIG_USB_ISP116X_HCD is not set |
| 989 | # CONFIG_USB_ISP1760_HCD is not set | 932 | # CONFIG_USB_ISP1760_HCD is not set |
| 990 | CONFIG_USB_OHCI_HCD=m | 933 | CONFIG_USB_OHCI_HCD=m |
| 934 | # CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set | ||
| 935 | # CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set | ||
| 991 | # CONFIG_USB_OHCI_HCD_PPC_OF is not set | 936 | # CONFIG_USB_OHCI_HCD_PPC_OF is not set |
| 992 | # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set | 937 | # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set |
| 993 | CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y | 938 | CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y |
| @@ -1115,6 +1060,10 @@ CONFIG_RTC_DRV_PS3=m | |||
| 1115 | # CONFIG_DMADEVICES is not set | 1060 | # CONFIG_DMADEVICES is not set |
| 1116 | # CONFIG_AUXDISPLAY is not set | 1061 | # CONFIG_AUXDISPLAY is not set |
| 1117 | # CONFIG_UIO is not set | 1062 | # CONFIG_UIO is not set |
| 1063 | |||
| 1064 | # | ||
| 1065 | # TI VLYNQ | ||
| 1066 | # | ||
| 1118 | # CONFIG_STAGING is not set | 1067 | # CONFIG_STAGING is not set |
| 1119 | 1068 | ||
| 1120 | # | 1069 | # |
| @@ -1141,11 +1090,12 @@ CONFIG_FS_MBCACHE=y | |||
| 1141 | # CONFIG_REISERFS_FS is not set | 1090 | # CONFIG_REISERFS_FS is not set |
| 1142 | # CONFIG_JFS_FS is not set | 1091 | # CONFIG_JFS_FS is not set |
| 1143 | # CONFIG_FS_POSIX_ACL is not set | 1092 | # CONFIG_FS_POSIX_ACL is not set |
| 1144 | CONFIG_FILE_LOCKING=y | ||
| 1145 | # CONFIG_XFS_FS is not set | 1093 | # CONFIG_XFS_FS is not set |
| 1146 | # CONFIG_GFS2_FS is not set | 1094 | # CONFIG_GFS2_FS is not set |
| 1147 | # CONFIG_OCFS2_FS is not set | 1095 | # CONFIG_OCFS2_FS is not set |
| 1148 | # CONFIG_BTRFS_FS is not set | 1096 | # CONFIG_BTRFS_FS is not set |
| 1097 | CONFIG_FILE_LOCKING=y | ||
| 1098 | CONFIG_FSNOTIFY=y | ||
| 1149 | CONFIG_DNOTIFY=y | 1099 | CONFIG_DNOTIFY=y |
| 1150 | CONFIG_INOTIFY=y | 1100 | CONFIG_INOTIFY=y |
| 1151 | CONFIG_INOTIFY_USER=y | 1101 | CONFIG_INOTIFY_USER=y |
| @@ -1205,7 +1155,6 @@ CONFIG_MISC_FILESYSTEMS=y | |||
| 1205 | # CONFIG_BEFS_FS is not set | 1155 | # CONFIG_BEFS_FS is not set |
| 1206 | # CONFIG_BFS_FS is not set | 1156 | # CONFIG_BFS_FS is not set |
| 1207 | # CONFIG_EFS_FS is not set | 1157 | # CONFIG_EFS_FS is not set |
| 1208 | # CONFIG_JFFS2_FS is not set | ||
| 1209 | # CONFIG_CRAMFS is not set | 1158 | # CONFIG_CRAMFS is not set |
| 1210 | # CONFIG_SQUASHFS is not set | 1159 | # CONFIG_SQUASHFS is not set |
| 1211 | # CONFIG_VXFS_FS is not set | 1160 | # CONFIG_VXFS_FS is not set |
| @@ -1222,6 +1171,7 @@ CONFIG_NFS_FS=y | |||
| 1222 | CONFIG_NFS_V3=y | 1171 | CONFIG_NFS_V3=y |
| 1223 | # CONFIG_NFS_V3_ACL is not set | 1172 | # CONFIG_NFS_V3_ACL is not set |
| 1224 | CONFIG_NFS_V4=y | 1173 | CONFIG_NFS_V4=y |
| 1174 | # CONFIG_NFS_V4_1 is not set | ||
| 1225 | CONFIG_ROOT_NFS=y | 1175 | CONFIG_ROOT_NFS=y |
| 1226 | # CONFIG_NFSD is not set | 1176 | # CONFIG_NFSD is not set |
| 1227 | CONFIG_LOCKD=y | 1177 | CONFIG_LOCKD=y |
| @@ -1359,7 +1309,6 @@ CONFIG_DEBUG_MEMORY_INIT=y | |||
| 1359 | CONFIG_DEBUG_LIST=y | 1309 | CONFIG_DEBUG_LIST=y |
| 1360 | # CONFIG_DEBUG_SG is not set | 1310 | # CONFIG_DEBUG_SG is not set |
| 1361 | # CONFIG_DEBUG_NOTIFIERS is not set | 1311 | # CONFIG_DEBUG_NOTIFIERS is not set |
| 1362 | # CONFIG_BOOT_PRINTK_DELAY is not set | ||
| 1363 | # CONFIG_RCU_TORTURE_TEST is not set | 1312 | # CONFIG_RCU_TORTURE_TEST is not set |
| 1364 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 1313 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
| 1365 | # CONFIG_BACKTRACE_SELF_TEST is not set | 1314 | # CONFIG_BACKTRACE_SELF_TEST is not set |
| @@ -1374,31 +1323,21 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y | |||
| 1374 | CONFIG_HAVE_DYNAMIC_FTRACE=y | 1323 | CONFIG_HAVE_DYNAMIC_FTRACE=y |
| 1375 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y | 1324 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y |
| 1376 | CONFIG_RING_BUFFER=y | 1325 | CONFIG_RING_BUFFER=y |
| 1326 | CONFIG_EVENT_TRACING=y | ||
| 1327 | CONFIG_CONTEXT_SWITCH_TRACER=y | ||
| 1377 | CONFIG_TRACING=y | 1328 | CONFIG_TRACING=y |
| 1378 | CONFIG_TRACING_SUPPORT=y | 1329 | CONFIG_TRACING_SUPPORT=y |
| 1379 | 1330 | # CONFIG_FTRACE is not set | |
| 1380 | # | ||
| 1381 | # Tracers | ||
| 1382 | # | ||
| 1383 | # CONFIG_FUNCTION_TRACER is not set | ||
| 1384 | # CONFIG_IRQSOFF_TRACER is not set | ||
| 1385 | # CONFIG_SCHED_TRACER is not set | ||
| 1386 | # CONFIG_CONTEXT_SWITCH_TRACER is not set | ||
| 1387 | # CONFIG_EVENT_TRACER is not set | ||
| 1388 | # CONFIG_BOOT_TRACER is not set | ||
| 1389 | # CONFIG_TRACE_BRANCH_PROFILING is not set | ||
| 1390 | # CONFIG_STACK_TRACER is not set | ||
| 1391 | # CONFIG_KMEMTRACE is not set | ||
| 1392 | # CONFIG_WORKQUEUE_TRACER is not set | ||
| 1393 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
| 1394 | # CONFIG_FTRACE_STARTUP_TEST is not set | ||
| 1395 | # CONFIG_DYNAMIC_DEBUG is not set | 1331 | # CONFIG_DYNAMIC_DEBUG is not set |
| 1396 | # CONFIG_SAMPLES is not set | 1332 | # CONFIG_SAMPLES is not set |
| 1397 | CONFIG_HAVE_ARCH_KGDB=y | 1333 | CONFIG_HAVE_ARCH_KGDB=y |
| 1398 | # CONFIG_KGDB is not set | 1334 | # CONFIG_KGDB is not set |
| 1335 | # CONFIG_PPC_DISABLE_WERROR is not set | ||
| 1336 | CONFIG_PPC_WERROR=y | ||
| 1399 | CONFIG_PRINT_STACK_DEPTH=64 | 1337 | CONFIG_PRINT_STACK_DEPTH=64 |
| 1400 | CONFIG_DEBUG_STACKOVERFLOW=y | 1338 | CONFIG_DEBUG_STACKOVERFLOW=y |
| 1401 | # CONFIG_DEBUG_STACK_USAGE is not set | 1339 | # CONFIG_DEBUG_STACK_USAGE is not set |
| 1340 | # CONFIG_PPC_EMULATED_STATS is not set | ||
| 1402 | # CONFIG_CODE_PATCHING_SELFTEST is not set | 1341 | # CONFIG_CODE_PATCHING_SELFTEST is not set |
| 1403 | # CONFIG_FTR_FIXUP_SELFTEST is not set | 1342 | # CONFIG_FTR_FIXUP_SELFTEST is not set |
| 1404 | # CONFIG_MSI_BITMAP_SELFTEST is not set | 1343 | # CONFIG_MSI_BITMAP_SELFTEST is not set |
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index b44aaabdd1a6..0c34371ec49c 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h | |||
| @@ -424,6 +424,29 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | |||
| 424 | #endif | 424 | #endif |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) | ||
| 428 | { | ||
| 429 | struct dma_mapping_ops *ops = get_dma_ops(dev); | ||
| 430 | |||
| 431 | if (ops->addr_needs_map && ops->addr_needs_map(dev, addr, size)) | ||
| 432 | return 0; | ||
| 433 | |||
| 434 | if (!dev->dma_mask) | ||
| 435 | return 0; | ||
| 436 | |||
| 437 | return addr + size <= *dev->dma_mask; | ||
| 438 | } | ||
| 439 | |||
| 440 | static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) | ||
| 441 | { | ||
| 442 | return paddr + get_dma_direct_offset(dev); | ||
| 443 | } | ||
| 444 | |||
| 445 | static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) | ||
| 446 | { | ||
| 447 | return daddr - get_dma_direct_offset(dev); | ||
| 448 | } | ||
| 449 | |||
| 427 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | 450 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) |
| 428 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | 451 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) |
| 429 | #ifdef CONFIG_NOT_COHERENT_CACHE | 452 | #ifdef CONFIG_NOT_COHERENT_CACHE |
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index fddc3ed715fa..c9c930ed11d7 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
| @@ -34,7 +34,8 @@ | |||
| 34 | #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 | 34 | #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 |
| 35 | 35 | ||
| 36 | /* We don't currently support large pages. */ | 36 | /* We don't currently support large pages. */ |
| 37 | #define KVM_PAGES_PER_HPAGE (1UL << 31) | 37 | #define KVM_NR_PAGE_SIZES 1 |
| 38 | #define KVM_PAGES_PER_HPAGE(x) (1UL<<31) | ||
| 38 | 39 | ||
| 39 | struct kvm; | 40 | struct kvm; |
| 40 | struct kvm_run; | 41 | struct kvm_run; |
| @@ -153,7 +154,6 @@ struct kvm_vcpu_arch { | |||
| 153 | u32 pid; | 154 | u32 pid; |
| 154 | u32 swap_pid; | 155 | u32 swap_pid; |
| 155 | 156 | ||
| 156 | u32 pvr; | ||
| 157 | u32 ccr0; | 157 | u32 ccr0; |
| 158 | u32 ccr1; | 158 | u32 ccr1; |
| 159 | u32 dbcr0; | 159 | u32 dbcr0; |
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index eb17da781128..2a5da069714e 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h | |||
| @@ -104,8 +104,8 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
| 104 | else | 104 | else |
| 105 | pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte)); | 105 | pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte)); |
| 106 | 106 | ||
| 107 | #elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) | 107 | #elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) |
| 108 | /* Second case is 32-bit with 64-bit PTE in SMP mode. In this case, we | 108 | /* Second case is 32-bit with 64-bit PTE. In this case, we |
| 109 | * can just store as long as we do the two halves in the right order | 109 | * can just store as long as we do the two halves in the right order |
| 110 | * with a barrier in between. This is possible because we take care, | 110 | * with a barrier in between. This is possible because we take care, |
| 111 | * in the hash code, to pre-invalidate if the PTE was already hashed, | 111 | * in the hash code, to pre-invalidate if the PTE was already hashed, |
| @@ -140,7 +140,7 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
| 140 | 140 | ||
| 141 | #else | 141 | #else |
| 142 | /* Anything else just stores the PTE normally. That covers all 64-bit | 142 | /* Anything else just stores the PTE normally. That covers all 64-bit |
| 143 | * cases, and 32-bit non-hash with 64-bit PTEs in UP mode | 143 | * cases, and 32-bit non-hash with 32-bit PTEs. |
| 144 | */ | 144 | */ |
| 145 | *ptep = pte; | 145 | *ptep = pte; |
| 146 | #endif | 146 | #endif |
diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h index 157c5ca581c8..f388f0ab193f 100644 --- a/arch/powerpc/include/asm/qe.h +++ b/arch/powerpc/include/asm/qe.h | |||
| @@ -154,6 +154,7 @@ int qe_get_snum(void); | |||
| 154 | void qe_put_snum(u8 snum); | 154 | void qe_put_snum(u8 snum); |
| 155 | unsigned int qe_get_num_of_risc(void); | 155 | unsigned int qe_get_num_of_risc(void); |
| 156 | unsigned int qe_get_num_of_snums(void); | 156 | unsigned int qe_get_num_of_snums(void); |
| 157 | int qe_alive_during_sleep(void); | ||
| 157 | 158 | ||
| 158 | /* we actually use cpm_muram implementation, define this for convenience */ | 159 | /* we actually use cpm_muram implementation, define this for convenience */ |
| 159 | #define qe_muram_init cpm_muram_init | 160 | #define qe_muram_init cpm_muram_init |
diff --git a/arch/powerpc/include/asm/socket.h b/arch/powerpc/include/asm/socket.h index 1e5cfad0e3f7..3ab8b3e6feb0 100644 --- a/arch/powerpc/include/asm/socket.h +++ b/arch/powerpc/include/asm/socket.h | |||
| @@ -64,4 +64,7 @@ | |||
| 64 | #define SO_TIMESTAMPING 37 | 64 | #define SO_TIMESTAMPING 37 |
| 65 | #define SCM_TIMESTAMPING SO_TIMESTAMPING | 65 | #define SCM_TIMESTAMPING SO_TIMESTAMPING |
| 66 | 66 | ||
| 67 | #define SO_PROTOCOL 38 | ||
| 68 | #define SO_DOMAIN 39 | ||
| 69 | |||
| 67 | #endif /* _ASM_POWERPC_SOCKET_H */ | 70 | #endif /* _ASM_POWERPC_SOCKET_H */ |
diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h index c3b193121f81..198266cf9e2d 100644 --- a/arch/powerpc/include/asm/spinlock.h +++ b/arch/powerpc/include/asm/spinlock.h | |||
| @@ -54,7 +54,7 @@ | |||
| 54 | * This returns the old value in the lock, so we succeeded | 54 | * This returns the old value in the lock, so we succeeded |
| 55 | * in getting the lock if the return value is 0. | 55 | * in getting the lock if the return value is 0. |
| 56 | */ | 56 | */ |
| 57 | static inline unsigned long __spin_trylock(raw_spinlock_t *lock) | 57 | static inline unsigned long arch_spin_trylock(raw_spinlock_t *lock) |
| 58 | { | 58 | { |
| 59 | unsigned long tmp, token; | 59 | unsigned long tmp, token; |
| 60 | 60 | ||
| @@ -76,7 +76,7 @@ static inline unsigned long __spin_trylock(raw_spinlock_t *lock) | |||
| 76 | static inline int __raw_spin_trylock(raw_spinlock_t *lock) | 76 | static inline int __raw_spin_trylock(raw_spinlock_t *lock) |
| 77 | { | 77 | { |
| 78 | CLEAR_IO_SYNC; | 78 | CLEAR_IO_SYNC; |
| 79 | return __spin_trylock(lock) == 0; | 79 | return arch_spin_trylock(lock) == 0; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | /* | 82 | /* |
| @@ -108,7 +108,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) | |||
| 108 | { | 108 | { |
| 109 | CLEAR_IO_SYNC; | 109 | CLEAR_IO_SYNC; |
| 110 | while (1) { | 110 | while (1) { |
| 111 | if (likely(__spin_trylock(lock) == 0)) | 111 | if (likely(arch_spin_trylock(lock) == 0)) |
| 112 | break; | 112 | break; |
| 113 | do { | 113 | do { |
| 114 | HMT_low(); | 114 | HMT_low(); |
| @@ -126,7 +126,7 @@ void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) | |||
| 126 | 126 | ||
| 127 | CLEAR_IO_SYNC; | 127 | CLEAR_IO_SYNC; |
| 128 | while (1) { | 128 | while (1) { |
| 129 | if (likely(__spin_trylock(lock) == 0)) | 129 | if (likely(arch_spin_trylock(lock) == 0)) |
| 130 | break; | 130 | break; |
| 131 | local_save_flags(flags_dis); | 131 | local_save_flags(flags_dis); |
| 132 | local_irq_restore(flags); | 132 | local_irq_restore(flags); |
| @@ -181,7 +181,7 @@ extern void __raw_spin_unlock_wait(raw_spinlock_t *lock); | |||
| 181 | * This returns the old value in the lock + 1, | 181 | * This returns the old value in the lock + 1, |
| 182 | * so we got a read lock if the return value is > 0. | 182 | * so we got a read lock if the return value is > 0. |
| 183 | */ | 183 | */ |
| 184 | static inline long __read_trylock(raw_rwlock_t *rw) | 184 | static inline long arch_read_trylock(raw_rwlock_t *rw) |
| 185 | { | 185 | { |
| 186 | long tmp; | 186 | long tmp; |
| 187 | 187 | ||
| @@ -205,7 +205,7 @@ static inline long __read_trylock(raw_rwlock_t *rw) | |||
| 205 | * This returns the old value in the lock, | 205 | * This returns the old value in the lock, |
| 206 | * so we got the write lock if the return value is 0. | 206 | * so we got the write lock if the return value is 0. |
| 207 | */ | 207 | */ |
| 208 | static inline long __write_trylock(raw_rwlock_t *rw) | 208 | static inline long arch_write_trylock(raw_rwlock_t *rw) |
| 209 | { | 209 | { |
| 210 | long tmp, token; | 210 | long tmp, token; |
| 211 | 211 | ||
| @@ -228,7 +228,7 @@ static inline long __write_trylock(raw_rwlock_t *rw) | |||
| 228 | static inline void __raw_read_lock(raw_rwlock_t *rw) | 228 | static inline void __raw_read_lock(raw_rwlock_t *rw) |
| 229 | { | 229 | { |
| 230 | while (1) { | 230 | while (1) { |
| 231 | if (likely(__read_trylock(rw) > 0)) | 231 | if (likely(arch_read_trylock(rw) > 0)) |
| 232 | break; | 232 | break; |
| 233 | do { | 233 | do { |
| 234 | HMT_low(); | 234 | HMT_low(); |
| @@ -242,7 +242,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw) | |||
| 242 | static inline void __raw_write_lock(raw_rwlock_t *rw) | 242 | static inline void __raw_write_lock(raw_rwlock_t *rw) |
| 243 | { | 243 | { |
| 244 | while (1) { | 244 | while (1) { |
| 245 | if (likely(__write_trylock(rw) == 0)) | 245 | if (likely(arch_write_trylock(rw) == 0)) |
| 246 | break; | 246 | break; |
| 247 | do { | 247 | do { |
| 248 | HMT_low(); | 248 | HMT_low(); |
| @@ -255,12 +255,12 @@ static inline void __raw_write_lock(raw_rwlock_t *rw) | |||
| 255 | 255 | ||
| 256 | static inline int __raw_read_trylock(raw_rwlock_t *rw) | 256 | static inline int __raw_read_trylock(raw_rwlock_t *rw) |
| 257 | { | 257 | { |
| 258 | return __read_trylock(rw) > 0; | 258 | return arch_read_trylock(rw) > 0; |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | static inline int __raw_write_trylock(raw_rwlock_t *rw) | 261 | static inline int __raw_write_trylock(raw_rwlock_t *rw) |
| 262 | { | 262 | { |
| 263 | return __write_trylock(rw) == 0; | 263 | return arch_write_trylock(rw) == 0; |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | static inline void __raw_read_unlock(raw_rwlock_t *rw) | 266 | static inline void __raw_read_unlock(raw_rwlock_t *rw) |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index b73396b93905..9619285f64e8 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
| @@ -97,7 +97,7 @@ obj64-$(CONFIG_AUDIT) += compat_audit.o | |||
| 97 | 97 | ||
| 98 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o | 98 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o |
| 99 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o | 99 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o |
| 100 | obj-$(CONFIG_PPC_PERF_CTRS) += perf_counter.o | 100 | obj-$(CONFIG_PPC_PERF_CTRS) += perf_counter.o perf_callchain.o |
| 101 | obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \ | 101 | obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \ |
| 102 | power5+-pmu.o power6-pmu.o power7-pmu.o | 102 | power5+-pmu.o power6-pmu.o power7-pmu.o |
| 103 | obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o | 103 | obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 561b64652311..197b15646eeb 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
| @@ -67,6 +67,8 @@ int main(void) | |||
| 67 | DEFINE(MMCONTEXTID, offsetof(struct mm_struct, context.id)); | 67 | DEFINE(MMCONTEXTID, offsetof(struct mm_struct, context.id)); |
| 68 | #ifdef CONFIG_PPC64 | 68 | #ifdef CONFIG_PPC64 |
| 69 | DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); | 69 | DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); |
| 70 | DEFINE(SIGSEGV, SIGSEGV); | ||
| 71 | DEFINE(NMI_MASK, NMI_MASK); | ||
| 70 | #else | 72 | #else |
| 71 | DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); | 73 | DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); |
| 72 | #endif /* CONFIG_PPC64 */ | 74 | #endif /* CONFIG_PPC64 */ |
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c index 68ccf11e4f19..e8a57de85bcf 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c | |||
| @@ -24,50 +24,12 @@ | |||
| 24 | int swiotlb __read_mostly; | 24 | int swiotlb __read_mostly; |
| 25 | unsigned int ppc_swiotlb_enable; | 25 | unsigned int ppc_swiotlb_enable; |
| 26 | 26 | ||
| 27 | void *swiotlb_bus_to_virt(struct device *hwdev, dma_addr_t addr) | ||
| 28 | { | ||
| 29 | unsigned long pfn = PFN_DOWN(swiotlb_bus_to_phys(hwdev, addr)); | ||
| 30 | void *pageaddr = page_address(pfn_to_page(pfn)); | ||
| 31 | |||
| 32 | if (pageaddr != NULL) | ||
| 33 | return pageaddr + (addr % PAGE_SIZE); | ||
| 34 | return NULL; | ||
| 35 | } | ||
| 36 | |||
| 37 | dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr) | ||
| 38 | { | ||
| 39 | return paddr + get_dma_direct_offset(hwdev); | ||
| 40 | } | ||
| 41 | |||
| 42 | phys_addr_t swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr) | ||
| 43 | |||
| 44 | { | ||
| 45 | return baddr - get_dma_direct_offset(hwdev); | ||
| 46 | } | ||
| 47 | |||
| 48 | /* | ||
| 49 | * Determine if an address needs bounce buffering via swiotlb. | ||
| 50 | * Going forward I expect the swiotlb code to generalize on using | ||
| 51 | * a dma_ops->addr_needs_map, and this function will move from here to the | ||
| 52 | * generic swiotlb code. | ||
| 53 | */ | ||
| 54 | int | ||
| 55 | swiotlb_arch_address_needs_mapping(struct device *hwdev, dma_addr_t addr, | ||
| 56 | size_t size) | ||
| 57 | { | ||
| 58 | struct dma_mapping_ops *dma_ops = get_dma_ops(hwdev); | ||
| 59 | |||
| 60 | BUG_ON(!dma_ops); | ||
| 61 | return dma_ops->addr_needs_map(hwdev, addr, size); | ||
| 62 | } | ||
| 63 | |||
| 64 | /* | 27 | /* |
| 65 | * Determine if an address is reachable by a pci device, or if we must bounce. | 28 | * Determine if an address is reachable by a pci device, or if we must bounce. |
| 66 | */ | 29 | */ |
| 67 | static int | 30 | static int |
| 68 | swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size) | 31 | swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size) |
| 69 | { | 32 | { |
| 70 | u64 mask = dma_get_mask(hwdev); | ||
| 71 | dma_addr_t max; | 33 | dma_addr_t max; |
| 72 | struct pci_controller *hose; | 34 | struct pci_controller *hose; |
| 73 | struct pci_dev *pdev = to_pci_dev(hwdev); | 35 | struct pci_dev *pdev = to_pci_dev(hwdev); |
| @@ -79,16 +41,9 @@ swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size) | |||
| 79 | if ((addr + size > max) | (addr < hose->dma_window_base_cur)) | 41 | if ((addr + size > max) | (addr < hose->dma_window_base_cur)) |
| 80 | return 1; | 42 | return 1; |
| 81 | 43 | ||
| 82 | return !is_buffer_dma_capable(mask, addr, size); | 44 | return 0; |
| 83 | } | ||
| 84 | |||
| 85 | static int | ||
| 86 | swiotlb_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size) | ||
| 87 | { | ||
| 88 | return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size); | ||
| 89 | } | 45 | } |
| 90 | 46 | ||
| 91 | |||
| 92 | /* | 47 | /* |
| 93 | * At the moment, all platforms that use this code only require | 48 | * At the moment, all platforms that use this code only require |
| 94 | * swiotlb to be used if we're operating on HIGHMEM. Since | 49 | * swiotlb to be used if we're operating on HIGHMEM. Since |
| @@ -104,7 +59,6 @@ struct dma_mapping_ops swiotlb_dma_ops = { | |||
| 104 | .dma_supported = swiotlb_dma_supported, | 59 | .dma_supported = swiotlb_dma_supported, |
| 105 | .map_page = swiotlb_map_page, | 60 | .map_page = swiotlb_map_page, |
| 106 | .unmap_page = swiotlb_unmap_page, | 61 | .unmap_page = swiotlb_unmap_page, |
| 107 | .addr_needs_map = swiotlb_addr_needs_map, | ||
| 108 | .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu, | 62 | .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu, |
| 109 | .sync_single_range_for_device = swiotlb_sync_single_range_for_device, | 63 | .sync_single_range_for_device = swiotlb_sync_single_range_for_device, |
| 110 | .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, | 64 | .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index eb898112e577..8ac85e08ffae 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
| @@ -729,6 +729,11 @@ BEGIN_FTR_SECTION | |||
| 729 | bne- do_ste_alloc /* If so handle it */ | 729 | bne- do_ste_alloc /* If so handle it */ |
| 730 | END_FTR_SECTION_IFCLR(CPU_FTR_SLB) | 730 | END_FTR_SECTION_IFCLR(CPU_FTR_SLB) |
| 731 | 731 | ||
| 732 | clrrdi r11,r1,THREAD_SHIFT | ||
| 733 | lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */ | ||
| 734 | andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */ | ||
| 735 | bne 77f /* then don't call hash_page now */ | ||
| 736 | |||
| 732 | /* | 737 | /* |
| 733 | * On iSeries, we soft-disable interrupts here, then | 738 | * On iSeries, we soft-disable interrupts here, then |
| 734 | * hard-enable interrupts so that the hash_page code can spin on | 739 | * hard-enable interrupts so that the hash_page code can spin on |
| @@ -833,6 +838,20 @@ handle_page_fault: | |||
| 833 | bl .low_hash_fault | 838 | bl .low_hash_fault |
| 834 | b .ret_from_except | 839 | b .ret_from_except |
| 835 | 840 | ||
| 841 | /* | ||
| 842 | * We come here as a result of a DSI at a point where we don't want | ||
| 843 | * to call hash_page, such as when we are accessing memory (possibly | ||
| 844 | * user memory) inside a PMU interrupt that occurred while interrupts | ||
| 845 | * were soft-disabled. We want to invoke the exception handler for | ||
| 846 | * the access, or panic if there isn't a handler. | ||
| 847 | */ | ||
| 848 | 77: bl .save_nvgprs | ||
| 849 | mr r4,r3 | ||
| 850 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
| 851 | li r5,SIGSEGV | ||
| 852 | bl .bad_page_fault | ||
| 853 | b .ret_from_except | ||
| 854 | |||
| 836 | /* here we have a segment miss */ | 855 | /* here we have a segment miss */ |
| 837 | do_ste_alloc: | 856 | do_ste_alloc: |
| 838 | bl .ste_allocate /* try to insert stab entry */ | 857 | bl .ste_allocate /* try to insert stab entry */ |
diff --git a/arch/powerpc/kernel/perf_callchain.c b/arch/powerpc/kernel/perf_callchain.c new file mode 100644 index 000000000000..f74b62c67511 --- /dev/null +++ b/arch/powerpc/kernel/perf_callchain.c | |||
| @@ -0,0 +1,527 @@ | |||
| 1 | /* | ||
| 2 | * Performance counter callchain support - powerpc architecture code | ||
| 3 | * | ||
| 4 | * Copyright © 2009 Paul Mackerras, IBM Corporation. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/sched.h> | ||
| 13 | #include <linux/perf_counter.h> | ||
| 14 | #include <linux/percpu.h> | ||
| 15 | #include <linux/uaccess.h> | ||
| 16 | #include <linux/mm.h> | ||
| 17 | #include <asm/ptrace.h> | ||
| 18 | #include <asm/pgtable.h> | ||
| 19 | #include <asm/sigcontext.h> | ||
| 20 | #include <asm/ucontext.h> | ||
| 21 | #include <asm/vdso.h> | ||
| 22 | #ifdef CONFIG_PPC64 | ||
| 23 | #include "ppc32.h" | ||
| 24 | #endif | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Store another value in a callchain_entry. | ||
| 28 | */ | ||
| 29 | static inline void callchain_store(struct perf_callchain_entry *entry, u64 ip) | ||
| 30 | { | ||
| 31 | unsigned int nr = entry->nr; | ||
| 32 | |||
| 33 | if (nr < PERF_MAX_STACK_DEPTH) { | ||
| 34 | entry->ip[nr] = ip; | ||
| 35 | entry->nr = nr + 1; | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | /* | ||
| 40 | * Is sp valid as the address of the next kernel stack frame after prev_sp? | ||
| 41 | * The next frame may be in a different stack area but should not go | ||
| 42 | * back down in the same stack area. | ||
| 43 | */ | ||
| 44 | static int valid_next_sp(unsigned long sp, unsigned long prev_sp) | ||
| 45 | { | ||
| 46 | if (sp & 0xf) | ||
| 47 | return 0; /* must be 16-byte aligned */ | ||
| 48 | if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD)) | ||
| 49 | return 0; | ||
| 50 | if (sp >= prev_sp + STACK_FRAME_OVERHEAD) | ||
| 51 | return 1; | ||
| 52 | /* | ||
| 53 | * sp could decrease when we jump off an interrupt stack | ||
| 54 | * back to the regular process stack. | ||
| 55 | */ | ||
| 56 | if ((sp & ~(THREAD_SIZE - 1)) != (prev_sp & ~(THREAD_SIZE - 1))) | ||
| 57 | return 1; | ||
| 58 | return 0; | ||
| 59 | } | ||
| 60 | |||
| 61 | static void perf_callchain_kernel(struct pt_regs *regs, | ||
| 62 | struct perf_callchain_entry *entry) | ||
| 63 | { | ||
| 64 | unsigned long sp, next_sp; | ||
| 65 | unsigned long next_ip; | ||
| 66 | unsigned long lr; | ||
| 67 | long level = 0; | ||
| 68 | unsigned long *fp; | ||
| 69 | |||
| 70 | lr = regs->link; | ||
| 71 | sp = regs->gpr[1]; | ||
| 72 | callchain_store(entry, PERF_CONTEXT_KERNEL); | ||
| 73 | callchain_store(entry, regs->nip); | ||
| 74 | |||
| 75 | if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD)) | ||
| 76 | return; | ||
| 77 | |||
| 78 | for (;;) { | ||
| 79 | fp = (unsigned long *) sp; | ||
| 80 | next_sp = fp[0]; | ||
| 81 | |||
| 82 | if (next_sp == sp + STACK_INT_FRAME_SIZE && | ||
| 83 | fp[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) { | ||
| 84 | /* | ||
| 85 | * This looks like an interrupt frame for an | ||
| 86 | * interrupt that occurred in the kernel | ||
| 87 | */ | ||
| 88 | regs = (struct pt_regs *)(sp + STACK_FRAME_OVERHEAD); | ||
| 89 | next_ip = regs->nip; | ||
| 90 | lr = regs->link; | ||
| 91 | level = 0; | ||
| 92 | callchain_store(entry, PERF_CONTEXT_KERNEL); | ||
| 93 | |||
| 94 | } else { | ||
| 95 | if (level == 0) | ||
| 96 | next_ip = lr; | ||
| 97 | else | ||
| 98 | next_ip = fp[STACK_FRAME_LR_SAVE]; | ||
| 99 | |||
| 100 | /* | ||
| 101 | * We can't tell which of the first two addresses | ||
| 102 | * we get are valid, but we can filter out the | ||
| 103 | * obviously bogus ones here. We replace them | ||
| 104 | * with 0 rather than removing them entirely so | ||
| 105 | * that userspace can tell which is which. | ||
| 106 | */ | ||
| 107 | if ((level == 1 && next_ip == lr) || | ||
| 108 | (level <= 1 && !kernel_text_address(next_ip))) | ||
| 109 | next_ip = 0; | ||
| 110 | |||
| 111 | ++level; | ||
| 112 | } | ||
| 113 | |||
| 114 | callchain_store(entry, next_ip); | ||
| 115 | if (!valid_next_sp(next_sp, sp)) | ||
| 116 | return; | ||
| 117 | sp = next_sp; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | #ifdef CONFIG_PPC64 | ||
| 122 | |||
| 123 | #ifdef CONFIG_HUGETLB_PAGE | ||
| 124 | #define is_huge_psize(pagesize) (HPAGE_SHIFT && mmu_huge_psizes[pagesize]) | ||
| 125 | #else | ||
| 126 | #define is_huge_psize(pagesize) 0 | ||
| 127 | #endif | ||
| 128 | |||
| 129 | /* | ||
| 130 | * On 64-bit we don't want to invoke hash_page on user addresses from | ||
| 131 | * interrupt context, so if the access faults, we read the page tables | ||
| 132 | * to find which page (if any) is mapped and access it directly. | ||
| 133 | */ | ||
| 134 | static int read_user_stack_slow(void __user *ptr, void *ret, int nb) | ||
| 135 | { | ||
| 136 | pgd_t *pgdir; | ||
| 137 | pte_t *ptep, pte; | ||
| 138 | int pagesize; | ||
| 139 | unsigned long addr = (unsigned long) ptr; | ||
| 140 | unsigned long offset; | ||
| 141 | unsigned long pfn; | ||
| 142 | void *kaddr; | ||
| 143 | |||
| 144 | pgdir = current->mm->pgd; | ||
| 145 | if (!pgdir) | ||
| 146 | return -EFAULT; | ||
| 147 | |||
| 148 | pagesize = get_slice_psize(current->mm, addr); | ||
| 149 | |||
| 150 | /* align address to page boundary */ | ||
| 151 | offset = addr & ((1ul << mmu_psize_defs[pagesize].shift) - 1); | ||
| 152 | addr -= offset; | ||
| 153 | |||
| 154 | if (is_huge_psize(pagesize)) | ||
| 155 | ptep = huge_pte_offset(current->mm, addr); | ||
| 156 | else | ||
| 157 | ptep = find_linux_pte(pgdir, addr); | ||
| 158 | |||
| 159 | if (ptep == NULL) | ||
| 160 | return -EFAULT; | ||
| 161 | pte = *ptep; | ||
| 162 | if (!pte_present(pte) || !(pte_val(pte) & _PAGE_USER)) | ||
| 163 | return -EFAULT; | ||
| 164 | pfn = pte_pfn(pte); | ||
| 165 | if (!page_is_ram(pfn)) | ||
| 166 | return -EFAULT; | ||
| 167 | |||
| 168 | /* no highmem to worry about here */ | ||
| 169 | kaddr = pfn_to_kaddr(pfn); | ||
| 170 | memcpy(ret, kaddr + offset, nb); | ||
| 171 | return 0; | ||
| 172 | } | ||
| 173 | |||
| 174 | static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret) | ||
| 175 | { | ||
| 176 | if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned long) || | ||
| 177 | ((unsigned long)ptr & 7)) | ||
| 178 | return -EFAULT; | ||
| 179 | |||
| 180 | if (!__get_user_inatomic(*ret, ptr)) | ||
| 181 | return 0; | ||
| 182 | |||
| 183 | return read_user_stack_slow(ptr, ret, 8); | ||
| 184 | } | ||
| 185 | |||
| 186 | static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret) | ||
| 187 | { | ||
| 188 | if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) || | ||
| 189 | ((unsigned long)ptr & 3)) | ||
| 190 | return -EFAULT; | ||
| 191 | |||
| 192 | if (!__get_user_inatomic(*ret, ptr)) | ||
| 193 | return 0; | ||
| 194 | |||
| 195 | return read_user_stack_slow(ptr, ret, 4); | ||
| 196 | } | ||
| 197 | |||
| 198 | static inline int valid_user_sp(unsigned long sp, int is_64) | ||
| 199 | { | ||
| 200 | if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x100000000UL) - 32) | ||
| 201 | return 0; | ||
| 202 | return 1; | ||
| 203 | } | ||
| 204 | |||
| 205 | /* | ||
| 206 | * 64-bit user processes use the same stack frame for RT and non-RT signals. | ||
| 207 | */ | ||
| 208 | struct signal_frame_64 { | ||
| 209 | char dummy[__SIGNAL_FRAMESIZE]; | ||
| 210 | struct ucontext uc; | ||
| 211 | unsigned long unused[2]; | ||
| 212 | unsigned int tramp[6]; | ||
| 213 | struct siginfo *pinfo; | ||
| 214 | void *puc; | ||
| 215 | struct siginfo info; | ||
| 216 | char abigap[288]; | ||
| 217 | }; | ||
| 218 | |||
| 219 | static int is_sigreturn_64_address(unsigned long nip, unsigned long fp) | ||
| 220 | { | ||
| 221 | if (nip == fp + offsetof(struct signal_frame_64, tramp)) | ||
| 222 | return 1; | ||
| 223 | if (vdso64_rt_sigtramp && current->mm->context.vdso_base && | ||
| 224 | nip == current->mm->context.vdso_base + vdso64_rt_sigtramp) | ||
| 225 | return 1; | ||
| 226 | return 0; | ||
| 227 | } | ||
| 228 | |||
| 229 | /* | ||
| 230 | * Do some sanity checking on the signal frame pointed to by sp. | ||
| 231 | * We check the pinfo and puc pointers in the frame. | ||
| 232 | */ | ||
| 233 | static int sane_signal_64_frame(unsigned long sp) | ||
| 234 | { | ||
| 235 | struct signal_frame_64 __user *sf; | ||
| 236 | unsigned long pinfo, puc; | ||
| 237 | |||
| 238 | sf = (struct signal_frame_64 __user *) sp; | ||
| 239 | if (read_user_stack_64((unsigned long __user *) &sf->pinfo, &pinfo) || | ||
| 240 | read_user_stack_64((unsigned long __user *) &sf->puc, &puc)) | ||
| 241 | return 0; | ||
| 242 | return pinfo == (unsigned long) &sf->info && | ||
| 243 | puc == (unsigned long) &sf->uc; | ||
| 244 | } | ||
| 245 | |||
| 246 | static void perf_callchain_user_64(struct pt_regs *regs, | ||
| 247 | struct perf_callchain_entry *entry) | ||
| 248 | { | ||
| 249 | unsigned long sp, next_sp; | ||
| 250 | unsigned long next_ip; | ||
| 251 | unsigned long lr; | ||
| 252 | long level = 0; | ||
| 253 | struct signal_frame_64 __user *sigframe; | ||
| 254 | unsigned long __user *fp, *uregs; | ||
| 255 | |||
| 256 | next_ip = regs->nip; | ||
| 257 | lr = regs->link; | ||
| 258 | sp = regs->gpr[1]; | ||
| 259 | callchain_store(entry, PERF_CONTEXT_USER); | ||
| 260 | callchain_store(entry, next_ip); | ||
| 261 | |||
| 262 | for (;;) { | ||
| 263 | fp = (unsigned long __user *) sp; | ||
| 264 | if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp)) | ||
| 265 | return; | ||
| 266 | if (level > 0 && read_user_stack_64(&fp[2], &next_ip)) | ||
| 267 | return; | ||
| 268 | |||
| 269 | /* | ||
| 270 | * Note: the next_sp - sp >= signal frame size check | ||
| 271 | * is true when next_sp < sp, which can happen when | ||
| 272 | * transitioning from an alternate signal stack to the | ||
| 273 | * normal stack. | ||
| 274 | */ | ||
| 275 | if (next_sp - sp >= sizeof(struct signal_frame_64) && | ||
| 276 | (is_sigreturn_64_address(next_ip, sp) || | ||
| 277 | (level <= 1 && is_sigreturn_64_address(lr, sp))) && | ||
| 278 | sane_signal_64_frame(sp)) { | ||
| 279 | /* | ||
| 280 | * This looks like an signal frame | ||
| 281 | */ | ||
| 282 | sigframe = (struct signal_frame_64 __user *) sp; | ||
| 283 | uregs = sigframe->uc.uc_mcontext.gp_regs; | ||
| 284 | if (read_user_stack_64(&uregs[PT_NIP], &next_ip) || | ||
| 285 | read_user_stack_64(&uregs[PT_LNK], &lr) || | ||
| 286 | read_user_stack_64(&uregs[PT_R1], &sp)) | ||
| 287 | return; | ||
| 288 | level = 0; | ||
| 289 | callchain_store(entry, PERF_CONTEXT_USER); | ||
| 290 | callchain_store(entry, next_ip); | ||
| 291 | continue; | ||
| 292 | } | ||
| 293 | |||
| 294 | if (level == 0) | ||
| 295 | next_ip = lr; | ||
| 296 | callchain_store(entry, next_ip); | ||
| 297 | ++level; | ||
| 298 | sp = next_sp; | ||
| 299 | } | ||
| 300 | } | ||
| 301 | |||
| 302 | static inline int current_is_64bit(void) | ||
| 303 | { | ||
| 304 | /* | ||
| 305 | * We can't use test_thread_flag() here because we may be on an | ||
| 306 | * interrupt stack, and the thread flags don't get copied over | ||
| 307 | * from the thread_info on the main stack to the interrupt stack. | ||
| 308 | */ | ||
| 309 | return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT); | ||
| 310 | } | ||
| 311 | |||
| 312 | #else /* CONFIG_PPC64 */ | ||
| 313 | /* | ||
| 314 | * On 32-bit we just access the address and let hash_page create a | ||
| 315 | * HPTE if necessary, so there is no need to fall back to reading | ||
| 316 | * the page tables. Since this is called at interrupt level, | ||
| 317 | * do_page_fault() won't treat a DSI as a page fault. | ||
| 318 | */ | ||
| 319 | static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret) | ||
| 320 | { | ||
| 321 | if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) || | ||
| 322 | ((unsigned long)ptr & 3)) | ||
| 323 | return -EFAULT; | ||
| 324 | |||
| 325 | return __get_user_inatomic(*ret, ptr); | ||
| 326 | } | ||
| 327 | |||
| 328 | static inline void perf_callchain_user_64(struct pt_regs *regs, | ||
| 329 | struct perf_callchain_entry *entry) | ||
| 330 | { | ||
| 331 | } | ||
| 332 | |||
| 333 | static inline int current_is_64bit(void) | ||
| 334 | { | ||
| 335 | return 0; | ||
| 336 | } | ||
| 337 | |||
| 338 | static inline int valid_user_sp(unsigned long sp, int is_64) | ||
| 339 | { | ||
| 340 | if (!sp || (sp & 7) || sp > TASK_SIZE - 32) | ||
| 341 | return 0; | ||
| 342 | return 1; | ||
| 343 | } | ||
| 344 | |||
| 345 | #define __SIGNAL_FRAMESIZE32 __SIGNAL_FRAMESIZE | ||
| 346 | #define sigcontext32 sigcontext | ||
| 347 | #define mcontext32 mcontext | ||
| 348 | #define ucontext32 ucontext | ||
| 349 | #define compat_siginfo_t struct siginfo | ||
| 350 | |||
| 351 | #endif /* CONFIG_PPC64 */ | ||
| 352 | |||
| 353 | /* | ||
| 354 | * Layout for non-RT signal frames | ||
| 355 | */ | ||
| 356 | struct signal_frame_32 { | ||
| 357 | char dummy[__SIGNAL_FRAMESIZE32]; | ||
| 358 | struct sigcontext32 sctx; | ||
| 359 | struct mcontext32 mctx; | ||
| 360 | int abigap[56]; | ||
| 361 | }; | ||
| 362 | |||
| 363 | /* | ||
| 364 | * Layout for RT signal frames | ||
| 365 | */ | ||
| 366 | struct rt_signal_frame_32 { | ||
| 367 | char dummy[__SIGNAL_FRAMESIZE32 + 16]; | ||
| 368 | compat_siginfo_t info; | ||
| 369 | struct ucontext32 uc; | ||
| 370 | int abigap[56]; | ||
| 371 | }; | ||
| 372 | |||
| 373 | static int is_sigreturn_32_address(unsigned int nip, unsigned int fp) | ||
| 374 | { | ||
| 375 | if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad)) | ||
| 376 | return 1; | ||
| 377 | if (vdso32_sigtramp && current->mm->context.vdso_base && | ||
| 378 | nip == current->mm->context.vdso_base + vdso32_sigtramp) | ||
| 379 | return 1; | ||
| 380 | return 0; | ||
| 381 | } | ||
| 382 | |||
| 383 | static int is_rt_sigreturn_32_address(unsigned int nip, unsigned int fp) | ||
| 384 | { | ||
| 385 | if (nip == fp + offsetof(struct rt_signal_frame_32, | ||
| 386 | uc.uc_mcontext.mc_pad)) | ||
| 387 | return 1; | ||
| 388 | if (vdso32_rt_sigtramp && current->mm->context.vdso_base && | ||
| 389 | nip == current->mm->context.vdso_base + vdso32_rt_sigtramp) | ||
| 390 | return 1; | ||
| 391 | return 0; | ||
| 392 | } | ||
| 393 | |||
| 394 | static int sane_signal_32_frame(unsigned int sp) | ||
| 395 | { | ||
| 396 | struct signal_frame_32 __user *sf; | ||
| 397 | unsigned int regs; | ||
| 398 | |||
| 399 | sf = (struct signal_frame_32 __user *) (unsigned long) sp; | ||
| 400 | if (read_user_stack_32((unsigned int __user *) &sf->sctx.regs, ®s)) | ||
| 401 | return 0; | ||
| 402 | return regs == (unsigned long) &sf->mctx; | ||
| 403 | } | ||
| 404 | |||
| 405 | static int sane_rt_signal_32_frame(unsigned int sp) | ||
| 406 | { | ||
| 407 | struct rt_signal_frame_32 __user *sf; | ||
| 408 | unsigned int regs; | ||
| 409 | |||
| 410 | sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp; | ||
| 411 | if (read_user_stack_32((unsigned int __user *) &sf->uc.uc_regs, ®s)) | ||
| 412 | return 0; | ||
| 413 | return regs == (unsigned long) &sf->uc.uc_mcontext; | ||
| 414 | } | ||
| 415 | |||
| 416 | static unsigned int __user *signal_frame_32_regs(unsigned int sp, | ||
| 417 | unsigned int next_sp, unsigned int next_ip) | ||
| 418 | { | ||
| 419 | struct mcontext32 __user *mctx = NULL; | ||
| 420 | struct signal_frame_32 __user *sf; | ||
| 421 | struct rt_signal_frame_32 __user *rt_sf; | ||
| 422 | |||
| 423 | /* | ||
| 424 | * Note: the next_sp - sp >= signal frame size check | ||
| 425 | * is true when next_sp < sp, for example, when | ||
| 426 | * transitioning from an alternate signal stack to the | ||
| 427 | * normal stack. | ||
| 428 | */ | ||
| 429 | if (next_sp - sp >= sizeof(struct signal_frame_32) && | ||
| 430 | is_sigreturn_32_address(next_ip, sp) && | ||
| 431 | sane_signal_32_frame(sp)) { | ||
| 432 | sf = (struct signal_frame_32 __user *) (unsigned long) sp; | ||
| 433 | mctx = &sf->mctx; | ||
| 434 | } | ||
| 435 | |||
| 436 | if (!mctx && next_sp - sp >= sizeof(struct rt_signal_frame_32) && | ||
| 437 | is_rt_sigreturn_32_address(next_ip, sp) && | ||
| 438 | sane_rt_signal_32_frame(sp)) { | ||
| 439 | rt_sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp; | ||
| 440 | mctx = &rt_sf->uc.uc_mcontext; | ||
| 441 | } | ||
| 442 | |||
| 443 | if (!mctx) | ||
| 444 | return NULL; | ||
| 445 | return mctx->mc_gregs; | ||
| 446 | } | ||
| 447 | |||
| 448 | static void perf_callchain_user_32(struct pt_regs *regs, | ||
| 449 | struct perf_callchain_entry *entry) | ||
| 450 | { | ||
| 451 | unsigned int sp, next_sp; | ||
| 452 | unsigned int next_ip; | ||
| 453 | unsigned int lr; | ||
| 454 | long level = 0; | ||
| 455 | unsigned int __user *fp, *uregs; | ||
| 456 | |||
| 457 | next_ip = regs->nip; | ||
| 458 | lr = regs->link; | ||
| 459 | sp = regs->gpr[1]; | ||
| 460 | callchain_store(entry, PERF_CONTEXT_USER); | ||
| 461 | callchain_store(entry, next_ip); | ||
| 462 | |||
| 463 | while (entry->nr < PERF_MAX_STACK_DEPTH) { | ||
| 464 | fp = (unsigned int __user *) (unsigned long) sp; | ||
| 465 | if (!valid_user_sp(sp, 0) || read_user_stack_32(fp, &next_sp)) | ||
| 466 | return; | ||
| 467 | if (level > 0 && read_user_stack_32(&fp[1], &next_ip)) | ||
| 468 | return; | ||
| 469 | |||
| 470 | uregs = signal_frame_32_regs(sp, next_sp, next_ip); | ||
| 471 | if (!uregs && level <= 1) | ||
| 472 | uregs = signal_frame_32_regs(sp, next_sp, lr); | ||
| 473 | if (uregs) { | ||
| 474 | /* | ||
| 475 | * This looks like an signal frame, so restart | ||
| 476 | * the stack trace with the values in it. | ||
| 477 | */ | ||
| 478 | if (read_user_stack_32(&uregs[PT_NIP], &next_ip) || | ||
| 479 | read_user_stack_32(&uregs[PT_LNK], &lr) || | ||
| 480 | read_user_stack_32(&uregs[PT_R1], &sp)) | ||
| 481 | return; | ||
| 482 | level = 0; | ||
| 483 | callchain_store(entry, PERF_CONTEXT_USER); | ||
| 484 | callchain_store(entry, next_ip); | ||
| 485 | continue; | ||
| 486 | } | ||
| 487 | |||
| 488 | if (level == 0) | ||
| 489 | next_ip = lr; | ||
| 490 | callchain_store(entry, next_ip); | ||
| 491 | ++level; | ||
| 492 | sp = next_sp; | ||
| 493 | } | ||
| 494 | } | ||
| 495 | |||
| 496 | /* | ||
| 497 | * Since we can't get PMU interrupts inside a PMU interrupt handler, | ||
| 498 | * we don't need separate irq and nmi entries here. | ||
| 499 | */ | ||
| 500 | static DEFINE_PER_CPU(struct perf_callchain_entry, callchain); | ||
| 501 | |||
| 502 | struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | ||
| 503 | { | ||
| 504 | struct perf_callchain_entry *entry = &__get_cpu_var(callchain); | ||
| 505 | |||
| 506 | entry->nr = 0; | ||
| 507 | |||
| 508 | if (current->pid == 0) /* idle task? */ | ||
| 509 | return entry; | ||
| 510 | |||
| 511 | if (!user_mode(regs)) { | ||
| 512 | perf_callchain_kernel(regs, entry); | ||
| 513 | if (current->mm) | ||
| 514 | regs = task_pt_regs(current); | ||
| 515 | else | ||
| 516 | regs = NULL; | ||
| 517 | } | ||
| 518 | |||
| 519 | if (regs) { | ||
| 520 | if (current_is_64bit()) | ||
| 521 | perf_callchain_user_64(regs, entry); | ||
| 522 | else | ||
| 523 | perf_callchain_user_32(regs, entry); | ||
| 524 | } | ||
| 525 | |||
| 526 | return entry; | ||
| 527 | } | ||
diff --git a/arch/powerpc/kernel/power7-pmu.c b/arch/powerpc/kernel/power7-pmu.c index 388cf57ad827..018d094d92f9 100644 --- a/arch/powerpc/kernel/power7-pmu.c +++ b/arch/powerpc/kernel/power7-pmu.c | |||
| @@ -317,7 +317,7 @@ static int power7_generic_events[] = { | |||
| 317 | */ | 317 | */ |
| 318 | static int power7_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | 318 | static int power7_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { |
| 319 | [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */ | 319 | [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */ |
| 320 | [C(OP_READ)] = { 0x400f0, 0xc880 }, | 320 | [C(OP_READ)] = { 0xc880, 0x400f0 }, |
| 321 | [C(OP_WRITE)] = { 0, 0x300f0 }, | 321 | [C(OP_WRITE)] = { 0, 0x300f0 }, |
| 322 | [C(OP_PREFETCH)] = { 0xd8b8, 0 }, | 322 | [C(OP_PREFETCH)] = { 0xd8b8, 0 }, |
| 323 | }, | 323 | }, |
| @@ -327,8 +327,8 @@ static int power7_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | |||
| 327 | [C(OP_PREFETCH)] = { 0x408a, 0 }, | 327 | [C(OP_PREFETCH)] = { 0x408a, 0 }, |
| 328 | }, | 328 | }, |
| 329 | [C(LL)] = { /* RESULT_ACCESS RESULT_MISS */ | 329 | [C(LL)] = { /* RESULT_ACCESS RESULT_MISS */ |
| 330 | [C(OP_READ)] = { 0x6080, 0x6084 }, | 330 | [C(OP_READ)] = { 0x16080, 0x26080 }, |
| 331 | [C(OP_WRITE)] = { 0x6082, 0x6086 }, | 331 | [C(OP_WRITE)] = { 0x16082, 0x26082 }, |
| 332 | [C(OP_PREFETCH)] = { 0, 0 }, | 332 | [C(OP_PREFETCH)] = { 0, 0 }, |
| 333 | }, | 333 | }, |
| 334 | [C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */ | 334 | [C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */ |
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c index 0cef809cec21..f4d1b55aa70b 100644 --- a/arch/powerpc/kvm/44x.c +++ b/arch/powerpc/kvm/44x.c | |||
| @@ -138,7 +138,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) | |||
| 138 | kmem_cache_free(kvm_vcpu_cache, vcpu_44x); | 138 | kmem_cache_free(kvm_vcpu_cache, vcpu_44x); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | static int kvmppc_44x_init(void) | 141 | static int __init kvmppc_44x_init(void) |
| 142 | { | 142 | { |
| 143 | int r; | 143 | int r; |
| 144 | 144 | ||
| @@ -149,7 +149,7 @@ static int kvmppc_44x_init(void) | |||
| 149 | return kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), THIS_MODULE); | 149 | return kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), THIS_MODULE); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | static void kvmppc_44x_exit(void) | 152 | static void __exit kvmppc_44x_exit(void) |
| 153 | { | 153 | { |
| 154 | kvmppc_booke_exit(); | 154 | kvmppc_booke_exit(); |
| 155 | } | 155 | } |
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c index 4a16f472cc18..ff3cb63b8117 100644 --- a/arch/powerpc/kvm/44x_tlb.c +++ b/arch/powerpc/kvm/44x_tlb.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include "timing.h" | 30 | #include "timing.h" |
| 31 | 31 | ||
| 32 | #include "44x_tlb.h" | 32 | #include "44x_tlb.h" |
| 33 | #include "trace.h" | ||
| 33 | 34 | ||
| 34 | #ifndef PPC44x_TLBE_SIZE | 35 | #ifndef PPC44x_TLBE_SIZE |
| 35 | #define PPC44x_TLBE_SIZE PPC44x_TLB_4K | 36 | #define PPC44x_TLBE_SIZE PPC44x_TLB_4K |
| @@ -263,7 +264,7 @@ static void kvmppc_44x_shadow_release(struct kvmppc_vcpu_44x *vcpu_44x, | |||
| 263 | 264 | ||
| 264 | /* XXX set tlb_44x_index to stlb_index? */ | 265 | /* XXX set tlb_44x_index to stlb_index? */ |
| 265 | 266 | ||
| 266 | KVMTRACE_1D(STLB_INVAL, &vcpu_44x->vcpu, stlb_index, handler); | 267 | trace_kvm_stlb_inval(stlb_index); |
| 267 | } | 268 | } |
| 268 | 269 | ||
| 269 | void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) | 270 | void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) |
| @@ -365,8 +366,8 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr, | |||
| 365 | /* Insert shadow mapping into hardware TLB. */ | 366 | /* Insert shadow mapping into hardware TLB. */ |
| 366 | kvmppc_44x_tlbe_set_modified(vcpu_44x, victim); | 367 | kvmppc_44x_tlbe_set_modified(vcpu_44x, victim); |
| 367 | kvmppc_44x_tlbwe(victim, &stlbe); | 368 | kvmppc_44x_tlbwe(victim, &stlbe); |
| 368 | KVMTRACE_5D(STLB_WRITE, vcpu, victim, stlbe.tid, stlbe.word0, stlbe.word1, | 369 | trace_kvm_stlb_write(victim, stlbe.tid, stlbe.word0, stlbe.word1, |
| 369 | stlbe.word2, handler); | 370 | stlbe.word2); |
| 370 | } | 371 | } |
| 371 | 372 | ||
| 372 | /* For a particular guest TLB entry, invalidate the corresponding host TLB | 373 | /* For a particular guest TLB entry, invalidate the corresponding host TLB |
| @@ -485,8 +486,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws) | |||
| 485 | kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index); | 486 | kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index); |
| 486 | } | 487 | } |
| 487 | 488 | ||
| 488 | KVMTRACE_5D(GTLB_WRITE, vcpu, gtlb_index, tlbe->tid, tlbe->word0, | 489 | trace_kvm_gtlb_write(gtlb_index, tlbe->tid, tlbe->word0, tlbe->word1, |
| 489 | tlbe->word1, tlbe->word2, handler); | 490 | tlbe->word2); |
| 490 | 491 | ||
| 491 | kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS); | 492 | kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS); |
| 492 | return EMULATE_DONE; | 493 | return EMULATE_DONE; |
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 5a152a52796f..c29926846613 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig | |||
| @@ -2,8 +2,7 @@ | |||
| 2 | # KVM configuration | 2 | # KVM configuration |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | config HAVE_KVM_IRQCHIP | 5 | source "virt/kvm/Kconfig" |
| 6 | bool | ||
| 7 | 6 | ||
| 8 | menuconfig VIRTUALIZATION | 7 | menuconfig VIRTUALIZATION |
| 9 | bool "Virtualization" | 8 | bool "Virtualization" |
| @@ -59,17 +58,6 @@ config KVM_E500 | |||
| 59 | 58 | ||
| 60 | If unsure, say N. | 59 | If unsure, say N. |
| 61 | 60 | ||
| 62 | config KVM_TRACE | ||
| 63 | bool "KVM trace support" | ||
| 64 | depends on KVM && MARKERS && SYSFS | ||
| 65 | select RELAY | ||
| 66 | select DEBUG_FS | ||
| 67 | default n | ||
| 68 | ---help--- | ||
| 69 | This option allows reading a trace of kvm-related events through | ||
| 70 | relayfs. Note the ABI is not considered stable and will be | ||
| 71 | modified in future updates. | ||
| 72 | |||
| 73 | source drivers/virtio/Kconfig | 61 | source drivers/virtio/Kconfig |
| 74 | 62 | ||
| 75 | endif # VIRTUALIZATION | 63 | endif # VIRTUALIZATION |
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 459c7ee580f7..37655fe19f2f 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile | |||
| @@ -8,7 +8,9 @@ EXTRA_CFLAGS += -Ivirt/kvm -Iarch/powerpc/kvm | |||
| 8 | 8 | ||
| 9 | common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) | 9 | common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) |
| 10 | 10 | ||
| 11 | common-objs-$(CONFIG_KVM_TRACE) += $(addprefix ../../../virt/kvm/, kvm_trace.o) | 11 | CFLAGS_44x_tlb.o := -I. |
| 12 | CFLAGS_e500_tlb.o := -I. | ||
| 13 | CFLAGS_emulate.o := -I. | ||
| 12 | 14 | ||
| 13 | kvm-objs := $(common-objs-y) powerpc.o emulate.o | 15 | kvm-objs := $(common-objs-y) powerpc.o emulate.o |
| 14 | obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o | 16 | obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o |
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 642e4204cf25..e7bf4d029484 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
| @@ -520,7 +520,7 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, | |||
| 520 | return kvmppc_core_vcpu_translate(vcpu, tr); | 520 | return kvmppc_core_vcpu_translate(vcpu, tr); |
| 521 | } | 521 | } |
| 522 | 522 | ||
| 523 | int kvmppc_booke_init(void) | 523 | int __init kvmppc_booke_init(void) |
| 524 | { | 524 | { |
| 525 | unsigned long ivor[16]; | 525 | unsigned long ivor[16]; |
| 526 | unsigned long max_ivor = 0; | 526 | unsigned long max_ivor = 0; |
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index d8067fd81cdd..64949eef43f1 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c | |||
| @@ -60,9 +60,6 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu) | |||
| 60 | 60 | ||
| 61 | kvmppc_e500_tlb_setup(vcpu_e500); | 61 | kvmppc_e500_tlb_setup(vcpu_e500); |
| 62 | 62 | ||
| 63 | /* Use the same core vertion as host's */ | ||
| 64 | vcpu->arch.pvr = mfspr(SPRN_PVR); | ||
| 65 | |||
| 66 | return 0; | 63 | return 0; |
| 67 | } | 64 | } |
| 68 | 65 | ||
| @@ -132,7 +129,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) | |||
| 132 | kmem_cache_free(kvm_vcpu_cache, vcpu_e500); | 129 | kmem_cache_free(kvm_vcpu_cache, vcpu_e500); |
| 133 | } | 130 | } |
| 134 | 131 | ||
| 135 | static int kvmppc_e500_init(void) | 132 | static int __init kvmppc_e500_init(void) |
| 136 | { | 133 | { |
| 137 | int r, i; | 134 | int r, i; |
| 138 | unsigned long ivor[3]; | 135 | unsigned long ivor[3]; |
| @@ -160,7 +157,7 @@ static int kvmppc_e500_init(void) | |||
| 160 | return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE); | 157 | return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE); |
| 161 | } | 158 | } |
| 162 | 159 | ||
| 163 | static void kvmppc_e500_exit(void) | 160 | static void __init kvmppc_e500_exit(void) |
| 164 | { | 161 | { |
| 165 | kvmppc_booke_exit(); | 162 | kvmppc_booke_exit(); |
| 166 | } | 163 | } |
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index 3f760414b9f8..be95b8d8e3b7 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c | |||
| @@ -180,6 +180,9 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) | |||
| 180 | case SPRN_MMUCSR0: | 180 | case SPRN_MMUCSR0: |
| 181 | vcpu->arch.gpr[rt] = 0; break; | 181 | vcpu->arch.gpr[rt] = 0; break; |
| 182 | 182 | ||
| 183 | case SPRN_MMUCFG: | ||
| 184 | vcpu->arch.gpr[rt] = mfspr(SPRN_MMUCFG); break; | ||
| 185 | |||
| 183 | /* extra exceptions */ | 186 | /* extra exceptions */ |
| 184 | case SPRN_IVOR32: | 187 | case SPRN_IVOR32: |
| 185 | vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; | 188 | vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; |
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c index 0e773fc2d5e4..fb1e1dc11ba5 100644 --- a/arch/powerpc/kvm/e500_tlb.c +++ b/arch/powerpc/kvm/e500_tlb.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | #include "../mm/mmu_decl.h" | 23 | #include "../mm/mmu_decl.h" |
| 24 | #include "e500_tlb.h" | 24 | #include "e500_tlb.h" |
| 25 | #include "trace.h" | ||
| 25 | 26 | ||
| 26 | #define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1) | 27 | #define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1) |
| 27 | 28 | ||
| @@ -224,9 +225,8 @@ static void kvmppc_e500_stlbe_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500, | |||
| 224 | 225 | ||
| 225 | kvmppc_e500_shadow_release(vcpu_e500, tlbsel, esel); | 226 | kvmppc_e500_shadow_release(vcpu_e500, tlbsel, esel); |
| 226 | stlbe->mas1 = 0; | 227 | stlbe->mas1 = 0; |
| 227 | KVMTRACE_5D(STLB_INVAL, &vcpu_e500->vcpu, index_of(tlbsel, esel), | 228 | trace_kvm_stlb_inval(index_of(tlbsel, esel), stlbe->mas1, stlbe->mas2, |
| 228 | stlbe->mas1, stlbe->mas2, stlbe->mas3, stlbe->mas7, | 229 | stlbe->mas3, stlbe->mas7); |
| 229 | handler); | ||
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | static void kvmppc_e500_tlb1_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500, | 232 | static void kvmppc_e500_tlb1_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500, |
| @@ -269,7 +269,7 @@ static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu, | |||
| 269 | tlbsel = (vcpu_e500->mas4 >> 28) & 0x1; | 269 | tlbsel = (vcpu_e500->mas4 >> 28) & 0x1; |
| 270 | victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0; | 270 | victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0; |
| 271 | pidsel = (vcpu_e500->mas4 >> 16) & 0xf; | 271 | pidsel = (vcpu_e500->mas4 >> 16) & 0xf; |
| 272 | tsized = (vcpu_e500->mas4 >> 8) & 0xf; | 272 | tsized = (vcpu_e500->mas4 >> 7) & 0x1f; |
| 273 | 273 | ||
| 274 | vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim) | 274 | vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim) |
| 275 | | MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]); | 275 | | MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]); |
| @@ -309,7 +309,7 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, | |||
| 309 | vcpu_e500->shadow_pages[tlbsel][esel] = new_page; | 309 | vcpu_e500->shadow_pages[tlbsel][esel] = new_page; |
| 310 | 310 | ||
| 311 | /* Force TS=1 IPROT=0 TSIZE=4KB for all guest mappings. */ | 311 | /* Force TS=1 IPROT=0 TSIZE=4KB for all guest mappings. */ |
| 312 | stlbe->mas1 = MAS1_TSIZE(BOOKE_PAGESZ_4K) | 312 | stlbe->mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K) |
| 313 | | MAS1_TID(get_tlb_tid(gtlbe)) | MAS1_TS | MAS1_VALID; | 313 | | MAS1_TID(get_tlb_tid(gtlbe)) | MAS1_TS | MAS1_VALID; |
| 314 | stlbe->mas2 = (gvaddr & MAS2_EPN) | 314 | stlbe->mas2 = (gvaddr & MAS2_EPN) |
| 315 | | e500_shadow_mas2_attrib(gtlbe->mas2, | 315 | | e500_shadow_mas2_attrib(gtlbe->mas2, |
| @@ -319,9 +319,8 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, | |||
| 319 | vcpu_e500->vcpu.arch.msr & MSR_PR); | 319 | vcpu_e500->vcpu.arch.msr & MSR_PR); |
| 320 | stlbe->mas7 = (hpaddr >> 32) & MAS7_RPN; | 320 | stlbe->mas7 = (hpaddr >> 32) & MAS7_RPN; |
| 321 | 321 | ||
| 322 | KVMTRACE_5D(STLB_WRITE, &vcpu_e500->vcpu, index_of(tlbsel, esel), | 322 | trace_kvm_stlb_write(index_of(tlbsel, esel), stlbe->mas1, stlbe->mas2, |
| 323 | stlbe->mas1, stlbe->mas2, stlbe->mas3, stlbe->mas7, | 323 | stlbe->mas3, stlbe->mas7); |
| 324 | handler); | ||
| 325 | } | 324 | } |
| 326 | 325 | ||
| 327 | /* XXX only map the one-one case, for now use TLB0 */ | 326 | /* XXX only map the one-one case, for now use TLB0 */ |
| @@ -535,9 +534,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) | |||
| 535 | gtlbe->mas3 = vcpu_e500->mas3; | 534 | gtlbe->mas3 = vcpu_e500->mas3; |
| 536 | gtlbe->mas7 = vcpu_e500->mas7; | 535 | gtlbe->mas7 = vcpu_e500->mas7; |
| 537 | 536 | ||
| 538 | KVMTRACE_5D(GTLB_WRITE, vcpu, vcpu_e500->mas0, | 537 | trace_kvm_gtlb_write(vcpu_e500->mas0, gtlbe->mas1, gtlbe->mas2, |
| 539 | gtlbe->mas1, gtlbe->mas2, gtlbe->mas3, gtlbe->mas7, | 538 | gtlbe->mas3, gtlbe->mas7); |
| 540 | handler); | ||
| 541 | 539 | ||
| 542 | /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */ | 540 | /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */ |
| 543 | if (tlbe_is_host_safe(vcpu, gtlbe)) { | 541 | if (tlbe_is_host_safe(vcpu, gtlbe)) { |
| @@ -545,7 +543,7 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) | |||
| 545 | case 0: | 543 | case 0: |
| 546 | /* TLB0 */ | 544 | /* TLB0 */ |
| 547 | gtlbe->mas1 &= ~MAS1_TSIZE(~0); | 545 | gtlbe->mas1 &= ~MAS1_TSIZE(~0); |
| 548 | gtlbe->mas1 |= MAS1_TSIZE(BOOKE_PAGESZ_4K); | 546 | gtlbe->mas1 |= MAS1_TSIZE(BOOK3E_PAGESZ_4K); |
| 549 | 547 | ||
| 550 | stlbsel = 0; | 548 | stlbsel = 0; |
| 551 | sesel = kvmppc_e500_stlbe_map(vcpu_e500, 0, esel); | 549 | sesel = kvmppc_e500_stlbe_map(vcpu_e500, 0, esel); |
| @@ -679,14 +677,14 @@ void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500) | |||
| 679 | 677 | ||
| 680 | /* Insert large initial mapping for guest. */ | 678 | /* Insert large initial mapping for guest. */ |
| 681 | tlbe = &vcpu_e500->guest_tlb[1][0]; | 679 | tlbe = &vcpu_e500->guest_tlb[1][0]; |
| 682 | tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOKE_PAGESZ_256M); | 680 | tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_256M); |
| 683 | tlbe->mas2 = 0; | 681 | tlbe->mas2 = 0; |
| 684 | tlbe->mas3 = E500_TLB_SUPER_PERM_MASK; | 682 | tlbe->mas3 = E500_TLB_SUPER_PERM_MASK; |
| 685 | tlbe->mas7 = 0; | 683 | tlbe->mas7 = 0; |
| 686 | 684 | ||
| 687 | /* 4K map for serial output. Used by kernel wrapper. */ | 685 | /* 4K map for serial output. Used by kernel wrapper. */ |
| 688 | tlbe = &vcpu_e500->guest_tlb[1][1]; | 686 | tlbe = &vcpu_e500->guest_tlb[1][1]; |
| 689 | tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOKE_PAGESZ_4K); | 687 | tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_4K); |
| 690 | tlbe->mas2 = (0xe0004500 & 0xFFFFF000) | MAS2_I | MAS2_G; | 688 | tlbe->mas2 = (0xe0004500 & 0xFFFFF000) | MAS2_I | MAS2_G; |
| 691 | tlbe->mas3 = (0xe0004500 & 0xFFFFF000) | E500_TLB_SUPER_PERM_MASK; | 689 | tlbe->mas3 = (0xe0004500 & 0xFFFFF000) | E500_TLB_SUPER_PERM_MASK; |
| 692 | tlbe->mas7 = 0; | 690 | tlbe->mas7 = 0; |
diff --git a/arch/powerpc/kvm/e500_tlb.h b/arch/powerpc/kvm/e500_tlb.h index 45b064b76906..d28e3010a5e2 100644 --- a/arch/powerpc/kvm/e500_tlb.h +++ b/arch/powerpc/kvm/e500_tlb.h | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #define __KVM_E500_TLB_H__ | 16 | #define __KVM_E500_TLB_H__ |
| 17 | 17 | ||
| 18 | #include <linux/kvm_host.h> | 18 | #include <linux/kvm_host.h> |
| 19 | #include <asm/mmu-fsl-booke.h> | 19 | #include <asm/mmu-book3e.h> |
| 20 | #include <asm/tlb.h> | 20 | #include <asm/tlb.h> |
| 21 | #include <asm/kvm_e500.h> | 21 | #include <asm/kvm_e500.h> |
| 22 | 22 | ||
| @@ -59,7 +59,7 @@ extern void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *); | |||
| 59 | /* TLB helper functions */ | 59 | /* TLB helper functions */ |
| 60 | static inline unsigned int get_tlb_size(const struct tlbe *tlbe) | 60 | static inline unsigned int get_tlb_size(const struct tlbe *tlbe) |
| 61 | { | 61 | { |
| 62 | return (tlbe->mas1 >> 8) & 0xf; | 62 | return (tlbe->mas1 >> 7) & 0x1f; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe) | 65 | static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe) |
| @@ -70,7 +70,7 @@ static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe) | |||
| 70 | static inline u64 get_tlb_bytes(const struct tlbe *tlbe) | 70 | static inline u64 get_tlb_bytes(const struct tlbe *tlbe) |
| 71 | { | 71 | { |
| 72 | unsigned int pgsize = get_tlb_size(tlbe); | 72 | unsigned int pgsize = get_tlb_size(tlbe); |
| 73 | return 1ULL << 10 << (pgsize << 1); | 73 | return 1ULL << 10 << pgsize; |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | static inline gva_t get_tlb_end(const struct tlbe *tlbe) | 76 | static inline gva_t get_tlb_end(const struct tlbe *tlbe) |
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index a561d6e8da1c..7737146af3fb 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <asm/kvm_ppc.h> | 29 | #include <asm/kvm_ppc.h> |
| 30 | #include <asm/disassemble.h> | 30 | #include <asm/disassemble.h> |
| 31 | #include "timing.h" | 31 | #include "timing.h" |
| 32 | #include "trace.h" | ||
| 32 | 33 | ||
| 33 | #define OP_TRAP 3 | 34 | #define OP_TRAP 3 |
| 34 | 35 | ||
| @@ -187,7 +188,9 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
| 187 | case SPRN_SRR1: | 188 | case SPRN_SRR1: |
| 188 | vcpu->arch.gpr[rt] = vcpu->arch.srr1; break; | 189 | vcpu->arch.gpr[rt] = vcpu->arch.srr1; break; |
| 189 | case SPRN_PVR: | 190 | case SPRN_PVR: |
| 190 | vcpu->arch.gpr[rt] = vcpu->arch.pvr; break; | 191 | vcpu->arch.gpr[rt] = mfspr(SPRN_PVR); break; |
| 192 | case SPRN_PIR: | ||
| 193 | vcpu->arch.gpr[rt] = mfspr(SPRN_PIR); break; | ||
| 191 | 194 | ||
| 192 | /* Note: mftb and TBRL/TBWL are user-accessible, so | 195 | /* Note: mftb and TBRL/TBWL are user-accessible, so |
| 193 | * the guest can always access the real TB anyways. | 196 | * the guest can always access the real TB anyways. |
| @@ -417,7 +420,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
| 417 | } | 420 | } |
| 418 | } | 421 | } |
| 419 | 422 | ||
| 420 | KVMTRACE_3D(PPC_INSTR, vcpu, inst, (int)vcpu->arch.pc, emulated, entryexit); | 423 | trace_kvm_ppc_instr(inst, vcpu->arch.pc, emulated); |
| 421 | 424 | ||
| 422 | if (advance) | 425 | if (advance) |
| 423 | vcpu->arch.pc += 4; /* Advance past emulated instruction. */ | 426 | vcpu->arch.pc += 4; /* Advance past emulated instruction. */ |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 2cf915e51e7e..2a4551f78f60 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
| @@ -31,25 +31,17 @@ | |||
| 31 | #include "timing.h" | 31 | #include "timing.h" |
| 32 | #include "../mm/mmu_decl.h" | 32 | #include "../mm/mmu_decl.h" |
| 33 | 33 | ||
| 34 | #define CREATE_TRACE_POINTS | ||
| 35 | #include "trace.h" | ||
| 36 | |||
| 34 | gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) | 37 | gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) |
| 35 | { | 38 | { |
| 36 | return gfn; | 39 | return gfn; |
| 37 | } | 40 | } |
| 38 | 41 | ||
| 39 | int kvm_cpu_has_interrupt(struct kvm_vcpu *v) | ||
| 40 | { | ||
| 41 | return !!(v->arch.pending_exceptions); | ||
| 42 | } | ||
| 43 | |||
| 44 | int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu) | ||
| 45 | { | ||
| 46 | /* do real check here */ | ||
| 47 | return 1; | ||
| 48 | } | ||
| 49 | |||
| 50 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) | 42 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) |
| 51 | { | 43 | { |
| 52 | return !(v->arch.msr & MSR_WE); | 44 | return !(v->arch.msr & MSR_WE) || !!(v->arch.pending_exceptions); |
| 53 | } | 45 | } |
| 54 | 46 | ||
| 55 | 47 | ||
| @@ -122,13 +114,17 @@ struct kvm *kvm_arch_create_vm(void) | |||
| 122 | static void kvmppc_free_vcpus(struct kvm *kvm) | 114 | static void kvmppc_free_vcpus(struct kvm *kvm) |
| 123 | { | 115 | { |
| 124 | unsigned int i; | 116 | unsigned int i; |
| 117 | struct kvm_vcpu *vcpu; | ||
| 125 | 118 | ||
| 126 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | 119 | kvm_for_each_vcpu(i, vcpu, kvm) |
| 127 | if (kvm->vcpus[i]) { | 120 | kvm_arch_vcpu_free(vcpu); |
| 128 | kvm_arch_vcpu_free(kvm->vcpus[i]); | 121 | |
| 129 | kvm->vcpus[i] = NULL; | 122 | mutex_lock(&kvm->lock); |
| 130 | } | 123 | for (i = 0; i < atomic_read(&kvm->online_vcpus); i++) |
| 131 | } | 124 | kvm->vcpus[i] = NULL; |
| 125 | |||
| 126 | atomic_set(&kvm->online_vcpus, 0); | ||
| 127 | mutex_unlock(&kvm->lock); | ||
| 132 | } | 128 | } |
| 133 | 129 | ||
| 134 | void kvm_arch_sync_events(struct kvm *kvm) | 130 | void kvm_arch_sync_events(struct kvm *kvm) |
diff --git a/arch/powerpc/kvm/trace.h b/arch/powerpc/kvm/trace.h new file mode 100644 index 000000000000..67f219de0455 --- /dev/null +++ b/arch/powerpc/kvm/trace.h | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | #if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ) | ||
| 2 | #define _TRACE_KVM_H | ||
| 3 | |||
| 4 | #include <linux/tracepoint.h> | ||
| 5 | |||
| 6 | #undef TRACE_SYSTEM | ||
| 7 | #define TRACE_SYSTEM kvm | ||
| 8 | #define TRACE_INCLUDE_PATH . | ||
| 9 | #define TRACE_INCLUDE_FILE trace | ||
| 10 | |||
| 11 | /* | ||
| 12 | * Tracepoint for guest mode entry. | ||
| 13 | */ | ||
| 14 | TRACE_EVENT(kvm_ppc_instr, | ||
| 15 | TP_PROTO(unsigned int inst, unsigned long pc, unsigned int emulate), | ||
| 16 | TP_ARGS(inst, pc, emulate), | ||
| 17 | |||
| 18 | TP_STRUCT__entry( | ||
| 19 | __field( unsigned int, inst ) | ||
| 20 | __field( unsigned long, pc ) | ||
| 21 | __field( unsigned int, emulate ) | ||
| 22 | ), | ||
| 23 | |||
| 24 | TP_fast_assign( | ||
| 25 | __entry->inst = inst; | ||
| 26 | __entry->pc = pc; | ||
| 27 | __entry->emulate = emulate; | ||
| 28 | ), | ||
| 29 | |||
| 30 | TP_printk("inst %u pc 0x%lx emulate %u\n", | ||
| 31 | __entry->inst, __entry->pc, __entry->emulate) | ||
| 32 | ); | ||
| 33 | |||
| 34 | TRACE_EVENT(kvm_stlb_inval, | ||
| 35 | TP_PROTO(unsigned int stlb_index), | ||
| 36 | TP_ARGS(stlb_index), | ||
| 37 | |||
| 38 | TP_STRUCT__entry( | ||
| 39 | __field( unsigned int, stlb_index ) | ||
| 40 | ), | ||
| 41 | |||
| 42 | TP_fast_assign( | ||
| 43 | __entry->stlb_index = stlb_index; | ||
| 44 | ), | ||
| 45 | |||
| 46 | TP_printk("stlb_index %u", __entry->stlb_index) | ||
| 47 | ); | ||
| 48 | |||
| 49 | TRACE_EVENT(kvm_stlb_write, | ||
| 50 | TP_PROTO(unsigned int victim, unsigned int tid, unsigned int word0, | ||
| 51 | unsigned int word1, unsigned int word2), | ||
| 52 | TP_ARGS(victim, tid, word0, word1, word2), | ||
| 53 | |||
| 54 | TP_STRUCT__entry( | ||
| 55 | __field( unsigned int, victim ) | ||
| 56 | __field( unsigned int, tid ) | ||
| 57 | __field( unsigned int, word0 ) | ||
| 58 | __field( unsigned int, word1 ) | ||
| 59 | __field( unsigned int, word2 ) | ||
| 60 | ), | ||
| 61 | |||
| 62 | TP_fast_assign( | ||
| 63 | __entry->victim = victim; | ||
| 64 | __entry->tid = tid; | ||
| 65 | __entry->word0 = word0; | ||
| 66 | __entry->word1 = word1; | ||
| 67 | __entry->word2 = word2; | ||
| 68 | ), | ||
| 69 | |||
| 70 | TP_printk("victim %u tid %u w0 %u w1 %u w2 %u", | ||
| 71 | __entry->victim, __entry->tid, __entry->word0, | ||
| 72 | __entry->word1, __entry->word2) | ||
| 73 | ); | ||
| 74 | |||
| 75 | TRACE_EVENT(kvm_gtlb_write, | ||
| 76 | TP_PROTO(unsigned int gtlb_index, unsigned int tid, unsigned int word0, | ||
| 77 | unsigned int word1, unsigned int word2), | ||
| 78 | TP_ARGS(gtlb_index, tid, word0, word1, word2), | ||
| 79 | |||
| 80 | TP_STRUCT__entry( | ||
| 81 | __field( unsigned int, gtlb_index ) | ||
| 82 | __field( unsigned int, tid ) | ||
| 83 | __field( unsigned int, word0 ) | ||
| 84 | __field( unsigned int, word1 ) | ||
| 85 | __field( unsigned int, word2 ) | ||
| 86 | ), | ||
| 87 | |||
| 88 | TP_fast_assign( | ||
| 89 | __entry->gtlb_index = gtlb_index; | ||
| 90 | __entry->tid = tid; | ||
| 91 | __entry->word0 = word0; | ||
| 92 | __entry->word1 = word1; | ||
| 93 | __entry->word2 = word2; | ||
| 94 | ), | ||
| 95 | |||
| 96 | TP_printk("gtlb_index %u tid %u w0 %u w1 %u w2 %u", | ||
| 97 | __entry->gtlb_index, __entry->tid, __entry->word0, | ||
| 98 | __entry->word1, __entry->word2) | ||
| 99 | ); | ||
| 100 | |||
| 101 | #endif /* _TRACE_KVM_H */ | ||
| 102 | |||
| 103 | /* This part must be outside protection */ | ||
| 104 | #include <trace/define_trace.h> | ||
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index 5b7038f248b6..a685652effeb 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c | |||
| @@ -92,15 +92,13 @@ static inline void create_shadowed_slbe(unsigned long ea, int ssize, | |||
| 92 | : "memory" ); | 92 | : "memory" ); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | void slb_flush_and_rebolt(void) | 95 | static void __slb_flush_and_rebolt(void) |
| 96 | { | 96 | { |
| 97 | /* If you change this make sure you change SLB_NUM_BOLTED | 97 | /* If you change this make sure you change SLB_NUM_BOLTED |
| 98 | * appropriately too. */ | 98 | * appropriately too. */ |
| 99 | unsigned long linear_llp, vmalloc_llp, lflags, vflags; | 99 | unsigned long linear_llp, vmalloc_llp, lflags, vflags; |
| 100 | unsigned long ksp_esid_data, ksp_vsid_data; | 100 | unsigned long ksp_esid_data, ksp_vsid_data; |
| 101 | 101 | ||
| 102 | WARN_ON(!irqs_disabled()); | ||
| 103 | |||
| 104 | linear_llp = mmu_psize_defs[mmu_linear_psize].sllp; | 102 | linear_llp = mmu_psize_defs[mmu_linear_psize].sllp; |
| 105 | vmalloc_llp = mmu_psize_defs[mmu_vmalloc_psize].sllp; | 103 | vmalloc_llp = mmu_psize_defs[mmu_vmalloc_psize].sllp; |
| 106 | lflags = SLB_VSID_KERNEL | linear_llp; | 104 | lflags = SLB_VSID_KERNEL | linear_llp; |
| @@ -117,12 +115,6 @@ void slb_flush_and_rebolt(void) | |||
| 117 | ksp_vsid_data = get_slb_shadow()->save_area[2].vsid; | 115 | ksp_vsid_data = get_slb_shadow()->save_area[2].vsid; |
| 118 | } | 116 | } |
| 119 | 117 | ||
| 120 | /* | ||
| 121 | * We can't take a PMU exception in the following code, so hard | ||
| 122 | * disable interrupts. | ||
| 123 | */ | ||
| 124 | hard_irq_disable(); | ||
| 125 | |||
| 126 | /* We need to do this all in asm, so we're sure we don't touch | 118 | /* We need to do this all in asm, so we're sure we don't touch |
| 127 | * the stack between the slbia and rebolting it. */ | 119 | * the stack between the slbia and rebolting it. */ |
| 128 | asm volatile("isync\n" | 120 | asm volatile("isync\n" |
| @@ -139,6 +131,21 @@ void slb_flush_and_rebolt(void) | |||
| 139 | : "memory"); | 131 | : "memory"); |
| 140 | } | 132 | } |
| 141 | 133 | ||
| 134 | void slb_flush_and_rebolt(void) | ||
| 135 | { | ||
| 136 | |||
| 137 | WARN_ON(!irqs_disabled()); | ||
| 138 | |||
| 139 | /* | ||
| 140 | * We can't take a PMU exception in the following code, so hard | ||
| 141 | * disable interrupts. | ||
| 142 | */ | ||
| 143 | hard_irq_disable(); | ||
| 144 | |||
| 145 | __slb_flush_and_rebolt(); | ||
| 146 | get_paca()->slb_cache_ptr = 0; | ||
| 147 | } | ||
| 148 | |||
| 142 | void slb_vmalloc_update(void) | 149 | void slb_vmalloc_update(void) |
| 143 | { | 150 | { |
| 144 | unsigned long vflags; | 151 | unsigned long vflags; |
| @@ -180,12 +187,20 @@ static inline int esids_match(unsigned long addr1, unsigned long addr2) | |||
| 180 | /* Flush all user entries from the segment table of the current processor. */ | 187 | /* Flush all user entries from the segment table of the current processor. */ |
| 181 | void switch_slb(struct task_struct *tsk, struct mm_struct *mm) | 188 | void switch_slb(struct task_struct *tsk, struct mm_struct *mm) |
| 182 | { | 189 | { |
| 183 | unsigned long offset = get_paca()->slb_cache_ptr; | 190 | unsigned long offset; |
| 184 | unsigned long slbie_data = 0; | 191 | unsigned long slbie_data = 0; |
| 185 | unsigned long pc = KSTK_EIP(tsk); | 192 | unsigned long pc = KSTK_EIP(tsk); |
| 186 | unsigned long stack = KSTK_ESP(tsk); | 193 | unsigned long stack = KSTK_ESP(tsk); |
| 187 | unsigned long unmapped_base; | 194 | unsigned long unmapped_base; |
| 188 | 195 | ||
| 196 | /* | ||
| 197 | * We need interrupts hard-disabled here, not just soft-disabled, | ||
| 198 | * so that a PMU interrupt can't occur, which might try to access | ||
| 199 | * user memory (to get a stack trace) and possible cause an SLB miss | ||
| 200 | * which would update the slb_cache/slb_cache_ptr fields in the PACA. | ||
| 201 | */ | ||
| 202 | hard_irq_disable(); | ||
| 203 | offset = get_paca()->slb_cache_ptr; | ||
| 189 | if (!cpu_has_feature(CPU_FTR_NO_SLBIE_B) && | 204 | if (!cpu_has_feature(CPU_FTR_NO_SLBIE_B) && |
| 190 | offset <= SLB_CACHE_ENTRIES) { | 205 | offset <= SLB_CACHE_ENTRIES) { |
| 191 | int i; | 206 | int i; |
| @@ -200,7 +215,7 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm) | |||
| 200 | } | 215 | } |
| 201 | asm volatile("isync" : : : "memory"); | 216 | asm volatile("isync" : : : "memory"); |
| 202 | } else { | 217 | } else { |
| 203 | slb_flush_and_rebolt(); | 218 | __slb_flush_and_rebolt(); |
| 204 | } | 219 | } |
| 205 | 220 | ||
| 206 | /* Workaround POWER5 < DD2.1 issue */ | 221 | /* Workaround POWER5 < DD2.1 issue */ |
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c index 98cd1dc2ae75..ab5fb48b3e90 100644 --- a/arch/powerpc/mm/stab.c +++ b/arch/powerpc/mm/stab.c | |||
| @@ -164,7 +164,7 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm) | |||
| 164 | { | 164 | { |
| 165 | struct stab_entry *stab = (struct stab_entry *) get_paca()->stab_addr; | 165 | struct stab_entry *stab = (struct stab_entry *) get_paca()->stab_addr; |
| 166 | struct stab_entry *ste; | 166 | struct stab_entry *ste; |
| 167 | unsigned long offset = __get_cpu_var(stab_cache_ptr); | 167 | unsigned long offset; |
| 168 | unsigned long pc = KSTK_EIP(tsk); | 168 | unsigned long pc = KSTK_EIP(tsk); |
| 169 | unsigned long stack = KSTK_ESP(tsk); | 169 | unsigned long stack = KSTK_ESP(tsk); |
| 170 | unsigned long unmapped_base; | 170 | unsigned long unmapped_base; |
| @@ -172,6 +172,15 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm) | |||
| 172 | /* Force previous translations to complete. DRENG */ | 172 | /* Force previous translations to complete. DRENG */ |
| 173 | asm volatile("isync" : : : "memory"); | 173 | asm volatile("isync" : : : "memory"); |
| 174 | 174 | ||
| 175 | /* | ||
| 176 | * We need interrupts hard-disabled here, not just soft-disabled, | ||
| 177 | * so that a PMU interrupt can't occur, which might try to access | ||
| 178 | * user memory (to get a stack trace) and possible cause an STAB miss | ||
| 179 | * which would update the stab_cache/stab_cache_ptr per-cpu variables. | ||
| 180 | */ | ||
| 181 | hard_irq_disable(); | ||
| 182 | |||
| 183 | offset = __get_cpu_var(stab_cache_ptr); | ||
| 175 | if (offset <= NR_STAB_CACHE_ENTRIES) { | 184 | if (offset <= NR_STAB_CACHE_ENTRIES) { |
| 176 | int i; | 185 | int i; |
| 177 | 186 | ||
diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c index b178a1e66c91..40b5cb433005 100644 --- a/arch/powerpc/platforms/ps3/time.c +++ b/arch/powerpc/platforms/ps3/time.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 23 | 23 | ||
| 24 | #include <asm/firmware.h> | ||
| 24 | #include <asm/rtc.h> | 25 | #include <asm/rtc.h> |
| 25 | #include <asm/lv1call.h> | 26 | #include <asm/lv1call.h> |
| 26 | #include <asm/ps3.h> | 27 | #include <asm/ps3.h> |
| @@ -84,6 +85,9 @@ static int __init ps3_rtc_init(void) | |||
| 84 | { | 85 | { |
| 85 | struct platform_device *pdev; | 86 | struct platform_device *pdev; |
| 86 | 87 | ||
| 88 | if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) | ||
| 89 | return -ENODEV; | ||
| 90 | |||
| 87 | pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0); | 91 | pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0); |
| 88 | if (IS_ERR(pdev)) | 92 | if (IS_ERR(pdev)) |
| 89 | return PTR_ERR(pdev); | 93 | return PTR_ERR(pdev); |
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 237e3654f48c..464271bea6c9 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
| @@ -65,6 +65,19 @@ static unsigned int qe_num_of_snum; | |||
| 65 | 65 | ||
| 66 | static phys_addr_t qebase = -1; | 66 | static phys_addr_t qebase = -1; |
| 67 | 67 | ||
| 68 | int qe_alive_during_sleep(void) | ||
| 69 | { | ||
| 70 | static int ret = -1; | ||
| 71 | |||
| 72 | if (ret != -1) | ||
| 73 | return ret; | ||
| 74 | |||
| 75 | ret = !of_find_compatible_node(NULL, NULL, "fsl,mpc8569-pmc"); | ||
| 76 | |||
| 77 | return ret; | ||
| 78 | } | ||
| 79 | EXPORT_SYMBOL(qe_alive_during_sleep); | ||
| 80 | |||
| 68 | phys_addr_t get_qe_base(void) | 81 | phys_addr_t get_qe_base(void) |
| 69 | { | 82 | { |
| 70 | struct device_node *qe; | 83 | struct device_node *qe; |
diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c index 3ee1fd37bbfc..40edad520770 100644 --- a/arch/powerpc/sysdev/xilinx_intc.c +++ b/arch/powerpc/sysdev/xilinx_intc.c | |||
| @@ -234,7 +234,6 @@ static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc) | |||
| 234 | generic_handle_irq(cascade_irq); | 234 | generic_handle_irq(cascade_irq); |
| 235 | 235 | ||
| 236 | /* Let xilinx_intc end the interrupt */ | 236 | /* Let xilinx_intc end the interrupt */ |
| 237 | desc->chip->ack(irq); | ||
| 238 | desc->chip->unmask(irq); | 237 | desc->chip->unmask(irq); |
| 239 | } | 238 | } |
| 240 | 239 | ||
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 2ae5d72f47ed..1c866efd217d 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
| @@ -84,7 +84,7 @@ config S390 | |||
| 84 | select HAVE_FUNCTION_TRACER | 84 | select HAVE_FUNCTION_TRACER |
| 85 | select HAVE_FUNCTION_TRACE_MCOUNT_TEST | 85 | select HAVE_FUNCTION_TRACE_MCOUNT_TEST |
| 86 | select HAVE_FTRACE_MCOUNT_RECORD | 86 | select HAVE_FTRACE_MCOUNT_RECORD |
| 87 | select HAVE_FTRACE_SYSCALLS | 87 | select HAVE_SYSCALL_TRACEPOINTS |
| 88 | select HAVE_DYNAMIC_FTRACE | 88 | select HAVE_DYNAMIC_FTRACE |
| 89 | select HAVE_FUNCTION_GRAPH_TRACER | 89 | select HAVE_FUNCTION_GRAPH_TRACER |
| 90 | select HAVE_DEFAULT_NO_SPIN_MUTEXES | 90 | select HAVE_DEFAULT_NO_SPIN_MUTEXES |
| @@ -95,7 +95,6 @@ config S390 | |||
| 95 | select HAVE_ARCH_TRACEHOOK | 95 | select HAVE_ARCH_TRACEHOOK |
| 96 | select INIT_ALL_POSSIBLE | 96 | select INIT_ALL_POSSIBLE |
| 97 | select HAVE_PERF_COUNTERS | 97 | select HAVE_PERF_COUNTERS |
| 98 | select GENERIC_ATOMIC64 if !64BIT | ||
| 99 | 98 | ||
| 100 | config SCHED_OMIT_FRAME_POINTER | 99 | config SCHED_OMIT_FRAME_POINTER |
| 101 | bool | 100 | bool |
| @@ -481,13 +480,6 @@ config CMM_IUCV | |||
| 481 | Select this option to enable the special message interface to | 480 | Select this option to enable the special message interface to |
| 482 | the cooperative memory management. | 481 | the cooperative memory management. |
| 483 | 482 | ||
| 484 | config PAGE_STATES | ||
| 485 | bool "Unused page notification" | ||
| 486 | help | ||
| 487 | This enables the notification of unused pages to the | ||
| 488 | hypervisor. The ESSA instruction is used to do the states | ||
| 489 | changes between a page that has content and the unused state. | ||
| 490 | |||
| 491 | config APPLDATA_BASE | 483 | config APPLDATA_BASE |
| 492 | bool "Linux - VM Monitor Stream, base infrastructure" | 484 | bool "Linux - VM Monitor Stream, base infrastructure" |
| 493 | depends on PROC_FS | 485 | depends on PROC_FS |
diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 0ff387cebf88..fc8fb20e7fc0 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile | |||
| @@ -88,8 +88,7 @@ LDFLAGS_vmlinux := -e start | |||
| 88 | head-y := arch/s390/kernel/head.o arch/s390/kernel/init_task.o | 88 | head-y := arch/s390/kernel/head.o arch/s390/kernel/init_task.o |
| 89 | 89 | ||
| 90 | core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \ | 90 | core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \ |
| 91 | arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/ \ | 91 | arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/ |
| 92 | arch/s390/power/ | ||
| 93 | 92 | ||
| 94 | libs-y += arch/s390/lib/ | 93 | libs-y += arch/s390/lib/ |
| 95 | drivers-y += drivers/s390/ | 94 | drivers-y += drivers/s390/ |
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c index 4aba83b31596..2bc479ab3a66 100644 --- a/arch/s390/crypto/des_s390.c +++ b/arch/s390/crypto/des_s390.c | |||
| @@ -250,8 +250,9 @@ static int des3_128_setkey(struct crypto_tfm *tfm, const u8 *key, | |||
| 250 | const u8 *temp_key = key; | 250 | const u8 *temp_key = key; |
| 251 | u32 *flags = &tfm->crt_flags; | 251 | u32 *flags = &tfm->crt_flags; |
| 252 | 252 | ||
| 253 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) { | 253 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE)) && |
| 254 | *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; | 254 | (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { |
| 255 | *flags |= CRYPTO_TFM_RES_WEAK_KEY; | ||
| 255 | return -EINVAL; | 256 | return -EINVAL; |
| 256 | } | 257 | } |
| 257 | for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) { | 258 | for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) { |
| @@ -411,9 +412,9 @@ static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key, | |||
| 411 | 412 | ||
| 412 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && | 413 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && |
| 413 | memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], | 414 | memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], |
| 414 | DES_KEY_SIZE))) { | 415 | DES_KEY_SIZE)) && |
| 415 | 416 | (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { | |
| 416 | *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; | 417 | *flags |= CRYPTO_TFM_RES_WEAK_KEY; |
| 417 | return -EINVAL; | 418 | return -EINVAL; |
| 418 | } | 419 | } |
| 419 | for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) { | 420 | for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) { |
diff --git a/arch/s390/crypto/sha1_s390.c b/arch/s390/crypto/sha1_s390.c index e85ba348722a..f6de7826c979 100644 --- a/arch/s390/crypto/sha1_s390.c +++ b/arch/s390/crypto/sha1_s390.c | |||
| @@ -46,12 +46,38 @@ static int sha1_init(struct shash_desc *desc) | |||
| 46 | return 0; | 46 | return 0; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | static int sha1_export(struct shash_desc *desc, void *out) | ||
| 50 | { | ||
| 51 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
| 52 | struct sha1_state *octx = out; | ||
| 53 | |||
| 54 | octx->count = sctx->count; | ||
| 55 | memcpy(octx->state, sctx->state, sizeof(octx->state)); | ||
| 56 | memcpy(octx->buffer, sctx->buf, sizeof(octx->buffer)); | ||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | static int sha1_import(struct shash_desc *desc, const void *in) | ||
| 61 | { | ||
| 62 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
| 63 | const struct sha1_state *ictx = in; | ||
| 64 | |||
| 65 | sctx->count = ictx->count; | ||
| 66 | memcpy(sctx->state, ictx->state, sizeof(ictx->state)); | ||
| 67 | memcpy(sctx->buf, ictx->buffer, sizeof(ictx->buffer)); | ||
| 68 | sctx->func = KIMD_SHA_1; | ||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | |||
| 49 | static struct shash_alg alg = { | 72 | static struct shash_alg alg = { |
| 50 | .digestsize = SHA1_DIGEST_SIZE, | 73 | .digestsize = SHA1_DIGEST_SIZE, |
| 51 | .init = sha1_init, | 74 | .init = sha1_init, |
| 52 | .update = s390_sha_update, | 75 | .update = s390_sha_update, |
| 53 | .final = s390_sha_final, | 76 | .final = s390_sha_final, |
| 77 | .export = sha1_export, | ||
| 78 | .import = sha1_import, | ||
| 54 | .descsize = sizeof(struct s390_sha_ctx), | 79 | .descsize = sizeof(struct s390_sha_ctx), |
| 80 | .statesize = sizeof(struct sha1_state), | ||
| 55 | .base = { | 81 | .base = { |
| 56 | .cra_name = "sha1", | 82 | .cra_name = "sha1", |
| 57 | .cra_driver_name= "sha1-s390", | 83 | .cra_driver_name= "sha1-s390", |
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c index f9fefc569632..61a7db372121 100644 --- a/arch/s390/crypto/sha256_s390.c +++ b/arch/s390/crypto/sha256_s390.c | |||
| @@ -42,12 +42,38 @@ static int sha256_init(struct shash_desc *desc) | |||
| 42 | return 0; | 42 | return 0; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | static int sha256_export(struct shash_desc *desc, void *out) | ||
| 46 | { | ||
| 47 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
| 48 | struct sha256_state *octx = out; | ||
| 49 | |||
| 50 | octx->count = sctx->count; | ||
| 51 | memcpy(octx->state, sctx->state, sizeof(octx->state)); | ||
| 52 | memcpy(octx->buf, sctx->buf, sizeof(octx->buf)); | ||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | |||
| 56 | static int sha256_import(struct shash_desc *desc, const void *in) | ||
| 57 | { | ||
| 58 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
| 59 | const struct sha256_state *ictx = in; | ||
| 60 | |||
| 61 | sctx->count = ictx->count; | ||
| 62 | memcpy(sctx->state, ictx->state, sizeof(ictx->state)); | ||
| 63 | memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); | ||
| 64 | sctx->func = KIMD_SHA_256; | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 45 | static struct shash_alg alg = { | 68 | static struct shash_alg alg = { |
| 46 | .digestsize = SHA256_DIGEST_SIZE, | 69 | .digestsize = SHA256_DIGEST_SIZE, |
| 47 | .init = sha256_init, | 70 | .init = sha256_init, |
| 48 | .update = s390_sha_update, | 71 | .update = s390_sha_update, |
| 49 | .final = s390_sha_final, | 72 | .final = s390_sha_final, |
| 73 | .export = sha256_export, | ||
| 74 | .import = sha256_import, | ||
| 50 | .descsize = sizeof(struct s390_sha_ctx), | 75 | .descsize = sizeof(struct s390_sha_ctx), |
| 76 | .statesize = sizeof(struct sha256_state), | ||
| 51 | .base = { | 77 | .base = { |
| 52 | .cra_name = "sha256", | 78 | .cra_name = "sha256", |
| 53 | .cra_driver_name= "sha256-s390", | 79 | .cra_driver_name= "sha256-s390", |
diff --git a/arch/s390/crypto/sha512_s390.c b/arch/s390/crypto/sha512_s390.c index 83192bfc8048..4bf73d0dc525 100644 --- a/arch/s390/crypto/sha512_s390.c +++ b/arch/s390/crypto/sha512_s390.c | |||
| @@ -13,7 +13,10 @@ | |||
| 13 | * | 13 | * |
| 14 | */ | 14 | */ |
| 15 | #include <crypto/internal/hash.h> | 15 | #include <crypto/internal/hash.h> |
| 16 | #include <crypto/sha.h> | ||
| 17 | #include <linux/errno.h> | ||
| 16 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | #include <linux/kernel.h> | ||
| 17 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 18 | 21 | ||
| 19 | #include "sha.h" | 22 | #include "sha.h" |
| @@ -37,12 +40,42 @@ static int sha512_init(struct shash_desc *desc) | |||
| 37 | return 0; | 40 | return 0; |
| 38 | } | 41 | } |
| 39 | 42 | ||
| 43 | static int sha512_export(struct shash_desc *desc, void *out) | ||
| 44 | { | ||
| 45 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
| 46 | struct sha512_state *octx = out; | ||
| 47 | |||
| 48 | octx->count[0] = sctx->count; | ||
| 49 | octx->count[1] = 0; | ||
| 50 | memcpy(octx->state, sctx->state, sizeof(octx->state)); | ||
| 51 | memcpy(octx->buf, sctx->buf, sizeof(octx->buf)); | ||
| 52 | return 0; | ||
| 53 | } | ||
| 54 | |||
| 55 | static int sha512_import(struct shash_desc *desc, const void *in) | ||
| 56 | { | ||
| 57 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
| 58 | const struct sha512_state *ictx = in; | ||
| 59 | |||
| 60 | if (unlikely(ictx->count[1])) | ||
| 61 | return -ERANGE; | ||
| 62 | sctx->count = ictx->count[0]; | ||
| 63 | |||
| 64 | memcpy(sctx->state, ictx->state, sizeof(ictx->state)); | ||
| 65 | memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); | ||
| 66 | sctx->func = KIMD_SHA_512; | ||
| 67 | return 0; | ||
| 68 | } | ||
| 69 | |||
| 40 | static struct shash_alg sha512_alg = { | 70 | static struct shash_alg sha512_alg = { |
| 41 | .digestsize = SHA512_DIGEST_SIZE, | 71 | .digestsize = SHA512_DIGEST_SIZE, |
| 42 | .init = sha512_init, | 72 | .init = sha512_init, |
| 43 | .update = s390_sha_update, | 73 | .update = s390_sha_update, |
| 44 | .final = s390_sha_final, | 74 | .final = s390_sha_final, |
| 75 | .export = sha512_export, | ||
| 76 | .import = sha512_import, | ||
| 45 | .descsize = sizeof(struct s390_sha_ctx), | 77 | .descsize = sizeof(struct s390_sha_ctx), |
| 78 | .statesize = sizeof(struct sha512_state), | ||
| 46 | .base = { | 79 | .base = { |
| 47 | .cra_name = "sha512", | 80 | .cra_name = "sha512", |
| 48 | .cra_driver_name= "sha512-s390", | 81 | .cra_driver_name= "sha512-s390", |
| @@ -78,7 +111,10 @@ static struct shash_alg sha384_alg = { | |||
| 78 | .init = sha384_init, | 111 | .init = sha384_init, |
| 79 | .update = s390_sha_update, | 112 | .update = s390_sha_update, |
| 80 | .final = s390_sha_final, | 113 | .final = s390_sha_final, |
| 114 | .export = sha512_export, | ||
| 115 | .import = sha512_import, | ||
| 81 | .descsize = sizeof(struct s390_sha_ctx), | 116 | .descsize = sizeof(struct s390_sha_ctx), |
| 117 | .statesize = sizeof(struct sha512_state), | ||
| 82 | .base = { | 118 | .base = { |
| 83 | .cra_name = "sha384", | 119 | .cra_name = "sha384", |
| 84 | .cra_driver_name= "sha384-s390", | 120 | .cra_driver_name= "sha384-s390", |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index fcba206529f3..4e91a2573cc4 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
| @@ -900,7 +900,7 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y | |||
| 900 | CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y | 900 | CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y |
| 901 | CONFIG_HAVE_DYNAMIC_FTRACE=y | 901 | CONFIG_HAVE_DYNAMIC_FTRACE=y |
| 902 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y | 902 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y |
| 903 | CONFIG_HAVE_FTRACE_SYSCALLS=y | 903 | CONFIG_HAVE_SYSCALL_TRACEPOINTS=y |
| 904 | CONFIG_TRACING_SUPPORT=y | 904 | CONFIG_TRACING_SUPPORT=y |
| 905 | CONFIG_FTRACE=y | 905 | CONFIG_FTRACE=y |
| 906 | # CONFIG_FUNCTION_TRACER is not set | 906 | # CONFIG_FUNCTION_TRACER is not set |
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 5a805df216bb..bd9914b89488 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c | |||
| @@ -355,11 +355,7 @@ static struct dentry *hypfs_create_file(struct super_block *sb, | |||
| 355 | { | 355 | { |
| 356 | struct dentry *dentry; | 356 | struct dentry *dentry; |
| 357 | struct inode *inode; | 357 | struct inode *inode; |
| 358 | struct qstr qname; | ||
| 359 | 358 | ||
| 360 | qname.name = name; | ||
| 361 | qname.len = strlen(name); | ||
| 362 | qname.hash = full_name_hash(name, qname.len); | ||
| 363 | mutex_lock(&parent->d_inode->i_mutex); | 359 | mutex_lock(&parent->d_inode->i_mutex); |
| 364 | dentry = lookup_one_len(name, parent, strlen(name)); | 360 | dentry = lookup_one_len(name, parent, strlen(name)); |
| 365 | if (IS_ERR(dentry)) { | 361 | if (IS_ERR(dentry)) { |
| @@ -426,7 +422,7 @@ struct dentry *hypfs_create_u64(struct super_block *sb, struct dentry *dir, | |||
| 426 | char tmp[TMP_SIZE]; | 422 | char tmp[TMP_SIZE]; |
| 427 | struct dentry *dentry; | 423 | struct dentry *dentry; |
| 428 | 424 | ||
| 429 | snprintf(tmp, TMP_SIZE, "%lld\n", (unsigned long long int)value); | 425 | snprintf(tmp, TMP_SIZE, "%llu\n", (unsigned long long int)value); |
| 430 | buffer = kstrdup(tmp, GFP_KERNEL); | 426 | buffer = kstrdup(tmp, GFP_KERNEL); |
| 431 | if (!buffer) | 427 | if (!buffer) |
| 432 | return ERR_PTR(-ENOMEM); | 428 | return ERR_PTR(-ENOMEM); |
diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h index c7d0abfb0f00..ae7c8f9f94a5 100644 --- a/arch/s390/include/asm/atomic.h +++ b/arch/s390/include/asm/atomic.h | |||
| @@ -1,33 +1,23 @@ | |||
| 1 | #ifndef __ARCH_S390_ATOMIC__ | 1 | #ifndef __ARCH_S390_ATOMIC__ |
| 2 | #define __ARCH_S390_ATOMIC__ | 2 | #define __ARCH_S390_ATOMIC__ |
| 3 | 3 | ||
| 4 | #include <linux/compiler.h> | ||
| 5 | #include <linux/types.h> | ||
| 6 | |||
| 7 | /* | 4 | /* |
| 8 | * include/asm-s390/atomic.h | 5 | * Copyright 1999,2009 IBM Corp. |
| 6 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>, | ||
| 7 | * Denis Joseph Barrow, | ||
| 8 | * Arnd Bergmann <arndb@de.ibm.com>, | ||
| 9 | * | 9 | * |
| 10 | * S390 version | 10 | * Atomic operations that C can't guarantee us. |
| 11 | * Copyright (C) 1999-2005 IBM Deutschland Entwicklung GmbH, IBM Corporation | 11 | * Useful for resource counting etc. |
| 12 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | 12 | * s390 uses 'Compare And Swap' for atomicity in SMP enviroment. |
| 13 | * Denis Joseph Barrow, | ||
| 14 | * Arnd Bergmann (arndb@de.ibm.com) | ||
| 15 | * | ||
| 16 | * Derived from "include/asm-i386/bitops.h" | ||
| 17 | * Copyright (C) 1992, Linus Torvalds | ||
| 18 | * | 13 | * |
| 19 | */ | 14 | */ |
| 20 | 15 | ||
| 21 | /* | 16 | #include <linux/compiler.h> |
| 22 | * Atomic operations that C can't guarantee us. Useful for | 17 | #include <linux/types.h> |
| 23 | * resource counting etc.. | ||
| 24 | * S390 uses 'Compare And Swap' for atomicity in SMP enviroment | ||
| 25 | */ | ||
| 26 | 18 | ||
| 27 | #define ATOMIC_INIT(i) { (i) } | 19 | #define ATOMIC_INIT(i) { (i) } |
| 28 | 20 | ||
| 29 | #ifdef __KERNEL__ | ||
| 30 | |||
| 31 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 21 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
| 32 | 22 | ||
| 33 | #define __CS_LOOP(ptr, op_val, op_string) ({ \ | 23 | #define __CS_LOOP(ptr, op_val, op_string) ({ \ |
| @@ -77,7 +67,7 @@ static inline void atomic_set(atomic_t *v, int i) | |||
| 77 | barrier(); | 67 | barrier(); |
| 78 | } | 68 | } |
| 79 | 69 | ||
| 80 | static __inline__ int atomic_add_return(int i, atomic_t * v) | 70 | static inline int atomic_add_return(int i, atomic_t *v) |
| 81 | { | 71 | { |
| 82 | return __CS_LOOP(v, i, "ar"); | 72 | return __CS_LOOP(v, i, "ar"); |
| 83 | } | 73 | } |
| @@ -87,7 +77,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v) | |||
| 87 | #define atomic_inc_return(_v) atomic_add_return(1, _v) | 77 | #define atomic_inc_return(_v) atomic_add_return(1, _v) |
| 88 | #define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0) | 78 | #define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0) |
| 89 | 79 | ||
| 90 | static __inline__ int atomic_sub_return(int i, atomic_t * v) | 80 | static inline int atomic_sub_return(int i, atomic_t *v) |
| 91 | { | 81 | { |
| 92 | return __CS_LOOP(v, i, "sr"); | 82 | return __CS_LOOP(v, i, "sr"); |
| 93 | } | 83 | } |
| @@ -97,19 +87,19 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) | |||
| 97 | #define atomic_dec_return(_v) atomic_sub_return(1, _v) | 87 | #define atomic_dec_return(_v) atomic_sub_return(1, _v) |
| 98 | #define atomic_dec_and_test(_v) (atomic_sub_return(1, _v) == 0) | 88 | #define atomic_dec_and_test(_v) (atomic_sub_return(1, _v) == 0) |
| 99 | 89 | ||
| 100 | static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t * v) | 90 | static inline void atomic_clear_mask(unsigned long mask, atomic_t *v) |
| 101 | { | 91 | { |
| 102 | __CS_LOOP(v, ~mask, "nr"); | 92 | __CS_LOOP(v, ~mask, "nr"); |
| 103 | } | 93 | } |
| 104 | 94 | ||
| 105 | static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v) | 95 | static inline void atomic_set_mask(unsigned long mask, atomic_t *v) |
| 106 | { | 96 | { |
| 107 | __CS_LOOP(v, mask, "or"); | 97 | __CS_LOOP(v, mask, "or"); |
| 108 | } | 98 | } |
| 109 | 99 | ||
| 110 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | 100 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) |
| 111 | 101 | ||
| 112 | static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) | 102 | static inline int atomic_cmpxchg(atomic_t *v, int old, int new) |
| 113 | { | 103 | { |
| 114 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 104 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
| 115 | asm volatile( | 105 | asm volatile( |
| @@ -127,7 +117,7 @@ static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) | |||
| 127 | return old; | 117 | return old; |
| 128 | } | 118 | } |
| 129 | 119 | ||
| 130 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | 120 | static inline int atomic_add_unless(atomic_t *v, int a, int u) |
| 131 | { | 121 | { |
| 132 | int c, old; | 122 | int c, old; |
| 133 | c = atomic_read(v); | 123 | c = atomic_read(v); |
| @@ -146,9 +136,10 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | |||
| 146 | 136 | ||
| 147 | #undef __CS_LOOP | 137 | #undef __CS_LOOP |
| 148 | 138 | ||
| 149 | #ifdef __s390x__ | ||
| 150 | #define ATOMIC64_INIT(i) { (i) } | 139 | #define ATOMIC64_INIT(i) { (i) } |
| 151 | 140 | ||
| 141 | #ifdef CONFIG_64BIT | ||
| 142 | |||
| 152 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 143 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
| 153 | 144 | ||
| 154 | #define __CSG_LOOP(ptr, op_val, op_string) ({ \ | 145 | #define __CSG_LOOP(ptr, op_val, op_string) ({ \ |
| @@ -162,7 +153,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | |||
| 162 | : "=&d" (old_val), "=&d" (new_val), \ | 153 | : "=&d" (old_val), "=&d" (new_val), \ |
| 163 | "=Q" (((atomic_t *)(ptr))->counter) \ | 154 | "=Q" (((atomic_t *)(ptr))->counter) \ |
| 164 | : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ | 155 | : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ |
| 165 | : "cc", "memory" ); \ | 156 | : "cc", "memory"); \ |
| 166 | new_val; \ | 157 | new_val; \ |
| 167 | }) | 158 | }) |
| 168 | 159 | ||
| @@ -180,7 +171,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | |||
| 180 | "=m" (((atomic_t *)(ptr))->counter) \ | 171 | "=m" (((atomic_t *)(ptr))->counter) \ |
| 181 | : "a" (ptr), "d" (op_val), \ | 172 | : "a" (ptr), "d" (op_val), \ |
| 182 | "m" (((atomic_t *)(ptr))->counter) \ | 173 | "m" (((atomic_t *)(ptr))->counter) \ |
| 183 | : "cc", "memory" ); \ | 174 | : "cc", "memory"); \ |
| 184 | new_val; \ | 175 | new_val; \ |
| 185 | }) | 176 | }) |
| 186 | 177 | ||
| @@ -198,39 +189,29 @@ static inline void atomic64_set(atomic64_t *v, long long i) | |||
| 198 | barrier(); | 189 | barrier(); |
| 199 | } | 190 | } |
| 200 | 191 | ||
| 201 | static __inline__ long long atomic64_add_return(long long i, atomic64_t * v) | 192 | static inline long long atomic64_add_return(long long i, atomic64_t *v) |
| 202 | { | 193 | { |
| 203 | return __CSG_LOOP(v, i, "agr"); | 194 | return __CSG_LOOP(v, i, "agr"); |
| 204 | } | 195 | } |
| 205 | #define atomic64_add(_i, _v) atomic64_add_return(_i, _v) | ||
| 206 | #define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0) | ||
| 207 | #define atomic64_inc(_v) atomic64_add_return(1, _v) | ||
| 208 | #define atomic64_inc_return(_v) atomic64_add_return(1, _v) | ||
| 209 | #define atomic64_inc_and_test(_v) (atomic64_add_return(1, _v) == 0) | ||
| 210 | 196 | ||
| 211 | static __inline__ long long atomic64_sub_return(long long i, atomic64_t * v) | 197 | static inline long long atomic64_sub_return(long long i, atomic64_t *v) |
| 212 | { | 198 | { |
| 213 | return __CSG_LOOP(v, i, "sgr"); | 199 | return __CSG_LOOP(v, i, "sgr"); |
| 214 | } | 200 | } |
| 215 | #define atomic64_sub(_i, _v) atomic64_sub_return(_i, _v) | ||
| 216 | #define atomic64_sub_and_test(_i, _v) (atomic64_sub_return(_i, _v) == 0) | ||
| 217 | #define atomic64_dec(_v) atomic64_sub_return(1, _v) | ||
| 218 | #define atomic64_dec_return(_v) atomic64_sub_return(1, _v) | ||
| 219 | #define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0) | ||
| 220 | 201 | ||
| 221 | static __inline__ void atomic64_clear_mask(unsigned long mask, atomic64_t * v) | 202 | static inline void atomic64_clear_mask(unsigned long mask, atomic64_t *v) |
| 222 | { | 203 | { |
| 223 | __CSG_LOOP(v, ~mask, "ngr"); | 204 | __CSG_LOOP(v, ~mask, "ngr"); |
| 224 | } | 205 | } |
| 225 | 206 | ||
| 226 | static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v) | 207 | static inline void atomic64_set_mask(unsigned long mask, atomic64_t *v) |
| 227 | { | 208 | { |
| 228 | __CSG_LOOP(v, mask, "ogr"); | 209 | __CSG_LOOP(v, mask, "ogr"); |
| 229 | } | 210 | } |
| 230 | 211 | ||
| 231 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) | 212 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) |
| 232 | 213 | ||
| 233 | static __inline__ long long atomic64_cmpxchg(atomic64_t *v, | 214 | static inline long long atomic64_cmpxchg(atomic64_t *v, |
| 234 | long long old, long long new) | 215 | long long old, long long new) |
| 235 | { | 216 | { |
| 236 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 217 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
| @@ -249,8 +230,112 @@ static __inline__ long long atomic64_cmpxchg(atomic64_t *v, | |||
| 249 | return old; | 230 | return old; |
| 250 | } | 231 | } |
| 251 | 232 | ||
| 252 | static __inline__ int atomic64_add_unless(atomic64_t *v, | 233 | #undef __CSG_LOOP |
| 253 | long long a, long long u) | 234 | |
| 235 | #else /* CONFIG_64BIT */ | ||
| 236 | |||
| 237 | typedef struct { | ||
| 238 | long long counter; | ||
| 239 | } atomic64_t; | ||
| 240 | |||
| 241 | static inline long long atomic64_read(const atomic64_t *v) | ||
| 242 | { | ||
| 243 | register_pair rp; | ||
| 244 | |||
| 245 | asm volatile( | ||
| 246 | " lm %0,%N0,0(%1)" | ||
| 247 | : "=&d" (rp) | ||
| 248 | : "a" (&v->counter), "m" (v->counter) | ||
| 249 | ); | ||
| 250 | return rp.pair; | ||
| 251 | } | ||
| 252 | |||
| 253 | static inline void atomic64_set(atomic64_t *v, long long i) | ||
| 254 | { | ||
| 255 | register_pair rp = {.pair = i}; | ||
| 256 | |||
| 257 | asm volatile( | ||
| 258 | " stm %1,%N1,0(%2)" | ||
| 259 | : "=m" (v->counter) | ||
| 260 | : "d" (rp), "a" (&v->counter) | ||
| 261 | ); | ||
| 262 | } | ||
| 263 | |||
| 264 | static inline long long atomic64_xchg(atomic64_t *v, long long new) | ||
| 265 | { | ||
| 266 | register_pair rp_new = {.pair = new}; | ||
| 267 | register_pair rp_old; | ||
| 268 | |||
| 269 | asm volatile( | ||
| 270 | " lm %0,%N0,0(%2)\n" | ||
| 271 | "0: cds %0,%3,0(%2)\n" | ||
| 272 | " jl 0b\n" | ||
| 273 | : "=&d" (rp_old), "+m" (v->counter) | ||
| 274 | : "a" (&v->counter), "d" (rp_new) | ||
| 275 | : "cc"); | ||
| 276 | return rp_old.pair; | ||
| 277 | } | ||
| 278 | |||
| 279 | static inline long long atomic64_cmpxchg(atomic64_t *v, | ||
| 280 | long long old, long long new) | ||
| 281 | { | ||
| 282 | register_pair rp_old = {.pair = old}; | ||
| 283 | register_pair rp_new = {.pair = new}; | ||
| 284 | |||
| 285 | asm volatile( | ||
| 286 | " cds %0,%3,0(%2)" | ||
| 287 | : "+&d" (rp_old), "+m" (v->counter) | ||
| 288 | : "a" (&v->counter), "d" (rp_new) | ||
| 289 | : "cc"); | ||
| 290 | return rp_old.pair; | ||
| 291 | } | ||
| 292 | |||
| 293 | |||
| 294 | static inline long long atomic64_add_return(long long i, atomic64_t *v) | ||
| 295 | { | ||
| 296 | long long old, new; | ||
| 297 | |||
| 298 | do { | ||
| 299 | old = atomic64_read(v); | ||
| 300 | new = old + i; | ||
| 301 | } while (atomic64_cmpxchg(v, old, new) != old); | ||
| 302 | return new; | ||
| 303 | } | ||
| 304 | |||
| 305 | static inline long long atomic64_sub_return(long long i, atomic64_t *v) | ||
| 306 | { | ||
| 307 | long long old, new; | ||
| 308 | |||
| 309 | do { | ||
| 310 | old = atomic64_read(v); | ||
| 311 | new = old - i; | ||
| 312 | } while (atomic64_cmpxchg(v, old, new) != old); | ||
| 313 | return new; | ||
| 314 | } | ||
| 315 | |||
| 316 | static inline void atomic64_set_mask(unsigned long long mask, atomic64_t *v) | ||
| 317 | { | ||
| 318 | long long old, new; | ||
| 319 | |||
| 320 | do { | ||
| 321 | old = atomic64_read(v); | ||
| 322 | new = old | mask; | ||
| 323 | } while (atomic64_cmpxchg(v, old, new) != old); | ||
| 324 | } | ||
| 325 | |||
| 326 | static inline void atomic64_clear_mask(unsigned long long mask, atomic64_t *v) | ||
| 327 | { | ||
| 328 | long long old, new; | ||
| 329 | |||
| 330 | do { | ||
| 331 | old = atomic64_read(v); | ||
| 332 | new = old & mask; | ||
| 333 | } while (atomic64_cmpxchg(v, old, new) != old); | ||
| 334 | } | ||
| 335 | |||
| 336 | #endif /* CONFIG_64BIT */ | ||
| 337 | |||
| 338 | static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) | ||
| 254 | { | 339 | { |
| 255 | long long c, old; | 340 | long long c, old; |
| 256 | c = atomic64_read(v); | 341 | c = atomic64_read(v); |
| @@ -265,15 +350,17 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, | |||
| 265 | return c != u; | 350 | return c != u; |
| 266 | } | 351 | } |
| 267 | 352 | ||
| 268 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 353 | #define atomic64_add(_i, _v) atomic64_add_return(_i, _v) |
| 269 | 354 | #define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0) | |
| 270 | #undef __CSG_LOOP | 355 | #define atomic64_inc(_v) atomic64_add_return(1, _v) |
| 271 | 356 | #define atomic64_inc_return(_v) atomic64_add_return(1, _v) | |
| 272 | #else /* __s390x__ */ | 357 | #define atomic64_inc_and_test(_v) (atomic64_add_return(1, _v) == 0) |
| 273 | 358 | #define atomic64_sub(_i, _v) atomic64_sub_return(_i, _v) | |
| 274 | #include <asm-generic/atomic64.h> | 359 | #define atomic64_sub_and_test(_i, _v) (atomic64_sub_return(_i, _v) == 0) |
| 275 | 360 | #define atomic64_dec(_v) atomic64_sub_return(1, _v) | |
| 276 | #endif /* __s390x__ */ | 361 | #define atomic64_dec_return(_v) atomic64_sub_return(1, _v) |
| 362 | #define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0) | ||
| 363 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | ||
| 277 | 364 | ||
| 278 | #define smp_mb__before_atomic_dec() smp_mb() | 365 | #define smp_mb__before_atomic_dec() smp_mb() |
| 279 | #define smp_mb__after_atomic_dec() smp_mb() | 366 | #define smp_mb__after_atomic_dec() smp_mb() |
| @@ -281,5 +368,5 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, | |||
| 281 | #define smp_mb__after_atomic_inc() smp_mb() | 368 | #define smp_mb__after_atomic_inc() smp_mb() |
| 282 | 369 | ||
| 283 | #include <asm-generic/atomic-long.h> | 370 | #include <asm-generic/atomic-long.h> |
| 284 | #endif /* __KERNEL__ */ | 371 | |
| 285 | #endif /* __ARCH_S390_ATOMIC__ */ | 372 | #endif /* __ARCH_S390_ATOMIC__ */ |
diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h index d5a8e7c1477c..6c00f6800a34 100644 --- a/arch/s390/include/asm/checksum.h +++ b/arch/s390/include/asm/checksum.h | |||
| @@ -78,28 +78,11 @@ csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum) | |||
| 78 | */ | 78 | */ |
| 79 | static inline __sum16 csum_fold(__wsum sum) | 79 | static inline __sum16 csum_fold(__wsum sum) |
| 80 | { | 80 | { |
| 81 | #ifndef __s390x__ | 81 | u32 csum = (__force u32) sum; |
| 82 | register_pair rp; | ||
| 83 | 82 | ||
| 84 | asm volatile( | 83 | csum += (csum >> 16) + (csum << 16); |
| 85 | " slr %N1,%N1\n" /* %0 = H L */ | 84 | csum >>= 16; |
| 86 | " lr %1,%0\n" /* %0 = H L, %1 = H L 0 0 */ | 85 | return (__force __sum16) ~csum; |
| 87 | " srdl %1,16\n" /* %0 = H L, %1 = 0 H L 0 */ | ||
| 88 | " alr %1,%N1\n" /* %0 = H L, %1 = L H L 0 */ | ||
| 89 | " alr %0,%1\n" /* %0 = H+L+C L+H */ | ||
| 90 | " srl %0,16\n" /* %0 = H+L+C */ | ||
| 91 | : "+&d" (sum), "=d" (rp) : : "cc"); | ||
| 92 | #else /* __s390x__ */ | ||
| 93 | asm volatile( | ||
| 94 | " sr 3,3\n" /* %0 = H*65536 + L */ | ||
| 95 | " lr 2,%0\n" /* %0 = H L, 2/3 = H L / 0 0 */ | ||
| 96 | " srdl 2,16\n" /* %0 = H L, 2/3 = 0 H / L 0 */ | ||
| 97 | " alr 2,3\n" /* %0 = H L, 2/3 = L H / L 0 */ | ||
| 98 | " alr %0,2\n" /* %0 = H+L+C L+H */ | ||
| 99 | " srl %0,16\n" /* %0 = H+L+C */ | ||
| 100 | : "+&d" (sum) : : "cc", "2", "3"); | ||
| 101 | #endif /* __s390x__ */ | ||
| 102 | return (__force __sum16) ~sum; | ||
| 103 | } | 86 | } |
| 104 | 87 | ||
| 105 | /* | 88 | /* |
diff --git a/arch/s390/include/asm/chsc.h b/arch/s390/include/asm/chsc.h index 807997f7414b..4943654ed7fd 100644 --- a/arch/s390/include/asm/chsc.h +++ b/arch/s390/include/asm/chsc.h | |||
| @@ -125,4 +125,32 @@ struct chsc_cpd_info { | |||
| 125 | #define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info) | 125 | #define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info) |
| 126 | #define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal) | 126 | #define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal) |
| 127 | 127 | ||
| 128 | #ifdef __KERNEL__ | ||
| 129 | |||
| 130 | struct css_general_char { | ||
| 131 | u64 : 12; | ||
| 132 | u32 dynio : 1; /* bit 12 */ | ||
| 133 | u32 : 28; | ||
| 134 | u32 aif : 1; /* bit 41 */ | ||
| 135 | u32 : 3; | ||
| 136 | u32 mcss : 1; /* bit 45 */ | ||
| 137 | u32 fcs : 1; /* bit 46 */ | ||
| 138 | u32 : 1; | ||
| 139 | u32 ext_mb : 1; /* bit 48 */ | ||
| 140 | u32 : 7; | ||
| 141 | u32 aif_tdd : 1; /* bit 56 */ | ||
| 142 | u32 : 1; | ||
| 143 | u32 qebsm : 1; /* bit 58 */ | ||
| 144 | u32 : 8; | ||
| 145 | u32 aif_osa : 1; /* bit 67 */ | ||
| 146 | u32 : 14; | ||
| 147 | u32 cib : 1; /* bit 82 */ | ||
| 148 | u32 : 5; | ||
| 149 | u32 fcx : 1; /* bit 88 */ | ||
| 150 | u32 : 7; | ||
| 151 | }__attribute__((packed)); | ||
| 152 | |||
| 153 | extern struct css_general_char css_general_characteristics; | ||
| 154 | |||
| 155 | #endif /* __KERNEL__ */ | ||
| 128 | #endif | 156 | #endif |
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index 619bf94b11f1..e85679af54dd 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h | |||
| @@ -15,228 +15,7 @@ | |||
| 15 | #define LPM_ANYPATH 0xff | 15 | #define LPM_ANYPATH 0xff |
| 16 | #define __MAX_CSSID 0 | 16 | #define __MAX_CSSID 0 |
| 17 | 17 | ||
| 18 | /** | 18 | #include <asm/scsw.h> |
| 19 | * struct cmd_scsw - command-mode subchannel status word | ||
| 20 | * @key: subchannel key | ||
| 21 | * @sctl: suspend control | ||
| 22 | * @eswf: esw format | ||
| 23 | * @cc: deferred condition code | ||
| 24 | * @fmt: format | ||
| 25 | * @pfch: prefetch | ||
| 26 | * @isic: initial-status interruption control | ||
| 27 | * @alcc: address-limit checking control | ||
| 28 | * @ssi: suppress-suspended interruption | ||
| 29 | * @zcc: zero condition code | ||
| 30 | * @ectl: extended control | ||
| 31 | * @pno: path not operational | ||
| 32 | * @res: reserved | ||
| 33 | * @fctl: function control | ||
| 34 | * @actl: activity control | ||
| 35 | * @stctl: status control | ||
| 36 | * @cpa: channel program address | ||
| 37 | * @dstat: device status | ||
| 38 | * @cstat: subchannel status | ||
| 39 | * @count: residual count | ||
| 40 | */ | ||
| 41 | struct cmd_scsw { | ||
| 42 | __u32 key : 4; | ||
| 43 | __u32 sctl : 1; | ||
| 44 | __u32 eswf : 1; | ||
| 45 | __u32 cc : 2; | ||
| 46 | __u32 fmt : 1; | ||
| 47 | __u32 pfch : 1; | ||
| 48 | __u32 isic : 1; | ||
| 49 | __u32 alcc : 1; | ||
| 50 | __u32 ssi : 1; | ||
| 51 | __u32 zcc : 1; | ||
| 52 | __u32 ectl : 1; | ||
| 53 | __u32 pno : 1; | ||
| 54 | __u32 res : 1; | ||
| 55 | __u32 fctl : 3; | ||
| 56 | __u32 actl : 7; | ||
| 57 | __u32 stctl : 5; | ||
| 58 | __u32 cpa; | ||
| 59 | __u32 dstat : 8; | ||
| 60 | __u32 cstat : 8; | ||
| 61 | __u32 count : 16; | ||
| 62 | } __attribute__ ((packed)); | ||
| 63 | |||
| 64 | /** | ||
| 65 | * struct tm_scsw - transport-mode subchannel status word | ||
| 66 | * @key: subchannel key | ||
| 67 | * @eswf: esw format | ||
| 68 | * @cc: deferred condition code | ||
| 69 | * @fmt: format | ||
| 70 | * @x: IRB-format control | ||
| 71 | * @q: interrogate-complete | ||
| 72 | * @ectl: extended control | ||
| 73 | * @pno: path not operational | ||
| 74 | * @fctl: function control | ||
| 75 | * @actl: activity control | ||
| 76 | * @stctl: status control | ||
| 77 | * @tcw: TCW address | ||
| 78 | * @dstat: device status | ||
| 79 | * @cstat: subchannel status | ||
| 80 | * @fcxs: FCX status | ||
| 81 | * @schxs: subchannel-extended status | ||
| 82 | */ | ||
| 83 | struct tm_scsw { | ||
| 84 | u32 key:4; | ||
| 85 | u32 :1; | ||
| 86 | u32 eswf:1; | ||
| 87 | u32 cc:2; | ||
| 88 | u32 fmt:3; | ||
| 89 | u32 x:1; | ||
| 90 | u32 q:1; | ||
| 91 | u32 :1; | ||
| 92 | u32 ectl:1; | ||
| 93 | u32 pno:1; | ||
| 94 | u32 :1; | ||
| 95 | u32 fctl:3; | ||
| 96 | u32 actl:7; | ||
| 97 | u32 stctl:5; | ||
| 98 | u32 tcw; | ||
| 99 | u32 dstat:8; | ||
| 100 | u32 cstat:8; | ||
| 101 | u32 fcxs:8; | ||
| 102 | u32 schxs:8; | ||
| 103 | } __attribute__ ((packed)); | ||
| 104 | |||
| 105 | /** | ||
| 106 | * union scsw - subchannel status word | ||
| 107 | * @cmd: command-mode SCSW | ||
| 108 | * @tm: transport-mode SCSW | ||
| 109 | */ | ||
| 110 | union scsw { | ||
| 111 | struct cmd_scsw cmd; | ||
| 112 | struct tm_scsw tm; | ||
| 113 | } __attribute__ ((packed)); | ||
| 114 | |||
| 115 | int scsw_is_tm(union scsw *scsw); | ||
| 116 | u32 scsw_key(union scsw *scsw); | ||
| 117 | u32 scsw_eswf(union scsw *scsw); | ||
| 118 | u32 scsw_cc(union scsw *scsw); | ||
| 119 | u32 scsw_ectl(union scsw *scsw); | ||
| 120 | u32 scsw_pno(union scsw *scsw); | ||
| 121 | u32 scsw_fctl(union scsw *scsw); | ||
| 122 | u32 scsw_actl(union scsw *scsw); | ||
| 123 | u32 scsw_stctl(union scsw *scsw); | ||
| 124 | u32 scsw_dstat(union scsw *scsw); | ||
| 125 | u32 scsw_cstat(union scsw *scsw); | ||
| 126 | int scsw_is_solicited(union scsw *scsw); | ||
| 127 | int scsw_is_valid_key(union scsw *scsw); | ||
| 128 | int scsw_is_valid_eswf(union scsw *scsw); | ||
| 129 | int scsw_is_valid_cc(union scsw *scsw); | ||
| 130 | int scsw_is_valid_ectl(union scsw *scsw); | ||
| 131 | int scsw_is_valid_pno(union scsw *scsw); | ||
| 132 | int scsw_is_valid_fctl(union scsw *scsw); | ||
| 133 | int scsw_is_valid_actl(union scsw *scsw); | ||
| 134 | int scsw_is_valid_stctl(union scsw *scsw); | ||
| 135 | int scsw_is_valid_dstat(union scsw *scsw); | ||
| 136 | int scsw_is_valid_cstat(union scsw *scsw); | ||
| 137 | int scsw_cmd_is_valid_key(union scsw *scsw); | ||
| 138 | int scsw_cmd_is_valid_sctl(union scsw *scsw); | ||
| 139 | int scsw_cmd_is_valid_eswf(union scsw *scsw); | ||
| 140 | int scsw_cmd_is_valid_cc(union scsw *scsw); | ||
| 141 | int scsw_cmd_is_valid_fmt(union scsw *scsw); | ||
| 142 | int scsw_cmd_is_valid_pfch(union scsw *scsw); | ||
| 143 | int scsw_cmd_is_valid_isic(union scsw *scsw); | ||
| 144 | int scsw_cmd_is_valid_alcc(union scsw *scsw); | ||
| 145 | int scsw_cmd_is_valid_ssi(union scsw *scsw); | ||
| 146 | int scsw_cmd_is_valid_zcc(union scsw *scsw); | ||
| 147 | int scsw_cmd_is_valid_ectl(union scsw *scsw); | ||
| 148 | int scsw_cmd_is_valid_pno(union scsw *scsw); | ||
| 149 | int scsw_cmd_is_valid_fctl(union scsw *scsw); | ||
| 150 | int scsw_cmd_is_valid_actl(union scsw *scsw); | ||
| 151 | int scsw_cmd_is_valid_stctl(union scsw *scsw); | ||
| 152 | int scsw_cmd_is_valid_dstat(union scsw *scsw); | ||
| 153 | int scsw_cmd_is_valid_cstat(union scsw *scsw); | ||
| 154 | int scsw_cmd_is_solicited(union scsw *scsw); | ||
| 155 | int scsw_tm_is_valid_key(union scsw *scsw); | ||
| 156 | int scsw_tm_is_valid_eswf(union scsw *scsw); | ||
| 157 | int scsw_tm_is_valid_cc(union scsw *scsw); | ||
| 158 | int scsw_tm_is_valid_fmt(union scsw *scsw); | ||
| 159 | int scsw_tm_is_valid_x(union scsw *scsw); | ||
| 160 | int scsw_tm_is_valid_q(union scsw *scsw); | ||
| 161 | int scsw_tm_is_valid_ectl(union scsw *scsw); | ||
| 162 | int scsw_tm_is_valid_pno(union scsw *scsw); | ||
| 163 | int scsw_tm_is_valid_fctl(union scsw *scsw); | ||
| 164 | int scsw_tm_is_valid_actl(union scsw *scsw); | ||
| 165 | int scsw_tm_is_valid_stctl(union scsw *scsw); | ||
| 166 | int scsw_tm_is_valid_dstat(union scsw *scsw); | ||
| 167 | int scsw_tm_is_valid_cstat(union scsw *scsw); | ||
| 168 | int scsw_tm_is_valid_fcxs(union scsw *scsw); | ||
| 169 | int scsw_tm_is_valid_schxs(union scsw *scsw); | ||
| 170 | int scsw_tm_is_solicited(union scsw *scsw); | ||
| 171 | |||
| 172 | #define SCSW_FCTL_CLEAR_FUNC 0x1 | ||
| 173 | #define SCSW_FCTL_HALT_FUNC 0x2 | ||
| 174 | #define SCSW_FCTL_START_FUNC 0x4 | ||
| 175 | |||
| 176 | #define SCSW_ACTL_SUSPENDED 0x1 | ||
| 177 | #define SCSW_ACTL_DEVACT 0x2 | ||
| 178 | #define SCSW_ACTL_SCHACT 0x4 | ||
| 179 | #define SCSW_ACTL_CLEAR_PEND 0x8 | ||
| 180 | #define SCSW_ACTL_HALT_PEND 0x10 | ||
| 181 | #define SCSW_ACTL_START_PEND 0x20 | ||
| 182 | #define SCSW_ACTL_RESUME_PEND 0x40 | ||
| 183 | |||
| 184 | #define SCSW_STCTL_STATUS_PEND 0x1 | ||
| 185 | #define SCSW_STCTL_SEC_STATUS 0x2 | ||
| 186 | #define SCSW_STCTL_PRIM_STATUS 0x4 | ||
| 187 | #define SCSW_STCTL_INTER_STATUS 0x8 | ||
| 188 | #define SCSW_STCTL_ALERT_STATUS 0x10 | ||
| 189 | |||
| 190 | #define DEV_STAT_ATTENTION 0x80 | ||
| 191 | #define DEV_STAT_STAT_MOD 0x40 | ||
| 192 | #define DEV_STAT_CU_END 0x20 | ||
| 193 | #define DEV_STAT_BUSY 0x10 | ||
| 194 | #define DEV_STAT_CHN_END 0x08 | ||
| 195 | #define DEV_STAT_DEV_END 0x04 | ||
| 196 | #define DEV_STAT_UNIT_CHECK 0x02 | ||
| 197 | #define DEV_STAT_UNIT_EXCEP 0x01 | ||
| 198 | |||
| 199 | #define SCHN_STAT_PCI 0x80 | ||
| 200 | #define SCHN_STAT_INCORR_LEN 0x40 | ||
| 201 | #define SCHN_STAT_PROG_CHECK 0x20 | ||
| 202 | #define SCHN_STAT_PROT_CHECK 0x10 | ||
| 203 | #define SCHN_STAT_CHN_DATA_CHK 0x08 | ||
| 204 | #define SCHN_STAT_CHN_CTRL_CHK 0x04 | ||
| 205 | #define SCHN_STAT_INTF_CTRL_CHK 0x02 | ||
| 206 | #define SCHN_STAT_CHAIN_CHECK 0x01 | ||
| 207 | |||
| 208 | /* | ||
| 209 | * architectured values for first sense byte | ||
| 210 | */ | ||
| 211 | #define SNS0_CMD_REJECT 0x80 | ||
| 212 | #define SNS_CMD_REJECT SNS0_CMD_REJEC | ||
| 213 | #define SNS0_INTERVENTION_REQ 0x40 | ||
| 214 | #define SNS0_BUS_OUT_CHECK 0x20 | ||
| 215 | #define SNS0_EQUIPMENT_CHECK 0x10 | ||
| 216 | #define SNS0_DATA_CHECK 0x08 | ||
| 217 | #define SNS0_OVERRUN 0x04 | ||
| 218 | #define SNS0_INCOMPL_DOMAIN 0x01 | ||
| 219 | |||
| 220 | /* | ||
| 221 | * architectured values for second sense byte | ||
| 222 | */ | ||
| 223 | #define SNS1_PERM_ERR 0x80 | ||
| 224 | #define SNS1_INV_TRACK_FORMAT 0x40 | ||
| 225 | #define SNS1_EOC 0x20 | ||
| 226 | #define SNS1_MESSAGE_TO_OPER 0x10 | ||
| 227 | #define SNS1_NO_REC_FOUND 0x08 | ||
| 228 | #define SNS1_FILE_PROTECTED 0x04 | ||
| 229 | #define SNS1_WRITE_INHIBITED 0x02 | ||
| 230 | #define SNS1_INPRECISE_END 0x01 | ||
| 231 | |||
| 232 | /* | ||
| 233 | * architectured values for third sense byte | ||
| 234 | */ | ||
| 235 | #define SNS2_REQ_INH_WRITE 0x80 | ||
| 236 | #define SNS2_CORRECTABLE 0x40 | ||
| 237 | #define SNS2_FIRST_LOG_ERR 0x20 | ||
| 238 | #define SNS2_ENV_DATA_PRESENT 0x10 | ||
| 239 | #define SNS2_INPRECISE_END 0x04 | ||
| 240 | 19 | ||
| 241 | /** | 20 | /** |
| 242 | * struct ccw1 - channel command word | 21 | * struct ccw1 - channel command word |
diff --git a/arch/s390/include/asm/cpu.h b/arch/s390/include/asm/cpu.h new file mode 100644 index 000000000000..471234b90574 --- /dev/null +++ b/arch/s390/include/asm/cpu.h | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* | ||
| 2 | * Copyright IBM Corp. 2000,2009 | ||
| 3 | * Author(s): Hartmut Penner <hp@de.ibm.com>, | ||
| 4 | * Martin Schwidefsky <schwidefsky@de.ibm.com>, | ||
| 5 | * Christian Ehrhardt <ehrhardt@de.ibm.com>, | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef _ASM_S390_CPU_H | ||
| 9 | #define _ASM_S390_CPU_H | ||
| 10 | |||
| 11 | #define MAX_CPU_ADDRESS 255 | ||
| 12 | |||
| 13 | #ifndef __ASSEMBLY__ | ||
| 14 | |||
| 15 | #include <linux/types.h> | ||
| 16 | |||
| 17 | struct cpuid | ||
| 18 | { | ||
| 19 | unsigned int version : 8; | ||
| 20 | unsigned int ident : 24; | ||
| 21 | unsigned int machine : 16; | ||
| 22 | unsigned int unused : 16; | ||
| 23 | } __packed; | ||
| 24 | |||
| 25 | #endif /* __ASSEMBLY__ */ | ||
| 26 | #endif /* _ASM_S390_CPU_H */ | ||
diff --git a/arch/s390/include/asm/cpuid.h b/arch/s390/include/asm/cpuid.h deleted file mode 100644 index 07836a2e5222..000000000000 --- a/arch/s390/include/asm/cpuid.h +++ /dev/null | |||
| @@ -1,25 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright IBM Corp. 2000,2009 | ||
| 3 | * Author(s): Hartmut Penner <hp@de.ibm.com>, | ||
| 4 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
| 5 | * Christian Ehrhardt <ehrhardt@de.ibm.com> | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef _ASM_S390_CPUID_H_ | ||
| 9 | #define _ASM_S390_CPUID_H_ | ||
| 10 | |||
| 11 | /* | ||
| 12 | * CPU type and hardware bug flags. Kept separately for each CPU. | ||
| 13 | * Members of this structure are referenced in head.S, so think twice | ||
| 14 | * before touching them. [mj] | ||
| 15 | */ | ||
| 16 | |||
| 17 | typedef struct | ||
| 18 | { | ||
| 19 | unsigned int version : 8; | ||
| 20 | unsigned int ident : 24; | ||
| 21 | unsigned int machine : 16; | ||
| 22 | unsigned int unused : 16; | ||
| 23 | } __attribute__ ((packed)) cpuid_t; | ||
| 24 | |||
| 25 | #endif /* _ASM_S390_CPUID_H_ */ | ||
diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h index 31ed5686a968..18124b75a7ab 100644 --- a/arch/s390/include/asm/debug.h +++ b/arch/s390/include/asm/debug.h | |||
| @@ -167,6 +167,10 @@ debug_text_event(debug_info_t* id, int level, const char* txt) | |||
| 167 | return debug_event_common(id,level,txt,strlen(txt)); | 167 | return debug_event_common(id,level,txt,strlen(txt)); |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | /* | ||
| 171 | * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are | ||
| 172 | * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details! | ||
| 173 | */ | ||
| 170 | extern debug_entry_t * | 174 | extern debug_entry_t * |
| 171 | debug_sprintf_event(debug_info_t* id,int level,char *string,...) | 175 | debug_sprintf_event(debug_info_t* id,int level,char *string,...) |
| 172 | __attribute__ ((format(printf, 3, 4))); | 176 | __attribute__ ((format(printf, 3, 4))); |
| @@ -206,7 +210,10 @@ debug_text_exception(debug_info_t* id, int level, const char* txt) | |||
| 206 | return debug_exception_common(id,level,txt,strlen(txt)); | 210 | return debug_exception_common(id,level,txt,strlen(txt)); |
| 207 | } | 211 | } |
| 208 | 212 | ||
| 209 | 213 | /* | |
| 214 | * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are | ||
| 215 | * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details! | ||
| 216 | */ | ||
| 210 | extern debug_entry_t * | 217 | extern debug_entry_t * |
| 211 | debug_sprintf_exception(debug_info_t* id,int level,char *string,...) | 218 | debug_sprintf_exception(debug_info_t* id,int level,char *string,...) |
| 212 | __attribute__ ((format(printf, 3, 4))); | 219 | __attribute__ ((format(printf, 3, 4))); |
diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h index 89ec7056da28..498bc3892385 100644 --- a/arch/s390/include/asm/hardirq.h +++ b/arch/s390/include/asm/hardirq.h | |||
| @@ -18,13 +18,6 @@ | |||
| 18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
| 19 | #include <asm/lowcore.h> | 19 | #include <asm/lowcore.h> |
| 20 | 20 | ||
| 21 | /* irq_cpustat_t is unused currently, but could be converted | ||
| 22 | * into a percpu variable instead of storing softirq_pending | ||
| 23 | * on the lowcore */ | ||
| 24 | typedef struct { | ||
| 25 | unsigned int __softirq_pending; | ||
| 26 | } irq_cpustat_t; | ||
| 27 | |||
| 28 | #define local_softirq_pending() (S390_lowcore.softirq_pending) | 21 | #define local_softirq_pending() (S390_lowcore.softirq_pending) |
| 29 | 22 | ||
| 30 | #define __ARCH_IRQ_STAT | 23 | #define __ARCH_IRQ_STAT |
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 1171e6d144a3..5e95d95450b3 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h | |||
| @@ -57,6 +57,8 @@ struct ipl_block_fcp { | |||
| 57 | } __attribute__((packed)); | 57 | } __attribute__((packed)); |
| 58 | 58 | ||
| 59 | #define DIAG308_VMPARM_SIZE 64 | 59 | #define DIAG308_VMPARM_SIZE 64 |
| 60 | #define DIAG308_SCPDATA_SIZE (PAGE_SIZE - (sizeof(struct ipl_list_hdr) + \ | ||
| 61 | offsetof(struct ipl_block_fcp, scp_data))) | ||
| 60 | 62 | ||
| 61 | struct ipl_block_ccw { | 63 | struct ipl_block_ccw { |
| 62 | u8 load_parm[8]; | 64 | u8 load_parm[8]; |
| @@ -91,7 +93,8 @@ extern void do_halt(void); | |||
| 91 | extern void do_poff(void); | 93 | extern void do_poff(void); |
| 92 | extern void ipl_save_parameters(void); | 94 | extern void ipl_save_parameters(void); |
| 93 | extern void ipl_update_parameters(void); | 95 | extern void ipl_update_parameters(void); |
| 94 | extern void get_ipl_vmparm(char *); | 96 | extern size_t append_ipl_vmparm(char *, size_t); |
| 97 | extern size_t append_ipl_scpdata(char *, size_t); | ||
| 95 | 98 | ||
| 96 | enum { | 99 | enum { |
| 97 | IPL_DEVNO_VALID = 1, | 100 | IPL_DEVNO_VALID = 1, |
diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h index 0b2f829f6d50..3dfcaeb5d7f4 100644 --- a/arch/s390/include/asm/kvm.h +++ b/arch/s390/include/asm/kvm.h | |||
| @@ -15,15 +15,6 @@ | |||
| 15 | */ | 15 | */ |
| 16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
| 17 | 17 | ||
| 18 | /* for KVM_GET_IRQCHIP and KVM_SET_IRQCHIP */ | ||
| 19 | struct kvm_pic_state { | ||
| 20 | /* no PIC for s390 */ | ||
| 21 | }; | ||
| 22 | |||
| 23 | struct kvm_ioapic_state { | ||
| 24 | /* no IOAPIC for s390 */ | ||
| 25 | }; | ||
| 26 | |||
| 27 | /* for KVM_GET_REGS and KVM_SET_REGS */ | 18 | /* for KVM_GET_REGS and KVM_SET_REGS */ |
| 28 | struct kvm_regs { | 19 | struct kvm_regs { |
| 29 | /* general purpose regs for s390 */ | 20 | /* general purpose regs for s390 */ |
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 1cd02f6073a0..27605b62b980 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * asm-s390/kvm_host.h - definition for kernel virtual machines on s390 | 2 | * asm-s390/kvm_host.h - definition for kernel virtual machines on s390 |
| 3 | * | 3 | * |
| 4 | * Copyright IBM Corp. 2008 | 4 | * Copyright IBM Corp. 2008,2009 |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License (version 2 only) | 7 | * it under the terms of the GNU General Public License (version 2 only) |
| @@ -17,7 +17,7 @@ | |||
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/kvm_host.h> | 18 | #include <linux/kvm_host.h> |
| 19 | #include <asm/debug.h> | 19 | #include <asm/debug.h> |
| 20 | #include <asm/cpuid.h> | 20 | #include <asm/cpu.h> |
| 21 | 21 | ||
| 22 | #define KVM_MAX_VCPUS 64 | 22 | #define KVM_MAX_VCPUS 64 |
| 23 | #define KVM_MEMORY_SLOTS 32 | 23 | #define KVM_MEMORY_SLOTS 32 |
| @@ -40,7 +40,11 @@ struct sca_block { | |||
| 40 | struct sca_entry cpu[64]; | 40 | struct sca_entry cpu[64]; |
| 41 | } __attribute__((packed)); | 41 | } __attribute__((packed)); |
| 42 | 42 | ||
| 43 | #define KVM_PAGES_PER_HPAGE 256 | 43 | #define KVM_NR_PAGE_SIZES 2 |
| 44 | #define KVM_HPAGE_SHIFT(x) (PAGE_SHIFT + ((x) - 1) * 8) | ||
| 45 | #define KVM_HPAGE_SIZE(x) (1UL << KVM_HPAGE_SHIFT(x)) | ||
| 46 | #define KVM_HPAGE_MASK(x) (~(KVM_HPAGE_SIZE(x) - 1)) | ||
| 47 | #define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE) | ||
| 44 | 48 | ||
| 45 | #define CPUSTAT_HOST 0x80000000 | 49 | #define CPUSTAT_HOST 0x80000000 |
| 46 | #define CPUSTAT_WAIT 0x10000000 | 50 | #define CPUSTAT_WAIT 0x10000000 |
| @@ -182,8 +186,9 @@ struct kvm_s390_interrupt_info { | |||
| 182 | }; | 186 | }; |
| 183 | 187 | ||
| 184 | /* for local_interrupt.action_flags */ | 188 | /* for local_interrupt.action_flags */ |
| 185 | #define ACTION_STORE_ON_STOP 1 | 189 | #define ACTION_STORE_ON_STOP (1<<0) |
| 186 | #define ACTION_STOP_ON_STOP 2 | 190 | #define ACTION_STOP_ON_STOP (1<<1) |
| 191 | #define ACTION_RELOADVCPU_ON_STOP (1<<2) | ||
| 187 | 192 | ||
| 188 | struct kvm_s390_local_interrupt { | 193 | struct kvm_s390_local_interrupt { |
| 189 | spinlock_t lock; | 194 | spinlock_t lock; |
| @@ -217,8 +222,8 @@ struct kvm_vcpu_arch { | |||
| 217 | struct hrtimer ckc_timer; | 222 | struct hrtimer ckc_timer; |
| 218 | struct tasklet_struct tasklet; | 223 | struct tasklet_struct tasklet; |
| 219 | union { | 224 | union { |
| 220 | cpuid_t cpu_id; | 225 | struct cpuid cpu_id; |
| 221 | u64 stidp_data; | 226 | u64 stidp_data; |
| 222 | }; | 227 | }; |
| 223 | }; | 228 | }; |
| 224 | 229 | ||
| @@ -227,8 +232,6 @@ struct kvm_vm_stat { | |||
| 227 | }; | 232 | }; |
| 228 | 233 | ||
| 229 | struct kvm_arch{ | 234 | struct kvm_arch{ |
| 230 | unsigned long guest_origin; | ||
| 231 | unsigned long guest_memsize; | ||
| 232 | struct sca_block *sca; | 235 | struct sca_block *sca; |
| 233 | debug_info_t *dbf; | 236 | debug_info_t *dbf; |
| 234 | struct kvm_s390_float_interrupt float_int; | 237 | struct kvm_s390_float_interrupt float_int; |
diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h index 2c503796b619..6964db226f83 100644 --- a/arch/s390/include/asm/kvm_para.h +++ b/arch/s390/include/asm/kvm_para.h | |||
| @@ -13,6 +13,8 @@ | |||
| 13 | #ifndef __S390_KVM_PARA_H | 13 | #ifndef __S390_KVM_PARA_H |
| 14 | #define __S390_KVM_PARA_H | 14 | #define __S390_KVM_PARA_H |
| 15 | 15 | ||
| 16 | #ifdef __KERNEL__ | ||
| 17 | |||
| 16 | /* | 18 | /* |
| 17 | * Hypercalls for KVM on s390. The calling convention is similar to the | 19 | * Hypercalls for KVM on s390. The calling convention is similar to the |
| 18 | * s390 ABI, so we use R2-R6 for parameters 1-5. In addition we use R1 | 20 | * s390 ABI, so we use R2-R6 for parameters 1-5. In addition we use R1 |
| @@ -147,4 +149,6 @@ static inline unsigned int kvm_arch_para_features(void) | |||
| 147 | return 0; | 149 | return 0; |
| 148 | } | 150 | } |
| 149 | 151 | ||
| 152 | #endif | ||
| 153 | |||
| 150 | #endif /* __S390_KVM_PARA_H */ | 154 | #endif /* __S390_KVM_PARA_H */ |
diff --git a/arch/s390/include/asm/kvm_virtio.h b/arch/s390/include/asm/kvm_virtio.h index 0503936f101f..acdfdff26611 100644 --- a/arch/s390/include/asm/kvm_virtio.h +++ b/arch/s390/include/asm/kvm_virtio.h | |||
| @@ -54,14 +54,4 @@ struct kvm_vqconfig { | |||
| 54 | * This is pagesize for historical reasons. */ | 54 | * This is pagesize for historical reasons. */ |
| 55 | #define KVM_S390_VIRTIO_RING_ALIGN 4096 | 55 | #define KVM_S390_VIRTIO_RING_ALIGN 4096 |
| 56 | 56 | ||
| 57 | #ifdef __KERNEL__ | ||
| 58 | /* early virtio console setup */ | ||
| 59 | #ifdef CONFIG_S390_GUEST | ||
| 60 | extern void s390_virtio_console_init(void); | ||
| 61 | #else | ||
| 62 | static inline void s390_virtio_console_init(void) | ||
| 63 | { | ||
| 64 | } | ||
| 65 | #endif /* CONFIG_VIRTIO_CONSOLE */ | ||
| 66 | #endif /* __KERNEL__ */ | ||
| 67 | #endif | 57 | #endif |
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 5046ad6b7a63..6bc9426a6fbf 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h | |||
| @@ -132,7 +132,7 @@ | |||
| 132 | 132 | ||
| 133 | #ifndef __ASSEMBLY__ | 133 | #ifndef __ASSEMBLY__ |
| 134 | 134 | ||
| 135 | #include <asm/cpuid.h> | 135 | #include <asm/cpu.h> |
| 136 | #include <asm/ptrace.h> | 136 | #include <asm/ptrace.h> |
| 137 | #include <linux/types.h> | 137 | #include <linux/types.h> |
| 138 | 138 | ||
| @@ -275,7 +275,7 @@ struct _lowcore | |||
| 275 | __u32 user_exec_asce; /* 0x02ac */ | 275 | __u32 user_exec_asce; /* 0x02ac */ |
| 276 | 276 | ||
| 277 | /* SMP info area */ | 277 | /* SMP info area */ |
| 278 | cpuid_t cpu_id; /* 0x02b0 */ | 278 | struct cpuid cpu_id; /* 0x02b0 */ |
| 279 | __u32 cpu_nr; /* 0x02b8 */ | 279 | __u32 cpu_nr; /* 0x02b8 */ |
| 280 | __u32 softirq_pending; /* 0x02bc */ | 280 | __u32 softirq_pending; /* 0x02bc */ |
| 281 | __u32 percpu_offset; /* 0x02c0 */ | 281 | __u32 percpu_offset; /* 0x02c0 */ |
| @@ -380,7 +380,7 @@ struct _lowcore | |||
| 380 | __u64 user_exec_asce; /* 0x0318 */ | 380 | __u64 user_exec_asce; /* 0x0318 */ |
| 381 | 381 | ||
| 382 | /* SMP info area */ | 382 | /* SMP info area */ |
| 383 | cpuid_t cpu_id; /* 0x0320 */ | 383 | struct cpuid cpu_id; /* 0x0320 */ |
| 384 | __u32 cpu_nr; /* 0x0328 */ | 384 | __u32 cpu_nr; /* 0x0328 */ |
| 385 | __u32 softirq_pending; /* 0x032c */ | 385 | __u32 softirq_pending; /* 0x032c */ |
| 386 | __u64 percpu_offset; /* 0x0330 */ | 386 | __u64 percpu_offset; /* 0x0330 */ |
diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h index 3b59216e6284..03be99919d62 100644 --- a/arch/s390/include/asm/mmu.h +++ b/arch/s390/include/asm/mmu.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #define __MMU_H | 2 | #define __MMU_H |
| 3 | 3 | ||
| 4 | typedef struct { | 4 | typedef struct { |
| 5 | spinlock_t list_lock; | ||
| 5 | struct list_head crst_list; | 6 | struct list_head crst_list; |
| 6 | struct list_head pgtable_list; | 7 | struct list_head pgtable_list; |
| 7 | unsigned long asce_bits; | 8 | unsigned long asce_bits; |
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 3e3594d01f83..5e9daf5d7f22 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h | |||
| @@ -125,8 +125,6 @@ page_get_storage_key(unsigned long addr) | |||
| 125 | return skey; | 125 | return skey; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | #ifdef CONFIG_PAGE_STATES | ||
| 129 | |||
| 130 | struct page; | 128 | struct page; |
| 131 | void arch_free_page(struct page *page, int order); | 129 | void arch_free_page(struct page *page, int order); |
| 132 | void arch_alloc_page(struct page *page, int order); | 130 | void arch_alloc_page(struct page *page, int order); |
| @@ -134,8 +132,6 @@ void arch_alloc_page(struct page *page, int order); | |||
| 134 | #define HAVE_ARCH_FREE_PAGE | 132 | #define HAVE_ARCH_FREE_PAGE |
| 135 | #define HAVE_ARCH_ALLOC_PAGE | 133 | #define HAVE_ARCH_ALLOC_PAGE |
| 136 | 134 | ||
| 137 | #endif | ||
| 138 | |||
| 139 | #endif /* !__ASSEMBLY__ */ | 135 | #endif /* !__ASSEMBLY__ */ |
| 140 | 136 | ||
| 141 | #define __PAGE_OFFSET 0x0UL | 137 | #define __PAGE_OFFSET 0x0UL |
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index b2658b9220fe..ddad5903341c 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h | |||
| @@ -140,6 +140,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | |||
| 140 | 140 | ||
| 141 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) | 141 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) |
| 142 | { | 142 | { |
| 143 | spin_lock_init(&mm->context.list_lock); | ||
| 143 | INIT_LIST_HEAD(&mm->context.crst_list); | 144 | INIT_LIST_HEAD(&mm->context.crst_list); |
| 144 | INIT_LIST_HEAD(&mm->context.pgtable_list); | 145 | INIT_LIST_HEAD(&mm->context.pgtable_list); |
| 145 | return (pgd_t *) crst_table_alloc(mm, s390_noexec); | 146 | return (pgd_t *) crst_table_alloc(mm, s390_noexec); |
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index c139fa7b8e89..cf8eed3fa779 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #define __ASM_S390_PROCESSOR_H | 14 | #define __ASM_S390_PROCESSOR_H |
| 15 | 15 | ||
| 16 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
| 17 | #include <asm/cpuid.h> | 17 | #include <asm/cpu.h> |
| 18 | #include <asm/page.h> | 18 | #include <asm/page.h> |
| 19 | #include <asm/ptrace.h> | 19 | #include <asm/ptrace.h> |
| 20 | #include <asm/setup.h> | 20 | #include <asm/setup.h> |
| @@ -26,7 +26,7 @@ | |||
| 26 | */ | 26 | */ |
| 27 | #define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; }) | 27 | #define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; }) |
| 28 | 28 | ||
| 29 | static inline void get_cpu_id(cpuid_t *ptr) | 29 | static inline void get_cpu_id(struct cpuid *ptr) |
| 30 | { | 30 | { |
| 31 | asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr)); | 31 | asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr)); |
| 32 | } | 32 | } |
diff --git a/arch/s390/include/asm/scatterlist.h b/arch/s390/include/asm/scatterlist.h index 29ec8e28c8df..35d786fe93ae 100644 --- a/arch/s390/include/asm/scatterlist.h +++ b/arch/s390/include/asm/scatterlist.h | |||
| @@ -1,19 +1 @@ | |||
| 1 | #ifndef _ASMS390_SCATTERLIST_H | #include <asm-generic/scatterlist.h> | |
| 2 | #define _ASMS390_SCATTERLIST_H | ||
| 3 | |||
| 4 | struct scatterlist { | ||
| 5 | #ifdef CONFIG_DEBUG_SG | ||
| 6 | unsigned long sg_magic; | ||
| 7 | #endif | ||
| 8 | unsigned long page_link; | ||
| 9 | unsigned int offset; | ||
| 10 | unsigned int length; | ||
| 11 | }; | ||
| 12 | |||
| 13 | #ifdef __s390x__ | ||
| 14 | #define ISA_DMA_THRESHOLD (0xffffffffffffffffUL) | ||
| 15 | #else | ||
| 16 | #define ISA_DMA_THRESHOLD (0xffffffffUL) | ||
| 17 | #endif | ||
| 18 | |||
| 19 | #endif /* _ASMS390X_SCATTERLIST_H */ | ||
diff --git a/arch/s390/include/asm/scsw.h b/arch/s390/include/asm/scsw.h new file mode 100644 index 000000000000..de389cb54d28 --- /dev/null +++ b/arch/s390/include/asm/scsw.h | |||
| @@ -0,0 +1,956 @@ | |||
| 1 | /* | ||
| 2 | * Helper functions for scsw access. | ||
| 3 | * | ||
| 4 | * Copyright IBM Corp. 2008,2009 | ||
| 5 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef _ASM_S390_SCSW_H_ | ||
| 9 | #define _ASM_S390_SCSW_H_ | ||
| 10 | |||
| 11 | #include <linux/types.h> | ||
| 12 | #include <asm/chsc.h> | ||
| 13 | #include <asm/cio.h> | ||
| 14 | |||
| 15 | /** | ||
| 16 | * struct cmd_scsw - command-mode subchannel status word | ||
| 17 | * @key: subchannel key | ||
| 18 | * @sctl: suspend control | ||
| 19 | * @eswf: esw format | ||
| 20 | * @cc: deferred condition code | ||
| 21 | * @fmt: format | ||
| 22 | * @pfch: prefetch | ||
| 23 | * @isic: initial-status interruption control | ||
| 24 | * @alcc: address-limit checking control | ||
| 25 | * @ssi: suppress-suspended interruption | ||
| 26 | * @zcc: zero condition code | ||
| 27 | * @ectl: extended control | ||
| 28 | * @pno: path not operational | ||
| 29 | * @res: reserved | ||
| 30 | * @fctl: function control | ||
| 31 | * @actl: activity control | ||
| 32 | * @stctl: status control | ||
| 33 | * @cpa: channel program address | ||
| 34 | * @dstat: device status | ||
| 35 | * @cstat: subchannel status | ||
| 36 | * @count: residual count | ||
| 37 | */ | ||
| 38 | struct cmd_scsw { | ||
| 39 | __u32 key : 4; | ||
| 40 | __u32 sctl : 1; | ||
| 41 | __u32 eswf : 1; | ||
| 42 | __u32 cc : 2; | ||
| 43 | __u32 fmt : 1; | ||
| 44 | __u32 pfch : 1; | ||
| 45 | __u32 isic : 1; | ||
| 46 | __u32 alcc : 1; | ||
| 47 | __u32 ssi : 1; | ||
| 48 | __u32 zcc : 1; | ||
| 49 | __u32 ectl : 1; | ||
| 50 | __u32 pno : 1; | ||
| 51 | __u32 res : 1; | ||
| 52 | __u32 fctl : 3; | ||
| 53 | __u32 actl : 7; | ||
| 54 | __u32 stctl : 5; | ||
| 55 | __u32 cpa; | ||
| 56 | __u32 dstat : 8; | ||
| 57 | __u32 cstat : 8; | ||
| 58 | __u32 count : 16; | ||
| 59 | } __attribute__ ((packed)); | ||
| 60 | |||
| 61 | /** | ||
| 62 | * struct tm_scsw - transport-mode subchannel status word | ||
| 63 | * @key: subchannel key | ||
| 64 | * @eswf: esw format | ||
| 65 | * @cc: deferred condition code | ||
| 66 | * @fmt: format | ||
| 67 | * @x: IRB-format control | ||
| 68 | * @q: interrogate-complete | ||
| 69 | * @ectl: extended control | ||
| 70 | * @pno: path not operational | ||
| 71 | * @fctl: function control | ||
| 72 | * @actl: activity control | ||
| 73 | * @stctl: status control | ||
| 74 | * @tcw: TCW address | ||
| 75 | * @dstat: device status | ||
| 76 | * @cstat: subchannel status | ||
| 77 | * @fcxs: FCX status | ||
| 78 | * @schxs: subchannel-extended status | ||
| 79 | */ | ||
| 80 | struct tm_scsw { | ||
| 81 | u32 key:4; | ||
| 82 | u32 :1; | ||
| 83 | u32 eswf:1; | ||
| 84 | u32 cc:2; | ||
| 85 | u32 fmt:3; | ||
| 86 | u32 x:1; | ||
| 87 | u32 q:1; | ||
| 88 | u32 :1; | ||
| 89 | u32 ectl:1; | ||
| 90 | u32 pno:1; | ||
| 91 | u32 :1; | ||
| 92 | u32 fctl:3; | ||
| 93 | u32 actl:7; | ||
| 94 | u32 stctl:5; | ||
| 95 | u32 tcw; | ||
| 96 | u32 dstat:8; | ||
| 97 | u32 cstat:8; | ||
| 98 | u32 fcxs:8; | ||
| 99 | u32 schxs:8; | ||
| 100 | } __attribute__ ((packed)); | ||
| 101 | |||
| 102 | /** | ||
| 103 | * union scsw - subchannel status word | ||
| 104 | * @cmd: command-mode SCSW | ||
| 105 | * @tm: transport-mode SCSW | ||
| 106 | */ | ||
| 107 | union scsw { | ||
| 108 | struct cmd_scsw cmd; | ||
| 109 | struct tm_scsw tm; | ||
| 110 | } __attribute__ ((packed)); | ||
| 111 | |||
| 112 | #define SCSW_FCTL_CLEAR_FUNC 0x1 | ||
| 113 | #define SCSW_FCTL_HALT_FUNC 0x2 | ||
| 114 | #define SCSW_FCTL_START_FUNC 0x4 | ||
| 115 | |||
| 116 | #define SCSW_ACTL_SUSPENDED 0x1 | ||
| 117 | #define SCSW_ACTL_DEVACT 0x2 | ||
| 118 | #define SCSW_ACTL_SCHACT 0x4 | ||
| 119 | #define SCSW_ACTL_CLEAR_PEND 0x8 | ||
| 120 | #define SCSW_ACTL_HALT_PEND 0x10 | ||
| 121 | #define SCSW_ACTL_START_PEND 0x20 | ||
| 122 | #define SCSW_ACTL_RESUME_PEND 0x40 | ||
| 123 | |||
| 124 | #define SCSW_STCTL_STATUS_PEND 0x1 | ||
| 125 | #define SCSW_STCTL_SEC_STATUS 0x2 | ||
| 126 | #define SCSW_STCTL_PRIM_STATUS 0x4 | ||
| 127 | #define SCSW_STCTL_INTER_STATUS 0x8 | ||
| 128 | #define SCSW_STCTL_ALERT_STATUS 0x10 | ||
| 129 | |||
| 130 | #define DEV_STAT_ATTENTION 0x80 | ||
| 131 | #define DEV_STAT_STAT_MOD 0x40 | ||
| 132 | #define DEV_STAT_CU_END 0x20 | ||
| 133 | #define DEV_STAT_BUSY 0x10 | ||
| 134 | #define DEV_STAT_CHN_END 0x08 | ||
| 135 | #define DEV_STAT_DEV_END 0x04 | ||
| 136 | #define DEV_STAT_UNIT_CHECK 0x02 | ||
| 137 | #define DEV_STAT_UNIT_EXCEP 0x01 | ||
| 138 | |||
| 139 | #define SCHN_STAT_PCI 0x80 | ||
| 140 | #define SCHN_STAT_INCORR_LEN 0x40 | ||
| 141 | #define SCHN_STAT_PROG_CHECK 0x20 | ||
| 142 | #define SCHN_STAT_PROT_CHECK 0x10 | ||
| 143 | #define SCHN_STAT_CHN_DATA_CHK 0x08 | ||
| 144 | #define SCHN_STAT_CHN_CTRL_CHK 0x04 | ||
| 145 | #define SCHN_STAT_INTF_CTRL_CHK 0x02 | ||
| 146 | #define SCHN_STAT_CHAIN_CHECK 0x01 | ||
| 147 | |||
| 148 | /* | ||
| 149 | * architectured values for first sense byte | ||
| 150 | */ | ||
| 151 | #define SNS0_CMD_REJECT 0x80 | ||
| 152 | #define SNS_CMD_REJECT SNS0_CMD_REJEC | ||
| 153 | #define SNS0_INTERVENTION_REQ 0x40 | ||
| 154 | #define SNS0_BUS_OUT_CHECK 0x20 | ||
| 155 | #define SNS0_EQUIPMENT_CHECK 0x10 | ||
| 156 | #define SNS0_DATA_CHECK 0x08 | ||
| 157 | #define SNS0_OVERRUN 0x04 | ||
| 158 | #define SNS0_INCOMPL_DOMAIN 0x01 | ||
| 159 | |||
| 160 | /* | ||
| 161 | * architectured values for second sense byte | ||
| 162 | */ | ||
| 163 | #define SNS1_PERM_ERR 0x80 | ||
| 164 | #define SNS1_INV_TRACK_FORMAT 0x40 | ||
| 165 | #define SNS1_EOC 0x20 | ||
| 166 | #define SNS1_MESSAGE_TO_OPER 0x10 | ||
| 167 | #define SNS1_NO_REC_FOUND 0x08 | ||
| 168 | #define SNS1_FILE_PROTECTED 0x04 | ||
| 169 | #define SNS1_WRITE_INHIBITED 0x02 | ||
| 170 | #define SNS1_INPRECISE_END 0x01 | ||
| 171 | |||
| 172 | /* | ||
| 173 | * architectured values for third sense byte | ||
| 174 | */ | ||
| 175 | #define SNS2_REQ_INH_WRITE 0x80 | ||
| 176 | #define SNS2_CORRECTABLE 0x40 | ||
| 177 | #define SNS2_FIRST_LOG_ERR 0x20 | ||
| 178 | #define SNS2_ENV_DATA_PRESENT 0x10 | ||
| 179 | #define SNS2_INPRECISE_END 0x04 | ||
| 180 | |||
| 181 | /** | ||
| 182 | * scsw_is_tm - check for transport mode scsw | ||
| 183 | * @scsw: pointer to scsw | ||
| 184 | * | ||
| 185 | * Return non-zero if the specified scsw is a transport mode scsw, zero | ||
| 186 | * otherwise. | ||
| 187 | */ | ||
| 188 | static inline int scsw_is_tm(union scsw *scsw) | ||
| 189 | { | ||
| 190 | return css_general_characteristics.fcx && (scsw->tm.x == 1); | ||
| 191 | } | ||
| 192 | |||
| 193 | /** | ||
| 194 | * scsw_key - return scsw key field | ||
| 195 | * @scsw: pointer to scsw | ||
| 196 | * | ||
| 197 | * Return the value of the key field of the specified scsw, regardless of | ||
| 198 | * whether it is a transport mode or command mode scsw. | ||
| 199 | */ | ||
| 200 | static inline u32 scsw_key(union scsw *scsw) | ||
| 201 | { | ||
| 202 | if (scsw_is_tm(scsw)) | ||
| 203 | return scsw->tm.key; | ||
| 204 | else | ||
| 205 | return scsw->cmd.key; | ||
| 206 | } | ||
| 207 | |||
| 208 | /** | ||
| 209 | * scsw_eswf - return scsw eswf field | ||
| 210 | * @scsw: pointer to scsw | ||
| 211 | * | ||
| 212 | * Return the value of the eswf field of the specified scsw, regardless of | ||
| 213 | * whether it is a transport mode or command mode scsw. | ||
| 214 | */ | ||
| 215 | static inline u32 scsw_eswf(union scsw *scsw) | ||
| 216 | { | ||
| 217 | if (scsw_is_tm(scsw)) | ||
| 218 | return scsw->tm.eswf; | ||
| 219 | else | ||
| 220 | return scsw->cmd.eswf; | ||
| 221 | } | ||
| 222 | |||
| 223 | /** | ||
| 224 | * scsw_cc - return scsw cc field | ||
| 225 | * @scsw: pointer to scsw | ||
| 226 | * | ||
| 227 | * Return the value of the cc field of the specified scsw, regardless of | ||
| 228 | * whether it is a transport mode or command mode scsw. | ||
| 229 | */ | ||
| 230 | static inline u32 scsw_cc(union scsw *scsw) | ||
| 231 | { | ||
| 232 | if (scsw_is_tm(scsw)) | ||
| 233 | return scsw->tm.cc; | ||
| 234 | else | ||
| 235 | return scsw->cmd.cc; | ||
| 236 | } | ||
| 237 | |||
| 238 | /** | ||
| 239 | * scsw_ectl - return scsw ectl field | ||
| 240 | * @scsw: pointer to scsw | ||
| 241 | * | ||
| 242 | * Return the value of the ectl field of the specified scsw, regardless of | ||
| 243 | * whether it is a transport mode or command mode scsw. | ||
| 244 | */ | ||
| 245 | static inline u32 scsw_ectl(union scsw *scsw) | ||
| 246 | { | ||
| 247 | if (scsw_is_tm(scsw)) | ||
| 248 | return scsw->tm.ectl; | ||
| 249 | else | ||
| 250 | return scsw->cmd.ectl; | ||
| 251 | } | ||
| 252 | |||
| 253 | /** | ||
| 254 | * scsw_pno - return scsw pno field | ||
| 255 | * @scsw: pointer to scsw | ||
| 256 | * | ||
| 257 | * Return the value of the pno field of the specified scsw, regardless of | ||
| 258 | * whether it is a transport mode or command mode scsw. | ||
| 259 | */ | ||
| 260 | static inline u32 scsw_pno(union scsw *scsw) | ||
| 261 | { | ||
| 262 | if (scsw_is_tm(scsw)) | ||
| 263 | return scsw->tm.pno; | ||
| 264 | else | ||
| 265 | return scsw->cmd.pno; | ||
| 266 | } | ||
| 267 | |||
| 268 | /** | ||
| 269 | * scsw_fctl - return scsw fctl field | ||
| 270 | * @scsw: pointer to scsw | ||
| 271 | * | ||
| 272 | * Return the value of the fctl field of the specified scsw, regardless of | ||
| 273 | * whether it is a transport mode or command mode scsw. | ||
| 274 | */ | ||
| 275 | static inline u32 scsw_fctl(union scsw *scsw) | ||
| 276 | { | ||
| 277 | if (scsw_is_tm(scsw)) | ||
| 278 | return scsw->tm.fctl; | ||
| 279 | else | ||
| 280 | return scsw->cmd.fctl; | ||
| 281 | } | ||
| 282 | |||
| 283 | /** | ||
| 284 | * scsw_actl - return scsw actl field | ||
| 285 | * @scsw: pointer to scsw | ||
| 286 | * | ||
| 287 | * Return the value of the actl field of the specified scsw, regardless of | ||
| 288 | * whether it is a transport mode or command mode scsw. | ||
| 289 | */ | ||
| 290 | static inline u32 scsw_actl(union scsw *scsw) | ||
| 291 | { | ||
| 292 | if (scsw_is_tm(scsw)) | ||
| 293 | return scsw->tm.actl; | ||
| 294 | else | ||
| 295 | return scsw->cmd.actl; | ||
| 296 | } | ||
| 297 | |||
| 298 | /** | ||
| 299 | * scsw_stctl - return scsw stctl field | ||
| 300 | * @scsw: pointer to scsw | ||
| 301 | * | ||
| 302 | * Return the value of the stctl field of the specified scsw, regardless of | ||
| 303 | * whether it is a transport mode or command mode scsw. | ||
| 304 | */ | ||
| 305 | static inline u32 scsw_stctl(union scsw *scsw) | ||
| 306 | { | ||
| 307 | if (scsw_is_tm(scsw)) | ||
| 308 | return scsw->tm.stctl; | ||
| 309 | else | ||
| 310 | return scsw->cmd.stctl; | ||
| 311 | } | ||
| 312 | |||
| 313 | /** | ||
| 314 | * scsw_dstat - return scsw dstat field | ||
| 315 | * @scsw: pointer to scsw | ||
| 316 | * | ||
| 317 | * Return the value of the dstat field of the specified scsw, regardless of | ||
| 318 | * whether it is a transport mode or command mode scsw. | ||
| 319 | */ | ||
| 320 | static inline u32 scsw_dstat(union scsw *scsw) | ||
| 321 | { | ||
| 322 | if (scsw_is_tm(scsw)) | ||
| 323 | return scsw->tm.dstat; | ||
| 324 | else | ||
| 325 | return scsw->cmd.dstat; | ||
| 326 | } | ||
| 327 | |||
| 328 | /** | ||
| 329 | * scsw_cstat - return scsw cstat field | ||
| 330 | * @scsw: pointer to scsw | ||
| 331 | * | ||
| 332 | * Return the value of the cstat field of the specified scsw, regardless of | ||
| 333 | * whether it is a transport mode or command mode scsw. | ||
| 334 | */ | ||
| 335 | static inline u32 scsw_cstat(union scsw *scsw) | ||
| 336 | { | ||
| 337 | if (scsw_is_tm(scsw)) | ||
| 338 | return scsw->tm.cstat; | ||
| 339 | else | ||
| 340 | return scsw->cmd.cstat; | ||
| 341 | } | ||
| 342 | |||
| 343 | /** | ||
| 344 | * scsw_cmd_is_valid_key - check key field validity | ||
| 345 | * @scsw: pointer to scsw | ||
| 346 | * | ||
| 347 | * Return non-zero if the key field of the specified command mode scsw is | ||
| 348 | * valid, zero otherwise. | ||
| 349 | */ | ||
| 350 | static inline int scsw_cmd_is_valid_key(union scsw *scsw) | ||
| 351 | { | ||
| 352 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 353 | } | ||
| 354 | |||
| 355 | /** | ||
| 356 | * scsw_cmd_is_valid_sctl - check fctl field validity | ||
| 357 | * @scsw: pointer to scsw | ||
| 358 | * | ||
| 359 | * Return non-zero if the fctl field of the specified command mode scsw is | ||
| 360 | * valid, zero otherwise. | ||
| 361 | */ | ||
| 362 | static inline int scsw_cmd_is_valid_sctl(union scsw *scsw) | ||
| 363 | { | ||
| 364 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 365 | } | ||
| 366 | |||
| 367 | /** | ||
| 368 | * scsw_cmd_is_valid_eswf - check eswf field validity | ||
| 369 | * @scsw: pointer to scsw | ||
| 370 | * | ||
| 371 | * Return non-zero if the eswf field of the specified command mode scsw is | ||
| 372 | * valid, zero otherwise. | ||
| 373 | */ | ||
| 374 | static inline int scsw_cmd_is_valid_eswf(union scsw *scsw) | ||
| 375 | { | ||
| 376 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND); | ||
| 377 | } | ||
| 378 | |||
| 379 | /** | ||
| 380 | * scsw_cmd_is_valid_cc - check cc field validity | ||
| 381 | * @scsw: pointer to scsw | ||
| 382 | * | ||
| 383 | * Return non-zero if the cc field of the specified command mode scsw is | ||
| 384 | * valid, zero otherwise. | ||
| 385 | */ | ||
| 386 | static inline int scsw_cmd_is_valid_cc(union scsw *scsw) | ||
| 387 | { | ||
| 388 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && | ||
| 389 | (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND); | ||
| 390 | } | ||
| 391 | |||
| 392 | /** | ||
| 393 | * scsw_cmd_is_valid_fmt - check fmt field validity | ||
| 394 | * @scsw: pointer to scsw | ||
| 395 | * | ||
| 396 | * Return non-zero if the fmt field of the specified command mode scsw is | ||
| 397 | * valid, zero otherwise. | ||
| 398 | */ | ||
| 399 | static inline int scsw_cmd_is_valid_fmt(union scsw *scsw) | ||
| 400 | { | ||
| 401 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 402 | } | ||
| 403 | |||
| 404 | /** | ||
| 405 | * scsw_cmd_is_valid_pfch - check pfch field validity | ||
| 406 | * @scsw: pointer to scsw | ||
| 407 | * | ||
| 408 | * Return non-zero if the pfch field of the specified command mode scsw is | ||
| 409 | * valid, zero otherwise. | ||
| 410 | */ | ||
| 411 | static inline int scsw_cmd_is_valid_pfch(union scsw *scsw) | ||
| 412 | { | ||
| 413 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 414 | } | ||
| 415 | |||
| 416 | /** | ||
| 417 | * scsw_cmd_is_valid_isic - check isic field validity | ||
| 418 | * @scsw: pointer to scsw | ||
| 419 | * | ||
| 420 | * Return non-zero if the isic field of the specified command mode scsw is | ||
| 421 | * valid, zero otherwise. | ||
| 422 | */ | ||
| 423 | static inline int scsw_cmd_is_valid_isic(union scsw *scsw) | ||
| 424 | { | ||
| 425 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 426 | } | ||
| 427 | |||
| 428 | /** | ||
| 429 | * scsw_cmd_is_valid_alcc - check alcc field validity | ||
| 430 | * @scsw: pointer to scsw | ||
| 431 | * | ||
| 432 | * Return non-zero if the alcc field of the specified command mode scsw is | ||
| 433 | * valid, zero otherwise. | ||
| 434 | */ | ||
| 435 | static inline int scsw_cmd_is_valid_alcc(union scsw *scsw) | ||
| 436 | { | ||
| 437 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 438 | } | ||
| 439 | |||
| 440 | /** | ||
| 441 | * scsw_cmd_is_valid_ssi - check ssi field validity | ||
| 442 | * @scsw: pointer to scsw | ||
| 443 | * | ||
| 444 | * Return non-zero if the ssi field of the specified command mode scsw is | ||
| 445 | * valid, zero otherwise. | ||
| 446 | */ | ||
| 447 | static inline int scsw_cmd_is_valid_ssi(union scsw *scsw) | ||
| 448 | { | ||
| 449 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 450 | } | ||
| 451 | |||
| 452 | /** | ||
| 453 | * scsw_cmd_is_valid_zcc - check zcc field validity | ||
| 454 | * @scsw: pointer to scsw | ||
| 455 | * | ||
| 456 | * Return non-zero if the zcc field of the specified command mode scsw is | ||
| 457 | * valid, zero otherwise. | ||
| 458 | */ | ||
| 459 | static inline int scsw_cmd_is_valid_zcc(union scsw *scsw) | ||
| 460 | { | ||
| 461 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && | ||
| 462 | (scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS); | ||
| 463 | } | ||
| 464 | |||
| 465 | /** | ||
| 466 | * scsw_cmd_is_valid_ectl - check ectl field validity | ||
| 467 | * @scsw: pointer to scsw | ||
| 468 | * | ||
| 469 | * Return non-zero if the ectl field of the specified command mode scsw is | ||
| 470 | * valid, zero otherwise. | ||
| 471 | */ | ||
| 472 | static inline int scsw_cmd_is_valid_ectl(union scsw *scsw) | ||
| 473 | { | ||
| 474 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 475 | !(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) && | ||
| 476 | (scsw->cmd.stctl & SCSW_STCTL_ALERT_STATUS); | ||
| 477 | } | ||
| 478 | |||
| 479 | /** | ||
| 480 | * scsw_cmd_is_valid_pno - check pno field validity | ||
| 481 | * @scsw: pointer to scsw | ||
| 482 | * | ||
| 483 | * Return non-zero if the pno field of the specified command mode scsw is | ||
| 484 | * valid, zero otherwise. | ||
| 485 | */ | ||
| 486 | static inline int scsw_cmd_is_valid_pno(union scsw *scsw) | ||
| 487 | { | ||
| 488 | return (scsw->cmd.fctl != 0) && | ||
| 489 | (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 490 | (!(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) || | ||
| 491 | ((scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) && | ||
| 492 | (scsw->cmd.actl & SCSW_ACTL_SUSPENDED))); | ||
| 493 | } | ||
| 494 | |||
| 495 | /** | ||
| 496 | * scsw_cmd_is_valid_fctl - check fctl field validity | ||
| 497 | * @scsw: pointer to scsw | ||
| 498 | * | ||
| 499 | * Return non-zero if the fctl field of the specified command mode scsw is | ||
| 500 | * valid, zero otherwise. | ||
| 501 | */ | ||
| 502 | static inline int scsw_cmd_is_valid_fctl(union scsw *scsw) | ||
| 503 | { | ||
| 504 | /* Only valid if pmcw.dnv == 1*/ | ||
| 505 | return 1; | ||
| 506 | } | ||
| 507 | |||
| 508 | /** | ||
| 509 | * scsw_cmd_is_valid_actl - check actl field validity | ||
| 510 | * @scsw: pointer to scsw | ||
| 511 | * | ||
| 512 | * Return non-zero if the actl field of the specified command mode scsw is | ||
| 513 | * valid, zero otherwise. | ||
| 514 | */ | ||
| 515 | static inline int scsw_cmd_is_valid_actl(union scsw *scsw) | ||
| 516 | { | ||
| 517 | /* Only valid if pmcw.dnv == 1*/ | ||
| 518 | return 1; | ||
| 519 | } | ||
| 520 | |||
| 521 | /** | ||
| 522 | * scsw_cmd_is_valid_stctl - check stctl field validity | ||
| 523 | * @scsw: pointer to scsw | ||
| 524 | * | ||
| 525 | * Return non-zero if the stctl field of the specified command mode scsw is | ||
| 526 | * valid, zero otherwise. | ||
| 527 | */ | ||
| 528 | static inline int scsw_cmd_is_valid_stctl(union scsw *scsw) | ||
| 529 | { | ||
| 530 | /* Only valid if pmcw.dnv == 1*/ | ||
| 531 | return 1; | ||
| 532 | } | ||
| 533 | |||
| 534 | /** | ||
| 535 | * scsw_cmd_is_valid_dstat - check dstat field validity | ||
| 536 | * @scsw: pointer to scsw | ||
| 537 | * | ||
| 538 | * Return non-zero if the dstat field of the specified command mode scsw is | ||
| 539 | * valid, zero otherwise. | ||
| 540 | */ | ||
| 541 | static inline int scsw_cmd_is_valid_dstat(union scsw *scsw) | ||
| 542 | { | ||
| 543 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 544 | (scsw->cmd.cc != 3); | ||
| 545 | } | ||
| 546 | |||
| 547 | /** | ||
| 548 | * scsw_cmd_is_valid_cstat - check cstat field validity | ||
| 549 | * @scsw: pointer to scsw | ||
| 550 | * | ||
| 551 | * Return non-zero if the cstat field of the specified command mode scsw is | ||
| 552 | * valid, zero otherwise. | ||
| 553 | */ | ||
| 554 | static inline int scsw_cmd_is_valid_cstat(union scsw *scsw) | ||
| 555 | { | ||
| 556 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 557 | (scsw->cmd.cc != 3); | ||
| 558 | } | ||
| 559 | |||
| 560 | /** | ||
| 561 | * scsw_tm_is_valid_key - check key field validity | ||
| 562 | * @scsw: pointer to scsw | ||
| 563 | * | ||
| 564 | * Return non-zero if the key field of the specified transport mode scsw is | ||
| 565 | * valid, zero otherwise. | ||
| 566 | */ | ||
| 567 | static inline int scsw_tm_is_valid_key(union scsw *scsw) | ||
| 568 | { | ||
| 569 | return (scsw->tm.fctl & SCSW_FCTL_START_FUNC); | ||
| 570 | } | ||
| 571 | |||
| 572 | /** | ||
| 573 | * scsw_tm_is_valid_eswf - check eswf field validity | ||
| 574 | * @scsw: pointer to scsw | ||
| 575 | * | ||
| 576 | * Return non-zero if the eswf field of the specified transport mode scsw is | ||
| 577 | * valid, zero otherwise. | ||
| 578 | */ | ||
| 579 | static inline int scsw_tm_is_valid_eswf(union scsw *scsw) | ||
| 580 | { | ||
| 581 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND); | ||
| 582 | } | ||
| 583 | |||
| 584 | /** | ||
| 585 | * scsw_tm_is_valid_cc - check cc field validity | ||
| 586 | * @scsw: pointer to scsw | ||
| 587 | * | ||
| 588 | * Return non-zero if the cc field of the specified transport mode scsw is | ||
| 589 | * valid, zero otherwise. | ||
| 590 | */ | ||
| 591 | static inline int scsw_tm_is_valid_cc(union scsw *scsw) | ||
| 592 | { | ||
| 593 | return (scsw->tm.fctl & SCSW_FCTL_START_FUNC) && | ||
| 594 | (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND); | ||
| 595 | } | ||
| 596 | |||
| 597 | /** | ||
| 598 | * scsw_tm_is_valid_fmt - check fmt field validity | ||
| 599 | * @scsw: pointer to scsw | ||
| 600 | * | ||
| 601 | * Return non-zero if the fmt field of the specified transport mode scsw is | ||
| 602 | * valid, zero otherwise. | ||
| 603 | */ | ||
| 604 | static inline int scsw_tm_is_valid_fmt(union scsw *scsw) | ||
| 605 | { | ||
| 606 | return 1; | ||
| 607 | } | ||
| 608 | |||
| 609 | /** | ||
| 610 | * scsw_tm_is_valid_x - check x field validity | ||
| 611 | * @scsw: pointer to scsw | ||
| 612 | * | ||
| 613 | * Return non-zero if the x field of the specified transport mode scsw is | ||
| 614 | * valid, zero otherwise. | ||
| 615 | */ | ||
| 616 | static inline int scsw_tm_is_valid_x(union scsw *scsw) | ||
| 617 | { | ||
| 618 | return 1; | ||
| 619 | } | ||
| 620 | |||
| 621 | /** | ||
| 622 | * scsw_tm_is_valid_q - check q field validity | ||
| 623 | * @scsw: pointer to scsw | ||
| 624 | * | ||
| 625 | * Return non-zero if the q field of the specified transport mode scsw is | ||
| 626 | * valid, zero otherwise. | ||
| 627 | */ | ||
| 628 | static inline int scsw_tm_is_valid_q(union scsw *scsw) | ||
| 629 | { | ||
| 630 | return 1; | ||
| 631 | } | ||
| 632 | |||
| 633 | /** | ||
| 634 | * scsw_tm_is_valid_ectl - check ectl field validity | ||
| 635 | * @scsw: pointer to scsw | ||
| 636 | * | ||
| 637 | * Return non-zero if the ectl field of the specified transport mode scsw is | ||
| 638 | * valid, zero otherwise. | ||
| 639 | */ | ||
| 640 | static inline int scsw_tm_is_valid_ectl(union scsw *scsw) | ||
| 641 | { | ||
| 642 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 643 | !(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) && | ||
| 644 | (scsw->tm.stctl & SCSW_STCTL_ALERT_STATUS); | ||
| 645 | } | ||
| 646 | |||
| 647 | /** | ||
| 648 | * scsw_tm_is_valid_pno - check pno field validity | ||
| 649 | * @scsw: pointer to scsw | ||
| 650 | * | ||
| 651 | * Return non-zero if the pno field of the specified transport mode scsw is | ||
| 652 | * valid, zero otherwise. | ||
| 653 | */ | ||
| 654 | static inline int scsw_tm_is_valid_pno(union scsw *scsw) | ||
| 655 | { | ||
| 656 | return (scsw->tm.fctl != 0) && | ||
| 657 | (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 658 | (!(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) || | ||
| 659 | ((scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) && | ||
| 660 | (scsw->tm.actl & SCSW_ACTL_SUSPENDED))); | ||
| 661 | } | ||
| 662 | |||
| 663 | /** | ||
| 664 | * scsw_tm_is_valid_fctl - check fctl field validity | ||
| 665 | * @scsw: pointer to scsw | ||
| 666 | * | ||
| 667 | * Return non-zero if the fctl field of the specified transport mode scsw is | ||
| 668 | * valid, zero otherwise. | ||
| 669 | */ | ||
| 670 | static inline int scsw_tm_is_valid_fctl(union scsw *scsw) | ||
| 671 | { | ||
| 672 | /* Only valid if pmcw.dnv == 1*/ | ||
| 673 | return 1; | ||
| 674 | } | ||
| 675 | |||
| 676 | /** | ||
| 677 | * scsw_tm_is_valid_actl - check actl field validity | ||
| 678 | * @scsw: pointer to scsw | ||
| 679 | * | ||
| 680 | * Return non-zero if the actl field of the specified transport mode scsw is | ||
| 681 | * valid, zero otherwise. | ||
| 682 | */ | ||
| 683 | static inline int scsw_tm_is_valid_actl(union scsw *scsw) | ||
| 684 | { | ||
| 685 | /* Only valid if pmcw.dnv == 1*/ | ||
| 686 | return 1; | ||
| 687 | } | ||
| 688 | |||
| 689 | /** | ||
| 690 | * scsw_tm_is_valid_stctl - check stctl field validity | ||
| 691 | * @scsw: pointer to scsw | ||
| 692 | * | ||
| 693 | * Return non-zero if the stctl field of the specified transport mode scsw is | ||
| 694 | * valid, zero otherwise. | ||
| 695 | */ | ||
| 696 | static inline int scsw_tm_is_valid_stctl(union scsw *scsw) | ||
| 697 | { | ||
| 698 | /* Only valid if pmcw.dnv == 1*/ | ||
| 699 | return 1; | ||
| 700 | } | ||
| 701 | |||
| 702 | /** | ||
| 703 | * scsw_tm_is_valid_dstat - check dstat field validity | ||
| 704 | * @scsw: pointer to scsw | ||
| 705 | * | ||
| 706 | * Return non-zero if the dstat field of the specified transport mode scsw is | ||
| 707 | * valid, zero otherwise. | ||
| 708 | */ | ||
| 709 | static inline int scsw_tm_is_valid_dstat(union scsw *scsw) | ||
| 710 | { | ||
| 711 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 712 | (scsw->tm.cc != 3); | ||
| 713 | } | ||
| 714 | |||
| 715 | /** | ||
| 716 | * scsw_tm_is_valid_cstat - check cstat field validity | ||
| 717 | * @scsw: pointer to scsw | ||
| 718 | * | ||
| 719 | * Return non-zero if the cstat field of the specified transport mode scsw is | ||
| 720 | * valid, zero otherwise. | ||
| 721 | */ | ||
| 722 | static inline int scsw_tm_is_valid_cstat(union scsw *scsw) | ||
| 723 | { | ||
| 724 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 725 | (scsw->tm.cc != 3); | ||
| 726 | } | ||
| 727 | |||
| 728 | /** | ||
| 729 | * scsw_tm_is_valid_fcxs - check fcxs field validity | ||
| 730 | * @scsw: pointer to scsw | ||
| 731 | * | ||
| 732 | * Return non-zero if the fcxs field of the specified transport mode scsw is | ||
| 733 | * valid, zero otherwise. | ||
| 734 | */ | ||
| 735 | static inline int scsw_tm_is_valid_fcxs(union scsw *scsw) | ||
| 736 | { | ||
| 737 | return 1; | ||
| 738 | } | ||
| 739 | |||
| 740 | /** | ||
| 741 | * scsw_tm_is_valid_schxs - check schxs field validity | ||
| 742 | * @scsw: pointer to scsw | ||
| 743 | * | ||
| 744 | * Return non-zero if the schxs field of the specified transport mode scsw is | ||
| 745 | * valid, zero otherwise. | ||
| 746 | */ | ||
| 747 | static inline int scsw_tm_is_valid_schxs(union scsw *scsw) | ||
| 748 | { | ||
| 749 | return (scsw->tm.cstat & (SCHN_STAT_PROG_CHECK | | ||
| 750 | SCHN_STAT_INTF_CTRL_CHK | | ||
| 751 | SCHN_STAT_PROT_CHECK | | ||
| 752 | SCHN_STAT_CHN_DATA_CHK)); | ||
| 753 | } | ||
| 754 | |||
| 755 | /** | ||
| 756 | * scsw_is_valid_actl - check actl field validity | ||
| 757 | * @scsw: pointer to scsw | ||
| 758 | * | ||
| 759 | * Return non-zero if the actl field of the specified scsw is valid, | ||
| 760 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 761 | * Return zero if the field does not contain a valid value. | ||
| 762 | */ | ||
| 763 | static inline int scsw_is_valid_actl(union scsw *scsw) | ||
| 764 | { | ||
| 765 | if (scsw_is_tm(scsw)) | ||
| 766 | return scsw_tm_is_valid_actl(scsw); | ||
| 767 | else | ||
| 768 | return scsw_cmd_is_valid_actl(scsw); | ||
| 769 | } | ||
| 770 | |||
| 771 | /** | ||
| 772 | * scsw_is_valid_cc - check cc field validity | ||
| 773 | * @scsw: pointer to scsw | ||
| 774 | * | ||
| 775 | * Return non-zero if the cc field of the specified scsw is valid, | ||
| 776 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 777 | * Return zero if the field does not contain a valid value. | ||
| 778 | */ | ||
| 779 | static inline int scsw_is_valid_cc(union scsw *scsw) | ||
| 780 | { | ||
| 781 | if (scsw_is_tm(scsw)) | ||
| 782 | return scsw_tm_is_valid_cc(scsw); | ||
| 783 | else | ||
| 784 | return scsw_cmd_is_valid_cc(scsw); | ||
| 785 | } | ||
| 786 | |||
| 787 | /** | ||
| 788 | * scsw_is_valid_cstat - check cstat field validity | ||
| 789 | * @scsw: pointer to scsw | ||
| 790 | * | ||
| 791 | * Return non-zero if the cstat field of the specified scsw is valid, | ||
| 792 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 793 | * Return zero if the field does not contain a valid value. | ||
| 794 | */ | ||
| 795 | static inline int scsw_is_valid_cstat(union scsw *scsw) | ||
| 796 | { | ||
| 797 | if (scsw_is_tm(scsw)) | ||
| 798 | return scsw_tm_is_valid_cstat(scsw); | ||
| 799 | else | ||
| 800 | return scsw_cmd_is_valid_cstat(scsw); | ||
| 801 | } | ||
| 802 | |||
| 803 | /** | ||
| 804 | * scsw_is_valid_dstat - check dstat field validity | ||
| 805 | * @scsw: pointer to scsw | ||
| 806 | * | ||
| 807 | * Return non-zero if the dstat field of the specified scsw is valid, | ||
| 808 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 809 | * Return zero if the field does not contain a valid value. | ||
| 810 | */ | ||
| 811 | static inline int scsw_is_valid_dstat(union scsw *scsw) | ||
| 812 | { | ||
| 813 | if (scsw_is_tm(scsw)) | ||
| 814 | return scsw_tm_is_valid_dstat(scsw); | ||
| 815 | else | ||
| 816 | return scsw_cmd_is_valid_dstat(scsw); | ||
| 817 | } | ||
| 818 | |||
| 819 | /** | ||
| 820 | * scsw_is_valid_ectl - check ectl field validity | ||
| 821 | * @scsw: pointer to scsw | ||
| 822 | * | ||
| 823 | * Return non-zero if the ectl field of the specified scsw is valid, | ||
| 824 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 825 | * Return zero if the field does not contain a valid value. | ||
| 826 | */ | ||
| 827 | static inline int scsw_is_valid_ectl(union scsw *scsw) | ||
| 828 | { | ||
| 829 | if (scsw_is_tm(scsw)) | ||
| 830 | return scsw_tm_is_valid_ectl(scsw); | ||
| 831 | else | ||
| 832 | return scsw_cmd_is_valid_ectl(scsw); | ||
| 833 | } | ||
| 834 | |||
| 835 | /** | ||
| 836 | * scsw_is_valid_eswf - check eswf field validity | ||
| 837 | * @scsw: pointer to scsw | ||
| 838 | * | ||
| 839 | * Return non-zero if the eswf field of the specified scsw is valid, | ||
| 840 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 841 | * Return zero if the field does not contain a valid value. | ||
| 842 | */ | ||
| 843 | static inline int scsw_is_valid_eswf(union scsw *scsw) | ||
| 844 | { | ||
| 845 | if (scsw_is_tm(scsw)) | ||
| 846 | return scsw_tm_is_valid_eswf(scsw); | ||
| 847 | else | ||
| 848 | return scsw_cmd_is_valid_eswf(scsw); | ||
| 849 | } | ||
| 850 | |||
| 851 | /** | ||
| 852 | * scsw_is_valid_fctl - check fctl field validity | ||
| 853 | * @scsw: pointer to scsw | ||
| 854 | * | ||
| 855 | * Return non-zero if the fctl field of the specified scsw is valid, | ||
| 856 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 857 | * Return zero if the field does not contain a valid value. | ||
| 858 | */ | ||
| 859 | static inline int scsw_is_valid_fctl(union scsw *scsw) | ||
| 860 | { | ||
| 861 | if (scsw_is_tm(scsw)) | ||
| 862 | return scsw_tm_is_valid_fctl(scsw); | ||
| 863 | else | ||
| 864 | return scsw_cmd_is_valid_fctl(scsw); | ||
| 865 | } | ||
| 866 | |||
| 867 | /** | ||
| 868 | * scsw_is_valid_key - check key field validity | ||
| 869 | * @scsw: pointer to scsw | ||
| 870 | * | ||
| 871 | * Return non-zero if the key field of the specified scsw is valid, | ||
| 872 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 873 | * Return zero if the field does not contain a valid value. | ||
| 874 | */ | ||
| 875 | static inline int scsw_is_valid_key(union scsw *scsw) | ||
| 876 | { | ||
| 877 | if (scsw_is_tm(scsw)) | ||
| 878 | return scsw_tm_is_valid_key(scsw); | ||
| 879 | else | ||
| 880 | return scsw_cmd_is_valid_key(scsw); | ||
| 881 | } | ||
| 882 | |||
| 883 | /** | ||
| 884 | * scsw_is_valid_pno - check pno field validity | ||
| 885 | * @scsw: pointer to scsw | ||
| 886 | * | ||
| 887 | * Return non-zero if the pno field of the specified scsw is valid, | ||
| 888 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 889 | * Return zero if the field does not contain a valid value. | ||
| 890 | */ | ||
| 891 | static inline int scsw_is_valid_pno(union scsw *scsw) | ||
| 892 | { | ||
| 893 | if (scsw_is_tm(scsw)) | ||
| 894 | return scsw_tm_is_valid_pno(scsw); | ||
| 895 | else | ||
| 896 | return scsw_cmd_is_valid_pno(scsw); | ||
| 897 | } | ||
| 898 | |||
| 899 | /** | ||
| 900 | * scsw_is_valid_stctl - check stctl field validity | ||
| 901 | * @scsw: pointer to scsw | ||
| 902 | * | ||
| 903 | * Return non-zero if the stctl field of the specified scsw is valid, | ||
| 904 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 905 | * Return zero if the field does not contain a valid value. | ||
| 906 | */ | ||
| 907 | static inline int scsw_is_valid_stctl(union scsw *scsw) | ||
| 908 | { | ||
| 909 | if (scsw_is_tm(scsw)) | ||
| 910 | return scsw_tm_is_valid_stctl(scsw); | ||
| 911 | else | ||
| 912 | return scsw_cmd_is_valid_stctl(scsw); | ||
| 913 | } | ||
| 914 | |||
| 915 | /** | ||
| 916 | * scsw_cmd_is_solicited - check for solicited scsw | ||
| 917 | * @scsw: pointer to scsw | ||
| 918 | * | ||
| 919 | * Return non-zero if the command mode scsw indicates that the associated | ||
| 920 | * status condition is solicited, zero if it is unsolicited. | ||
| 921 | */ | ||
| 922 | static inline int scsw_cmd_is_solicited(union scsw *scsw) | ||
| 923 | { | ||
| 924 | return (scsw->cmd.cc != 0) || (scsw->cmd.stctl != | ||
| 925 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)); | ||
| 926 | } | ||
| 927 | |||
| 928 | /** | ||
| 929 | * scsw_tm_is_solicited - check for solicited scsw | ||
| 930 | * @scsw: pointer to scsw | ||
| 931 | * | ||
| 932 | * Return non-zero if the transport mode scsw indicates that the associated | ||
| 933 | * status condition is solicited, zero if it is unsolicited. | ||
| 934 | */ | ||
| 935 | static inline int scsw_tm_is_solicited(union scsw *scsw) | ||
| 936 | { | ||
| 937 | return (scsw->tm.cc != 0) || (scsw->tm.stctl != | ||
| 938 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)); | ||
| 939 | } | ||
| 940 | |||
| 941 | /** | ||
| 942 | * scsw_is_solicited - check for solicited scsw | ||
| 943 | * @scsw: pointer to scsw | ||
| 944 | * | ||
| 945 | * Return non-zero if the transport or command mode scsw indicates that the | ||
| 946 | * associated status condition is solicited, zero if it is unsolicited. | ||
| 947 | */ | ||
| 948 | static inline int scsw_is_solicited(union scsw *scsw) | ||
| 949 | { | ||
| 950 | if (scsw_is_tm(scsw)) | ||
| 951 | return scsw_tm_is_solicited(scsw); | ||
| 952 | else | ||
| 953 | return scsw_cmd_is_solicited(scsw); | ||
| 954 | } | ||
| 955 | |||
| 956 | #endif /* _ASM_S390_SCSW_H_ */ | ||
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 38b0fc221ed7..e37478e87286 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #ifndef _ASM_S390_SETUP_H | 8 | #ifndef _ASM_S390_SETUP_H |
| 9 | #define _ASM_S390_SETUP_H | 9 | #define _ASM_S390_SETUP_H |
| 10 | 10 | ||
| 11 | #define COMMAND_LINE_SIZE 1024 | 11 | #define COMMAND_LINE_SIZE 4096 |
| 12 | 12 | ||
| 13 | #define ARCH_COMMAND_LINE_SIZE 896 | 13 | #define ARCH_COMMAND_LINE_SIZE 896 |
| 14 | 14 | ||
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index 72137bc907ac..c991fe6473c9 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h | |||
| @@ -51,32 +51,7 @@ extern void machine_power_off_smp(void); | |||
| 51 | #define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ | 51 | #define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ |
| 52 | 52 | ||
| 53 | #define raw_smp_processor_id() (S390_lowcore.cpu_nr) | 53 | #define raw_smp_processor_id() (S390_lowcore.cpu_nr) |
| 54 | 54 | #define cpu_logical_map(cpu) (cpu) | |
| 55 | /* | ||
| 56 | * returns 1 if cpu is in stopped/check stopped state or not operational | ||
| 57 | * returns 0 otherwise | ||
| 58 | */ | ||
| 59 | static inline int | ||
| 60 | smp_cpu_not_running(int cpu) | ||
| 61 | { | ||
| 62 | __u32 status; | ||
| 63 | |||
| 64 | switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { | ||
| 65 | case sigp_order_code_accepted: | ||
| 66 | case sigp_status_stored: | ||
| 67 | /* Check for stopped and check stop state */ | ||
| 68 | if (status & 0x50) | ||
| 69 | return 1; | ||
| 70 | break; | ||
| 71 | case sigp_not_operational: | ||
| 72 | return 1; | ||
| 73 | default: | ||
| 74 | break; | ||
| 75 | } | ||
| 76 | return 0; | ||
| 77 | } | ||
| 78 | |||
| 79 | #define cpu_logical_map(cpu) (cpu) | ||
| 80 | 55 | ||
| 81 | extern int __cpu_disable (void); | 56 | extern int __cpu_disable (void); |
| 82 | extern void __cpu_die (unsigned int cpu); | 57 | extern void __cpu_die (unsigned int cpu); |
| @@ -91,11 +66,6 @@ extern void arch_send_call_function_ipi(cpumask_t mask); | |||
| 91 | 66 | ||
| 92 | #endif | 67 | #endif |
| 93 | 68 | ||
| 94 | #ifndef CONFIG_SMP | ||
| 95 | #define hard_smp_processor_id() 0 | ||
| 96 | #define smp_cpu_not_running(cpu) 1 | ||
| 97 | #endif | ||
| 98 | |||
| 99 | #ifdef CONFIG_HOTPLUG_CPU | 69 | #ifdef CONFIG_HOTPLUG_CPU |
| 100 | extern int smp_rescan_cpus(void); | 70 | extern int smp_rescan_cpus(void); |
| 101 | #else | 71 | #else |
diff --git a/arch/s390/include/asm/socket.h b/arch/s390/include/asm/socket.h index 02330c50241b..e42df89a0b85 100644 --- a/arch/s390/include/asm/socket.h +++ b/arch/s390/include/asm/socket.h | |||
| @@ -65,4 +65,7 @@ | |||
| 65 | #define SO_TIMESTAMPING 37 | 65 | #define SO_TIMESTAMPING 37 |
| 66 | #define SCM_TIMESTAMPING SO_TIMESTAMPING | 66 | #define SCM_TIMESTAMPING SO_TIMESTAMPING |
| 67 | 67 | ||
| 68 | #define SO_PROTOCOL 38 | ||
| 69 | #define SO_DOMAIN 39 | ||
| 70 | |||
| 68 | #endif /* _ASM_SOCKET_H */ | 71 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h index c9af0d19c7ab..41ce6861174e 100644 --- a/arch/s390/include/asm/spinlock.h +++ b/arch/s390/include/asm/spinlock.h | |||
| @@ -191,4 +191,33 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) | |||
| 191 | #define _raw_read_relax(lock) cpu_relax() | 191 | #define _raw_read_relax(lock) cpu_relax() |
| 192 | #define _raw_write_relax(lock) cpu_relax() | 192 | #define _raw_write_relax(lock) cpu_relax() |
| 193 | 193 | ||
| 194 | #define __always_inline__spin_lock | ||
| 195 | #define __always_inline__read_lock | ||
| 196 | #define __always_inline__write_lock | ||
| 197 | #define __always_inline__spin_lock_bh | ||
| 198 | #define __always_inline__read_lock_bh | ||
| 199 | #define __always_inline__write_lock_bh | ||
| 200 | #define __always_inline__spin_lock_irq | ||
| 201 | #define __always_inline__read_lock_irq | ||
| 202 | #define __always_inline__write_lock_irq | ||
| 203 | #define __always_inline__spin_lock_irqsave | ||
| 204 | #define __always_inline__read_lock_irqsave | ||
| 205 | #define __always_inline__write_lock_irqsave | ||
| 206 | #define __always_inline__spin_trylock | ||
| 207 | #define __always_inline__read_trylock | ||
| 208 | #define __always_inline__write_trylock | ||
| 209 | #define __always_inline__spin_trylock_bh | ||
| 210 | #define __always_inline__spin_unlock | ||
| 211 | #define __always_inline__read_unlock | ||
| 212 | #define __always_inline__write_unlock | ||
| 213 | #define __always_inline__spin_unlock_bh | ||
| 214 | #define __always_inline__read_unlock_bh | ||
| 215 | #define __always_inline__write_unlock_bh | ||
| 216 | #define __always_inline__spin_unlock_irq | ||
| 217 | #define __always_inline__read_unlock_irq | ||
| 218 | #define __always_inline__write_unlock_irq | ||
| 219 | #define __always_inline__spin_unlock_irqrestore | ||
| 220 | #define __always_inline__read_unlock_irqrestore | ||
| 221 | #define __always_inline__write_unlock_irqrestore | ||
| 222 | |||
| 194 | #endif /* __ASM_SPINLOCK_H */ | 223 | #endif /* __ASM_SPINLOCK_H */ |
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 4fb83c1cdb77..379661d2f81a 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h | |||
| @@ -109,11 +109,7 @@ extern void pfault_fini(void); | |||
| 109 | #define pfault_fini() do { } while (0) | 109 | #define pfault_fini() do { } while (0) |
| 110 | #endif /* CONFIG_PFAULT */ | 110 | #endif /* CONFIG_PFAULT */ |
| 111 | 111 | ||
| 112 | #ifdef CONFIG_PAGE_STATES | ||
| 113 | extern void cmma_init(void); | 112 | extern void cmma_init(void); |
| 114 | #else | ||
| 115 | static inline void cmma_init(void) { } | ||
| 116 | #endif | ||
| 117 | 113 | ||
| 118 | #define finish_arch_switch(prev) do { \ | 114 | #define finish_arch_switch(prev) do { \ |
| 119 | set_fs(current->thread.mm_segment); \ | 115 | set_fs(current->thread.mm_segment); \ |
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index ba1cab9fc1f9..07eb61b2fb3a 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h | |||
| @@ -92,7 +92,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 92 | #define TIF_SYSCALL_TRACE 8 /* syscall trace active */ | 92 | #define TIF_SYSCALL_TRACE 8 /* syscall trace active */ |
| 93 | #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ | 93 | #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ |
| 94 | #define TIF_SECCOMP 10 /* secure computing */ | 94 | #define TIF_SECCOMP 10 /* secure computing */ |
| 95 | #define TIF_SYSCALL_FTRACE 11 /* ftrace syscall instrumentation */ | 95 | #define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */ |
| 96 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ | 96 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ |
| 97 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling | 97 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling |
| 98 | TIF_NEED_RESCHED */ | 98 | TIF_NEED_RESCHED */ |
| @@ -111,7 +111,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 111 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 111 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
| 112 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) | 112 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) |
| 113 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) | 113 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) |
| 114 | #define _TIF_SYSCALL_FTRACE (1<<TIF_SYSCALL_FTRACE) | 114 | #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) |
| 115 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) | 115 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) |
| 116 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 116 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
| 117 | #define _TIF_31BIT (1<<TIF_31BIT) | 117 | #define _TIF_31BIT (1<<TIF_31BIT) |
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index a07e699bb65c..68d9fea34b4b 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h | |||
| @@ -98,4 +98,18 @@ void stck_to_timespec(unsigned long long stck, struct timespec *ts) | |||
| 98 | 98 | ||
| 99 | extern u64 sched_clock_base_cc; | 99 | extern u64 sched_clock_base_cc; |
| 100 | 100 | ||
| 101 | /** | ||
| 102 | * get_clock_monotonic - returns current time in clock rate units | ||
| 103 | * | ||
| 104 | * The caller must ensure that preemption is disabled. | ||
| 105 | * The clock and sched_clock_base get changed via stop_machine. | ||
| 106 | * Therefore preemption must be disabled when calling this | ||
| 107 | * function, otherwise the returned value is not guaranteed to | ||
| 108 | * be monotonic. | ||
| 109 | */ | ||
| 110 | static inline unsigned long long get_clock_monotonic(void) | ||
| 111 | { | ||
| 112 | return get_clock_xt() - sched_clock_base_cc; | ||
| 113 | } | ||
| 114 | |||
| 101 | #endif | 115 | #endif |
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index c75ed43b1a18..c7be8e10b87e 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
| @@ -32,7 +32,7 @@ extra-y += head.o init_task.o vmlinux.lds | |||
| 32 | 32 | ||
| 33 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o | 33 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o |
| 34 | obj-$(CONFIG_SMP) += smp.o topology.o | 34 | obj-$(CONFIG_SMP) += smp.o topology.o |
| 35 | 35 | obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o | |
| 36 | obj-$(CONFIG_AUDIT) += audit.o | 36 | obj-$(CONFIG_AUDIT) += audit.o |
| 37 | compat-obj-$(CONFIG_AUDIT) += compat_audit.o | 37 | compat-obj-$(CONFIG_AUDIT) += compat_audit.o |
| 38 | obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ | 38 | obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ |
| @@ -41,7 +41,7 @@ obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ | |||
| 41 | 41 | ||
| 42 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 42 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
| 43 | obj-$(CONFIG_KPROBES) += kprobes.o | 43 | obj-$(CONFIG_KPROBES) += kprobes.o |
| 44 | obj-$(CONFIG_FUNCTION_TRACER) += mcount.o | 44 | obj-$(CONFIG_FUNCTION_TRACER) += $(if $(CONFIG_64BIT),mcount64.o,mcount.o) |
| 45 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o | 45 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o |
| 46 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o | 46 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o |
| 47 | 47 | ||
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index cae14c499511..bf8b4ae7ff2d 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
| @@ -6,6 +6,9 @@ | |||
| 6 | * Heiko Carstens <heiko.carstens@de.ibm.com> | 6 | * Heiko Carstens <heiko.carstens@de.ibm.com> |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #define KMSG_COMPONENT "setup" | ||
| 10 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
| 11 | |||
| 9 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
| 10 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 11 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
| @@ -16,6 +19,7 @@ | |||
| 16 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 17 | #include <linux/pfn.h> | 20 | #include <linux/pfn.h> |
| 18 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
| 22 | #include <linux/kernel.h> | ||
| 19 | #include <asm/ebcdic.h> | 23 | #include <asm/ebcdic.h> |
| 20 | #include <asm/ipl.h> | 24 | #include <asm/ipl.h> |
| 21 | #include <asm/lowcore.h> | 25 | #include <asm/lowcore.h> |
| @@ -35,8 +39,6 @@ | |||
| 35 | 39 | ||
| 36 | char kernel_nss_name[NSS_NAME_SIZE + 1]; | 40 | char kernel_nss_name[NSS_NAME_SIZE + 1]; |
| 37 | 41 | ||
| 38 | static unsigned long machine_flags; | ||
| 39 | |||
| 40 | static void __init setup_boot_command_line(void); | 42 | static void __init setup_boot_command_line(void); |
| 41 | 43 | ||
| 42 | /* | 44 | /* |
| @@ -81,6 +83,8 @@ asm( | |||
| 81 | " br 14\n" | 83 | " br 14\n" |
| 82 | " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); | 84 | " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); |
| 83 | 85 | ||
| 86 | static __initdata char upper_command_line[COMMAND_LINE_SIZE]; | ||
| 87 | |||
| 84 | static noinline __init void create_kernel_nss(void) | 88 | static noinline __init void create_kernel_nss(void) |
| 85 | { | 89 | { |
| 86 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; | 90 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; |
| @@ -90,7 +94,6 @@ static noinline __init void create_kernel_nss(void) | |||
| 90 | int response; | 94 | int response; |
| 91 | size_t len; | 95 | size_t len; |
| 92 | char *savesys_ptr; | 96 | char *savesys_ptr; |
| 93 | char upper_command_line[COMMAND_LINE_SIZE]; | ||
| 94 | char defsys_cmd[DEFSYS_CMD_SIZE]; | 97 | char defsys_cmd[DEFSYS_CMD_SIZE]; |
| 95 | char savesys_cmd[SAVESYS_CMD_SIZE]; | 98 | char savesys_cmd[SAVESYS_CMD_SIZE]; |
| 96 | 99 | ||
| @@ -141,6 +144,8 @@ static noinline __init void create_kernel_nss(void) | |||
| 141 | __cpcmd(defsys_cmd, NULL, 0, &response); | 144 | __cpcmd(defsys_cmd, NULL, 0, &response); |
| 142 | 145 | ||
| 143 | if (response != 0) { | 146 | if (response != 0) { |
| 147 | pr_err("Defining the Linux kernel NSS failed with rc=%d\n", | ||
| 148 | response); | ||
| 144 | kernel_nss_name[0] = '\0'; | 149 | kernel_nss_name[0] = '\0'; |
| 145 | return; | 150 | return; |
| 146 | } | 151 | } |
| @@ -153,8 +158,11 @@ static noinline __init void create_kernel_nss(void) | |||
| 153 | * max SAVESYS_CMD_SIZE | 158 | * max SAVESYS_CMD_SIZE |
| 154 | * On error: response contains the numeric portion of cp error message. | 159 | * On error: response contains the numeric portion of cp error message. |
| 155 | * for SAVESYS it will be >= 263 | 160 | * for SAVESYS it will be >= 263 |
| 161 | * for missing privilege class, it will be 1 | ||
| 156 | */ | 162 | */ |
| 157 | if (response > SAVESYS_CMD_SIZE) { | 163 | if (response > SAVESYS_CMD_SIZE || response == 1) { |
| 164 | pr_err("Saving the Linux kernel NSS failed with rc=%d\n", | ||
| 165 | response); | ||
| 158 | kernel_nss_name[0] = '\0'; | 166 | kernel_nss_name[0] = '\0'; |
| 159 | return; | 167 | return; |
| 160 | } | 168 | } |
| @@ -205,12 +213,9 @@ static noinline __init void detect_machine_type(void) | |||
| 205 | 213 | ||
| 206 | /* Running under KVM? If not we assume z/VM */ | 214 | /* Running under KVM? If not we assume z/VM */ |
| 207 | if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3)) | 215 | if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3)) |
| 208 | machine_flags |= MACHINE_FLAG_KVM; | 216 | S390_lowcore.machine_flags |= MACHINE_FLAG_KVM; |
| 209 | else | 217 | else |
| 210 | machine_flags |= MACHINE_FLAG_VM; | 218 | S390_lowcore.machine_flags |= MACHINE_FLAG_VM; |
| 211 | |||
| 212 | /* Store machine flags for setting up lowcore early */ | ||
| 213 | S390_lowcore.machine_flags = machine_flags; | ||
| 214 | } | 219 | } |
| 215 | 220 | ||
| 216 | static __init void early_pgm_check_handler(void) | 221 | static __init void early_pgm_check_handler(void) |
| @@ -245,7 +250,7 @@ static noinline __init void setup_hpage(void) | |||
| 245 | facilities = stfl(); | 250 | facilities = stfl(); |
| 246 | if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29))) | 251 | if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29))) |
| 247 | return; | 252 | return; |
| 248 | machine_flags |= MACHINE_FLAG_HPAGE; | 253 | S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE; |
| 249 | __ctl_set_bit(0, 23); | 254 | __ctl_set_bit(0, 23); |
| 250 | #endif | 255 | #endif |
| 251 | } | 256 | } |
| @@ -263,7 +268,7 @@ static __init void detect_mvpg(void) | |||
| 263 | EX_TABLE(0b,1b) | 268 | EX_TABLE(0b,1b) |
| 264 | : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0"); | 269 | : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0"); |
| 265 | if (!rc) | 270 | if (!rc) |
| 266 | machine_flags |= MACHINE_FLAG_MVPG; | 271 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVPG; |
| 267 | #endif | 272 | #endif |
| 268 | } | 273 | } |
| 269 | 274 | ||
| @@ -279,7 +284,7 @@ static __init void detect_ieee(void) | |||
| 279 | EX_TABLE(0b,1b) | 284 | EX_TABLE(0b,1b) |
| 280 | : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc"); | 285 | : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc"); |
| 281 | if (!rc) | 286 | if (!rc) |
| 282 | machine_flags |= MACHINE_FLAG_IEEE; | 287 | S390_lowcore.machine_flags |= MACHINE_FLAG_IEEE; |
| 283 | #endif | 288 | #endif |
| 284 | } | 289 | } |
| 285 | 290 | ||
| @@ -298,7 +303,7 @@ static __init void detect_csp(void) | |||
| 298 | EX_TABLE(0b,1b) | 303 | EX_TABLE(0b,1b) |
| 299 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2"); | 304 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2"); |
| 300 | if (!rc) | 305 | if (!rc) |
| 301 | machine_flags |= MACHINE_FLAG_CSP; | 306 | S390_lowcore.machine_flags |= MACHINE_FLAG_CSP; |
| 302 | #endif | 307 | #endif |
| 303 | } | 308 | } |
| 304 | 309 | ||
| @@ -315,7 +320,7 @@ static __init void detect_diag9c(void) | |||
| 315 | EX_TABLE(0b,1b) | 320 | EX_TABLE(0b,1b) |
| 316 | : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); | 321 | : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); |
| 317 | if (!rc) | 322 | if (!rc) |
| 318 | machine_flags |= MACHINE_FLAG_DIAG9C; | 323 | S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG9C; |
| 319 | } | 324 | } |
| 320 | 325 | ||
| 321 | static __init void detect_diag44(void) | 326 | static __init void detect_diag44(void) |
| @@ -330,7 +335,7 @@ static __init void detect_diag44(void) | |||
| 330 | EX_TABLE(0b,1b) | 335 | EX_TABLE(0b,1b) |
| 331 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc"); | 336 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc"); |
| 332 | if (!rc) | 337 | if (!rc) |
| 333 | machine_flags |= MACHINE_FLAG_DIAG44; | 338 | S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG44; |
| 334 | #endif | 339 | #endif |
| 335 | } | 340 | } |
| 336 | 341 | ||
| @@ -341,11 +346,11 @@ static __init void detect_machine_facilities(void) | |||
| 341 | 346 | ||
| 342 | facilities = stfl(); | 347 | facilities = stfl(); |
| 343 | if (facilities & (1 << 28)) | 348 | if (facilities & (1 << 28)) |
| 344 | machine_flags |= MACHINE_FLAG_IDTE; | 349 | S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; |
| 345 | if (facilities & (1 << 23)) | 350 | if (facilities & (1 << 23)) |
| 346 | machine_flags |= MACHINE_FLAG_PFMF; | 351 | S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF; |
| 347 | if (facilities & (1 << 4)) | 352 | if (facilities & (1 << 4)) |
| 348 | machine_flags |= MACHINE_FLAG_MVCOS; | 353 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; |
| 349 | #endif | 354 | #endif |
| 350 | } | 355 | } |
| 351 | 356 | ||
| @@ -367,21 +372,35 @@ static __init void rescue_initrd(void) | |||
| 367 | } | 372 | } |
| 368 | 373 | ||
| 369 | /* Set up boot command line */ | 374 | /* Set up boot command line */ |
| 370 | static void __init setup_boot_command_line(void) | 375 | static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t)) |
| 371 | { | 376 | { |
| 372 | char *parm = NULL; | 377 | char *parm, *delim; |
| 378 | size_t rc, len; | ||
| 379 | |||
| 380 | len = strlen(boot_command_line); | ||
| 381 | |||
| 382 | delim = boot_command_line + len; /* '\0' character position */ | ||
| 383 | parm = boot_command_line + len + 1; /* append right after '\0' */ | ||
| 373 | 384 | ||
| 385 | rc = ipl_data(parm, COMMAND_LINE_SIZE - len - 1); | ||
| 386 | if (rc) { | ||
| 387 | if (*parm == '=') | ||
| 388 | memmove(boot_command_line, parm + 1, rc); | ||
| 389 | else | ||
| 390 | *delim = ' '; /* replace '\0' with space */ | ||
| 391 | } | ||
| 392 | } | ||
| 393 | |||
| 394 | static void __init setup_boot_command_line(void) | ||
| 395 | { | ||
| 374 | /* copy arch command line */ | 396 | /* copy arch command line */ |
| 375 | strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); | 397 | strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); |
| 376 | 398 | ||
| 377 | /* append IPL PARM data to the boot command line */ | 399 | /* append IPL PARM data to the boot command line */ |
| 378 | if (MACHINE_IS_VM) { | 400 | if (MACHINE_IS_VM) |
| 379 | parm = boot_command_line + strlen(boot_command_line); | 401 | append_to_cmdline(append_ipl_vmparm); |
| 380 | *parm++ = ' '; | 402 | |
| 381 | get_ipl_vmparm(parm); | 403 | append_to_cmdline(append_ipl_scpdata); |
| 382 | if (parm[0] == '=') | ||
| 383 | memmove(boot_command_line, parm + 1, strlen(parm)); | ||
| 384 | } | ||
| 385 | } | 404 | } |
| 386 | 405 | ||
| 387 | 406 | ||
| @@ -413,7 +432,6 @@ void __init startup_init(void) | |||
| 413 | setup_hpage(); | 432 | setup_hpage(); |
| 414 | sclp_facilities_detect(); | 433 | sclp_facilities_detect(); |
| 415 | detect_memory_layout(memory_chunk); | 434 | detect_memory_layout(memory_chunk); |
| 416 | S390_lowcore.machine_flags = machine_flags; | ||
| 417 | #ifdef CONFIG_DYNAMIC_FTRACE | 435 | #ifdef CONFIG_DYNAMIC_FTRACE |
| 418 | S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; | 436 | S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; |
| 419 | #endif | 437 | #endif |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index c4c80a22bc1f..f43d2ee54464 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
| @@ -54,7 +54,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | |||
| 54 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | 54 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
| 55 | _TIF_MCCK_PENDING) | 55 | _TIF_MCCK_PENDING) |
| 56 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ | 56 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ |
| 57 | _TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8) | 57 | _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8) |
| 58 | 58 | ||
| 59 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER | 59 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER |
| 60 | STACK_SIZE = 1 << STACK_SHIFT | 60 | STACK_SIZE = 1 << STACK_SHIFT |
| @@ -278,7 +278,8 @@ sysc_return: | |||
| 278 | bnz BASED(sysc_work) # there is work to do (signals etc.) | 278 | bnz BASED(sysc_work) # there is work to do (signals etc.) |
| 279 | sysc_restore: | 279 | sysc_restore: |
| 280 | #ifdef CONFIG_TRACE_IRQFLAGS | 280 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 281 | la %r1,BASED(sysc_restore_trace_psw) | 281 | la %r1,BASED(sysc_restore_trace_psw_addr) |
| 282 | l %r1,0(%r1) | ||
| 282 | lpsw 0(%r1) | 283 | lpsw 0(%r1) |
| 283 | sysc_restore_trace: | 284 | sysc_restore_trace: |
| 284 | TRACE_IRQS_CHECK | 285 | TRACE_IRQS_CHECK |
| @@ -289,10 +290,15 @@ sysc_leave: | |||
| 289 | sysc_done: | 290 | sysc_done: |
| 290 | 291 | ||
| 291 | #ifdef CONFIG_TRACE_IRQFLAGS | 292 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 293 | sysc_restore_trace_psw_addr: | ||
| 294 | .long sysc_restore_trace_psw | ||
| 295 | |||
| 296 | .section .data,"aw",@progbits | ||
| 292 | .align 8 | 297 | .align 8 |
| 293 | .globl sysc_restore_trace_psw | 298 | .globl sysc_restore_trace_psw |
| 294 | sysc_restore_trace_psw: | 299 | sysc_restore_trace_psw: |
| 295 | .long 0, sysc_restore_trace + 0x80000000 | 300 | .long 0, sysc_restore_trace + 0x80000000 |
| 301 | .previous | ||
| 296 | #endif | 302 | #endif |
| 297 | 303 | ||
| 298 | # | 304 | # |
| @@ -606,7 +612,8 @@ io_return: | |||
| 606 | bnz BASED(io_work) # there is work to do (signals etc.) | 612 | bnz BASED(io_work) # there is work to do (signals etc.) |
| 607 | io_restore: | 613 | io_restore: |
| 608 | #ifdef CONFIG_TRACE_IRQFLAGS | 614 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 609 | la %r1,BASED(io_restore_trace_psw) | 615 | la %r1,BASED(io_restore_trace_psw_addr) |
| 616 | l %r1,0(%r1) | ||
| 610 | lpsw 0(%r1) | 617 | lpsw 0(%r1) |
| 611 | io_restore_trace: | 618 | io_restore_trace: |
| 612 | TRACE_IRQS_CHECK | 619 | TRACE_IRQS_CHECK |
| @@ -617,10 +624,15 @@ io_leave: | |||
| 617 | io_done: | 624 | io_done: |
| 618 | 625 | ||
| 619 | #ifdef CONFIG_TRACE_IRQFLAGS | 626 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 627 | io_restore_trace_psw_addr: | ||
| 628 | .long io_restore_trace_psw | ||
| 629 | |||
| 630 | .section .data,"aw",@progbits | ||
| 620 | .align 8 | 631 | .align 8 |
| 621 | .globl io_restore_trace_psw | 632 | .globl io_restore_trace_psw |
| 622 | io_restore_trace_psw: | 633 | io_restore_trace_psw: |
| 623 | .long 0, io_restore_trace + 0x80000000 | 634 | .long 0, io_restore_trace + 0x80000000 |
| 635 | .previous | ||
| 624 | #endif | 636 | #endif |
| 625 | 637 | ||
| 626 | # | 638 | # |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index f6618e9e15ef..a6f7b20df616 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
| @@ -57,7 +57,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | |||
| 57 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | 57 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
| 58 | _TIF_MCCK_PENDING) | 58 | _TIF_MCCK_PENDING) |
| 59 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ | 59 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ |
| 60 | _TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8) | 60 | _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8) |
| 61 | 61 | ||
| 62 | #define BASED(name) name-system_call(%r13) | 62 | #define BASED(name) name-system_call(%r13) |
| 63 | 63 | ||
| @@ -284,10 +284,12 @@ sysc_leave: | |||
| 284 | sysc_done: | 284 | sysc_done: |
| 285 | 285 | ||
| 286 | #ifdef CONFIG_TRACE_IRQFLAGS | 286 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 287 | .section .data,"aw",@progbits | ||
| 287 | .align 8 | 288 | .align 8 |
| 288 | .globl sysc_restore_trace_psw | 289 | .globl sysc_restore_trace_psw |
| 289 | sysc_restore_trace_psw: | 290 | sysc_restore_trace_psw: |
| 290 | .quad 0, sysc_restore_trace | 291 | .quad 0, sysc_restore_trace |
| 292 | .previous | ||
| 291 | #endif | 293 | #endif |
| 292 | 294 | ||
| 293 | # | 295 | # |
| @@ -595,10 +597,12 @@ io_leave: | |||
| 595 | io_done: | 597 | io_done: |
| 596 | 598 | ||
| 597 | #ifdef CONFIG_TRACE_IRQFLAGS | 599 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 600 | .section .data,"aw",@progbits | ||
| 598 | .align 8 | 601 | .align 8 |
| 599 | .globl io_restore_trace_psw | 602 | .globl io_restore_trace_psw |
| 600 | io_restore_trace_psw: | 603 | io_restore_trace_psw: |
| 601 | .quad 0, io_restore_trace | 604 | .quad 0, io_restore_trace |
| 605 | .previous | ||
| 602 | #endif | 606 | #endif |
| 603 | 607 | ||
| 604 | # | 608 | # |
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index 3e298e64f0db..57bdcb1e3cdf 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c | |||
| @@ -220,6 +220,29 @@ struct syscall_metadata *syscall_nr_to_meta(int nr) | |||
| 220 | return syscalls_metadata[nr]; | 220 | return syscalls_metadata[nr]; |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | int syscall_name_to_nr(char *name) | ||
| 224 | { | ||
| 225 | int i; | ||
| 226 | |||
| 227 | if (!syscalls_metadata) | ||
| 228 | return -1; | ||
| 229 | for (i = 0; i < NR_syscalls; i++) | ||
| 230 | if (syscalls_metadata[i]) | ||
| 231 | if (!strcmp(syscalls_metadata[i]->name, name)) | ||
| 232 | return i; | ||
| 233 | return -1; | ||
| 234 | } | ||
| 235 | |||
| 236 | void set_syscall_enter_id(int num, int id) | ||
| 237 | { | ||
| 238 | syscalls_metadata[num]->enter_id = id; | ||
| 239 | } | ||
| 240 | |||
| 241 | void set_syscall_exit_id(int num, int id) | ||
| 242 | { | ||
| 243 | syscalls_metadata[num]->exit_id = id; | ||
| 244 | } | ||
| 245 | |||
| 223 | static struct syscall_metadata *find_syscall_meta(unsigned long syscall) | 246 | static struct syscall_metadata *find_syscall_meta(unsigned long syscall) |
| 224 | { | 247 | { |
| 225 | struct syscall_metadata *start; | 248 | struct syscall_metadata *start; |
| @@ -237,24 +260,19 @@ static struct syscall_metadata *find_syscall_meta(unsigned long syscall) | |||
| 237 | return NULL; | 260 | return NULL; |
| 238 | } | 261 | } |
| 239 | 262 | ||
| 240 | void arch_init_ftrace_syscalls(void) | 263 | static int __init arch_init_ftrace_syscalls(void) |
| 241 | { | 264 | { |
| 242 | struct syscall_metadata *meta; | 265 | struct syscall_metadata *meta; |
| 243 | int i; | 266 | int i; |
| 244 | static atomic_t refs; | ||
| 245 | |||
| 246 | if (atomic_inc_return(&refs) != 1) | ||
| 247 | goto out; | ||
| 248 | syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * NR_syscalls, | 267 | syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * NR_syscalls, |
| 249 | GFP_KERNEL); | 268 | GFP_KERNEL); |
| 250 | if (!syscalls_metadata) | 269 | if (!syscalls_metadata) |
| 251 | goto out; | 270 | return -ENOMEM; |
| 252 | for (i = 0; i < NR_syscalls; i++) { | 271 | for (i = 0; i < NR_syscalls; i++) { |
| 253 | meta = find_syscall_meta((unsigned long)sys_call_table[i]); | 272 | meta = find_syscall_meta((unsigned long)sys_call_table[i]); |
| 254 | syscalls_metadata[i] = meta; | 273 | syscalls_metadata[i] = meta; |
| 255 | } | 274 | } |
| 256 | return; | 275 | return 0; |
| 257 | out: | ||
| 258 | atomic_dec(&refs); | ||
| 259 | } | 276 | } |
| 277 | arch_initcall(arch_init_ftrace_syscalls); | ||
| 260 | #endif | 278 | #endif |
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index ec6882348520..c52b4f7742fa 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <asm/asm-offsets.h> | 27 | #include <asm/asm-offsets.h> |
| 28 | #include <asm/thread_info.h> | 28 | #include <asm/thread_info.h> |
| 29 | #include <asm/page.h> | 29 | #include <asm/page.h> |
| 30 | #include <asm/cpu.h> | ||
| 30 | 31 | ||
| 31 | #ifdef CONFIG_64BIT | 32 | #ifdef CONFIG_64BIT |
| 32 | #define ARCH_OFFSET 4 | 33 | #define ARCH_OFFSET 4 |
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index 2ced846065b7..602b508cd4c4 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S | |||
| @@ -24,6 +24,7 @@ startup_continue: | |||
| 24 | # Setup stack | 24 | # Setup stack |
| 25 | # | 25 | # |
| 26 | l %r15,.Linittu-.LPG1(%r13) | 26 | l %r15,.Linittu-.LPG1(%r13) |
| 27 | st %r15,__LC_THREAD_INFO # cache thread info in lowcore | ||
| 27 | mvc __LC_CURRENT(4),__TI_task(%r15) | 28 | mvc __LC_CURRENT(4),__TI_task(%r15) |
| 28 | ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE | 29 | ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE |
| 29 | st %r15,__LC_KERNEL_STACK # set end of kernel stack | 30 | st %r15,__LC_KERNEL_STACK # set end of kernel stack |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 65667b2e65ce..6a250808092b 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
| @@ -62,9 +62,9 @@ startup_continue: | |||
| 62 | clr %r11,%r12 | 62 | clr %r11,%r12 |
| 63 | je 5f # no more space in prefix array | 63 | je 5f # no more space in prefix array |
| 64 | 4: | 64 | 4: |
| 65 | ahi %r8,1 # next cpu (r8 += 1) | 65 | ahi %r8,1 # next cpu (r8 += 1) |
| 66 | cl %r8,.Llast_cpu-.LPG1(%r13) # is last possible cpu ? | 66 | chi %r8,MAX_CPU_ADDRESS # is last possible cpu ? |
| 67 | jl 1b # jump if not last cpu | 67 | jle 1b # jump if not last cpu |
| 68 | 5: | 68 | 5: |
| 69 | lhi %r1,2 # mode 2 = esame (dump) | 69 | lhi %r1,2 # mode 2 = esame (dump) |
| 70 | j 6f | 70 | j 6f |
| @@ -92,6 +92,7 @@ startup_continue: | |||
| 92 | # Setup stack | 92 | # Setup stack |
| 93 | # | 93 | # |
| 94 | larl %r15,init_thread_union | 94 | larl %r15,init_thread_union |
| 95 | stg %r15,__LC_THREAD_INFO # cache thread info in lowcore | ||
| 95 | lg %r14,__TI_task(%r15) # cache current in lowcore | 96 | lg %r14,__TI_task(%r15) # cache current in lowcore |
| 96 | stg %r14,__LC_CURRENT | 97 | stg %r14,__LC_CURRENT |
| 97 | aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE | 98 | aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE |
| @@ -129,8 +130,6 @@ startup_continue: | |||
| 129 | #ifdef CONFIG_ZFCPDUMP | 130 | #ifdef CONFIG_ZFCPDUMP |
| 130 | .Lcurrent_cpu: | 131 | .Lcurrent_cpu: |
| 131 | .long 0x0 | 132 | .long 0x0 |
| 132 | .Llast_cpu: | ||
| 133 | .long 0x0000ffff | ||
| 134 | .Lpref_arr_ptr: | 133 | .Lpref_arr_ptr: |
| 135 | .long zfcpdump_prefix_array | 134 | .long zfcpdump_prefix_array |
| 136 | #endif /* CONFIG_ZFCPDUMP */ | 135 | #endif /* CONFIG_ZFCPDUMP */ |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 371a2d88f4ac..ee57a42e6e93 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
| @@ -272,17 +272,18 @@ static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr, | |||
| 272 | static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); | 272 | static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); |
| 273 | 273 | ||
| 274 | /* VM IPL PARM routines */ | 274 | /* VM IPL PARM routines */ |
| 275 | static void reipl_get_ascii_vmparm(char *dest, | 275 | size_t reipl_get_ascii_vmparm(char *dest, size_t size, |
| 276 | const struct ipl_parameter_block *ipb) | 276 | const struct ipl_parameter_block *ipb) |
| 277 | { | 277 | { |
| 278 | int i; | 278 | int i; |
| 279 | int len = 0; | 279 | size_t len; |
| 280 | char has_lowercase = 0; | 280 | char has_lowercase = 0; |
| 281 | 281 | ||
| 282 | len = 0; | ||
| 282 | if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) && | 283 | if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) && |
| 283 | (ipb->ipl_info.ccw.vm_parm_len > 0)) { | 284 | (ipb->ipl_info.ccw.vm_parm_len > 0)) { |
| 284 | 285 | ||
| 285 | len = ipb->ipl_info.ccw.vm_parm_len; | 286 | len = min_t(size_t, size - 1, ipb->ipl_info.ccw.vm_parm_len); |
| 286 | memcpy(dest, ipb->ipl_info.ccw.vm_parm, len); | 287 | memcpy(dest, ipb->ipl_info.ccw.vm_parm, len); |
| 287 | /* If at least one character is lowercase, we assume mixed | 288 | /* If at least one character is lowercase, we assume mixed |
| 288 | * case; otherwise we convert everything to lowercase. | 289 | * case; otherwise we convert everything to lowercase. |
| @@ -299,14 +300,20 @@ static void reipl_get_ascii_vmparm(char *dest, | |||
| 299 | EBCASC(dest, len); | 300 | EBCASC(dest, len); |
| 300 | } | 301 | } |
| 301 | dest[len] = 0; | 302 | dest[len] = 0; |
| 303 | |||
| 304 | return len; | ||
| 302 | } | 305 | } |
| 303 | 306 | ||
| 304 | void get_ipl_vmparm(char *dest) | 307 | size_t append_ipl_vmparm(char *dest, size_t size) |
| 305 | { | 308 | { |
| 309 | size_t rc; | ||
| 310 | |||
| 311 | rc = 0; | ||
| 306 | if (diag308_set_works && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW)) | 312 | if (diag308_set_works && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW)) |
| 307 | reipl_get_ascii_vmparm(dest, &ipl_block); | 313 | rc = reipl_get_ascii_vmparm(dest, size, &ipl_block); |
| 308 | else | 314 | else |
| 309 | dest[0] = 0; | 315 | dest[0] = 0; |
| 316 | return rc; | ||
| 310 | } | 317 | } |
| 311 | 318 | ||
| 312 | static ssize_t ipl_vm_parm_show(struct kobject *kobj, | 319 | static ssize_t ipl_vm_parm_show(struct kobject *kobj, |
| @@ -314,10 +321,65 @@ static ssize_t ipl_vm_parm_show(struct kobject *kobj, | |||
| 314 | { | 321 | { |
| 315 | char parm[DIAG308_VMPARM_SIZE + 1] = {}; | 322 | char parm[DIAG308_VMPARM_SIZE + 1] = {}; |
| 316 | 323 | ||
| 317 | get_ipl_vmparm(parm); | 324 | append_ipl_vmparm(parm, sizeof(parm)); |
| 318 | return sprintf(page, "%s\n", parm); | 325 | return sprintf(page, "%s\n", parm); |
| 319 | } | 326 | } |
| 320 | 327 | ||
| 328 | static size_t scpdata_length(const char* buf, size_t count) | ||
| 329 | { | ||
| 330 | while (count) { | ||
| 331 | if (buf[count - 1] != '\0' && buf[count - 1] != ' ') | ||
| 332 | break; | ||
| 333 | count--; | ||
| 334 | } | ||
| 335 | return count; | ||
| 336 | } | ||
| 337 | |||
| 338 | size_t reipl_append_ascii_scpdata(char *dest, size_t size, | ||
| 339 | const struct ipl_parameter_block *ipb) | ||
| 340 | { | ||
| 341 | size_t count; | ||
| 342 | size_t i; | ||
| 343 | int has_lowercase; | ||
| 344 | |||
| 345 | count = min(size - 1, scpdata_length(ipb->ipl_info.fcp.scp_data, | ||
| 346 | ipb->ipl_info.fcp.scp_data_len)); | ||
| 347 | if (!count) | ||
| 348 | goto out; | ||
| 349 | |||
| 350 | has_lowercase = 0; | ||
| 351 | for (i = 0; i < count; i++) { | ||
| 352 | if (!isascii(ipb->ipl_info.fcp.scp_data[i])) { | ||
| 353 | count = 0; | ||
| 354 | goto out; | ||
| 355 | } | ||
| 356 | if (!has_lowercase && islower(ipb->ipl_info.fcp.scp_data[i])) | ||
| 357 | has_lowercase = 1; | ||
| 358 | } | ||
| 359 | |||
| 360 | if (has_lowercase) | ||
| 361 | memcpy(dest, ipb->ipl_info.fcp.scp_data, count); | ||
| 362 | else | ||
| 363 | for (i = 0; i < count; i++) | ||
| 364 | dest[i] = tolower(ipb->ipl_info.fcp.scp_data[i]); | ||
| 365 | out: | ||
| 366 | dest[count] = '\0'; | ||
| 367 | return count; | ||
| 368 | } | ||
| 369 | |||
| 370 | size_t append_ipl_scpdata(char *dest, size_t len) | ||
| 371 | { | ||
| 372 | size_t rc; | ||
| 373 | |||
| 374 | rc = 0; | ||
| 375 | if (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP) | ||
| 376 | rc = reipl_append_ascii_scpdata(dest, len, &ipl_block); | ||
| 377 | else | ||
| 378 | dest[0] = 0; | ||
| 379 | return rc; | ||
| 380 | } | ||
| 381 | |||
| 382 | |||
| 321 | static struct kobj_attribute sys_ipl_vm_parm_attr = | 383 | static struct kobj_attribute sys_ipl_vm_parm_attr = |
| 322 | __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL); | 384 | __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL); |
| 323 | 385 | ||
| @@ -553,7 +615,7 @@ static ssize_t reipl_generic_vmparm_show(struct ipl_parameter_block *ipb, | |||
| 553 | { | 615 | { |
| 554 | char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; | 616 | char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; |
| 555 | 617 | ||
| 556 | reipl_get_ascii_vmparm(vmparm, ipb); | 618 | reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb); |
| 557 | return sprintf(page, "%s\n", vmparm); | 619 | return sprintf(page, "%s\n", vmparm); |
| 558 | } | 620 | } |
| 559 | 621 | ||
| @@ -626,6 +688,59 @@ static struct kobj_attribute sys_reipl_ccw_vmparm_attr = | |||
| 626 | 688 | ||
| 627 | /* FCP reipl device attributes */ | 689 | /* FCP reipl device attributes */ |
| 628 | 690 | ||
| 691 | static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj, | ||
| 692 | struct bin_attribute *attr, | ||
| 693 | char *buf, loff_t off, size_t count) | ||
| 694 | { | ||
| 695 | size_t size = reipl_block_fcp->ipl_info.fcp.scp_data_len; | ||
| 696 | void *scp_data = reipl_block_fcp->ipl_info.fcp.scp_data; | ||
| 697 | |||
| 698 | return memory_read_from_buffer(buf, count, &off, scp_data, size); | ||
| 699 | } | ||
| 700 | |||
| 701 | static ssize_t reipl_fcp_scpdata_write(struct kobject *kobj, | ||
| 702 | struct bin_attribute *attr, | ||
| 703 | char *buf, loff_t off, size_t count) | ||
| 704 | { | ||
| 705 | size_t padding; | ||
| 706 | size_t scpdata_len; | ||
| 707 | |||
| 708 | if (off < 0) | ||
| 709 | return -EINVAL; | ||
| 710 | |||
| 711 | if (off >= DIAG308_SCPDATA_SIZE) | ||
| 712 | return -ENOSPC; | ||
| 713 | |||
| 714 | if (count > DIAG308_SCPDATA_SIZE - off) | ||
| 715 | count = DIAG308_SCPDATA_SIZE - off; | ||
| 716 | |||
| 717 | memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf + off, count); | ||
| 718 | scpdata_len = off + count; | ||
| 719 | |||
| 720 | if (scpdata_len % 8) { | ||
| 721 | padding = 8 - (scpdata_len % 8); | ||
| 722 | memset(reipl_block_fcp->ipl_info.fcp.scp_data + scpdata_len, | ||
| 723 | 0, padding); | ||
| 724 | scpdata_len += padding; | ||
| 725 | } | ||
| 726 | |||
| 727 | reipl_block_fcp->ipl_info.fcp.scp_data_len = scpdata_len; | ||
| 728 | reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN + scpdata_len; | ||
| 729 | reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN + scpdata_len; | ||
| 730 | |||
| 731 | return count; | ||
| 732 | } | ||
| 733 | |||
| 734 | static struct bin_attribute sys_reipl_fcp_scp_data_attr = { | ||
| 735 | .attr = { | ||
| 736 | .name = "scp_data", | ||
| 737 | .mode = S_IRUGO | S_IWUSR, | ||
| 738 | }, | ||
| 739 | .size = PAGE_SIZE, | ||
| 740 | .read = reipl_fcp_scpdata_read, | ||
| 741 | .write = reipl_fcp_scpdata_write, | ||
| 742 | }; | ||
| 743 | |||
| 629 | DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", | 744 | DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", |
| 630 | reipl_block_fcp->ipl_info.fcp.wwpn); | 745 | reipl_block_fcp->ipl_info.fcp.wwpn); |
| 631 | DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n", | 746 | DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n", |
| @@ -647,7 +762,6 @@ static struct attribute *reipl_fcp_attrs[] = { | |||
| 647 | }; | 762 | }; |
| 648 | 763 | ||
| 649 | static struct attribute_group reipl_fcp_attr_group = { | 764 | static struct attribute_group reipl_fcp_attr_group = { |
| 650 | .name = IPL_FCP_STR, | ||
| 651 | .attrs = reipl_fcp_attrs, | 765 | .attrs = reipl_fcp_attrs, |
| 652 | }; | 766 | }; |
| 653 | 767 | ||
| @@ -895,6 +1009,7 @@ static struct kobj_attribute reipl_type_attr = | |||
| 895 | __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); | 1009 | __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); |
| 896 | 1010 | ||
| 897 | static struct kset *reipl_kset; | 1011 | static struct kset *reipl_kset; |
| 1012 | static struct kset *reipl_fcp_kset; | ||
| 898 | 1013 | ||
| 899 | static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, | 1014 | static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, |
| 900 | const enum ipl_method m) | 1015 | const enum ipl_method m) |
| @@ -906,7 +1021,7 @@ static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, | |||
| 906 | 1021 | ||
| 907 | reipl_get_ascii_loadparm(loadparm, ipb); | 1022 | reipl_get_ascii_loadparm(loadparm, ipb); |
| 908 | reipl_get_ascii_nss_name(nss_name, ipb); | 1023 | reipl_get_ascii_nss_name(nss_name, ipb); |
| 909 | reipl_get_ascii_vmparm(vmparm, ipb); | 1024 | reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb); |
| 910 | 1025 | ||
| 911 | switch (m) { | 1026 | switch (m) { |
| 912 | case REIPL_METHOD_CCW_VM: | 1027 | case REIPL_METHOD_CCW_VM: |
| @@ -1076,23 +1191,44 @@ static int __init reipl_fcp_init(void) | |||
| 1076 | int rc; | 1191 | int rc; |
| 1077 | 1192 | ||
| 1078 | if (!diag308_set_works) { | 1193 | if (!diag308_set_works) { |
| 1079 | if (ipl_info.type == IPL_TYPE_FCP) | 1194 | if (ipl_info.type == IPL_TYPE_FCP) { |
| 1080 | make_attrs_ro(reipl_fcp_attrs); | 1195 | make_attrs_ro(reipl_fcp_attrs); |
| 1081 | else | 1196 | sys_reipl_fcp_scp_data_attr.attr.mode = S_IRUGO; |
| 1197 | } else | ||
| 1082 | return 0; | 1198 | return 0; |
| 1083 | } | 1199 | } |
| 1084 | 1200 | ||
| 1085 | reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); | 1201 | reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); |
| 1086 | if (!reipl_block_fcp) | 1202 | if (!reipl_block_fcp) |
| 1087 | return -ENOMEM; | 1203 | return -ENOMEM; |
| 1088 | rc = sysfs_create_group(&reipl_kset->kobj, &reipl_fcp_attr_group); | 1204 | |
| 1205 | /* sysfs: create fcp kset for mixing attr group and bin attrs */ | ||
| 1206 | reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL, | ||
| 1207 | &reipl_kset->kobj); | ||
| 1208 | if (!reipl_kset) { | ||
| 1209 | free_page((unsigned long) reipl_block_fcp); | ||
| 1210 | return -ENOMEM; | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | rc = sysfs_create_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group); | ||
| 1214 | if (rc) { | ||
| 1215 | kset_unregister(reipl_fcp_kset); | ||
| 1216 | free_page((unsigned long) reipl_block_fcp); | ||
| 1217 | return rc; | ||
| 1218 | } | ||
| 1219 | |||
| 1220 | rc = sysfs_create_bin_file(&reipl_fcp_kset->kobj, | ||
| 1221 | &sys_reipl_fcp_scp_data_attr); | ||
| 1089 | if (rc) { | 1222 | if (rc) { |
| 1090 | free_page((unsigned long)reipl_block_fcp); | 1223 | sysfs_remove_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group); |
| 1224 | kset_unregister(reipl_fcp_kset); | ||
| 1225 | free_page((unsigned long) reipl_block_fcp); | ||
| 1091 | return rc; | 1226 | return rc; |
| 1092 | } | 1227 | } |
| 1093 | if (ipl_info.type == IPL_TYPE_FCP) { | 1228 | |
| 1229 | if (ipl_info.type == IPL_TYPE_FCP) | ||
| 1094 | memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); | 1230 | memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); |
| 1095 | } else { | 1231 | else { |
| 1096 | reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; | 1232 | reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; |
| 1097 | reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; | 1233 | reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; |
| 1098 | reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; | 1234 | reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; |
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 2a0a5e97ba8c..dfe015d7398c 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S | |||
| @@ -11,111 +11,27 @@ | |||
| 11 | ftrace_stub: | 11 | ftrace_stub: |
| 12 | br %r14 | 12 | br %r14 |
| 13 | 13 | ||
| 14 | #ifdef CONFIG_64BIT | ||
| 15 | |||
| 16 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 17 | |||
| 18 | .globl _mcount | 14 | .globl _mcount |
| 19 | _mcount: | 15 | _mcount: |
| 20 | br %r14 | 16 | #ifdef CONFIG_DYNAMIC_FTRACE |
| 21 | |||
| 22 | .globl ftrace_caller | ||
| 23 | ftrace_caller: | ||
| 24 | larl %r1,function_trace_stop | ||
| 25 | icm %r1,0xf,0(%r1) | ||
| 26 | bnzr %r14 | ||
| 27 | stmg %r2,%r5,32(%r15) | ||
| 28 | stg %r14,112(%r15) | ||
| 29 | lgr %r1,%r15 | ||
| 30 | aghi %r15,-160 | ||
| 31 | stg %r1,__SF_BACKCHAIN(%r15) | ||
| 32 | lgr %r2,%r14 | ||
| 33 | lg %r3,168(%r15) | ||
| 34 | larl %r14,ftrace_dyn_func | ||
| 35 | lg %r14,0(%r14) | ||
| 36 | basr %r14,%r14 | ||
| 37 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 38 | .globl ftrace_graph_caller | ||
| 39 | ftrace_graph_caller: | ||
| 40 | # This unconditional branch gets runtime patched. Change only if | ||
| 41 | # you know what you are doing. See ftrace_enable_graph_caller(). | ||
| 42 | j 0f | ||
| 43 | lg %r2,272(%r15) | ||
| 44 | lg %r3,168(%r15) | ||
| 45 | brasl %r14,prepare_ftrace_return | ||
| 46 | stg %r2,168(%r15) | ||
| 47 | 0: | ||
| 48 | #endif | ||
| 49 | aghi %r15,160 | ||
| 50 | lmg %r2,%r5,32(%r15) | ||
| 51 | lg %r14,112(%r15) | ||
| 52 | br %r14 | 17 | br %r14 |
| 53 | 18 | ||
| 54 | .data | 19 | .data |
| 55 | .globl ftrace_dyn_func | 20 | .globl ftrace_dyn_func |
| 56 | ftrace_dyn_func: | 21 | ftrace_dyn_func: |
| 57 | .quad ftrace_stub | 22 | .long ftrace_stub |
| 58 | .previous | 23 | .previous |
| 59 | 24 | ||
| 60 | #else /* CONFIG_DYNAMIC_FTRACE */ | ||
| 61 | |||
| 62 | .globl _mcount | ||
| 63 | _mcount: | ||
| 64 | larl %r1,function_trace_stop | ||
| 65 | icm %r1,0xf,0(%r1) | ||
| 66 | bnzr %r14 | ||
| 67 | stmg %r2,%r5,32(%r15) | ||
| 68 | stg %r14,112(%r15) | ||
| 69 | lgr %r1,%r15 | ||
| 70 | aghi %r15,-160 | ||
| 71 | stg %r1,__SF_BACKCHAIN(%r15) | ||
| 72 | lgr %r2,%r14 | ||
| 73 | lg %r3,168(%r15) | ||
| 74 | larl %r14,ftrace_trace_function | ||
| 75 | lg %r14,0(%r14) | ||
| 76 | basr %r14,%r14 | ||
| 77 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 78 | lg %r2,272(%r15) | ||
| 79 | lg %r3,168(%r15) | ||
| 80 | brasl %r14,prepare_ftrace_return | ||
| 81 | stg %r2,168(%r15) | ||
| 82 | #endif | ||
| 83 | aghi %r15,160 | ||
| 84 | lmg %r2,%r5,32(%r15) | ||
| 85 | lg %r14,112(%r15) | ||
| 86 | br %r14 | ||
| 87 | |||
| 88 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
| 89 | |||
| 90 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 91 | |||
| 92 | .globl return_to_handler | ||
| 93 | return_to_handler: | ||
| 94 | stmg %r2,%r5,32(%r15) | ||
| 95 | lgr %r1,%r15 | ||
| 96 | aghi %r15,-160 | ||
| 97 | stg %r1,__SF_BACKCHAIN(%r15) | ||
| 98 | brasl %r14,ftrace_return_to_handler | ||
| 99 | aghi %r15,160 | ||
| 100 | lgr %r14,%r2 | ||
| 101 | lmg %r2,%r5,32(%r15) | ||
| 102 | br %r14 | ||
| 103 | |||
| 104 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
| 105 | |||
| 106 | #else /* CONFIG_64BIT */ | ||
| 107 | |||
| 108 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 109 | |||
| 110 | .globl _mcount | ||
| 111 | _mcount: | ||
| 112 | br %r14 | ||
| 113 | |||
| 114 | .globl ftrace_caller | 25 | .globl ftrace_caller |
| 115 | ftrace_caller: | 26 | ftrace_caller: |
| 27 | #endif | ||
| 116 | stm %r2,%r5,16(%r15) | 28 | stm %r2,%r5,16(%r15) |
| 117 | bras %r1,2f | 29 | bras %r1,2f |
| 30 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 31 | 0: .long ftrace_dyn_func | ||
| 32 | #else | ||
| 118 | 0: .long ftrace_trace_function | 33 | 0: .long ftrace_trace_function |
| 34 | #endif | ||
| 119 | 1: .long function_trace_stop | 35 | 1: .long function_trace_stop |
| 120 | 2: l %r2,1b-0b(%r1) | 36 | 2: l %r2,1b-0b(%r1) |
| 121 | icm %r2,0xf,0(%r2) | 37 | icm %r2,0xf,0(%r2) |
| @@ -131,53 +47,13 @@ ftrace_caller: | |||
| 131 | l %r14,0(%r14) | 47 | l %r14,0(%r14) |
| 132 | basr %r14,%r14 | 48 | basr %r14,%r14 |
| 133 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 49 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 50 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 134 | .globl ftrace_graph_caller | 51 | .globl ftrace_graph_caller |
| 135 | ftrace_graph_caller: | 52 | ftrace_graph_caller: |
| 136 | # This unconditional branch gets runtime patched. Change only if | 53 | # This unconditional branch gets runtime patched. Change only if |
| 137 | # you know what you are doing. See ftrace_enable_graph_caller(). | 54 | # you know what you are doing. See ftrace_enable_graph_caller(). |
| 138 | j 1f | 55 | j 1f |
| 139 | bras %r1,0f | ||
| 140 | .long prepare_ftrace_return | ||
| 141 | 0: l %r2,152(%r15) | ||
| 142 | l %r4,0(%r1) | ||
| 143 | l %r3,100(%r15) | ||
| 144 | basr %r14,%r4 | ||
| 145 | st %r2,100(%r15) | ||
| 146 | 1: | ||
| 147 | #endif | 56 | #endif |
| 148 | ahi %r15,96 | ||
| 149 | l %r14,56(%r15) | ||
| 150 | 3: lm %r2,%r5,16(%r15) | ||
| 151 | br %r14 | ||
| 152 | |||
| 153 | .data | ||
| 154 | .globl ftrace_dyn_func | ||
| 155 | ftrace_dyn_func: | ||
| 156 | .long ftrace_stub | ||
| 157 | .previous | ||
| 158 | |||
| 159 | #else /* CONFIG_DYNAMIC_FTRACE */ | ||
| 160 | |||
| 161 | .globl _mcount | ||
| 162 | _mcount: | ||
| 163 | stm %r2,%r5,16(%r15) | ||
| 164 | bras %r1,2f | ||
| 165 | 0: .long ftrace_trace_function | ||
| 166 | 1: .long function_trace_stop | ||
| 167 | 2: l %r2,1b-0b(%r1) | ||
| 168 | icm %r2,0xf,0(%r2) | ||
| 169 | jnz 3f | ||
| 170 | st %r14,56(%r15) | ||
| 171 | lr %r0,%r15 | ||
| 172 | ahi %r15,-96 | ||
| 173 | l %r3,100(%r15) | ||
| 174 | la %r2,0(%r14) | ||
| 175 | st %r0,__SF_BACKCHAIN(%r15) | ||
| 176 | la %r3,0(%r3) | ||
| 177 | l %r14,0b-0b(%r1) | ||
| 178 | l %r14,0(%r14) | ||
| 179 | basr %r14,%r14 | ||
| 180 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 181 | bras %r1,0f | 57 | bras %r1,0f |
| 182 | .long prepare_ftrace_return | 58 | .long prepare_ftrace_return |
| 183 | 0: l %r2,152(%r15) | 59 | 0: l %r2,152(%r15) |
| @@ -185,14 +61,13 @@ _mcount: | |||
| 185 | l %r3,100(%r15) | 61 | l %r3,100(%r15) |
| 186 | basr %r14,%r4 | 62 | basr %r14,%r4 |
| 187 | st %r2,100(%r15) | 63 | st %r2,100(%r15) |
| 64 | 1: | ||
| 188 | #endif | 65 | #endif |
| 189 | ahi %r15,96 | 66 | ahi %r15,96 |
| 190 | l %r14,56(%r15) | 67 | l %r14,56(%r15) |
| 191 | 3: lm %r2,%r5,16(%r15) | 68 | 3: lm %r2,%r5,16(%r15) |
| 192 | br %r14 | 69 | br %r14 |
| 193 | 70 | ||
| 194 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
| 195 | |||
| 196 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 71 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 197 | 72 | ||
| 198 | .globl return_to_handler | 73 | .globl return_to_handler |
| @@ -211,6 +86,4 @@ return_to_handler: | |||
| 211 | lm %r2,%r5,16(%r15) | 86 | lm %r2,%r5,16(%r15) |
| 212 | br %r14 | 87 | br %r14 |
| 213 | 88 | ||
| 214 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 89 | #endif |
| 215 | |||
| 216 | #endif /* CONFIG_64BIT */ | ||
diff --git a/arch/s390/kernel/mcount64.S b/arch/s390/kernel/mcount64.S new file mode 100644 index 000000000000..c37211c6092b --- /dev/null +++ b/arch/s390/kernel/mcount64.S | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | /* | ||
| 2 | * Copyright IBM Corp. 2008,2009 | ||
| 3 | * | ||
| 4 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, | ||
| 5 | * | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <asm/asm-offsets.h> | ||
| 9 | |||
| 10 | .globl ftrace_stub | ||
| 11 | ftrace_stub: | ||
| 12 | br %r14 | ||
| 13 | |||
| 14 | .globl _mcount | ||
| 15 | _mcount: | ||
| 16 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 17 | br %r14 | ||
| 18 | |||
| 19 | .data | ||
| 20 | .globl ftrace_dyn_func | ||
| 21 | ftrace_dyn_func: | ||
| 22 | .quad ftrace_stub | ||
| 23 | .previous | ||
| 24 | |||
| 25 | .globl ftrace_caller | ||
| 26 | ftrace_caller: | ||
| 27 | #endif | ||
| 28 | larl %r1,function_trace_stop | ||
| 29 | icm %r1,0xf,0(%r1) | ||
| 30 | bnzr %r14 | ||
| 31 | stmg %r2,%r5,32(%r15) | ||
| 32 | stg %r14,112(%r15) | ||
| 33 | lgr %r1,%r15 | ||
| 34 | aghi %r15,-160 | ||
| 35 | stg %r1,__SF_BACKCHAIN(%r15) | ||
| 36 | lgr %r2,%r14 | ||
| 37 | lg %r3,168(%r15) | ||
| 38 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 39 | larl %r14,ftrace_dyn_func | ||
| 40 | #else | ||
| 41 | larl %r14,ftrace_trace_function | ||
| 42 | #endif | ||
| 43 | lg %r14,0(%r14) | ||
| 44 | basr %r14,%r14 | ||
| 45 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 46 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 47 | .globl ftrace_graph_caller | ||
| 48 | ftrace_graph_caller: | ||
| 49 | # This unconditional branch gets runtime patched. Change only if | ||
| 50 | # you know what you are doing. See ftrace_enable_graph_caller(). | ||
| 51 | j 0f | ||
| 52 | #endif | ||
| 53 | lg %r2,272(%r15) | ||
| 54 | lg %r3,168(%r15) | ||
| 55 | brasl %r14,prepare_ftrace_return | ||
| 56 | stg %r2,168(%r15) | ||
| 57 | 0: | ||
| 58 | #endif | ||
| 59 | aghi %r15,160 | ||
| 60 | lmg %r2,%r5,32(%r15) | ||
| 61 | lg %r14,112(%r15) | ||
| 62 | br %r14 | ||
| 63 | |||
| 64 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 65 | |||
| 66 | .globl return_to_handler | ||
| 67 | return_to_handler: | ||
| 68 | stmg %r2,%r5,32(%r15) | ||
| 69 | lgr %r1,%r15 | ||
| 70 | aghi %r15,-160 | ||
| 71 | stg %r1,__SF_BACKCHAIN(%r15) | ||
| 72 | brasl %r14,ftrace_return_to_handler | ||
| 73 | aghi %r15,160 | ||
| 74 | lgr %r14,%r2 | ||
| 75 | lmg %r2,%r5,32(%r15) | ||
| 76 | br %r14 | ||
| 77 | |||
| 78 | #endif | ||
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 43acd73105b7..f3ddd7ac06c5 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
| @@ -51,6 +51,9 @@ | |||
| 51 | #include "compat_ptrace.h" | 51 | #include "compat_ptrace.h" |
| 52 | #endif | 52 | #endif |
| 53 | 53 | ||
| 54 | #define CREATE_TRACE_POINTS | ||
| 55 | #include <trace/events/syscalls.h> | ||
| 56 | |||
| 54 | enum s390_regset { | 57 | enum s390_regset { |
| 55 | REGSET_GENERAL, | 58 | REGSET_GENERAL, |
| 56 | REGSET_FP, | 59 | REGSET_FP, |
| @@ -661,8 +664,8 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) | |||
| 661 | ret = -1; | 664 | ret = -1; |
| 662 | } | 665 | } |
| 663 | 666 | ||
| 664 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) | 667 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
| 665 | ftrace_syscall_enter(regs); | 668 | trace_sys_enter(regs, regs->gprs[2]); |
| 666 | 669 | ||
| 667 | if (unlikely(current->audit_context)) | 670 | if (unlikely(current->audit_context)) |
| 668 | audit_syscall_entry(is_compat_task() ? | 671 | audit_syscall_entry(is_compat_task() ? |
| @@ -679,8 +682,8 @@ asmlinkage void do_syscall_trace_exit(struct pt_regs *regs) | |||
| 679 | audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), | 682 | audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), |
| 680 | regs->gprs[2]); | 683 | regs->gprs[2]); |
| 681 | 684 | ||
| 682 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) | 685 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
| 683 | ftrace_syscall_exit(regs); | 686 | trace_sys_exit(regs, regs->gprs[2]); |
| 684 | 687 | ||
| 685 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 688 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
| 686 | tracehook_report_syscall_exit(regs, 0); | 689 | tracehook_report_syscall_exit(regs, 0); |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 9717717c6fea..9ed13a1ed376 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
| @@ -154,6 +154,16 @@ static int __init condev_setup(char *str) | |||
| 154 | 154 | ||
| 155 | __setup("condev=", condev_setup); | 155 | __setup("condev=", condev_setup); |
| 156 | 156 | ||
| 157 | static void __init set_preferred_console(void) | ||
| 158 | { | ||
| 159 | if (MACHINE_IS_KVM) | ||
| 160 | add_preferred_console("hvc", 0, NULL); | ||
| 161 | else if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP) | ||
| 162 | add_preferred_console("ttyS", 0, NULL); | ||
| 163 | else if (CONSOLE_IS_3270) | ||
| 164 | add_preferred_console("tty3270", 0, NULL); | ||
| 165 | } | ||
| 166 | |||
| 157 | static int __init conmode_setup(char *str) | 167 | static int __init conmode_setup(char *str) |
| 158 | { | 168 | { |
| 159 | #if defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE) | 169 | #if defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE) |
| @@ -168,6 +178,7 @@ static int __init conmode_setup(char *str) | |||
| 168 | if (strncmp(str, "3270", 5) == 0) | 178 | if (strncmp(str, "3270", 5) == 0) |
| 169 | SET_CONSOLE_3270; | 179 | SET_CONSOLE_3270; |
| 170 | #endif | 180 | #endif |
| 181 | set_preferred_console(); | ||
| 171 | return 1; | 182 | return 1; |
| 172 | } | 183 | } |
| 173 | 184 | ||
| @@ -780,9 +791,6 @@ static void __init setup_hwcaps(void) | |||
| 780 | void __init | 791 | void __init |
| 781 | setup_arch(char **cmdline_p) | 792 | setup_arch(char **cmdline_p) |
| 782 | { | 793 | { |
| 783 | /* set up preferred console */ | ||
| 784 | add_preferred_console("ttyS", 0, NULL); | ||
| 785 | |||
| 786 | /* | 794 | /* |
| 787 | * print what head.S has found out about the machine | 795 | * print what head.S has found out about the machine |
| 788 | */ | 796 | */ |
| @@ -802,11 +810,9 @@ setup_arch(char **cmdline_p) | |||
| 802 | if (MACHINE_IS_VM) | 810 | if (MACHINE_IS_VM) |
| 803 | pr_info("Linux is running as a z/VM " | 811 | pr_info("Linux is running as a z/VM " |
| 804 | "guest operating system in 64-bit mode\n"); | 812 | "guest operating system in 64-bit mode\n"); |
| 805 | else if (MACHINE_IS_KVM) { | 813 | else if (MACHINE_IS_KVM) |
| 806 | pr_info("Linux is running under KVM in 64-bit mode\n"); | 814 | pr_info("Linux is running under KVM in 64-bit mode\n"); |
| 807 | add_preferred_console("hvc", 0, NULL); | 815 | else |
| 808 | s390_virtio_console_init(); | ||
| 809 | } else | ||
| 810 | pr_info("Linux is running natively in 64-bit mode\n"); | 816 | pr_info("Linux is running natively in 64-bit mode\n"); |
| 811 | #endif /* CONFIG_64BIT */ | 817 | #endif /* CONFIG_64BIT */ |
| 812 | 818 | ||
| @@ -851,6 +857,7 @@ setup_arch(char **cmdline_p) | |||
| 851 | 857 | ||
| 852 | /* Setup default console */ | 858 | /* Setup default console */ |
| 853 | conmode_default(); | 859 | conmode_default(); |
| 860 | set_preferred_console(); | ||
| 854 | 861 | ||
| 855 | /* Setup zfcpdump support */ | 862 | /* Setup zfcpdump support */ |
| 856 | setup_zfcpdump(console_devno); | 863 | setup_zfcpdump(console_devno); |
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 062bd64e65fa..6b4fef877f9d 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
| @@ -536,4 +536,6 @@ void do_notify_resume(struct pt_regs *regs) | |||
| 536 | { | 536 | { |
| 537 | clear_thread_flag(TIF_NOTIFY_RESUME); | 537 | clear_thread_flag(TIF_NOTIFY_RESUME); |
| 538 | tracehook_notify_resume(regs); | 538 | tracehook_notify_resume(regs); |
| 539 | if (current->replacement_session_keyring) | ||
| 540 | key_replace_session_keyring(); | ||
| 539 | } | 541 | } |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index be2cae083406..56c16876b919 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | #include <asm/sclp.h> | 49 | #include <asm/sclp.h> |
| 50 | #include <asm/cputime.h> | 50 | #include <asm/cputime.h> |
| 51 | #include <asm/vdso.h> | 51 | #include <asm/vdso.h> |
| 52 | #include <asm/cpu.h> | ||
| 52 | #include "entry.h" | 53 | #include "entry.h" |
| 53 | 54 | ||
| 54 | static struct task_struct *current_set[NR_CPUS]; | 55 | static struct task_struct *current_set[NR_CPUS]; |
| @@ -70,6 +71,23 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); | |||
| 70 | 71 | ||
| 71 | static void smp_ext_bitcall(int, ec_bit_sig); | 72 | static void smp_ext_bitcall(int, ec_bit_sig); |
| 72 | 73 | ||
| 74 | static int cpu_stopped(int cpu) | ||
| 75 | { | ||
| 76 | __u32 status; | ||
| 77 | |||
| 78 | switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { | ||
| 79 | case sigp_order_code_accepted: | ||
| 80 | case sigp_status_stored: | ||
| 81 | /* Check for stopped and check stop state */ | ||
| 82 | if (status & 0x50) | ||
| 83 | return 1; | ||
| 84 | break; | ||
| 85 | default: | ||
| 86 | break; | ||
| 87 | } | ||
| 88 | return 0; | ||
| 89 | } | ||
| 90 | |||
| 73 | void smp_send_stop(void) | 91 | void smp_send_stop(void) |
| 74 | { | 92 | { |
| 75 | int cpu, rc; | 93 | int cpu, rc; |
| @@ -86,7 +104,7 @@ void smp_send_stop(void) | |||
| 86 | rc = signal_processor(cpu, sigp_stop); | 104 | rc = signal_processor(cpu, sigp_stop); |
| 87 | } while (rc == sigp_busy); | 105 | } while (rc == sigp_busy); |
| 88 | 106 | ||
| 89 | while (!smp_cpu_not_running(cpu)) | 107 | while (!cpu_stopped(cpu)) |
| 90 | cpu_relax(); | 108 | cpu_relax(); |
| 91 | } | 109 | } |
| 92 | } | 110 | } |
| @@ -269,19 +287,6 @@ static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { } | |||
| 269 | 287 | ||
| 270 | #endif /* CONFIG_ZFCPDUMP */ | 288 | #endif /* CONFIG_ZFCPDUMP */ |
| 271 | 289 | ||
| 272 | static int cpu_stopped(int cpu) | ||
| 273 | { | ||
| 274 | __u32 status; | ||
| 275 | |||
| 276 | /* Check for stopped state */ | ||
| 277 | if (signal_processor_ps(&status, 0, cpu, sigp_sense) == | ||
| 278 | sigp_status_stored) { | ||
| 279 | if (status & 0x40) | ||
| 280 | return 1; | ||
| 281 | } | ||
| 282 | return 0; | ||
| 283 | } | ||
| 284 | |||
| 285 | static int cpu_known(int cpu_id) | 290 | static int cpu_known(int cpu_id) |
| 286 | { | 291 | { |
| 287 | int cpu; | 292 | int cpu; |
| @@ -300,7 +305,7 @@ static int smp_rescan_cpus_sigp(cpumask_t avail) | |||
| 300 | logical_cpu = cpumask_first(&avail); | 305 | logical_cpu = cpumask_first(&avail); |
| 301 | if (logical_cpu >= nr_cpu_ids) | 306 | if (logical_cpu >= nr_cpu_ids) |
| 302 | return 0; | 307 | return 0; |
| 303 | for (cpu_id = 0; cpu_id <= 65535; cpu_id++) { | 308 | for (cpu_id = 0; cpu_id <= MAX_CPU_ADDRESS; cpu_id++) { |
| 304 | if (cpu_known(cpu_id)) | 309 | if (cpu_known(cpu_id)) |
| 305 | continue; | 310 | continue; |
| 306 | __cpu_logical_map[logical_cpu] = cpu_id; | 311 | __cpu_logical_map[logical_cpu] = cpu_id; |
| @@ -379,7 +384,7 @@ static void __init smp_detect_cpus(void) | |||
| 379 | /* Use sigp detection algorithm if sclp doesn't work. */ | 384 | /* Use sigp detection algorithm if sclp doesn't work. */ |
| 380 | if (sclp_get_cpu_info(info)) { | 385 | if (sclp_get_cpu_info(info)) { |
| 381 | smp_use_sigp_detection = 1; | 386 | smp_use_sigp_detection = 1; |
| 382 | for (cpu = 0; cpu <= 65535; cpu++) { | 387 | for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) { |
| 383 | if (cpu == boot_cpu_addr) | 388 | if (cpu == boot_cpu_addr) |
| 384 | continue; | 389 | continue; |
| 385 | __cpu_logical_map[CPU_INIT_NO] = cpu; | 390 | __cpu_logical_map[CPU_INIT_NO] = cpu; |
| @@ -635,7 +640,7 @@ int __cpu_disable(void) | |||
| 635 | void __cpu_die(unsigned int cpu) | 640 | void __cpu_die(unsigned int cpu) |
| 636 | { | 641 | { |
| 637 | /* Wait until target cpu is down */ | 642 | /* Wait until target cpu is down */ |
| 638 | while (!smp_cpu_not_running(cpu)) | 643 | while (!cpu_stopped(cpu)) |
| 639 | cpu_relax(); | 644 | cpu_relax(); |
| 640 | smp_free_lowcore(cpu); | 645 | smp_free_lowcore(cpu); |
| 641 | pr_info("Processor %d stopped\n", cpu); | 646 | pr_info("Processor %d stopped\n", cpu); |
diff --git a/arch/s390/power/swsusp.c b/arch/s390/kernel/suspend.c index bd1f5c6b0b8c..086bee970cae 100644 --- a/arch/s390/power/swsusp.c +++ b/arch/s390/kernel/suspend.c | |||
| @@ -1,13 +1,44 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Support for suspend and resume on s390 | 2 | * Suspend support specific for s390. |
| 3 | * | 3 | * |
| 4 | * Copyright IBM Corp. 2009 | 4 | * Copyright IBM Corp. 2009 |
| 5 | * | 5 | * |
| 6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> | 6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> |
| 7 | * | ||
| 8 | */ | 7 | */ |
| 9 | 8 | ||
| 9 | #include <linux/suspend.h> | ||
| 10 | #include <linux/reboot.h> | ||
| 11 | #include <linux/pfn.h> | ||
| 12 | #include <linux/mm.h> | ||
| 13 | #include <asm/sections.h> | ||
| 10 | #include <asm/system.h> | 14 | #include <asm/system.h> |
| 15 | #include <asm/ipl.h> | ||
| 16 | |||
| 17 | /* | ||
| 18 | * References to section boundaries | ||
| 19 | */ | ||
| 20 | extern const void __nosave_begin, __nosave_end; | ||
| 21 | |||
| 22 | /* | ||
| 23 | * check if given pfn is in the 'nosave' or in the read only NSS section | ||
| 24 | */ | ||
| 25 | int pfn_is_nosave(unsigned long pfn) | ||
| 26 | { | ||
| 27 | unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; | ||
| 28 | unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) | ||
| 29 | >> PAGE_SHIFT; | ||
| 30 | unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1; | ||
| 31 | unsigned long stext_pfn = PFN_DOWN(__pa(&_stext)); | ||
| 32 | |||
| 33 | if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn) | ||
| 34 | return 1; | ||
| 35 | if (pfn >= stext_pfn && pfn <= eshared_pfn) { | ||
| 36 | if (ipl_info.type == IPL_TYPE_NSS) | ||
| 37 | return 1; | ||
| 38 | } else if ((tprot(pfn * PAGE_SIZE) && pfn > 0)) | ||
| 39 | return 1; | ||
| 40 | return 0; | ||
| 41 | } | ||
| 11 | 42 | ||
| 12 | void save_processor_state(void) | 43 | void save_processor_state(void) |
| 13 | { | 44 | { |
diff --git a/arch/s390/power/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S index b26df5c5933e..7cd6b096f0d1 100644 --- a/arch/s390/power/swsusp_asm64.S +++ b/arch/s390/kernel/swsusp_asm64.S | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | * This function runs with disabled interrupts. | 21 | * This function runs with disabled interrupts. |
| 22 | */ | 22 | */ |
| 23 | .section .text | 23 | .section .text |
| 24 | .align 2 | 24 | .align 4 |
| 25 | .globl swsusp_arch_suspend | 25 | .globl swsusp_arch_suspend |
| 26 | swsusp_arch_suspend: | 26 | swsusp_arch_suspend: |
| 27 | stmg %r6,%r15,__SF_GPRS(%r15) | 27 | stmg %r6,%r15,__SF_GPRS(%r15) |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 9693d98d4d4a..e3dc28b8075d 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
| @@ -60,6 +60,7 @@ | |||
| 60 | #define TICK_SIZE tick | 60 | #define TICK_SIZE tick |
| 61 | 61 | ||
| 62 | u64 sched_clock_base_cc = -1; /* Force to data section. */ | 62 | u64 sched_clock_base_cc = -1; /* Force to data section. */ |
| 63 | EXPORT_SYMBOL_GPL(sched_clock_base_cc); | ||
| 63 | 64 | ||
| 64 | static DEFINE_PER_CPU(struct clock_event_device, comparators); | 65 | static DEFINE_PER_CPU(struct clock_event_device, comparators); |
| 65 | 66 | ||
| @@ -68,7 +69,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators); | |||
| 68 | */ | 69 | */ |
| 69 | unsigned long long notrace sched_clock(void) | 70 | unsigned long long notrace sched_clock(void) |
| 70 | { | 71 | { |
| 71 | return ((get_clock_xt() - sched_clock_base_cc) * 125) >> 9; | 72 | return (get_clock_monotonic() * 125) >> 9; |
| 72 | } | 73 | } |
| 73 | 74 | ||
| 74 | /* | 75 | /* |
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index a53db23ee092..7315f9e67e1d 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S | |||
| @@ -52,55 +52,18 @@ SECTIONS | |||
| 52 | . = ALIGN(PAGE_SIZE); | 52 | . = ALIGN(PAGE_SIZE); |
| 53 | _eshared = .; /* End of shareable data */ | 53 | _eshared = .; /* End of shareable data */ |
| 54 | 54 | ||
| 55 | . = ALIGN(16); /* Exception table */ | 55 | EXCEPTION_TABLE(16) :data |
| 56 | __ex_table : { | ||
| 57 | __start___ex_table = .; | ||
| 58 | *(__ex_table) | ||
| 59 | __stop___ex_table = .; | ||
| 60 | } :data | ||
| 61 | |||
| 62 | .data : { /* Data */ | ||
| 63 | DATA_DATA | ||
| 64 | CONSTRUCTORS | ||
| 65 | } | ||
| 66 | |||
| 67 | . = ALIGN(PAGE_SIZE); | ||
| 68 | .data_nosave : { | ||
| 69 | __nosave_begin = .; | ||
| 70 | *(.data.nosave) | ||
| 71 | } | ||
| 72 | . = ALIGN(PAGE_SIZE); | ||
| 73 | __nosave_end = .; | ||
| 74 | |||
| 75 | . = ALIGN(PAGE_SIZE); | ||
| 76 | .data.page_aligned : { | ||
| 77 | *(.data.idt) | ||
| 78 | } | ||
| 79 | 56 | ||
| 80 | . = ALIGN(0x100); | 57 | RW_DATA_SECTION(0x100, PAGE_SIZE, THREAD_SIZE) |
| 81 | .data.cacheline_aligned : { | ||
| 82 | *(.data.cacheline_aligned) | ||
| 83 | } | ||
| 84 | 58 | ||
| 85 | . = ALIGN(0x100); | ||
| 86 | .data.read_mostly : { | ||
| 87 | *(.data.read_mostly) | ||
| 88 | } | ||
| 89 | _edata = .; /* End of data section */ | 59 | _edata = .; /* End of data section */ |
| 90 | 60 | ||
| 91 | . = ALIGN(THREAD_SIZE); /* init_task */ | ||
| 92 | .data.init_task : { | ||
| 93 | *(.data.init_task) | ||
| 94 | } | ||
| 95 | |||
| 96 | /* will be freed after init */ | 61 | /* will be freed after init */ |
| 97 | . = ALIGN(PAGE_SIZE); /* Init code and data */ | 62 | . = ALIGN(PAGE_SIZE); /* Init code and data */ |
| 98 | __init_begin = .; | 63 | __init_begin = .; |
| 99 | .init.text : { | 64 | |
| 100 | _sinittext = .; | 65 | INIT_TEXT_SECTION(PAGE_SIZE) |
| 101 | INIT_TEXT | 66 | |
| 102 | _einittext = .; | ||
| 103 | } | ||
| 104 | /* | 67 | /* |
| 105 | * .exit.text is discarded at runtime, not link time, | 68 | * .exit.text is discarded at runtime, not link time, |
| 106 | * to deal with references from __bug_table | 69 | * to deal with references from __bug_table |
| @@ -111,49 +74,13 @@ SECTIONS | |||
| 111 | 74 | ||
| 112 | /* early.c uses stsi, which requires page aligned data. */ | 75 | /* early.c uses stsi, which requires page aligned data. */ |
| 113 | . = ALIGN(PAGE_SIZE); | 76 | . = ALIGN(PAGE_SIZE); |
| 114 | .init.data : { | 77 | INIT_DATA_SECTION(0x100) |
| 115 | INIT_DATA | ||
| 116 | } | ||
| 117 | . = ALIGN(0x100); | ||
| 118 | .init.setup : { | ||
| 119 | __setup_start = .; | ||
| 120 | *(.init.setup) | ||
| 121 | __setup_end = .; | ||
| 122 | } | ||
| 123 | .initcall.init : { | ||
| 124 | __initcall_start = .; | ||
| 125 | INITCALLS | ||
| 126 | __initcall_end = .; | ||
| 127 | } | ||
| 128 | |||
| 129 | .con_initcall.init : { | ||
| 130 | __con_initcall_start = .; | ||
| 131 | *(.con_initcall.init) | ||
| 132 | __con_initcall_end = .; | ||
| 133 | } | ||
| 134 | SECURITY_INIT | ||
| 135 | |||
| 136 | #ifdef CONFIG_BLK_DEV_INITRD | ||
| 137 | . = ALIGN(0x100); | ||
| 138 | .init.ramfs : { | ||
| 139 | __initramfs_start = .; | ||
| 140 | *(.init.ramfs) | ||
| 141 | . = ALIGN(2); | ||
| 142 | __initramfs_end = .; | ||
| 143 | } | ||
| 144 | #endif | ||
| 145 | 78 | ||
| 146 | PERCPU(PAGE_SIZE) | 79 | PERCPU(PAGE_SIZE) |
| 147 | . = ALIGN(PAGE_SIZE); | 80 | . = ALIGN(PAGE_SIZE); |
| 148 | __init_end = .; /* freed after init ends here */ | 81 | __init_end = .; /* freed after init ends here */ |
| 149 | 82 | ||
| 150 | /* BSS */ | 83 | BSS_SECTION(0, 2, 0) |
| 151 | .bss : { | ||
| 152 | __bss_start = .; | ||
| 153 | *(.bss) | ||
| 154 | . = ALIGN(2); | ||
| 155 | __bss_stop = .; | ||
| 156 | } | ||
| 157 | 84 | ||
| 158 | _end = . ; | 85 | _end = . ; |
| 159 | 86 | ||
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index 3e260b7e37b2..bf164fc21864 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig | |||
| @@ -1,11 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # KVM configuration | 2 | # KVM configuration |
| 3 | # | 3 | # |
| 4 | config HAVE_KVM | 4 | source "virt/kvm/Kconfig" |
| 5 | bool | ||
| 6 | |||
| 7 | config HAVE_KVM_IRQCHIP | ||
| 8 | bool | ||
| 9 | 5 | ||
| 10 | menuconfig VIRTUALIZATION | 6 | menuconfig VIRTUALIZATION |
| 11 | bool "Virtualization" | 7 | bool "Virtualization" |
| @@ -38,9 +34,6 @@ config KVM | |||
| 38 | 34 | ||
| 39 | If unsure, say N. | 35 | If unsure, say N. |
| 40 | 36 | ||
| 41 | config KVM_TRACE | ||
| 42 | bool | ||
| 43 | |||
| 44 | # OK, it's a little counter-intuitive to do this, but it puts it neatly under | 37 | # OK, it's a little counter-intuitive to do this, but it puts it neatly under |
| 45 | # the virtualization menu. | 38 | # the virtualization menu. |
| 46 | source drivers/virtio/Kconfig | 39 | source drivers/virtio/Kconfig |
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h index ed60f3a74a85..03c716a0f01f 100644 --- a/arch/s390/kvm/gaccess.h +++ b/arch/s390/kvm/gaccess.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * gaccess.h - access guest memory | 2 | * gaccess.h - access guest memory |
| 3 | * | 3 | * |
| 4 | * Copyright IBM Corp. 2008 | 4 | * Copyright IBM Corp. 2008,2009 |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License (version 2 only) | 7 | * it under the terms of the GNU General Public License (version 2 only) |
| @@ -16,13 +16,14 @@ | |||
| 16 | #include <linux/compiler.h> | 16 | #include <linux/compiler.h> |
| 17 | #include <linux/kvm_host.h> | 17 | #include <linux/kvm_host.h> |
| 18 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
| 19 | #include "kvm-s390.h" | ||
| 19 | 20 | ||
| 20 | static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu, | 21 | static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu, |
| 21 | unsigned long guestaddr) | 22 | unsigned long guestaddr) |
| 22 | { | 23 | { |
| 23 | unsigned long prefix = vcpu->arch.sie_block->prefix; | 24 | unsigned long prefix = vcpu->arch.sie_block->prefix; |
| 24 | unsigned long origin = vcpu->kvm->arch.guest_origin; | 25 | unsigned long origin = vcpu->arch.sie_block->gmsor; |
| 25 | unsigned long memsize = vcpu->kvm->arch.guest_memsize; | 26 | unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu); |
| 26 | 27 | ||
| 27 | if (guestaddr < 2 * PAGE_SIZE) | 28 | if (guestaddr < 2 * PAGE_SIZE) |
| 28 | guestaddr += prefix; | 29 | guestaddr += prefix; |
| @@ -158,8 +159,8 @@ static inline int copy_to_guest(struct kvm_vcpu *vcpu, unsigned long guestdest, | |||
| 158 | const void *from, unsigned long n) | 159 | const void *from, unsigned long n) |
| 159 | { | 160 | { |
| 160 | unsigned long prefix = vcpu->arch.sie_block->prefix; | 161 | unsigned long prefix = vcpu->arch.sie_block->prefix; |
| 161 | unsigned long origin = vcpu->kvm->arch.guest_origin; | 162 | unsigned long origin = vcpu->arch.sie_block->gmsor; |
| 162 | unsigned long memsize = vcpu->kvm->arch.guest_memsize; | 163 | unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu); |
| 163 | 164 | ||
| 164 | if ((guestdest < 2 * PAGE_SIZE) && (guestdest + n > 2 * PAGE_SIZE)) | 165 | if ((guestdest < 2 * PAGE_SIZE) && (guestdest + n > 2 * PAGE_SIZE)) |
| 165 | goto slowpath; | 166 | goto slowpath; |
| @@ -209,8 +210,8 @@ static inline int copy_from_guest(struct kvm_vcpu *vcpu, void *to, | |||
| 209 | unsigned long guestsrc, unsigned long n) | 210 | unsigned long guestsrc, unsigned long n) |
| 210 | { | 211 | { |
| 211 | unsigned long prefix = vcpu->arch.sie_block->prefix; | 212 | unsigned long prefix = vcpu->arch.sie_block->prefix; |
| 212 | unsigned long origin = vcpu->kvm->arch.guest_origin; | 213 | unsigned long origin = vcpu->arch.sie_block->gmsor; |
| 213 | unsigned long memsize = vcpu->kvm->arch.guest_memsize; | 214 | unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu); |
| 214 | 215 | ||
| 215 | if ((guestsrc < 2 * PAGE_SIZE) && (guestsrc + n > 2 * PAGE_SIZE)) | 216 | if ((guestsrc < 2 * PAGE_SIZE) && (guestsrc + n > 2 * PAGE_SIZE)) |
| 216 | goto slowpath; | 217 | goto slowpath; |
| @@ -244,8 +245,8 @@ static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu, | |||
| 244 | unsigned long guestdest, | 245 | unsigned long guestdest, |
| 245 | const void *from, unsigned long n) | 246 | const void *from, unsigned long n) |
| 246 | { | 247 | { |
| 247 | unsigned long origin = vcpu->kvm->arch.guest_origin; | 248 | unsigned long origin = vcpu->arch.sie_block->gmsor; |
| 248 | unsigned long memsize = vcpu->kvm->arch.guest_memsize; | 249 | unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu); |
| 249 | 250 | ||
| 250 | if (guestdest + n > memsize) | 251 | if (guestdest + n > memsize) |
| 251 | return -EFAULT; | 252 | return -EFAULT; |
| @@ -262,8 +263,8 @@ static inline int copy_from_guest_absolute(struct kvm_vcpu *vcpu, void *to, | |||
| 262 | unsigned long guestsrc, | 263 | unsigned long guestsrc, |
| 263 | unsigned long n) | 264 | unsigned long n) |
| 264 | { | 265 | { |
| 265 | unsigned long origin = vcpu->kvm->arch.guest_origin; | 266 | unsigned long origin = vcpu->arch.sie_block->gmsor; |
| 266 | unsigned long memsize = vcpu->kvm->arch.guest_memsize; | 267 | unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu); |
| 267 | 268 | ||
| 268 | if (guestsrc + n > memsize) | 269 | if (guestsrc + n > memsize) |
| 269 | return -EFAULT; | 270 | return -EFAULT; |
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 98997ccba501..ba9d8a7bc1ac 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * intercept.c - in-kernel handling for sie intercepts | 2 | * intercept.c - in-kernel handling for sie intercepts |
| 3 | * | 3 | * |
| 4 | * Copyright IBM Corp. 2008 | 4 | * Copyright IBM Corp. 2008,2009 |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License (version 2 only) | 7 | * it under the terms of the GNU General Public License (version 2 only) |
| @@ -128,7 +128,7 @@ static int handle_noop(struct kvm_vcpu *vcpu) | |||
| 128 | 128 | ||
| 129 | static int handle_stop(struct kvm_vcpu *vcpu) | 129 | static int handle_stop(struct kvm_vcpu *vcpu) |
| 130 | { | 130 | { |
| 131 | int rc; | 131 | int rc = 0; |
| 132 | 132 | ||
| 133 | vcpu->stat.exit_stop_request++; | 133 | vcpu->stat.exit_stop_request++; |
| 134 | atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); | 134 | atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); |
| @@ -141,12 +141,18 @@ static int handle_stop(struct kvm_vcpu *vcpu) | |||
| 141 | rc = -ENOTSUPP; | 141 | rc = -ENOTSUPP; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | if (vcpu->arch.local_int.action_bits & ACTION_RELOADVCPU_ON_STOP) { | ||
| 145 | vcpu->arch.local_int.action_bits &= ~ACTION_RELOADVCPU_ON_STOP; | ||
| 146 | rc = SIE_INTERCEPT_RERUNVCPU; | ||
| 147 | vcpu->run->exit_reason = KVM_EXIT_INTR; | ||
| 148 | } | ||
| 149 | |||
| 144 | if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) { | 150 | if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) { |
| 145 | vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP; | 151 | vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP; |
| 146 | VCPU_EVENT(vcpu, 3, "%s", "cpu stopped"); | 152 | VCPU_EVENT(vcpu, 3, "%s", "cpu stopped"); |
| 147 | rc = -ENOTSUPP; | 153 | rc = -ENOTSUPP; |
| 148 | } else | 154 | } |
| 149 | rc = 0; | 155 | |
| 150 | spin_unlock_bh(&vcpu->arch.local_int.lock); | 156 | spin_unlock_bh(&vcpu->arch.local_int.lock); |
| 151 | return rc; | 157 | return rc; |
| 152 | } | 158 | } |
| @@ -158,9 +164,9 @@ static int handle_validity(struct kvm_vcpu *vcpu) | |||
| 158 | 164 | ||
| 159 | vcpu->stat.exit_validity++; | 165 | vcpu->stat.exit_validity++; |
| 160 | if ((viwhy == 0x37) && (vcpu->arch.sie_block->prefix | 166 | if ((viwhy == 0x37) && (vcpu->arch.sie_block->prefix |
| 161 | <= vcpu->kvm->arch.guest_memsize - 2*PAGE_SIZE)){ | 167 | <= kvm_s390_vcpu_get_memsize(vcpu) - 2*PAGE_SIZE)) { |
| 162 | rc = fault_in_pages_writeable((char __user *) | 168 | rc = fault_in_pages_writeable((char __user *) |
| 163 | vcpu->kvm->arch.guest_origin + | 169 | vcpu->arch.sie_block->gmsor + |
| 164 | vcpu->arch.sie_block->prefix, | 170 | vcpu->arch.sie_block->prefix, |
| 165 | 2*PAGE_SIZE); | 171 | 2*PAGE_SIZE); |
| 166 | if (rc) | 172 | if (rc) |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 4d613415c435..2c2f98353415 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
| @@ -283,7 +283,7 @@ static int __try_deliver_ckc_interrupt(struct kvm_vcpu *vcpu) | |||
| 283 | return 1; | 283 | return 1; |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu) | 286 | static int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu) |
| 287 | { | 287 | { |
| 288 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | 288 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; |
| 289 | struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int; | 289 | struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int; |
| @@ -320,12 +320,6 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu) | |||
| 320 | return rc; | 320 | return rc; |
| 321 | } | 321 | } |
| 322 | 322 | ||
| 323 | int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu) | ||
| 324 | { | ||
| 325 | /* do real check here */ | ||
| 326 | return 1; | ||
| 327 | } | ||
| 328 | |||
| 329 | int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) | 323 | int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) |
| 330 | { | 324 | { |
| 331 | return 0; | 325 | return 0; |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 90d9d1ba258b..07ced89740d7 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * s390host.c -- hosting zSeries kernel virtual machines | 2 | * s390host.c -- hosting zSeries kernel virtual machines |
| 3 | * | 3 | * |
| 4 | * Copyright IBM Corp. 2008 | 4 | * Copyright IBM Corp. 2008,2009 |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License (version 2 only) | 7 | * it under the terms of the GNU General Public License (version 2 only) |
| @@ -10,6 +10,7 @@ | |||
| 10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 10 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
| 11 | * Christian Borntraeger <borntraeger@de.ibm.com> | 11 | * Christian Borntraeger <borntraeger@de.ibm.com> |
| 12 | * Heiko Carstens <heiko.carstens@de.ibm.com> | 12 | * Heiko Carstens <heiko.carstens@de.ibm.com> |
| 13 | * Christian Ehrhardt <ehrhardt@de.ibm.com> | ||
| 13 | */ | 14 | */ |
| 14 | 15 | ||
| 15 | #include <linux/compiler.h> | 16 | #include <linux/compiler.h> |
| @@ -210,13 +211,17 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) | |||
| 210 | static void kvm_free_vcpus(struct kvm *kvm) | 211 | static void kvm_free_vcpus(struct kvm *kvm) |
| 211 | { | 212 | { |
| 212 | unsigned int i; | 213 | unsigned int i; |
| 214 | struct kvm_vcpu *vcpu; | ||
| 213 | 215 | ||
| 214 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | 216 | kvm_for_each_vcpu(i, vcpu, kvm) |
| 215 | if (kvm->vcpus[i]) { | 217 | kvm_arch_vcpu_destroy(vcpu); |
| 216 | kvm_arch_vcpu_destroy(kvm->vcpus[i]); | 218 | |
| 217 | kvm->vcpus[i] = NULL; | 219 | mutex_lock(&kvm->lock); |
| 218 | } | 220 | for (i = 0; i < atomic_read(&kvm->online_vcpus); i++) |
| 219 | } | 221 | kvm->vcpus[i] = NULL; |
| 222 | |||
| 223 | atomic_set(&kvm->online_vcpus, 0); | ||
| 224 | mutex_unlock(&kvm->lock); | ||
| 220 | } | 225 | } |
| 221 | 226 | ||
| 222 | void kvm_arch_sync_events(struct kvm *kvm) | 227 | void kvm_arch_sync_events(struct kvm *kvm) |
| @@ -278,16 +283,10 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu) | |||
| 278 | vcpu->arch.sie_block->gbea = 1; | 283 | vcpu->arch.sie_block->gbea = 1; |
| 279 | } | 284 | } |
| 280 | 285 | ||
| 281 | /* The current code can have up to 256 pages for virtio */ | ||
| 282 | #define VIRTIODESCSPACE (256ul * 4096ul) | ||
| 283 | |||
| 284 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | 286 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) |
| 285 | { | 287 | { |
| 286 | atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH); | 288 | atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH); |
| 287 | vcpu->arch.sie_block->gmslm = vcpu->kvm->arch.guest_memsize + | 289 | set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests); |
| 288 | vcpu->kvm->arch.guest_origin + | ||
| 289 | VIRTIODESCSPACE - 1ul; | ||
| 290 | vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin; | ||
| 291 | vcpu->arch.sie_block->ecb = 2; | 290 | vcpu->arch.sie_block->ecb = 2; |
| 292 | vcpu->arch.sie_block->eca = 0xC1002001U; | 291 | vcpu->arch.sie_block->eca = 0xC1002001U; |
| 293 | vcpu->arch.sie_block->fac = (int) (long) facilities; | 292 | vcpu->arch.sie_block->fac = (int) (long) facilities; |
| @@ -319,8 +318,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
| 319 | BUG_ON(!kvm->arch.sca); | 318 | BUG_ON(!kvm->arch.sca); |
| 320 | if (!kvm->arch.sca->cpu[id].sda) | 319 | if (!kvm->arch.sca->cpu[id].sda) |
| 321 | kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block; | 320 | kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block; |
| 322 | else | ||
| 323 | BUG_ON(!kvm->vcpus[id]); /* vcpu does already exist */ | ||
| 324 | vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32); | 321 | vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32); |
| 325 | vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca; | 322 | vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca; |
| 326 | 323 | ||
| @@ -490,9 +487,15 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 490 | 487 | ||
| 491 | vcpu_load(vcpu); | 488 | vcpu_load(vcpu); |
| 492 | 489 | ||
| 490 | rerun_vcpu: | ||
| 491 | if (vcpu->requests) | ||
| 492 | if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) | ||
| 493 | kvm_s390_vcpu_set_mem(vcpu); | ||
| 494 | |||
| 493 | /* verify, that memory has been registered */ | 495 | /* verify, that memory has been registered */ |
| 494 | if (!vcpu->kvm->arch.guest_memsize) { | 496 | if (!vcpu->arch.sie_block->gmslm) { |
| 495 | vcpu_put(vcpu); | 497 | vcpu_put(vcpu); |
| 498 | VCPU_EVENT(vcpu, 3, "%s", "no memory registered to run vcpu"); | ||
| 496 | return -EINVAL; | 499 | return -EINVAL; |
| 497 | } | 500 | } |
| 498 | 501 | ||
| @@ -509,6 +512,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 509 | vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr; | 512 | vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr; |
| 510 | break; | 513 | break; |
| 511 | case KVM_EXIT_UNKNOWN: | 514 | case KVM_EXIT_UNKNOWN: |
| 515 | case KVM_EXIT_INTR: | ||
| 512 | case KVM_EXIT_S390_RESET: | 516 | case KVM_EXIT_S390_RESET: |
| 513 | break; | 517 | break; |
| 514 | default: | 518 | default: |
| @@ -522,8 +526,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 522 | rc = kvm_handle_sie_intercept(vcpu); | 526 | rc = kvm_handle_sie_intercept(vcpu); |
| 523 | } while (!signal_pending(current) && !rc); | 527 | } while (!signal_pending(current) && !rc); |
| 524 | 528 | ||
| 525 | if (signal_pending(current) && !rc) | 529 | if (rc == SIE_INTERCEPT_RERUNVCPU) |
| 530 | goto rerun_vcpu; | ||
| 531 | |||
| 532 | if (signal_pending(current) && !rc) { | ||
| 533 | kvm_run->exit_reason = KVM_EXIT_INTR; | ||
| 526 | rc = -EINTR; | 534 | rc = -EINTR; |
| 535 | } | ||
| 527 | 536 | ||
| 528 | if (rc == -ENOTSUPP) { | 537 | if (rc == -ENOTSUPP) { |
| 529 | /* intercept cannot be handled in-kernel, prepare kvm-run */ | 538 | /* intercept cannot be handled in-kernel, prepare kvm-run */ |
| @@ -676,6 +685,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm, | |||
| 676 | int user_alloc) | 685 | int user_alloc) |
| 677 | { | 686 | { |
| 678 | int i; | 687 | int i; |
| 688 | struct kvm_vcpu *vcpu; | ||
| 679 | 689 | ||
| 680 | /* A few sanity checks. We can have exactly one memory slot which has | 690 | /* A few sanity checks. We can have exactly one memory slot which has |
| 681 | to start at guest virtual zero and which has to be located at a | 691 | to start at guest virtual zero and which has to be located at a |
| @@ -684,7 +694,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm, | |||
| 684 | vmas. It is okay to mmap() and munmap() stuff in this slot after | 694 | vmas. It is okay to mmap() and munmap() stuff in this slot after |
| 685 | doing this call at any time */ | 695 | doing this call at any time */ |
| 686 | 696 | ||
| 687 | if (mem->slot || kvm->arch.guest_memsize) | 697 | if (mem->slot) |
| 688 | return -EINVAL; | 698 | return -EINVAL; |
| 689 | 699 | ||
| 690 | if (mem->guest_phys_addr) | 700 | if (mem->guest_phys_addr) |
| @@ -699,36 +709,14 @@ int kvm_arch_set_memory_region(struct kvm *kvm, | |||
| 699 | if (!user_alloc) | 709 | if (!user_alloc) |
| 700 | return -EINVAL; | 710 | return -EINVAL; |
| 701 | 711 | ||
| 702 | /* lock all vcpus */ | 712 | /* request update of sie control block for all available vcpus */ |
| 703 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | 713 | kvm_for_each_vcpu(i, vcpu, kvm) { |
| 704 | if (!kvm->vcpus[i]) | 714 | if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) |
| 705 | continue; | 715 | continue; |
| 706 | if (!mutex_trylock(&kvm->vcpus[i]->mutex)) | 716 | kvm_s390_inject_sigp_stop(vcpu, ACTION_RELOADVCPU_ON_STOP); |
| 707 | goto fail_out; | ||
| 708 | } | ||
| 709 | |||
| 710 | kvm->arch.guest_origin = mem->userspace_addr; | ||
| 711 | kvm->arch.guest_memsize = mem->memory_size; | ||
| 712 | |||
| 713 | /* update sie control blocks, and unlock all vcpus */ | ||
| 714 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | ||
| 715 | if (kvm->vcpus[i]) { | ||
| 716 | kvm->vcpus[i]->arch.sie_block->gmsor = | ||
| 717 | kvm->arch.guest_origin; | ||
| 718 | kvm->vcpus[i]->arch.sie_block->gmslm = | ||
| 719 | kvm->arch.guest_memsize + | ||
| 720 | kvm->arch.guest_origin + | ||
| 721 | VIRTIODESCSPACE - 1ul; | ||
| 722 | mutex_unlock(&kvm->vcpus[i]->mutex); | ||
| 723 | } | ||
| 724 | } | 717 | } |
| 725 | 718 | ||
| 726 | return 0; | 719 | return 0; |
| 727 | |||
| 728 | fail_out: | ||
| 729 | for (; i >= 0; i--) | ||
| 730 | mutex_unlock(&kvm->vcpus[i]->mutex); | ||
| 731 | return -EINVAL; | ||
| 732 | } | 720 | } |
| 733 | 721 | ||
| 734 | void kvm_arch_flush_shadow(struct kvm *kvm) | 722 | void kvm_arch_flush_shadow(struct kvm *kvm) |
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 748fee872323..ec5eee7c25d8 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * kvm_s390.h - definition for kvm on s390 | 2 | * kvm_s390.h - definition for kvm on s390 |
| 3 | * | 3 | * |
| 4 | * Copyright IBM Corp. 2008 | 4 | * Copyright IBM Corp. 2008,2009 |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License (version 2 only) | 7 | * it under the terms of the GNU General Public License (version 2 only) |
| @@ -9,6 +9,7 @@ | |||
| 9 | * | 9 | * |
| 10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 10 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
| 11 | * Christian Borntraeger <borntraeger@de.ibm.com> | 11 | * Christian Borntraeger <borntraeger@de.ibm.com> |
| 12 | * Christian Ehrhardt <ehrhardt@de.ibm.com> | ||
| 12 | */ | 13 | */ |
| 13 | 14 | ||
| 14 | #ifndef ARCH_S390_KVM_S390_H | 15 | #ifndef ARCH_S390_KVM_S390_H |
| @@ -18,8 +19,13 @@ | |||
| 18 | #include <linux/kvm.h> | 19 | #include <linux/kvm.h> |
| 19 | #include <linux/kvm_host.h> | 20 | #include <linux/kvm_host.h> |
| 20 | 21 | ||
| 22 | /* The current code can have up to 256 pages for virtio */ | ||
| 23 | #define VIRTIODESCSPACE (256ul * 4096ul) | ||
| 24 | |||
| 21 | typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); | 25 | typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); |
| 22 | 26 | ||
| 27 | /* negativ values are error codes, positive values for internal conditions */ | ||
| 28 | #define SIE_INTERCEPT_RERUNVCPU (1<<0) | ||
| 23 | int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu); | 29 | int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu); |
| 24 | 30 | ||
| 25 | #define VM_EVENT(d_kvm, d_loglevel, d_string, d_args...)\ | 31 | #define VM_EVENT(d_kvm, d_loglevel, d_string, d_args...)\ |
| @@ -50,6 +56,30 @@ int kvm_s390_inject_vm(struct kvm *kvm, | |||
| 50 | int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, | 56 | int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, |
| 51 | struct kvm_s390_interrupt *s390int); | 57 | struct kvm_s390_interrupt *s390int); |
| 52 | int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); | 58 | int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); |
| 59 | int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action); | ||
| 60 | |||
| 61 | static inline int kvm_s390_vcpu_get_memsize(struct kvm_vcpu *vcpu) | ||
| 62 | { | ||
| 63 | return vcpu->arch.sie_block->gmslm | ||
| 64 | - vcpu->arch.sie_block->gmsor | ||
| 65 | - VIRTIODESCSPACE + 1ul; | ||
| 66 | } | ||
| 67 | |||
| 68 | static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu) | ||
| 69 | { | ||
| 70 | struct kvm_memory_slot *mem; | ||
| 71 | |||
| 72 | down_read(&vcpu->kvm->slots_lock); | ||
| 73 | mem = &vcpu->kvm->memslots[0]; | ||
| 74 | |||
| 75 | vcpu->arch.sie_block->gmsor = mem->userspace_addr; | ||
| 76 | vcpu->arch.sie_block->gmslm = | ||
| 77 | mem->userspace_addr + | ||
| 78 | (mem->npages << PAGE_SHIFT) + | ||
| 79 | VIRTIODESCSPACE - 1ul; | ||
| 80 | |||
| 81 | up_read(&vcpu->kvm->slots_lock); | ||
| 82 | } | ||
| 53 | 83 | ||
| 54 | /* implemented in priv.c */ | 84 | /* implemented in priv.c */ |
| 55 | int kvm_s390_handle_b2(struct kvm_vcpu *vcpu); | 85 | int kvm_s390_handle_b2(struct kvm_vcpu *vcpu); |
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 0ef81d6776e9..40c8c6748cfe 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * sigp.c - handlinge interprocessor communication | 2 | * sigp.c - handlinge interprocessor communication |
| 3 | * | 3 | * |
| 4 | * Copyright IBM Corp. 2008 | 4 | * Copyright IBM Corp. 2008,2009 |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License (version 2 only) | 7 | * it under the terms of the GNU General Public License (version 2 only) |
| @@ -9,6 +9,7 @@ | |||
| 9 | * | 9 | * |
| 10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 10 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
| 11 | * Christian Borntraeger <borntraeger@de.ibm.com> | 11 | * Christian Borntraeger <borntraeger@de.ibm.com> |
| 12 | * Christian Ehrhardt <ehrhardt@de.ibm.com> | ||
| 12 | */ | 13 | */ |
| 13 | 14 | ||
| 14 | #include <linux/kvm.h> | 15 | #include <linux/kvm.h> |
| @@ -107,46 +108,57 @@ unlock: | |||
| 107 | return rc; | 108 | return rc; |
| 108 | } | 109 | } |
| 109 | 110 | ||
| 110 | static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int store) | 111 | static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action) |
| 111 | { | 112 | { |
| 112 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; | ||
| 113 | struct kvm_s390_local_interrupt *li; | ||
| 114 | struct kvm_s390_interrupt_info *inti; | 113 | struct kvm_s390_interrupt_info *inti; |
| 115 | int rc; | ||
| 116 | |||
| 117 | if (cpu_addr >= KVM_MAX_VCPUS) | ||
| 118 | return 3; /* not operational */ | ||
| 119 | 114 | ||
| 120 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); | 115 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); |
| 121 | if (!inti) | 116 | if (!inti) |
| 122 | return -ENOMEM; | 117 | return -ENOMEM; |
| 123 | |||
| 124 | inti->type = KVM_S390_SIGP_STOP; | 118 | inti->type = KVM_S390_SIGP_STOP; |
| 125 | 119 | ||
| 126 | spin_lock(&fi->lock); | ||
| 127 | li = fi->local_int[cpu_addr]; | ||
| 128 | if (li == NULL) { | ||
| 129 | rc = 3; /* not operational */ | ||
| 130 | kfree(inti); | ||
| 131 | goto unlock; | ||
| 132 | } | ||
| 133 | spin_lock_bh(&li->lock); | 120 | spin_lock_bh(&li->lock); |
| 134 | list_add_tail(&inti->list, &li->list); | 121 | list_add_tail(&inti->list, &li->list); |
| 135 | atomic_set(&li->active, 1); | 122 | atomic_set(&li->active, 1); |
| 136 | atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags); | 123 | atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags); |
| 137 | if (store) | 124 | li->action_bits |= action; |
| 138 | li->action_bits |= ACTION_STORE_ON_STOP; | ||
| 139 | li->action_bits |= ACTION_STOP_ON_STOP; | ||
| 140 | if (waitqueue_active(&li->wq)) | 125 | if (waitqueue_active(&li->wq)) |
| 141 | wake_up_interruptible(&li->wq); | 126 | wake_up_interruptible(&li->wq); |
| 142 | spin_unlock_bh(&li->lock); | 127 | spin_unlock_bh(&li->lock); |
| 143 | rc = 0; /* order accepted */ | 128 | |
| 129 | return 0; /* order accepted */ | ||
| 130 | } | ||
| 131 | |||
| 132 | static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action) | ||
| 133 | { | ||
| 134 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; | ||
| 135 | struct kvm_s390_local_interrupt *li; | ||
| 136 | int rc; | ||
| 137 | |||
| 138 | if (cpu_addr >= KVM_MAX_VCPUS) | ||
| 139 | return 3; /* not operational */ | ||
| 140 | |||
| 141 | spin_lock(&fi->lock); | ||
| 142 | li = fi->local_int[cpu_addr]; | ||
| 143 | if (li == NULL) { | ||
| 144 | rc = 3; /* not operational */ | ||
| 145 | goto unlock; | ||
| 146 | } | ||
| 147 | |||
| 148 | rc = __inject_sigp_stop(li, action); | ||
| 149 | |||
| 144 | unlock: | 150 | unlock: |
| 145 | spin_unlock(&fi->lock); | 151 | spin_unlock(&fi->lock); |
| 146 | VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr); | 152 | VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr); |
| 147 | return rc; | 153 | return rc; |
| 148 | } | 154 | } |
| 149 | 155 | ||
| 156 | int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action) | ||
| 157 | { | ||
| 158 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
| 159 | return __inject_sigp_stop(li, action); | ||
| 160 | } | ||
| 161 | |||
| 150 | static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) | 162 | static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) |
| 151 | { | 163 | { |
| 152 | int rc; | 164 | int rc; |
| @@ -177,9 +189,9 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, | |||
| 177 | /* make sure that the new value is valid memory */ | 189 | /* make sure that the new value is valid memory */ |
| 178 | address = address & 0x7fffe000u; | 190 | address = address & 0x7fffe000u; |
| 179 | if ((copy_from_guest(vcpu, &tmp, | 191 | if ((copy_from_guest(vcpu, &tmp, |
| 180 | (u64) (address + vcpu->kvm->arch.guest_origin) , 1)) || | 192 | (u64) (address + vcpu->arch.sie_block->gmsor) , 1)) || |
| 181 | (copy_from_guest(vcpu, &tmp, (u64) (address + | 193 | (copy_from_guest(vcpu, &tmp, (u64) (address + |
| 182 | vcpu->kvm->arch.guest_origin + PAGE_SIZE), 1))) { | 194 | vcpu->arch.sie_block->gmsor + PAGE_SIZE), 1))) { |
| 183 | *reg |= SIGP_STAT_INVALID_PARAMETER; | 195 | *reg |= SIGP_STAT_INVALID_PARAMETER; |
| 184 | return 1; /* invalid parameter */ | 196 | return 1; /* invalid parameter */ |
| 185 | } | 197 | } |
| @@ -262,11 +274,11 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) | |||
| 262 | break; | 274 | break; |
| 263 | case SIGP_STOP: | 275 | case SIGP_STOP: |
| 264 | vcpu->stat.instruction_sigp_stop++; | 276 | vcpu->stat.instruction_sigp_stop++; |
| 265 | rc = __sigp_stop(vcpu, cpu_addr, 0); | 277 | rc = __sigp_stop(vcpu, cpu_addr, ACTION_STOP_ON_STOP); |
| 266 | break; | 278 | break; |
| 267 | case SIGP_STOP_STORE_STATUS: | 279 | case SIGP_STOP_STORE_STATUS: |
| 268 | vcpu->stat.instruction_sigp_stop++; | 280 | vcpu->stat.instruction_sigp_stop++; |
| 269 | rc = __sigp_stop(vcpu, cpu_addr, 1); | 281 | rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP); |
| 270 | break; | 282 | break; |
| 271 | case SIGP_SET_ARCH: | 283 | case SIGP_SET_ARCH: |
| 272 | vcpu->stat.instruction_sigp_arch++; | 284 | vcpu->stat.instruction_sigp_arch++; |
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile index db05661ac895..eec054484419 100644 --- a/arch/s390/mm/Makefile +++ b/arch/s390/mm/Makefile | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Makefile for the linux s390-specific parts of the memory manager. | 2 | # Makefile for the linux s390-specific parts of the memory manager. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o | 5 | obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o \ |
| 6 | page-states.o | ||
| 6 | obj-$(CONFIG_CMM) += cmm.o | 7 | obj-$(CONFIG_CMM) += cmm.o |
| 7 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 8 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
| 8 | obj-$(CONFIG_PAGE_STATES) += page-states.o | ||
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index e5e119fe03b2..1abbadd497e1 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | * Copyright (C) 1995 Linus Torvalds | 10 | * Copyright (C) 1995 Linus Torvalds |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/perf_counter.h> | ||
| 13 | #include <linux/signal.h> | 14 | #include <linux/signal.h> |
| 14 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
| 15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| @@ -305,7 +306,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int write) | |||
| 305 | * interrupts again and then search the VMAs | 306 | * interrupts again and then search the VMAs |
| 306 | */ | 307 | */ |
| 307 | local_irq_enable(); | 308 | local_irq_enable(); |
| 308 | 309 | perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address); | |
| 309 | down_read(&mm->mmap_sem); | 310 | down_read(&mm->mmap_sem); |
| 310 | 311 | ||
| 311 | si_code = SEGV_MAPERR; | 312 | si_code = SEGV_MAPERR; |
| @@ -363,11 +364,15 @@ good_area: | |||
| 363 | } | 364 | } |
| 364 | BUG(); | 365 | BUG(); |
| 365 | } | 366 | } |
| 366 | if (fault & VM_FAULT_MAJOR) | 367 | if (fault & VM_FAULT_MAJOR) { |
| 367 | tsk->maj_flt++; | 368 | tsk->maj_flt++; |
| 368 | else | 369 | perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, |
| 370 | regs, address); | ||
| 371 | } else { | ||
| 369 | tsk->min_flt++; | 372 | tsk->min_flt++; |
| 370 | 373 | perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, | |
| 374 | regs, address); | ||
| 375 | } | ||
| 371 | up_read(&mm->mmap_sem); | 376 | up_read(&mm->mmap_sem); |
| 372 | /* | 377 | /* |
| 373 | * The instruction that caused the program check will | 378 | * The instruction that caused the program check will |
diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c index fc0ad73ffd90..f92ec203ad92 100644 --- a/arch/s390/mm/page-states.c +++ b/arch/s390/mm/page-states.c | |||
| @@ -1,6 +1,4 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * arch/s390/mm/page-states.c | ||
| 3 | * | ||
| 4 | * Copyright IBM Corp. 2008 | 2 | * Copyright IBM Corp. 2008 |
| 5 | * | 3 | * |
| 6 | * Guest page hinting for unused pages. | 4 | * Guest page hinting for unused pages. |
| @@ -17,11 +15,12 @@ | |||
| 17 | #define ESSA_SET_STABLE 1 | 15 | #define ESSA_SET_STABLE 1 |
| 18 | #define ESSA_SET_UNUSED 2 | 16 | #define ESSA_SET_UNUSED 2 |
| 19 | 17 | ||
| 20 | static int cmma_flag; | 18 | static int cmma_flag = 1; |
| 21 | 19 | ||
| 22 | static int __init cmma(char *str) | 20 | static int __init cmma(char *str) |
| 23 | { | 21 | { |
| 24 | char *parm; | 22 | char *parm; |
| 23 | |||
| 25 | parm = strstrip(str); | 24 | parm = strstrip(str); |
| 26 | if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) { | 25 | if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) { |
| 27 | cmma_flag = 1; | 26 | cmma_flag = 1; |
| @@ -32,7 +31,6 @@ static int __init cmma(char *str) | |||
| 32 | return 1; | 31 | return 1; |
| 33 | return 0; | 32 | return 0; |
| 34 | } | 33 | } |
| 35 | |||
| 36 | __setup("cmma=", cmma); | 34 | __setup("cmma=", cmma); |
| 37 | 35 | ||
| 38 | void __init cmma_init(void) | 36 | void __init cmma_init(void) |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 565667207985..c70215247071 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
| @@ -78,9 +78,9 @@ unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec) | |||
| 78 | } | 78 | } |
| 79 | page->index = page_to_phys(shadow); | 79 | page->index = page_to_phys(shadow); |
| 80 | } | 80 | } |
| 81 | spin_lock(&mm->page_table_lock); | 81 | spin_lock(&mm->context.list_lock); |
| 82 | list_add(&page->lru, &mm->context.crst_list); | 82 | list_add(&page->lru, &mm->context.crst_list); |
| 83 | spin_unlock(&mm->page_table_lock); | 83 | spin_unlock(&mm->context.list_lock); |
| 84 | return (unsigned long *) page_to_phys(page); | 84 | return (unsigned long *) page_to_phys(page); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| @@ -89,9 +89,9 @@ void crst_table_free(struct mm_struct *mm, unsigned long *table) | |||
| 89 | unsigned long *shadow = get_shadow_table(table); | 89 | unsigned long *shadow = get_shadow_table(table); |
| 90 | struct page *page = virt_to_page(table); | 90 | struct page *page = virt_to_page(table); |
| 91 | 91 | ||
| 92 | spin_lock(&mm->page_table_lock); | 92 | spin_lock(&mm->context.list_lock); |
| 93 | list_del(&page->lru); | 93 | list_del(&page->lru); |
| 94 | spin_unlock(&mm->page_table_lock); | 94 | spin_unlock(&mm->context.list_lock); |
| 95 | if (shadow) | 95 | if (shadow) |
| 96 | free_pages((unsigned long) shadow, ALLOC_ORDER); | 96 | free_pages((unsigned long) shadow, ALLOC_ORDER); |
| 97 | free_pages((unsigned long) table, ALLOC_ORDER); | 97 | free_pages((unsigned long) table, ALLOC_ORDER); |
| @@ -182,7 +182,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) | |||
| 182 | unsigned long bits; | 182 | unsigned long bits; |
| 183 | 183 | ||
| 184 | bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; | 184 | bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; |
| 185 | spin_lock(&mm->page_table_lock); | 185 | spin_lock(&mm->context.list_lock); |
| 186 | page = NULL; | 186 | page = NULL; |
| 187 | if (!list_empty(&mm->context.pgtable_list)) { | 187 | if (!list_empty(&mm->context.pgtable_list)) { |
| 188 | page = list_first_entry(&mm->context.pgtable_list, | 188 | page = list_first_entry(&mm->context.pgtable_list, |
| @@ -191,7 +191,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) | |||
| 191 | page = NULL; | 191 | page = NULL; |
| 192 | } | 192 | } |
| 193 | if (!page) { | 193 | if (!page) { |
| 194 | spin_unlock(&mm->page_table_lock); | 194 | spin_unlock(&mm->context.list_lock); |
| 195 | page = alloc_page(GFP_KERNEL|__GFP_REPEAT); | 195 | page = alloc_page(GFP_KERNEL|__GFP_REPEAT); |
| 196 | if (!page) | 196 | if (!page) |
| 197 | return NULL; | 197 | return NULL; |
| @@ -202,7 +202,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) | |||
| 202 | clear_table_pgstes(table); | 202 | clear_table_pgstes(table); |
| 203 | else | 203 | else |
| 204 | clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE); | 204 | clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE); |
| 205 | spin_lock(&mm->page_table_lock); | 205 | spin_lock(&mm->context.list_lock); |
| 206 | list_add(&page->lru, &mm->context.pgtable_list); | 206 | list_add(&page->lru, &mm->context.pgtable_list); |
| 207 | } | 207 | } |
| 208 | table = (unsigned long *) page_to_phys(page); | 208 | table = (unsigned long *) page_to_phys(page); |
| @@ -213,7 +213,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) | |||
| 213 | page->flags |= bits; | 213 | page->flags |= bits; |
| 214 | if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1)) | 214 | if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1)) |
| 215 | list_move_tail(&page->lru, &mm->context.pgtable_list); | 215 | list_move_tail(&page->lru, &mm->context.pgtable_list); |
| 216 | spin_unlock(&mm->page_table_lock); | 216 | spin_unlock(&mm->context.list_lock); |
| 217 | return table; | 217 | return table; |
| 218 | } | 218 | } |
| 219 | 219 | ||
| @@ -225,7 +225,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) | |||
| 225 | bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; | 225 | bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; |
| 226 | bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long); | 226 | bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long); |
| 227 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); | 227 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); |
| 228 | spin_lock(&mm->page_table_lock); | 228 | spin_lock(&mm->context.list_lock); |
| 229 | page->flags ^= bits; | 229 | page->flags ^= bits; |
| 230 | if (page->flags & FRAG_MASK) { | 230 | if (page->flags & FRAG_MASK) { |
| 231 | /* Page now has some free pgtable fragments. */ | 231 | /* Page now has some free pgtable fragments. */ |
| @@ -234,7 +234,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) | |||
| 234 | } else | 234 | } else |
| 235 | /* All fragments of the 4K page have been freed. */ | 235 | /* All fragments of the 4K page have been freed. */ |
| 236 | list_del(&page->lru); | 236 | list_del(&page->lru); |
| 237 | spin_unlock(&mm->page_table_lock); | 237 | spin_unlock(&mm->context.list_lock); |
| 238 | if (page) { | 238 | if (page) { |
| 239 | pgtable_page_dtor(page); | 239 | pgtable_page_dtor(page); |
| 240 | __free_page(page); | 240 | __free_page(page); |
| @@ -245,7 +245,7 @@ void disable_noexec(struct mm_struct *mm, struct task_struct *tsk) | |||
| 245 | { | 245 | { |
| 246 | struct page *page; | 246 | struct page *page; |
| 247 | 247 | ||
| 248 | spin_lock(&mm->page_table_lock); | 248 | spin_lock(&mm->context.list_lock); |
| 249 | /* Free shadow region and segment tables. */ | 249 | /* Free shadow region and segment tables. */ |
| 250 | list_for_each_entry(page, &mm->context.crst_list, lru) | 250 | list_for_each_entry(page, &mm->context.crst_list, lru) |
| 251 | if (page->index) { | 251 | if (page->index) { |
| @@ -255,7 +255,7 @@ void disable_noexec(struct mm_struct *mm, struct task_struct *tsk) | |||
| 255 | /* "Free" second halves of page tables. */ | 255 | /* "Free" second halves of page tables. */ |
| 256 | list_for_each_entry(page, &mm->context.pgtable_list, lru) | 256 | list_for_each_entry(page, &mm->context.pgtable_list, lru) |
| 257 | page->flags &= ~SECOND_HALVES; | 257 | page->flags &= ~SECOND_HALVES; |
| 258 | spin_unlock(&mm->page_table_lock); | 258 | spin_unlock(&mm->context.list_lock); |
| 259 | mm->context.noexec = 0; | 259 | mm->context.noexec = 0; |
| 260 | update_mm(mm, tsk); | 260 | update_mm(mm, tsk); |
| 261 | } | 261 | } |
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index e4868bfc672f..5f91a38d7592 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c | |||
| @@ -331,6 +331,7 @@ void __init vmem_map_init(void) | |||
| 331 | unsigned long start, end; | 331 | unsigned long start, end; |
| 332 | int i; | 332 | int i; |
| 333 | 333 | ||
| 334 | spin_lock_init(&init_mm.context.list_lock); | ||
| 334 | INIT_LIST_HEAD(&init_mm.context.crst_list); | 335 | INIT_LIST_HEAD(&init_mm.context.crst_list); |
| 335 | INIT_LIST_HEAD(&init_mm.context.pgtable_list); | 336 | INIT_LIST_HEAD(&init_mm.context.pgtable_list); |
| 336 | init_mm.context.noexec = 0; | 337 | init_mm.context.noexec = 0; |
diff --git a/arch/s390/power/Makefile b/arch/s390/power/Makefile deleted file mode 100644 index 973bb45a8fec..000000000000 --- a/arch/s390/power/Makefile +++ /dev/null | |||
| @@ -1,8 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Makefile for s390 PM support | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-$(CONFIG_HIBERNATION) += suspend.o | ||
| 6 | obj-$(CONFIG_HIBERNATION) += swsusp.o | ||
| 7 | obj-$(CONFIG_HIBERNATION) += swsusp_64.o | ||
| 8 | obj-$(CONFIG_HIBERNATION) += swsusp_asm64.o | ||
diff --git a/arch/s390/power/suspend.c b/arch/s390/power/suspend.c deleted file mode 100644 index b3351eceebbe..000000000000 --- a/arch/s390/power/suspend.c +++ /dev/null | |||
| @@ -1,40 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Suspend support specific for s390. | ||
| 3 | * | ||
| 4 | * Copyright IBM Corp. 2009 | ||
| 5 | * | ||
| 6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/mm.h> | ||
| 10 | #include <linux/suspend.h> | ||
| 11 | #include <linux/reboot.h> | ||
| 12 | #include <linux/pfn.h> | ||
| 13 | #include <asm/sections.h> | ||
| 14 | #include <asm/ipl.h> | ||
| 15 | |||
| 16 | /* | ||
| 17 | * References to section boundaries | ||
| 18 | */ | ||
| 19 | extern const void __nosave_begin, __nosave_end; | ||
| 20 | |||
| 21 | /* | ||
| 22 | * check if given pfn is in the 'nosave' or in the read only NSS section | ||
| 23 | */ | ||
| 24 | int pfn_is_nosave(unsigned long pfn) | ||
| 25 | { | ||
| 26 | unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; | ||
| 27 | unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) | ||
| 28 | >> PAGE_SHIFT; | ||
| 29 | unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1; | ||
| 30 | unsigned long stext_pfn = PFN_DOWN(__pa(&_stext)); | ||
| 31 | |||
| 32 | if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn) | ||
| 33 | return 1; | ||
| 34 | if (pfn >= stext_pfn && pfn <= eshared_pfn) { | ||
| 35 | if (ipl_info.type == IPL_TYPE_NSS) | ||
| 36 | return 1; | ||
| 37 | } else if ((tprot(pfn * PAGE_SIZE) && pfn > 0)) | ||
| 38 | return 1; | ||
| 39 | return 0; | ||
| 40 | } | ||
diff --git a/arch/s390/power/swsusp_64.c b/arch/s390/power/swsusp_64.c deleted file mode 100644 index 9516a517d72f..000000000000 --- a/arch/s390/power/swsusp_64.c +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Support for suspend and resume on s390 | ||
| 3 | * | ||
| 4 | * Copyright IBM Corp. 2009 | ||
| 5 | * | ||
| 6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> | ||
| 7 | * | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <asm/system.h> | ||
| 11 | #include <linux/interrupt.h> | ||
| 12 | |||
| 13 | void do_after_copyback(void) | ||
| 14 | { | ||
| 15 | mb(); | ||
| 16 | } | ||
| 17 | |||
diff --git a/arch/sh/include/asm/sh_eth.h b/arch/sh/include/asm/sh_eth.h index bb832584f3c1..acf99700deed 100644 --- a/arch/sh/include/asm/sh_eth.h +++ b/arch/sh/include/asm/sh_eth.h | |||
| @@ -6,6 +6,9 @@ enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN}; | |||
| 6 | struct sh_eth_plat_data { | 6 | struct sh_eth_plat_data { |
| 7 | int phy; | 7 | int phy; |
| 8 | int edmac_endian; | 8 | int edmac_endian; |
| 9 | |||
| 10 | unsigned no_ether_link:1; | ||
| 11 | unsigned ether_link_active_low:1; | ||
| 9 | }; | 12 | }; |
| 10 | 13 | ||
| 11 | #endif | 14 | #endif |
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index b5afbec1db59..04a21883f327 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c | |||
| @@ -640,5 +640,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0, | |||
| 640 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 640 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
| 641 | clear_thread_flag(TIF_NOTIFY_RESUME); | 641 | clear_thread_flag(TIF_NOTIFY_RESUME); |
| 642 | tracehook_notify_resume(regs); | 642 | tracehook_notify_resume(regs); |
| 643 | if (current->replacement_session_keyring) | ||
| 644 | key_replace_session_keyring(); | ||
| 643 | } | 645 | } |
| 644 | } | 646 | } |
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index 0663a0ee6021..9e5c9b1d7e98 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c | |||
| @@ -772,5 +772,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info | |||
| 772 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 772 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
| 773 | clear_thread_flag(TIF_NOTIFY_RESUME); | 773 | clear_thread_flag(TIF_NOTIFY_RESUME); |
| 774 | tracehook_notify_resume(regs); | 774 | tracehook_notify_resume(regs); |
| 775 | if (current->replacement_session_keyring) | ||
| 776 | key_replace_session_keyring(); | ||
| 775 | } | 777 | } |
| 776 | } | 778 | } |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 3f8b6a92eabd..2bd5c287538a 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
| @@ -25,6 +25,9 @@ config SPARC | |||
| 25 | select ARCH_WANT_OPTIONAL_GPIOLIB | 25 | select ARCH_WANT_OPTIONAL_GPIOLIB |
| 26 | select RTC_CLASS | 26 | select RTC_CLASS |
| 27 | select RTC_DRV_M48T59 | 27 | select RTC_DRV_M48T59 |
| 28 | select HAVE_PERF_COUNTERS | ||
| 29 | select HAVE_DMA_ATTRS | ||
| 30 | select HAVE_DMA_API_DEBUG | ||
| 28 | 31 | ||
| 29 | config SPARC32 | 32 | config SPARC32 |
| 30 | def_bool !64BIT | 33 | def_bool !64BIT |
| @@ -44,6 +47,7 @@ config SPARC64 | |||
| 44 | select RTC_DRV_BQ4802 | 47 | select RTC_DRV_BQ4802 |
| 45 | select RTC_DRV_SUN4V | 48 | select RTC_DRV_SUN4V |
| 46 | select RTC_DRV_STARFIRE | 49 | select RTC_DRV_STARFIRE |
| 50 | select HAVE_PERF_COUNTERS | ||
| 47 | 51 | ||
| 48 | config ARCH_DEFCONFIG | 52 | config ARCH_DEFCONFIG |
| 49 | string | 53 | string |
| @@ -437,6 +441,17 @@ config SERIAL_CONSOLE | |||
| 437 | 441 | ||
| 438 | If unsure, say N. | 442 | If unsure, say N. |
| 439 | 443 | ||
| 444 | config SPARC_LEON | ||
| 445 | bool "Sparc Leon processor family" | ||
| 446 | depends on SPARC32 | ||
| 447 | ---help--- | ||
| 448 | If you say Y here if you are running on a SPARC-LEON processor. | ||
| 449 | The LEON processor is a synthesizable VHDL model of the | ||
| 450 | SPARC-v8 standard. LEON is part of the GRLIB collection of | ||
| 451 | IP cores that are distributed under GPL. GRLIB can be downloaded | ||
| 452 | from www.gaisler.com. You can download a sparc-linux cross-compilation | ||
| 453 | toolchain at www.gaisler.com. | ||
| 454 | |||
| 440 | endmenu | 455 | endmenu |
| 441 | 456 | ||
| 442 | menu "Bus options (PCI etc.)" | 457 | menu "Bus options (PCI etc.)" |
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index 2003ded054c2..467221dd5702 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile | |||
| @@ -38,10 +38,6 @@ CPPFLAGS_vmlinux.lds += -m32 | |||
| 38 | # Actual linking is done with "make image". | 38 | # Actual linking is done with "make image". |
| 39 | LDFLAGS_vmlinux = -r | 39 | LDFLAGS_vmlinux = -r |
| 40 | 40 | ||
| 41 | # Default target | ||
| 42 | all: zImage | ||
| 43 | |||
| 44 | |||
| 45 | else | 41 | else |
| 46 | ##### | 42 | ##### |
| 47 | # sparc64 | 43 | # sparc64 |
| @@ -91,6 +87,9 @@ endif | |||
| 91 | 87 | ||
| 92 | boot := arch/sparc/boot | 88 | boot := arch/sparc/boot |
| 93 | 89 | ||
| 90 | # Default target | ||
| 91 | all: zImage | ||
| 92 | |||
| 94 | image zImage tftpboot.img vmlinux.aout: vmlinux | 93 | image zImage tftpboot.img vmlinux.aout: vmlinux |
| 95 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ | 94 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ |
| 96 | 95 | ||
| @@ -109,8 +108,9 @@ define archhelp | |||
| 109 | endef | 108 | endef |
| 110 | else | 109 | else |
| 111 | define archhelp | 110 | define archhelp |
| 112 | echo '* vmlinux - Standard sparc64 kernel' | 111 | echo '* vmlinux - standard sparc64 kernel' |
| 113 | echo ' vmlinux.aout - a.out kernel for sparc64' | 112 | echo '* zImage - stripped and compressed sparc64 kernel ($(boot)/zImage)' |
| 113 | echo ' vmlinux.aout - a.out kernel for sparc64' | ||
| 114 | echo ' tftpboot.img - image prepared for tftp' | 114 | echo ' tftpboot.img - image prepared for tftp' |
| 115 | endef | 115 | endef |
| 116 | endif | 116 | endif |
diff --git a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile index 1ff0fd924756..97e3feb9ff1b 100644 --- a/arch/sparc/boot/Makefile +++ b/arch/sparc/boot/Makefile | |||
| @@ -79,6 +79,9 @@ $(obj)/image: vmlinux FORCE | |||
| 79 | $(call if_changed,strip) | 79 | $(call if_changed,strip) |
| 80 | @echo ' kernel: $@ is ready' | 80 | @echo ' kernel: $@ is ready' |
| 81 | 81 | ||
| 82 | $(obj)/zImage: $(obj)/image | ||
| 83 | $(call if_changed,gzip) | ||
| 84 | |||
| 82 | $(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback_64 System.map $(ROOT_IMG) FORCE | 85 | $(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback_64 System.map $(ROOT_IMG) FORCE |
| 83 | $(call if_changed,elftoaout) | 86 | $(call if_changed,elftoaout) |
| 84 | $(call if_changed,piggy) | 87 | $(call if_changed,piggy) |
diff --git a/arch/sparc/configs/sparc32_defconfig b/arch/sparc/configs/sparc32_defconfig index 8bcd27af724b..a0f62a808edb 100644 --- a/arch/sparc/configs/sparc32_defconfig +++ b/arch/sparc/configs/sparc32_defconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.30-rc2 | 3 | # Linux kernel version: 2.6.31-rc1 |
| 4 | # Fri Apr 17 04:04:46 2009 | 4 | # Tue Aug 18 23:45:52 2009 |
| 5 | # | 5 | # |
| 6 | # CONFIG_64BIT is not set | 6 | # CONFIG_64BIT is not set |
| 7 | CONFIG_SPARC=y | 7 | CONFIG_SPARC=y |
| @@ -17,6 +17,7 @@ CONFIG_GENERIC_ISA_DMA=y | |||
| 17 | CONFIG_ARCH_NO_VIRT_TO_BUS=y | 17 | CONFIG_ARCH_NO_VIRT_TO_BUS=y |
| 18 | CONFIG_OF=y | 18 | CONFIG_OF=y |
| 19 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 19 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
| 20 | CONFIG_CONSTRUCTORS=y | ||
| 20 | 21 | ||
| 21 | # | 22 | # |
| 22 | # General setup | 23 | # General setup |
| @@ -74,7 +75,6 @@ CONFIG_SYSCTL_SYSCALL=y | |||
| 74 | CONFIG_KALLSYMS=y | 75 | CONFIG_KALLSYMS=y |
| 75 | # CONFIG_KALLSYMS_ALL is not set | 76 | # CONFIG_KALLSYMS_ALL is not set |
| 76 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 77 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
| 77 | # CONFIG_STRIP_ASM_SYMS is not set | ||
| 78 | CONFIG_HOTPLUG=y | 78 | CONFIG_HOTPLUG=y |
| 79 | CONFIG_PRINTK=y | 79 | CONFIG_PRINTK=y |
| 80 | CONFIG_BUG=y | 80 | CONFIG_BUG=y |
| @@ -87,8 +87,13 @@ CONFIG_TIMERFD=y | |||
| 87 | CONFIG_EVENTFD=y | 87 | CONFIG_EVENTFD=y |
| 88 | CONFIG_SHMEM=y | 88 | CONFIG_SHMEM=y |
| 89 | CONFIG_AIO=y | 89 | CONFIG_AIO=y |
| 90 | |||
| 91 | # | ||
| 92 | # Performance Counters | ||
| 93 | # | ||
| 90 | CONFIG_VM_EVENT_COUNTERS=y | 94 | CONFIG_VM_EVENT_COUNTERS=y |
| 91 | CONFIG_PCI_QUIRKS=y | 95 | CONFIG_PCI_QUIRKS=y |
| 96 | # CONFIG_STRIP_ASM_SYMS is not set | ||
| 92 | CONFIG_COMPAT_BRK=y | 97 | CONFIG_COMPAT_BRK=y |
| 93 | CONFIG_SLAB=y | 98 | CONFIG_SLAB=y |
| 94 | # CONFIG_SLUB is not set | 99 | # CONFIG_SLUB is not set |
| @@ -97,6 +102,10 @@ CONFIG_SLAB=y | |||
| 97 | # CONFIG_MARKERS is not set | 102 | # CONFIG_MARKERS is not set |
| 98 | CONFIG_HAVE_OPROFILE=y | 103 | CONFIG_HAVE_OPROFILE=y |
| 99 | CONFIG_HAVE_ARCH_TRACEHOOK=y | 104 | CONFIG_HAVE_ARCH_TRACEHOOK=y |
| 105 | |||
| 106 | # | ||
| 107 | # GCOV-based kernel profiling | ||
| 108 | # | ||
| 100 | # CONFIG_SLOW_WORK is not set | 109 | # CONFIG_SLOW_WORK is not set |
| 101 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set | 110 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set |
| 102 | CONFIG_SLABINFO=y | 111 | CONFIG_SLABINFO=y |
| @@ -109,7 +118,7 @@ CONFIG_MODULE_UNLOAD=y | |||
| 109 | # CONFIG_MODVERSIONS is not set | 118 | # CONFIG_MODVERSIONS is not set |
| 110 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 119 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
| 111 | CONFIG_BLOCK=y | 120 | CONFIG_BLOCK=y |
| 112 | # CONFIG_LBD is not set | 121 | CONFIG_LBDAF=y |
| 113 | # CONFIG_BLK_DEV_BSG is not set | 122 | # CONFIG_BLK_DEV_BSG is not set |
| 114 | # CONFIG_BLK_DEV_INTEGRITY is not set | 123 | # CONFIG_BLK_DEV_INTEGRITY is not set |
| 115 | 124 | ||
| @@ -154,9 +163,9 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 | |||
| 154 | # CONFIG_PHYS_ADDR_T_64BIT is not set | 163 | # CONFIG_PHYS_ADDR_T_64BIT is not set |
| 155 | CONFIG_ZONE_DMA_FLAG=1 | 164 | CONFIG_ZONE_DMA_FLAG=1 |
| 156 | CONFIG_BOUNCE=y | 165 | CONFIG_BOUNCE=y |
| 157 | CONFIG_UNEVICTABLE_LRU=y | ||
| 158 | CONFIG_HAVE_MLOCK=y | 166 | CONFIG_HAVE_MLOCK=y |
| 159 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | 167 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y |
| 168 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
| 160 | CONFIG_SUN_PM=y | 169 | CONFIG_SUN_PM=y |
| 161 | # CONFIG_SPARC_LED is not set | 170 | # CONFIG_SPARC_LED is not set |
| 162 | CONFIG_SERIAL_CONSOLE=y | 171 | CONFIG_SERIAL_CONSOLE=y |
| @@ -264,6 +273,7 @@ CONFIG_IPV6_TUNNEL=m | |||
| 264 | # CONFIG_ECONET is not set | 273 | # CONFIG_ECONET is not set |
| 265 | # CONFIG_WAN_ROUTER is not set | 274 | # CONFIG_WAN_ROUTER is not set |
| 266 | # CONFIG_PHONET is not set | 275 | # CONFIG_PHONET is not set |
| 276 | # CONFIG_IEEE802154 is not set | ||
| 267 | # CONFIG_NET_SCHED is not set | 277 | # CONFIG_NET_SCHED is not set |
| 268 | # CONFIG_DCB is not set | 278 | # CONFIG_DCB is not set |
| 269 | 279 | ||
| @@ -281,7 +291,11 @@ CONFIG_WIRELESS=y | |||
| 281 | CONFIG_WIRELESS_OLD_REGULATORY=y | 291 | CONFIG_WIRELESS_OLD_REGULATORY=y |
| 282 | # CONFIG_WIRELESS_EXT is not set | 292 | # CONFIG_WIRELESS_EXT is not set |
| 283 | # CONFIG_LIB80211 is not set | 293 | # CONFIG_LIB80211 is not set |
| 284 | # CONFIG_MAC80211 is not set | 294 | |
| 295 | # | ||
| 296 | # CFG80211 needs to be enabled for MAC80211 | ||
| 297 | # | ||
| 298 | CONFIG_MAC80211_DEFAULT_PS_VALUE=0 | ||
| 285 | # CONFIG_WIMAX is not set | 299 | # CONFIG_WIMAX is not set |
| 286 | # CONFIG_RFKILL is not set | 300 | # CONFIG_RFKILL is not set |
| 287 | # CONFIG_NET_9P is not set | 301 | # CONFIG_NET_9P is not set |
| @@ -335,6 +349,7 @@ CONFIG_MISC_DEVICES=y | |||
| 335 | # EEPROM support | 349 | # EEPROM support |
| 336 | # | 350 | # |
| 337 | # CONFIG_EEPROM_93CX6 is not set | 351 | # CONFIG_EEPROM_93CX6 is not set |
| 352 | # CONFIG_CB710_CORE is not set | ||
| 338 | CONFIG_HAVE_IDE=y | 353 | CONFIG_HAVE_IDE=y |
| 339 | # CONFIG_IDE is not set | 354 | # CONFIG_IDE is not set |
| 340 | 355 | ||
| @@ -358,10 +373,6 @@ CONFIG_BLK_DEV_SR=m | |||
| 358 | # CONFIG_BLK_DEV_SR_VENDOR is not set | 373 | # CONFIG_BLK_DEV_SR_VENDOR is not set |
| 359 | CONFIG_CHR_DEV_SG=m | 374 | CONFIG_CHR_DEV_SG=m |
| 360 | # CONFIG_CHR_DEV_SCH is not set | 375 | # CONFIG_CHR_DEV_SCH is not set |
| 361 | |||
| 362 | # | ||
| 363 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | ||
| 364 | # | ||
| 365 | # CONFIG_SCSI_MULTI_LUN is not set | 376 | # CONFIG_SCSI_MULTI_LUN is not set |
| 366 | # CONFIG_SCSI_CONSTANTS is not set | 377 | # CONFIG_SCSI_CONSTANTS is not set |
| 367 | # CONFIG_SCSI_LOGGING is not set | 378 | # CONFIG_SCSI_LOGGING is not set |
| @@ -379,6 +390,7 @@ CONFIG_SCSI_SPI_ATTRS=y | |||
| 379 | CONFIG_SCSI_LOWLEVEL=y | 390 | CONFIG_SCSI_LOWLEVEL=y |
| 380 | # CONFIG_ISCSI_TCP is not set | 391 | # CONFIG_ISCSI_TCP is not set |
| 381 | # CONFIG_SCSI_CXGB3_ISCSI is not set | 392 | # CONFIG_SCSI_CXGB3_ISCSI is not set |
| 393 | # CONFIG_SCSI_BNX2_ISCSI is not set | ||
| 382 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | 394 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set |
| 383 | # CONFIG_SCSI_3W_9XXX is not set | 395 | # CONFIG_SCSI_3W_9XXX is not set |
| 384 | # CONFIG_SCSI_ACARD is not set | 396 | # CONFIG_SCSI_ACARD is not set |
| @@ -387,6 +399,7 @@ CONFIG_SCSI_LOWLEVEL=y | |||
| 387 | # CONFIG_SCSI_AIC7XXX_OLD is not set | 399 | # CONFIG_SCSI_AIC7XXX_OLD is not set |
| 388 | # CONFIG_SCSI_AIC79XX is not set | 400 | # CONFIG_SCSI_AIC79XX is not set |
| 389 | # CONFIG_SCSI_AIC94XX is not set | 401 | # CONFIG_SCSI_AIC94XX is not set |
| 402 | # CONFIG_SCSI_MVSAS is not set | ||
| 390 | # CONFIG_SCSI_ARCMSR is not set | 403 | # CONFIG_SCSI_ARCMSR is not set |
| 391 | # CONFIG_MEGARAID_NEWGEN is not set | 404 | # CONFIG_MEGARAID_NEWGEN is not set |
| 392 | # CONFIG_MEGARAID_LEGACY is not set | 405 | # CONFIG_MEGARAID_LEGACY is not set |
| @@ -401,7 +414,6 @@ CONFIG_SCSI_LOWLEVEL=y | |||
| 401 | # CONFIG_SCSI_IPS is not set | 414 | # CONFIG_SCSI_IPS is not set |
| 402 | # CONFIG_SCSI_INITIO is not set | 415 | # CONFIG_SCSI_INITIO is not set |
| 403 | # CONFIG_SCSI_INIA100 is not set | 416 | # CONFIG_SCSI_INIA100 is not set |
| 404 | # CONFIG_SCSI_MVSAS is not set | ||
| 405 | # CONFIG_SCSI_STEX is not set | 417 | # CONFIG_SCSI_STEX is not set |
| 406 | # CONFIG_SCSI_SYM53C8XX_2 is not set | 418 | # CONFIG_SCSI_SYM53C8XX_2 is not set |
| 407 | # CONFIG_SCSI_QLOGIC_1280 is not set | 419 | # CONFIG_SCSI_QLOGIC_1280 is not set |
| @@ -426,13 +438,16 @@ CONFIG_SCSI_SUNESP=y | |||
| 426 | # | 438 | # |
| 427 | 439 | ||
| 428 | # | 440 | # |
| 429 | # Enable only one of the two stacks, unless you know what you are doing | 441 | # You can enable one or both FireWire driver stacks. |
| 442 | # | ||
| 443 | |||
| 444 | # | ||
| 445 | # See the help texts for more information. | ||
| 430 | # | 446 | # |
| 431 | # CONFIG_FIREWIRE is not set | 447 | # CONFIG_FIREWIRE is not set |
| 432 | # CONFIG_IEEE1394 is not set | 448 | # CONFIG_IEEE1394 is not set |
| 433 | # CONFIG_I2O is not set | 449 | # CONFIG_I2O is not set |
| 434 | CONFIG_NETDEVICES=y | 450 | CONFIG_NETDEVICES=y |
| 435 | CONFIG_COMPAT_NET_DEV_OPS=y | ||
| 436 | CONFIG_DUMMY=m | 451 | CONFIG_DUMMY=m |
| 437 | # CONFIG_BONDING is not set | 452 | # CONFIG_BONDING is not set |
| 438 | # CONFIG_MACVLAN is not set | 453 | # CONFIG_MACVLAN is not set |
| @@ -463,6 +478,7 @@ CONFIG_SUNQE=m | |||
| 463 | # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set | 478 | # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set |
| 464 | # CONFIG_NET_PCI is not set | 479 | # CONFIG_NET_PCI is not set |
| 465 | # CONFIG_B44 is not set | 480 | # CONFIG_B44 is not set |
| 481 | # CONFIG_KS8842 is not set | ||
| 466 | # CONFIG_ATL2 is not set | 482 | # CONFIG_ATL2 is not set |
| 467 | CONFIG_NETDEV_1000=y | 483 | CONFIG_NETDEV_1000=y |
| 468 | # CONFIG_ACENIC is not set | 484 | # CONFIG_ACENIC is not set |
| @@ -482,6 +498,7 @@ CONFIG_NETDEV_1000=y | |||
| 482 | # CONFIG_VIA_VELOCITY is not set | 498 | # CONFIG_VIA_VELOCITY is not set |
| 483 | # CONFIG_TIGON3 is not set | 499 | # CONFIG_TIGON3 is not set |
| 484 | # CONFIG_BNX2 is not set | 500 | # CONFIG_BNX2 is not set |
| 501 | # CONFIG_CNIC is not set | ||
| 485 | # CONFIG_QLA3XXX is not set | 502 | # CONFIG_QLA3XXX is not set |
| 486 | # CONFIG_ATL1 is not set | 503 | # CONFIG_ATL1 is not set |
| 487 | # CONFIG_ATL1E is not set | 504 | # CONFIG_ATL1E is not set |
| @@ -629,6 +646,11 @@ CONFIG_HW_RANDOM=m | |||
| 629 | CONFIG_DEVPORT=y | 646 | CONFIG_DEVPORT=y |
| 630 | # CONFIG_I2C is not set | 647 | # CONFIG_I2C is not set |
| 631 | # CONFIG_SPI is not set | 648 | # CONFIG_SPI is not set |
| 649 | |||
| 650 | # | ||
| 651 | # PPS support | ||
| 652 | # | ||
| 653 | # CONFIG_PPS is not set | ||
| 632 | CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y | 654 | CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y |
| 633 | # CONFIG_GPIOLIB is not set | 655 | # CONFIG_GPIOLIB is not set |
| 634 | # CONFIG_W1 is not set | 656 | # CONFIG_W1 is not set |
| @@ -668,22 +690,7 @@ CONFIG_SSB_POSSIBLE=y | |||
| 668 | # CONFIG_HTC_PASIC3 is not set | 690 | # CONFIG_HTC_PASIC3 is not set |
| 669 | # CONFIG_MFD_TMIO is not set | 691 | # CONFIG_MFD_TMIO is not set |
| 670 | # CONFIG_REGULATOR is not set | 692 | # CONFIG_REGULATOR is not set |
| 671 | 693 | # CONFIG_MEDIA_SUPPORT is not set | |
| 672 | # | ||
| 673 | # Multimedia devices | ||
| 674 | # | ||
| 675 | |||
| 676 | # | ||
| 677 | # Multimedia core support | ||
| 678 | # | ||
| 679 | # CONFIG_VIDEO_DEV is not set | ||
| 680 | # CONFIG_DVB_CORE is not set | ||
| 681 | # CONFIG_VIDEO_MEDIA is not set | ||
| 682 | |||
| 683 | # | ||
| 684 | # Multimedia drivers | ||
| 685 | # | ||
| 686 | # CONFIG_DAB is not set | ||
| 687 | 694 | ||
| 688 | # | 695 | # |
| 689 | # Graphics support | 696 | # Graphics support |
| @@ -776,6 +783,10 @@ CONFIG_RTC_DRV_M48T59=y | |||
| 776 | # CONFIG_DMADEVICES is not set | 783 | # CONFIG_DMADEVICES is not set |
| 777 | # CONFIG_AUXDISPLAY is not set | 784 | # CONFIG_AUXDISPLAY is not set |
| 778 | # CONFIG_UIO is not set | 785 | # CONFIG_UIO is not set |
| 786 | |||
| 787 | # | ||
| 788 | # TI VLYNQ | ||
| 789 | # | ||
| 779 | # CONFIG_STAGING is not set | 790 | # CONFIG_STAGING is not set |
| 780 | 791 | ||
| 781 | # | 792 | # |
| @@ -799,10 +810,12 @@ CONFIG_FS_MBCACHE=y | |||
| 799 | # CONFIG_REISERFS_FS is not set | 810 | # CONFIG_REISERFS_FS is not set |
| 800 | # CONFIG_JFS_FS is not set | 811 | # CONFIG_JFS_FS is not set |
| 801 | CONFIG_FS_POSIX_ACL=y | 812 | CONFIG_FS_POSIX_ACL=y |
| 802 | CONFIG_FILE_LOCKING=y | ||
| 803 | # CONFIG_XFS_FS is not set | 813 | # CONFIG_XFS_FS is not set |
| 814 | # CONFIG_GFS2_FS is not set | ||
| 804 | # CONFIG_OCFS2_FS is not set | 815 | # CONFIG_OCFS2_FS is not set |
| 805 | # CONFIG_BTRFS_FS is not set | 816 | # CONFIG_BTRFS_FS is not set |
| 817 | CONFIG_FILE_LOCKING=y | ||
| 818 | CONFIG_FSNOTIFY=y | ||
| 806 | CONFIG_DNOTIFY=y | 819 | CONFIG_DNOTIFY=y |
| 807 | CONFIG_INOTIFY=y | 820 | CONFIG_INOTIFY=y |
| 808 | CONFIG_INOTIFY_USER=y | 821 | CONFIG_INOTIFY_USER=y |
| @@ -985,6 +998,7 @@ CONFIG_KGDB=y | |||
| 985 | CONFIG_KGDB_SERIAL_CONSOLE=y | 998 | CONFIG_KGDB_SERIAL_CONSOLE=y |
| 986 | CONFIG_KGDB_TESTS=y | 999 | CONFIG_KGDB_TESTS=y |
| 987 | # CONFIG_KGDB_TESTS_ON_BOOT is not set | 1000 | # CONFIG_KGDB_TESTS_ON_BOOT is not set |
| 1001 | # CONFIG_KMEMCHECK is not set | ||
| 988 | # CONFIG_DEBUG_STACK_USAGE is not set | 1002 | # CONFIG_DEBUG_STACK_USAGE is not set |
| 989 | # CONFIG_STACK_DEBUG is not set | 1003 | # CONFIG_STACK_DEBUG is not set |
| 990 | 1004 | ||
diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig index 0123a4c596ce..fdddf7a6f725 100644 --- a/arch/sparc/configs/sparc64_defconfig +++ b/arch/sparc/configs/sparc64_defconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.30 | 3 | # Linux kernel version: 2.6.31-rc1 |
| 4 | # Tue Jun 16 04:59:36 2009 | 4 | # Tue Aug 18 23:56:02 2009 |
| 5 | # | 5 | # |
| 6 | CONFIG_64BIT=y | 6 | CONFIG_64BIT=y |
| 7 | CONFIG_SPARC=y | 7 | CONFIG_SPARC=y |
| @@ -26,6 +26,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y | |||
| 26 | CONFIG_OF=y | 26 | CONFIG_OF=y |
| 27 | CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y | 27 | CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y |
| 28 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 28 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
| 29 | CONFIG_CONSTRUCTORS=y | ||
| 29 | 30 | ||
| 30 | # | 31 | # |
| 31 | # General setup | 32 | # General setup |
| @@ -119,6 +120,11 @@ CONFIG_HAVE_KPROBES=y | |||
| 119 | CONFIG_HAVE_KRETPROBES=y | 120 | CONFIG_HAVE_KRETPROBES=y |
| 120 | CONFIG_HAVE_ARCH_TRACEHOOK=y | 121 | CONFIG_HAVE_ARCH_TRACEHOOK=y |
| 121 | CONFIG_USE_GENERIC_SMP_HELPERS=y | 122 | CONFIG_USE_GENERIC_SMP_HELPERS=y |
| 123 | |||
| 124 | # | ||
| 125 | # GCOV-based kernel profiling | ||
| 126 | # | ||
| 127 | # CONFIG_GCOV_KERNEL is not set | ||
| 122 | # CONFIG_SLOW_WORK is not set | 128 | # CONFIG_SLOW_WORK is not set |
| 123 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set | 129 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set |
| 124 | CONFIG_SLABINFO=y | 130 | CONFIG_SLABINFO=y |
| @@ -204,7 +210,6 @@ CONFIG_MIGRATION=y | |||
| 204 | CONFIG_PHYS_ADDR_T_64BIT=y | 210 | CONFIG_PHYS_ADDR_T_64BIT=y |
| 205 | CONFIG_ZONE_DMA_FLAG=0 | 211 | CONFIG_ZONE_DMA_FLAG=0 |
| 206 | CONFIG_NR_QUICK=1 | 212 | CONFIG_NR_QUICK=1 |
| 207 | CONFIG_UNEVICTABLE_LRU=y | ||
| 208 | CONFIG_HAVE_MLOCK=y | 213 | CONFIG_HAVE_MLOCK=y |
| 209 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | 214 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y |
| 210 | CONFIG_DEFAULT_MMAP_MIN_ADDR=8192 | 215 | CONFIG_DEFAULT_MMAP_MIN_ADDR=8192 |
| @@ -410,6 +415,7 @@ CONFIG_MISC_DEVICES=y | |||
| 410 | # | 415 | # |
| 411 | # CONFIG_EEPROM_AT24 is not set | 416 | # CONFIG_EEPROM_AT24 is not set |
| 412 | # CONFIG_EEPROM_LEGACY is not set | 417 | # CONFIG_EEPROM_LEGACY is not set |
| 418 | # CONFIG_EEPROM_MAX6875 is not set | ||
| 413 | # CONFIG_EEPROM_93CX6 is not set | 419 | # CONFIG_EEPROM_93CX6 is not set |
| 414 | # CONFIG_CB710_CORE is not set | 420 | # CONFIG_CB710_CORE is not set |
| 415 | CONFIG_HAVE_IDE=y | 421 | CONFIG_HAVE_IDE=y |
| @@ -562,6 +568,7 @@ CONFIG_BLK_DEV_DM=m | |||
| 562 | CONFIG_DM_CRYPT=m | 568 | CONFIG_DM_CRYPT=m |
| 563 | CONFIG_DM_SNAPSHOT=m | 569 | CONFIG_DM_SNAPSHOT=m |
| 564 | CONFIG_DM_MIRROR=m | 570 | CONFIG_DM_MIRROR=m |
| 571 | # CONFIG_DM_LOG_USERSPACE is not set | ||
| 565 | CONFIG_DM_ZERO=m | 572 | CONFIG_DM_ZERO=m |
| 566 | # CONFIG_DM_MULTIPATH is not set | 573 | # CONFIG_DM_MULTIPATH is not set |
| 567 | # CONFIG_DM_DELAY is not set | 574 | # CONFIG_DM_DELAY is not set |
| @@ -573,7 +580,11 @@ CONFIG_DM_ZERO=m | |||
| 573 | # | 580 | # |
| 574 | 581 | ||
| 575 | # | 582 | # |
| 576 | # Enable only one of the two stacks, unless you know what you are doing | 583 | # You can enable one or both FireWire driver stacks. |
| 584 | # | ||
| 585 | |||
| 586 | # | ||
| 587 | # See the help texts for more information. | ||
| 577 | # | 588 | # |
| 578 | # CONFIG_FIREWIRE is not set | 589 | # CONFIG_FIREWIRE is not set |
| 579 | # CONFIG_IEEE1394 is not set | 590 | # CONFIG_IEEE1394 is not set |
| @@ -667,6 +678,7 @@ CONFIG_E1000E=m | |||
| 667 | # CONFIG_VIA_VELOCITY is not set | 678 | # CONFIG_VIA_VELOCITY is not set |
| 668 | CONFIG_TIGON3=m | 679 | CONFIG_TIGON3=m |
| 669 | CONFIG_BNX2=m | 680 | CONFIG_BNX2=m |
| 681 | # CONFIG_CNIC is not set | ||
| 670 | # CONFIG_QLA3XXX is not set | 682 | # CONFIG_QLA3XXX is not set |
| 671 | # CONFIG_ATL1 is not set | 683 | # CONFIG_ATL1 is not set |
| 672 | # CONFIG_ATL1E is not set | 684 | # CONFIG_ATL1E is not set |
| @@ -773,6 +785,7 @@ CONFIG_MOUSE_SERIAL=y | |||
| 773 | # CONFIG_MOUSE_APPLETOUCH is not set | 785 | # CONFIG_MOUSE_APPLETOUCH is not set |
| 774 | # CONFIG_MOUSE_BCM5974 is not set | 786 | # CONFIG_MOUSE_BCM5974 is not set |
| 775 | # CONFIG_MOUSE_VSXXXAA is not set | 787 | # CONFIG_MOUSE_VSXXXAA is not set |
| 788 | # CONFIG_MOUSE_SYNAPTICS_I2C is not set | ||
| 776 | # CONFIG_INPUT_JOYSTICK is not set | 789 | # CONFIG_INPUT_JOYSTICK is not set |
| 777 | # CONFIG_INPUT_TABLET is not set | 790 | # CONFIG_INPUT_TABLET is not set |
| 778 | # CONFIG_INPUT_TOUCHSCREEN is not set | 791 | # CONFIG_INPUT_TOUCHSCREEN is not set |
| @@ -870,6 +883,7 @@ CONFIG_I2C_ALGOBIT=y | |||
| 870 | # | 883 | # |
| 871 | # I2C system bus drivers (mostly embedded / system-on-chip) | 884 | # I2C system bus drivers (mostly embedded / system-on-chip) |
| 872 | # | 885 | # |
| 886 | # CONFIG_I2C_DESIGNWARE is not set | ||
| 873 | # CONFIG_I2C_OCORES is not set | 887 | # CONFIG_I2C_OCORES is not set |
| 874 | # CONFIG_I2C_SIMTEC is not set | 888 | # CONFIG_I2C_SIMTEC is not set |
| 875 | 889 | ||
| @@ -898,13 +912,17 @@ CONFIG_I2C_ALGOBIT=y | |||
| 898 | # CONFIG_SENSORS_PCF8574 is not set | 912 | # CONFIG_SENSORS_PCF8574 is not set |
| 899 | # CONFIG_PCF8575 is not set | 913 | # CONFIG_PCF8575 is not set |
| 900 | # CONFIG_SENSORS_PCA9539 is not set | 914 | # CONFIG_SENSORS_PCA9539 is not set |
| 901 | # CONFIG_SENSORS_MAX6875 is not set | ||
| 902 | # CONFIG_SENSORS_TSL2550 is not set | 915 | # CONFIG_SENSORS_TSL2550 is not set |
| 903 | # CONFIG_I2C_DEBUG_CORE is not set | 916 | # CONFIG_I2C_DEBUG_CORE is not set |
| 904 | # CONFIG_I2C_DEBUG_ALGO is not set | 917 | # CONFIG_I2C_DEBUG_ALGO is not set |
| 905 | # CONFIG_I2C_DEBUG_BUS is not set | 918 | # CONFIG_I2C_DEBUG_BUS is not set |
| 906 | # CONFIG_I2C_DEBUG_CHIP is not set | 919 | # CONFIG_I2C_DEBUG_CHIP is not set |
| 907 | # CONFIG_SPI is not set | 920 | # CONFIG_SPI is not set |
| 921 | |||
| 922 | # | ||
| 923 | # PPS support | ||
| 924 | # | ||
| 925 | # CONFIG_PPS is not set | ||
| 908 | CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y | 926 | CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y |
| 909 | # CONFIG_GPIOLIB is not set | 927 | # CONFIG_GPIOLIB is not set |
| 910 | # CONFIG_W1 is not set | 928 | # CONFIG_W1 is not set |
| @@ -959,6 +977,7 @@ CONFIG_HWMON=y | |||
| 959 | # CONFIG_SENSORS_SMSC47B397 is not set | 977 | # CONFIG_SENSORS_SMSC47B397 is not set |
| 960 | # CONFIG_SENSORS_ADS7828 is not set | 978 | # CONFIG_SENSORS_ADS7828 is not set |
| 961 | # CONFIG_SENSORS_THMC50 is not set | 979 | # CONFIG_SENSORS_THMC50 is not set |
| 980 | # CONFIG_SENSORS_TMP401 is not set | ||
| 962 | # CONFIG_SENSORS_VIA686A is not set | 981 | # CONFIG_SENSORS_VIA686A is not set |
| 963 | # CONFIG_SENSORS_VT1211 is not set | 982 | # CONFIG_SENSORS_VT1211 is not set |
| 964 | # CONFIG_SENSORS_VT8231 is not set | 983 | # CONFIG_SENSORS_VT8231 is not set |
| @@ -994,23 +1013,9 @@ CONFIG_SSB_POSSIBLE=y | |||
| 994 | # CONFIG_MFD_WM8400 is not set | 1013 | # CONFIG_MFD_WM8400 is not set |
| 995 | # CONFIG_MFD_WM8350_I2C is not set | 1014 | # CONFIG_MFD_WM8350_I2C is not set |
| 996 | # CONFIG_MFD_PCF50633 is not set | 1015 | # CONFIG_MFD_PCF50633 is not set |
| 1016 | # CONFIG_AB3100_CORE is not set | ||
| 997 | # CONFIG_REGULATOR is not set | 1017 | # CONFIG_REGULATOR is not set |
| 998 | 1018 | # CONFIG_MEDIA_SUPPORT is not set | |
| 999 | # | ||
| 1000 | # Multimedia devices | ||
| 1001 | # | ||
| 1002 | |||
| 1003 | # | ||
| 1004 | # Multimedia core support | ||
| 1005 | # | ||
| 1006 | # CONFIG_VIDEO_DEV is not set | ||
| 1007 | # CONFIG_DVB_CORE is not set | ||
| 1008 | # CONFIG_VIDEO_MEDIA is not set | ||
| 1009 | |||
| 1010 | # | ||
| 1011 | # Multimedia drivers | ||
| 1012 | # | ||
| 1013 | # CONFIG_DAB is not set | ||
| 1014 | 1019 | ||
| 1015 | # | 1020 | # |
| 1016 | # Graphics support | 1021 | # Graphics support |
| @@ -1284,7 +1289,6 @@ CONFIG_USB=y | |||
| 1284 | # | 1289 | # |
| 1285 | # Miscellaneous USB options | 1290 | # Miscellaneous USB options |
| 1286 | # | 1291 | # |
| 1287 | CONFIG_USB_DEVICEFS=y | ||
| 1288 | # CONFIG_USB_DEVICE_CLASS is not set | 1292 | # CONFIG_USB_DEVICE_CLASS is not set |
| 1289 | # CONFIG_USB_DYNAMIC_MINORS is not set | 1293 | # CONFIG_USB_DYNAMIC_MINORS is not set |
| 1290 | # CONFIG_USB_OTG is not set | 1294 | # CONFIG_USB_OTG is not set |
| @@ -1296,6 +1300,7 @@ CONFIG_USB_DEVICEFS=y | |||
| 1296 | # USB Host Controller Drivers | 1300 | # USB Host Controller Drivers |
| 1297 | # | 1301 | # |
| 1298 | # CONFIG_USB_C67X00_HCD is not set | 1302 | # CONFIG_USB_C67X00_HCD is not set |
| 1303 | # CONFIG_USB_XHCI_HCD is not set | ||
| 1299 | CONFIG_USB_EHCI_HCD=m | 1304 | CONFIG_USB_EHCI_HCD=m |
| 1300 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set | 1305 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set |
| 1301 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set | 1306 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set |
| @@ -1374,7 +1379,6 @@ CONFIG_USB_STORAGE=m | |||
| 1374 | # CONFIG_USB_LD is not set | 1379 | # CONFIG_USB_LD is not set |
| 1375 | # CONFIG_USB_TRANCEVIBRATOR is not set | 1380 | # CONFIG_USB_TRANCEVIBRATOR is not set |
| 1376 | # CONFIG_USB_IOWARRIOR is not set | 1381 | # CONFIG_USB_IOWARRIOR is not set |
| 1377 | # CONFIG_USB_TEST is not set | ||
| 1378 | # CONFIG_USB_ISIGHTFW is not set | 1382 | # CONFIG_USB_ISIGHTFW is not set |
| 1379 | # CONFIG_USB_VST is not set | 1383 | # CONFIG_USB_VST is not set |
| 1380 | # CONFIG_USB_GADGET is not set | 1384 | # CONFIG_USB_GADGET is not set |
| @@ -1420,6 +1424,7 @@ CONFIG_RTC_INTF_DEV=y | |||
| 1420 | # CONFIG_RTC_DRV_S35390A is not set | 1424 | # CONFIG_RTC_DRV_S35390A is not set |
| 1421 | # CONFIG_RTC_DRV_FM3130 is not set | 1425 | # CONFIG_RTC_DRV_FM3130 is not set |
| 1422 | # CONFIG_RTC_DRV_RX8581 is not set | 1426 | # CONFIG_RTC_DRV_RX8581 is not set |
| 1427 | # CONFIG_RTC_DRV_RX8025 is not set | ||
| 1423 | 1428 | ||
| 1424 | # | 1429 | # |
| 1425 | # SPI RTC drivers | 1430 | # SPI RTC drivers |
| @@ -1448,6 +1453,10 @@ CONFIG_RTC_DRV_STARFIRE=y | |||
| 1448 | # CONFIG_DMADEVICES is not set | 1453 | # CONFIG_DMADEVICES is not set |
| 1449 | # CONFIG_AUXDISPLAY is not set | 1454 | # CONFIG_AUXDISPLAY is not set |
| 1450 | # CONFIG_UIO is not set | 1455 | # CONFIG_UIO is not set |
| 1456 | |||
| 1457 | # | ||
| 1458 | # TI VLYNQ | ||
| 1459 | # | ||
| 1451 | # CONFIG_STAGING is not set | 1460 | # CONFIG_STAGING is not set |
| 1452 | 1461 | ||
| 1453 | # | 1462 | # |
| @@ -1480,11 +1489,11 @@ CONFIG_FS_MBCACHE=y | |||
| 1480 | # CONFIG_REISERFS_FS is not set | 1489 | # CONFIG_REISERFS_FS is not set |
| 1481 | # CONFIG_JFS_FS is not set | 1490 | # CONFIG_JFS_FS is not set |
| 1482 | CONFIG_FS_POSIX_ACL=y | 1491 | CONFIG_FS_POSIX_ACL=y |
| 1483 | CONFIG_FILE_LOCKING=y | ||
| 1484 | # CONFIG_XFS_FS is not set | 1492 | # CONFIG_XFS_FS is not set |
| 1485 | # CONFIG_GFS2_FS is not set | 1493 | # CONFIG_GFS2_FS is not set |
| 1486 | # CONFIG_OCFS2_FS is not set | 1494 | # CONFIG_OCFS2_FS is not set |
| 1487 | # CONFIG_BTRFS_FS is not set | 1495 | # CONFIG_BTRFS_FS is not set |
| 1496 | CONFIG_FILE_LOCKING=y | ||
| 1488 | CONFIG_FSNOTIFY=y | 1497 | CONFIG_FSNOTIFY=y |
| 1489 | CONFIG_DNOTIFY=y | 1498 | CONFIG_DNOTIFY=y |
| 1490 | CONFIG_INOTIFY=y | 1499 | CONFIG_INOTIFY=y |
| @@ -1560,7 +1569,7 @@ CONFIG_NETWORK_FILESYSTEMS=y | |||
| 1560 | # CONFIG_PARTITION_ADVANCED is not set | 1569 | # CONFIG_PARTITION_ADVANCED is not set |
| 1561 | CONFIG_MSDOS_PARTITION=y | 1570 | CONFIG_MSDOS_PARTITION=y |
| 1562 | CONFIG_SUN_PARTITION=y | 1571 | CONFIG_SUN_PARTITION=y |
| 1563 | CONFIG_NLS=m | 1572 | CONFIG_NLS=y |
| 1564 | CONFIG_NLS_DEFAULT="iso8859-1" | 1573 | CONFIG_NLS_DEFAULT="iso8859-1" |
| 1565 | # CONFIG_NLS_CODEPAGE_437 is not set | 1574 | # CONFIG_NLS_CODEPAGE_437 is not set |
| 1566 | # CONFIG_NLS_CODEPAGE_737 is not set | 1575 | # CONFIG_NLS_CODEPAGE_737 is not set |
diff --git a/arch/sparc/include/asm/asi.h b/arch/sparc/include/asm/asi.h index 74703c5ef985..b2e3db63a64b 100644 --- a/arch/sparc/include/asm/asi.h +++ b/arch/sparc/include/asm/asi.h | |||
| @@ -40,7 +40,11 @@ | |||
| 40 | #define ASI_M_UNA01 0x01 /* Same here... */ | 40 | #define ASI_M_UNA01 0x01 /* Same here... */ |
| 41 | #define ASI_M_MXCC 0x02 /* Access to TI VIKING MXCC registers */ | 41 | #define ASI_M_MXCC 0x02 /* Access to TI VIKING MXCC registers */ |
| 42 | #define ASI_M_FLUSH_PROBE 0x03 /* Reference MMU Flush/Probe; rw, ss */ | 42 | #define ASI_M_FLUSH_PROBE 0x03 /* Reference MMU Flush/Probe; rw, ss */ |
| 43 | #ifndef CONFIG_SPARC_LEON | ||
| 43 | #define ASI_M_MMUREGS 0x04 /* MMU Registers; rw, ss */ | 44 | #define ASI_M_MMUREGS 0x04 /* MMU Registers; rw, ss */ |
| 45 | #else | ||
| 46 | #define ASI_M_MMUREGS 0x19 | ||
| 47 | #endif /* CONFIG_SPARC_LEON */ | ||
| 44 | #define ASI_M_TLBDIAG 0x05 /* MMU TLB only Diagnostics */ | 48 | #define ASI_M_TLBDIAG 0x05 /* MMU TLB only Diagnostics */ |
| 45 | #define ASI_M_DIAGS 0x06 /* Reference MMU Diagnostics */ | 49 | #define ASI_M_DIAGS 0x06 /* Reference MMU Diagnostics */ |
| 46 | #define ASI_M_IODIAG 0x07 /* MMU I/O TLB only Diagnostics */ | 50 | #define ASI_M_IODIAG 0x07 /* MMU I/O TLB only Diagnostics */ |
diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index 204e4bf64438..5a8c308e2b5c 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include <linux/scatterlist.h> | 4 | #include <linux/scatterlist.h> |
| 5 | #include <linux/mm.h> | 5 | #include <linux/mm.h> |
| 6 | #include <linux/dma-debug.h> | ||
| 6 | 7 | ||
| 7 | #define DMA_ERROR_CODE (~(dma_addr_t)0x0) | 8 | #define DMA_ERROR_CODE (~(dma_addr_t)0x0) |
| 8 | 9 | ||
| @@ -13,142 +14,40 @@ extern int dma_set_mask(struct device *dev, u64 dma_mask); | |||
| 13 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | 14 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) |
| 14 | #define dma_is_consistent(d, h) (1) | 15 | #define dma_is_consistent(d, h) (1) |
| 15 | 16 | ||
| 16 | struct dma_ops { | 17 | extern struct dma_map_ops *dma_ops, pci32_dma_ops; |
| 17 | void *(*alloc_coherent)(struct device *dev, size_t size, | 18 | extern struct bus_type pci_bus_type; |
| 18 | dma_addr_t *dma_handle, gfp_t flag); | ||
| 19 | void (*free_coherent)(struct device *dev, size_t size, | ||
| 20 | void *cpu_addr, dma_addr_t dma_handle); | ||
| 21 | dma_addr_t (*map_page)(struct device *dev, struct page *page, | ||
| 22 | unsigned long offset, size_t size, | ||
| 23 | enum dma_data_direction direction); | ||
| 24 | void (*unmap_page)(struct device *dev, dma_addr_t dma_addr, | ||
| 25 | size_t size, | ||
| 26 | enum dma_data_direction direction); | ||
| 27 | int (*map_sg)(struct device *dev, struct scatterlist *sg, int nents, | ||
| 28 | enum dma_data_direction direction); | ||
| 29 | void (*unmap_sg)(struct device *dev, struct scatterlist *sg, | ||
| 30 | int nhwentries, | ||
| 31 | enum dma_data_direction direction); | ||
| 32 | void (*sync_single_for_cpu)(struct device *dev, | ||
| 33 | dma_addr_t dma_handle, size_t size, | ||
| 34 | enum dma_data_direction direction); | ||
| 35 | void (*sync_single_for_device)(struct device *dev, | ||
| 36 | dma_addr_t dma_handle, size_t size, | ||
| 37 | enum dma_data_direction direction); | ||
| 38 | void (*sync_sg_for_cpu)(struct device *dev, struct scatterlist *sg, | ||
| 39 | int nelems, | ||
| 40 | enum dma_data_direction direction); | ||
| 41 | void (*sync_sg_for_device)(struct device *dev, | ||
| 42 | struct scatterlist *sg, int nents, | ||
| 43 | enum dma_data_direction dir); | ||
| 44 | }; | ||
| 45 | extern const struct dma_ops *dma_ops; | ||
| 46 | 19 | ||
| 47 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | 20 | static inline struct dma_map_ops *get_dma_ops(struct device *dev) |
| 48 | dma_addr_t *dma_handle, gfp_t flag) | ||
| 49 | { | ||
| 50 | return dma_ops->alloc_coherent(dev, size, dma_handle, flag); | ||
| 51 | } | ||
| 52 | |||
| 53 | static inline void dma_free_coherent(struct device *dev, size_t size, | ||
| 54 | void *cpu_addr, dma_addr_t dma_handle) | ||
| 55 | { | ||
| 56 | dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); | ||
| 57 | } | ||
| 58 | |||
| 59 | static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, | ||
| 60 | size_t size, | ||
| 61 | enum dma_data_direction direction) | ||
| 62 | { | ||
| 63 | return dma_ops->map_page(dev, virt_to_page(cpu_addr), | ||
| 64 | (unsigned long)cpu_addr & ~PAGE_MASK, size, | ||
| 65 | direction); | ||
| 66 | } | ||
| 67 | |||
| 68 | static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, | ||
| 69 | size_t size, | ||
| 70 | enum dma_data_direction direction) | ||
| 71 | { | ||
| 72 | dma_ops->unmap_page(dev, dma_addr, size, direction); | ||
| 73 | } | ||
| 74 | |||
| 75 | static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, | ||
| 76 | unsigned long offset, size_t size, | ||
| 77 | enum dma_data_direction direction) | ||
| 78 | { | ||
| 79 | return dma_ops->map_page(dev, page, offset, size, direction); | ||
| 80 | } | ||
| 81 | |||
| 82 | static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address, | ||
| 83 | size_t size, | ||
| 84 | enum dma_data_direction direction) | ||
| 85 | { | ||
| 86 | dma_ops->unmap_page(dev, dma_address, size, direction); | ||
| 87 | } | ||
| 88 | |||
| 89 | static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, | ||
| 90 | int nents, enum dma_data_direction direction) | ||
| 91 | { | ||
| 92 | return dma_ops->map_sg(dev, sg, nents, direction); | ||
| 93 | } | ||
| 94 | |||
| 95 | static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, | ||
| 96 | int nents, enum dma_data_direction direction) | ||
| 97 | { | 21 | { |
| 98 | dma_ops->unmap_sg(dev, sg, nents, direction); | 22 | #if defined(CONFIG_SPARC32) && defined(CONFIG_PCI) |
| 99 | } | 23 | if (dev->bus == &pci_bus_type) |
| 100 | 24 | return &pci32_dma_ops; | |
| 101 | static inline void dma_sync_single_for_cpu(struct device *dev, | 25 | #endif |
| 102 | dma_addr_t dma_handle, size_t size, | 26 | return dma_ops; |
| 103 | enum dma_data_direction direction) | ||
| 104 | { | ||
| 105 | dma_ops->sync_single_for_cpu(dev, dma_handle, size, direction); | ||
| 106 | } | 27 | } |
| 107 | 28 | ||
| 108 | static inline void dma_sync_single_for_device(struct device *dev, | 29 | #include <asm-generic/dma-mapping-common.h> |
| 109 | dma_addr_t dma_handle, | ||
| 110 | size_t size, | ||
| 111 | enum dma_data_direction direction) | ||
| 112 | { | ||
| 113 | if (dma_ops->sync_single_for_device) | ||
| 114 | dma_ops->sync_single_for_device(dev, dma_handle, size, | ||
| 115 | direction); | ||
| 116 | } | ||
| 117 | 30 | ||
| 118 | static inline void dma_sync_sg_for_cpu(struct device *dev, | 31 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, |
| 119 | struct scatterlist *sg, int nelems, | 32 | dma_addr_t *dma_handle, gfp_t flag) |
| 120 | enum dma_data_direction direction) | ||
| 121 | { | 33 | { |
| 122 | dma_ops->sync_sg_for_cpu(dev, sg, nelems, direction); | 34 | struct dma_map_ops *ops = get_dma_ops(dev); |
| 123 | } | 35 | void *cpu_addr; |
| 124 | 36 | ||
| 125 | static inline void dma_sync_sg_for_device(struct device *dev, | 37 | cpu_addr = ops->alloc_coherent(dev, size, dma_handle, flag); |
| 126 | struct scatterlist *sg, int nelems, | 38 | debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); |
| 127 | enum dma_data_direction direction) | 39 | return cpu_addr; |
| 128 | { | ||
| 129 | if (dma_ops->sync_sg_for_device) | ||
| 130 | dma_ops->sync_sg_for_device(dev, sg, nelems, direction); | ||
| 131 | } | 40 | } |
| 132 | 41 | ||
| 133 | static inline void dma_sync_single_range_for_cpu(struct device *dev, | 42 | static inline void dma_free_coherent(struct device *dev, size_t size, |
| 134 | dma_addr_t dma_handle, | 43 | void *cpu_addr, dma_addr_t dma_handle) |
| 135 | unsigned long offset, | ||
| 136 | size_t size, | ||
| 137 | enum dma_data_direction dir) | ||
| 138 | { | 44 | { |
| 139 | dma_sync_single_for_cpu(dev, dma_handle+offset, size, dir); | 45 | struct dma_map_ops *ops = get_dma_ops(dev); |
| 140 | } | ||
| 141 | 46 | ||
| 142 | static inline void dma_sync_single_range_for_device(struct device *dev, | 47 | debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); |
| 143 | dma_addr_t dma_handle, | 48 | ops->free_coherent(dev, size, cpu_addr, dma_handle); |
| 144 | unsigned long offset, | ||
| 145 | size_t size, | ||
| 146 | enum dma_data_direction dir) | ||
| 147 | { | ||
| 148 | dma_sync_single_for_device(dev, dma_handle+offset, size, dir); | ||
| 149 | } | 49 | } |
| 150 | 50 | ||
| 151 | |||
| 152 | static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | 51 | static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) |
| 153 | { | 52 | { |
| 154 | return (dma_addr == DMA_ERROR_CODE); | 53 | return (dma_addr == DMA_ERROR_CODE); |
diff --git a/arch/sparc/include/asm/irq_64.h b/arch/sparc/include/asm/irq_64.h index 1934f2cbf513..a0b443cb3c1f 100644 --- a/arch/sparc/include/asm/irq_64.h +++ b/arch/sparc/include/asm/irq_64.h | |||
| @@ -89,8 +89,8 @@ static inline unsigned long get_softint(void) | |||
| 89 | return retval; | 89 | return retval; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | void __trigger_all_cpu_backtrace(void); | 92 | void arch_trigger_all_cpu_backtrace(void); |
| 93 | #define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace() | 93 | #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace |
| 94 | 94 | ||
| 95 | extern void *hardirq_stack[NR_CPUS]; | 95 | extern void *hardirq_stack[NR_CPUS]; |
| 96 | extern void *softirq_stack[NR_CPUS]; | 96 | extern void *softirq_stack[NR_CPUS]; |
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h new file mode 100644 index 000000000000..28a42b73f64f --- /dev/null +++ b/arch/sparc/include/asm/leon.h | |||
| @@ -0,0 +1,362 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2004 Konrad Eisele (eiselekd@web.de,konrad@gaisler.com) Gaisler Research | ||
| 3 | * Copyright (C) 2004 Stefan Holst (mail@s-holst.de) Uni-Stuttgart | ||
| 4 | * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB | ||
| 5 | * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef LEON_H_INCLUDE | ||
| 9 | #define LEON_H_INCLUDE | ||
| 10 | |||
| 11 | #ifdef CONFIG_SPARC_LEON | ||
| 12 | |||
| 13 | #define ASI_LEON_NOCACHE 0x01 | ||
| 14 | |||
| 15 | #define ASI_LEON_DCACHE_MISS 0x1 | ||
| 16 | |||
| 17 | #define ASI_LEON_CACHEREGS 0x02 | ||
| 18 | #define ASI_LEON_IFLUSH 0x10 | ||
| 19 | #define ASI_LEON_DFLUSH 0x11 | ||
| 20 | |||
| 21 | #define ASI_LEON_MMUFLUSH 0x18 | ||
| 22 | #define ASI_LEON_MMUREGS 0x19 | ||
| 23 | #define ASI_LEON_BYPASS 0x1c | ||
| 24 | #define ASI_LEON_FLUSH_PAGE 0x10 | ||
| 25 | |||
| 26 | /* mmu register access, ASI_LEON_MMUREGS */ | ||
| 27 | #define LEON_CNR_CTRL 0x000 | ||
| 28 | #define LEON_CNR_CTXP 0x100 | ||
| 29 | #define LEON_CNR_CTX 0x200 | ||
| 30 | #define LEON_CNR_F 0x300 | ||
| 31 | #define LEON_CNR_FADDR 0x400 | ||
| 32 | |||
| 33 | #define LEON_CNR_CTX_NCTX 256 /*number of MMU ctx */ | ||
| 34 | |||
| 35 | #define LEON_CNR_CTRL_TLBDIS 0x80000000 | ||
| 36 | |||
| 37 | #define LEON_MMUTLB_ENT_MAX 64 | ||
| 38 | |||
| 39 | /* | ||
| 40 | * diagnostic access from mmutlb.vhd: | ||
| 41 | * 0: pte address | ||
| 42 | * 4: pte | ||
| 43 | * 8: additional flags | ||
| 44 | */ | ||
| 45 | #define LEON_DIAGF_LVL 0x3 | ||
| 46 | #define LEON_DIAGF_WR 0x8 | ||
| 47 | #define LEON_DIAGF_WR_SHIFT 3 | ||
| 48 | #define LEON_DIAGF_HIT 0x10 | ||
| 49 | #define LEON_DIAGF_HIT_SHIFT 4 | ||
| 50 | #define LEON_DIAGF_CTX 0x1fe0 | ||
| 51 | #define LEON_DIAGF_CTX_SHIFT 5 | ||
| 52 | #define LEON_DIAGF_VALID 0x2000 | ||
| 53 | #define LEON_DIAGF_VALID_SHIFT 13 | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Interrupt Sources | ||
| 57 | * | ||
| 58 | * The interrupt source numbers directly map to the trap type and to | ||
| 59 | * the bits used in the Interrupt Clear, Interrupt Force, Interrupt Mask, | ||
| 60 | * and the Interrupt Pending Registers. | ||
| 61 | */ | ||
| 62 | #define LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR 1 | ||
| 63 | #define LEON_INTERRUPT_UART_1_RX_TX 2 | ||
| 64 | #define LEON_INTERRUPT_UART_0_RX_TX 3 | ||
| 65 | #define LEON_INTERRUPT_EXTERNAL_0 4 | ||
| 66 | #define LEON_INTERRUPT_EXTERNAL_1 5 | ||
| 67 | #define LEON_INTERRUPT_EXTERNAL_2 6 | ||
| 68 | #define LEON_INTERRUPT_EXTERNAL_3 7 | ||
| 69 | #define LEON_INTERRUPT_TIMER1 8 | ||
| 70 | #define LEON_INTERRUPT_TIMER2 9 | ||
| 71 | #define LEON_INTERRUPT_EMPTY1 10 | ||
| 72 | #define LEON_INTERRUPT_EMPTY2 11 | ||
| 73 | #define LEON_INTERRUPT_OPEN_ETH 12 | ||
| 74 | #define LEON_INTERRUPT_EMPTY4 13 | ||
| 75 | #define LEON_INTERRUPT_EMPTY5 14 | ||
| 76 | #define LEON_INTERRUPT_EMPTY6 15 | ||
| 77 | |||
| 78 | /* irq masks */ | ||
| 79 | #define LEON_HARD_INT(x) (1 << (x)) /* irq 0-15 */ | ||
| 80 | #define LEON_IRQMASK_R 0x0000fffe /* bit 15- 1 of lregs.irqmask */ | ||
| 81 | #define LEON_IRQPRIO_R 0xfffe0000 /* bit 31-17 of lregs.irqmask */ | ||
| 82 | |||
| 83 | /* leon uart register definitions */ | ||
| 84 | #define LEON_OFF_UDATA 0x0 | ||
| 85 | #define LEON_OFF_USTAT 0x4 | ||
| 86 | #define LEON_OFF_UCTRL 0x8 | ||
| 87 | #define LEON_OFF_USCAL 0xc | ||
| 88 | |||
| 89 | #define LEON_UCTRL_RE 0x01 | ||
| 90 | #define LEON_UCTRL_TE 0x02 | ||
| 91 | #define LEON_UCTRL_RI 0x04 | ||
| 92 | #define LEON_UCTRL_TI 0x08 | ||
| 93 | #define LEON_UCTRL_PS 0x10 | ||
| 94 | #define LEON_UCTRL_PE 0x20 | ||
| 95 | #define LEON_UCTRL_FL 0x40 | ||
| 96 | #define LEON_UCTRL_LB 0x80 | ||
| 97 | |||
| 98 | #define LEON_USTAT_DR 0x01 | ||
| 99 | #define LEON_USTAT_TS 0x02 | ||
| 100 | #define LEON_USTAT_TH 0x04 | ||
| 101 | #define LEON_USTAT_BR 0x08 | ||
| 102 | #define LEON_USTAT_OV 0x10 | ||
| 103 | #define LEON_USTAT_PE 0x20 | ||
| 104 | #define LEON_USTAT_FE 0x40 | ||
| 105 | |||
| 106 | #define LEON_MCFG2_SRAMDIS 0x00002000 | ||
| 107 | #define LEON_MCFG2_SDRAMEN 0x00004000 | ||
| 108 | #define LEON_MCFG2_SRAMBANKSZ 0x00001e00 /* [12-9] */ | ||
| 109 | #define LEON_MCFG2_SRAMBANKSZ_SHIFT 9 | ||
| 110 | #define LEON_MCFG2_SDRAMBANKSZ 0x03800000 /* [25-23] */ | ||
| 111 | #define LEON_MCFG2_SDRAMBANKSZ_SHIFT 23 | ||
| 112 | |||
| 113 | #define LEON_TCNT0_MASK 0x7fffff | ||
| 114 | |||
| 115 | #define LEON_USTAT_ERROR (LEON_USTAT_OV | LEON_USTAT_PE | LEON_USTAT_FE) | ||
| 116 | /* no break yet */ | ||
| 117 | |||
| 118 | #define ASI_LEON3_SYSCTRL 0x02 | ||
| 119 | #define ASI_LEON3_SYSCTRL_ICFG 0x08 | ||
| 120 | #define ASI_LEON3_SYSCTRL_DCFG 0x0c | ||
| 121 | #define ASI_LEON3_SYSCTRL_CFG_SNOOPING (1 << 27) | ||
| 122 | #define ASI_LEON3_SYSCTRL_CFG_SSIZE(c) (1 << ((c >> 20) & 0xf)) | ||
| 123 | |||
| 124 | #ifndef __ASSEMBLY__ | ||
| 125 | |||
| 126 | /* do a virtual address read without cache */ | ||
| 127 | static inline unsigned long leon_readnobuffer_reg(unsigned long paddr) | ||
| 128 | { | ||
| 129 | unsigned long retval; | ||
| 130 | __asm__ __volatile__("lda [%1] %2, %0\n\t" : | ||
| 131 | "=r"(retval) : "r"(paddr), "i"(ASI_LEON_NOCACHE)); | ||
| 132 | return retval; | ||
| 133 | } | ||
| 134 | |||
| 135 | /* do a physical address bypass write, i.e. for 0x80000000 */ | ||
| 136 | static inline void leon_store_reg(unsigned long paddr, unsigned long value) | ||
| 137 | { | ||
| 138 | __asm__ __volatile__("sta %0, [%1] %2\n\t" : : "r"(value), "r"(paddr), | ||
| 139 | "i"(ASI_LEON_BYPASS) : "memory"); | ||
| 140 | } | ||
| 141 | |||
| 142 | /* do a physical address bypass load, i.e. for 0x80000000 */ | ||
| 143 | static inline unsigned long leon_load_reg(unsigned long paddr) | ||
| 144 | { | ||
| 145 | unsigned long retval; | ||
| 146 | __asm__ __volatile__("lda [%1] %2, %0\n\t" : | ||
| 147 | "=r"(retval) : "r"(paddr), "i"(ASI_LEON_BYPASS)); | ||
| 148 | return retval; | ||
| 149 | } | ||
| 150 | |||
| 151 | extern inline void leon_srmmu_disabletlb(void) | ||
| 152 | { | ||
| 153 | unsigned int retval; | ||
| 154 | __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0), | ||
| 155 | "i"(ASI_LEON_MMUREGS)); | ||
| 156 | retval |= LEON_CNR_CTRL_TLBDIS; | ||
| 157 | __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0), | ||
| 158 | "i"(ASI_LEON_MMUREGS) : "memory"); | ||
| 159 | } | ||
| 160 | |||
| 161 | extern inline void leon_srmmu_enabletlb(void) | ||
| 162 | { | ||
| 163 | unsigned int retval; | ||
| 164 | __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0), | ||
| 165 | "i"(ASI_LEON_MMUREGS)); | ||
| 166 | retval = retval & ~LEON_CNR_CTRL_TLBDIS; | ||
| 167 | __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0), | ||
| 168 | "i"(ASI_LEON_MMUREGS) : "memory"); | ||
| 169 | } | ||
| 170 | |||
| 171 | /* macro access for leon_load_reg() and leon_store_reg() */ | ||
| 172 | #define LEON3_BYPASS_LOAD_PA(x) (leon_load_reg((unsigned long)(x))) | ||
| 173 | #define LEON3_BYPASS_STORE_PA(x, v) (leon_store_reg((unsigned long)(x), (unsigned long)(v))) | ||
| 174 | #define LEON3_BYPASS_ANDIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) & v) | ||
| 175 | #define LEON3_BYPASS_ORIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) | v) | ||
| 176 | #define LEON_BYPASS_LOAD_PA(x) leon_load_reg((unsigned long)(x)) | ||
| 177 | #define LEON_BYPASS_STORE_PA(x, v) leon_store_reg((unsigned long)(x), (unsigned long)(v)) | ||
| 178 | #define LEON_REGLOAD_PA(x) leon_load_reg((unsigned long)(x)+LEON_PREGS) | ||
| 179 | #define LEON_REGSTORE_PA(x, v) leon_store_reg((unsigned long)(x)+LEON_PREGS, (unsigned long)(v)) | ||
| 180 | #define LEON_REGSTORE_OR_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) | (unsigned long)(v)) | ||
| 181 | #define LEON_REGSTORE_AND_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) & (unsigned long)(v)) | ||
| 182 | |||
| 183 | /* macro access for leon_readnobuffer_reg() */ | ||
| 184 | #define LEON_BYPASSCACHE_LOAD_VA(x) leon_readnobuffer_reg((unsigned long)(x)) | ||
| 185 | |||
| 186 | extern void sparc_leon_eirq_register(int eirq); | ||
| 187 | extern void leon_init(void); | ||
| 188 | extern void leon_switch_mm(void); | ||
| 189 | extern void leon_init_IRQ(void); | ||
| 190 | |||
| 191 | extern unsigned long last_valid_pfn; | ||
| 192 | |||
| 193 | extern inline unsigned long sparc_leon3_get_dcachecfg(void) | ||
| 194 | { | ||
| 195 | unsigned int retval; | ||
| 196 | __asm__ __volatile__("lda [%1] %2, %0\n\t" : | ||
| 197 | "=r"(retval) : | ||
| 198 | "r"(ASI_LEON3_SYSCTRL_DCFG), | ||
| 199 | "i"(ASI_LEON3_SYSCTRL)); | ||
| 200 | return retval; | ||
| 201 | } | ||
| 202 | |||
| 203 | /* enable snooping */ | ||
| 204 | extern inline void sparc_leon3_enable_snooping(void) | ||
| 205 | { | ||
| 206 | __asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t" | ||
| 207 | "set 0x800000, %%l2\n\t" | ||
| 208 | "or %%l2, %%l1, %%l2\n\t" | ||
| 209 | "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2"); | ||
| 210 | }; | ||
| 211 | |||
| 212 | extern inline void sparc_leon3_disable_cache(void) | ||
| 213 | { | ||
| 214 | __asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t" | ||
| 215 | "set 0x00000f, %%l2\n\t" | ||
| 216 | "andn %%l2, %%l1, %%l2\n\t" | ||
| 217 | "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2"); | ||
| 218 | }; | ||
| 219 | |||
| 220 | #endif /*!__ASSEMBLY__*/ | ||
| 221 | |||
| 222 | #ifdef CONFIG_SMP | ||
| 223 | # define LEON3_IRQ_RESCHEDULE 13 | ||
| 224 | # define LEON3_IRQ_TICKER (leon_percpu_timer_dev[0].irq) | ||
| 225 | # define LEON3_IRQ_CROSS_CALL 15 | ||
| 226 | #endif | ||
| 227 | |||
| 228 | #if defined(PAGE_SIZE_LEON_8K) | ||
| 229 | #define LEON_PAGE_SIZE_LEON 1 | ||
| 230 | #elif defined(PAGE_SIZE_LEON_16K) | ||
| 231 | #define LEON_PAGE_SIZE_LEON 2) | ||
| 232 | #else | ||
| 233 | #define LEON_PAGE_SIZE_LEON 0 | ||
| 234 | #endif | ||
| 235 | |||
| 236 | #if LEON_PAGE_SIZE_LEON == 0 | ||
| 237 | /* [ 8, 6, 6 ] + 12 */ | ||
| 238 | #define LEON_PGD_SH 24 | ||
| 239 | #define LEON_PGD_M 0xff | ||
| 240 | #define LEON_PMD_SH 18 | ||
| 241 | #define LEON_PMD_SH_V (LEON_PGD_SH-2) | ||
| 242 | #define LEON_PMD_M 0x3f | ||
| 243 | #define LEON_PTE_SH 12 | ||
| 244 | #define LEON_PTE_M 0x3f | ||
| 245 | #elif LEON_PAGE_SIZE_LEON == 1 | ||
| 246 | /* [ 7, 6, 6 ] + 13 */ | ||
| 247 | #define LEON_PGD_SH 25 | ||
| 248 | #define LEON_PGD_M 0x7f | ||
| 249 | #define LEON_PMD_SH 19 | ||
| 250 | #define LEON_PMD_SH_V (LEON_PGD_SH-1) | ||
| 251 | #define LEON_PMD_M 0x3f | ||
| 252 | #define LEON_PTE_SH 13 | ||
| 253 | #define LEON_PTE_M 0x3f | ||
| 254 | #elif LEON_PAGE_SIZE_LEON == 2 | ||
| 255 | /* [ 6, 6, 6 ] + 14 */ | ||
| 256 | #define LEON_PGD_SH 26 | ||
| 257 | #define LEON_PGD_M 0x3f | ||
| 258 | #define LEON_PMD_SH 20 | ||
| 259 | #define LEON_PMD_SH_V (LEON_PGD_SH-0) | ||
| 260 | #define LEON_PMD_M 0x3f | ||
| 261 | #define LEON_PTE_SH 14 | ||
| 262 | #define LEON_PTE_M 0x3f | ||
| 263 | #elif LEON_PAGE_SIZE_LEON == 3 | ||
| 264 | /* [ 4, 7, 6 ] + 15 */ | ||
| 265 | #define LEON_PGD_SH 28 | ||
| 266 | #define LEON_PGD_M 0x0f | ||
| 267 | #define LEON_PMD_SH 21 | ||
| 268 | #define LEON_PMD_SH_V (LEON_PGD_SH-0) | ||
| 269 | #define LEON_PMD_M 0x7f | ||
| 270 | #define LEON_PTE_SH 15 | ||
| 271 | #define LEON_PTE_M 0x3f | ||
| 272 | #else | ||
| 273 | #error cannot determine LEON_PAGE_SIZE_LEON | ||
| 274 | #endif | ||
| 275 | |||
| 276 | #define PAGE_MIN_SHIFT (12) | ||
| 277 | #define PAGE_MIN_SIZE (1UL << PAGE_MIN_SHIFT) | ||
| 278 | |||
| 279 | #define LEON3_XCCR_SETS_MASK 0x07000000UL | ||
| 280 | #define LEON3_XCCR_SSIZE_MASK 0x00f00000UL | ||
| 281 | |||
| 282 | #define LEON2_CCR_DSETS_MASK 0x03000000UL | ||
| 283 | #define LEON2_CFG_SSIZE_MASK 0x00007000UL | ||
| 284 | |||
| 285 | #ifndef __ASSEMBLY__ | ||
| 286 | extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr); | ||
| 287 | extern void leon_flush_icache_all(void); | ||
| 288 | extern void leon_flush_dcache_all(void); | ||
| 289 | extern void leon_flush_cache_all(void); | ||
| 290 | extern void leon_flush_tlb_all(void); | ||
| 291 | extern int leon_flush_during_switch; | ||
| 292 | extern int leon_flush_needed(void); | ||
| 293 | |||
| 294 | struct vm_area_struct; | ||
| 295 | extern void leon_flush_icache_all(void); | ||
| 296 | extern void leon_flush_dcache_all(void); | ||
| 297 | extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page); | ||
| 298 | extern void leon_flush_cache_all(void); | ||
| 299 | extern void leon_flush_tlb_all(void); | ||
| 300 | extern int leon_flush_during_switch; | ||
| 301 | extern int leon_flush_needed(void); | ||
| 302 | extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page); | ||
| 303 | |||
| 304 | /* struct that hold LEON3 cache configuration registers */ | ||
| 305 | struct leon3_cacheregs { | ||
| 306 | unsigned long ccr; /* 0x00 - Cache Control Register */ | ||
| 307 | unsigned long iccr; /* 0x08 - Instruction Cache Configuration Register */ | ||
| 308 | unsigned long dccr; /* 0x0c - Data Cache Configuration Register */ | ||
| 309 | }; | ||
| 310 | |||
| 311 | /* struct that hold LEON2 cache configuration register | ||
| 312 | * & configuration register | ||
| 313 | */ | ||
| 314 | struct leon2_cacheregs { | ||
| 315 | unsigned long ccr, cfg; | ||
| 316 | }; | ||
| 317 | |||
| 318 | #ifdef __KERNEL__ | ||
| 319 | |||
| 320 | #include <linux/interrupt.h> | ||
| 321 | |||
| 322 | struct device_node; | ||
| 323 | extern int sparc_leon_eirq_get(int eirq, int cpu); | ||
| 324 | extern irqreturn_t sparc_leon_eirq_isr(int dummy, void *dev_id); | ||
| 325 | extern void sparc_leon_eirq_register(int eirq); | ||
| 326 | extern void leon_clear_clock_irq(void); | ||
| 327 | extern void leon_load_profile_irq(int cpu, unsigned int limit); | ||
| 328 | extern void leon_init_timers(irq_handler_t counter_fn); | ||
| 329 | extern void leon_clear_clock_irq(void); | ||
| 330 | extern void leon_load_profile_irq(int cpu, unsigned int limit); | ||
| 331 | extern void leon_trans_init(struct device_node *dp); | ||
| 332 | extern void leon_node_init(struct device_node *dp, struct device_node ***nextp); | ||
| 333 | extern void leon_init_IRQ(void); | ||
| 334 | extern void leon_init(void); | ||
| 335 | extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr); | ||
| 336 | extern void init_leon(void); | ||
| 337 | extern void poke_leonsparc(void); | ||
| 338 | extern void leon3_getCacheRegs(struct leon3_cacheregs *regs); | ||
| 339 | extern int leon_flush_needed(void); | ||
| 340 | extern void leon_switch_mm(void); | ||
| 341 | extern int srmmu_swprobe_trace; | ||
| 342 | |||
| 343 | #endif /* __KERNEL__ */ | ||
| 344 | |||
| 345 | #endif /* __ASSEMBLY__ */ | ||
| 346 | |||
| 347 | /* macros used in leon_mm.c */ | ||
| 348 | #define PFN(x) ((x) >> PAGE_SHIFT) | ||
| 349 | #define _pfn_valid(pfn) ((pfn < last_valid_pfn) && (pfn >= PFN(phys_base))) | ||
| 350 | #define _SRMMU_PTE_PMASK_LEON 0xffffffff | ||
| 351 | |||
| 352 | #else /* defined(CONFIG_SPARC_LEON) */ | ||
| 353 | |||
| 354 | /* nop definitions for !LEON case */ | ||
| 355 | #define leon_init() do {} while (0) | ||
| 356 | #define leon_switch_mm() do {} while (0) | ||
| 357 | #define leon_init_IRQ() do {} while (0) | ||
| 358 | #define init_leon() do {} while (0) | ||
| 359 | |||
| 360 | #endif /* !defined(CONFIG_SPARC_LEON) */ | ||
| 361 | |||
| 362 | #endif | ||
diff --git a/arch/sparc/include/asm/leon_amba.h b/arch/sparc/include/asm/leon_amba.h new file mode 100644 index 000000000000..618e88821795 --- /dev/null +++ b/arch/sparc/include/asm/leon_amba.h | |||
| @@ -0,0 +1,263 @@ | |||
| 1 | /* | ||
| 2 | *Copyright (C) 2004 Konrad Eisele (eiselekd@web.de,konrad@gaisler.com), Gaisler Research | ||
| 3 | *Copyright (C) 2004 Stefan Holst (mail@s-holst.de), Uni-Stuttgart | ||
| 4 | *Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com),Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef LEON_AMBA_H_INCLUDE | ||
| 8 | #define LEON_AMBA_H_INCLUDE | ||
| 9 | |||
| 10 | #ifndef __ASSEMBLY__ | ||
| 11 | |||
| 12 | struct amba_prom_registers { | ||
| 13 | unsigned int phys_addr; /* The physical address of this register */ | ||
| 14 | unsigned int reg_size; /* How many bytes does this register take up? */ | ||
| 15 | }; | ||
| 16 | |||
| 17 | #endif | ||
| 18 | |||
| 19 | /* | ||
| 20 | * The following defines the bits in the LEON UART Status Registers. | ||
| 21 | */ | ||
| 22 | |||
| 23 | #define LEON_REG_UART_STATUS_DR 0x00000001 /* Data Ready */ | ||
| 24 | #define LEON_REG_UART_STATUS_TSE 0x00000002 /* TX Send Register Empty */ | ||
| 25 | #define LEON_REG_UART_STATUS_THE 0x00000004 /* TX Hold Register Empty */ | ||
| 26 | #define LEON_REG_UART_STATUS_BR 0x00000008 /* Break Error */ | ||
| 27 | #define LEON_REG_UART_STATUS_OE 0x00000010 /* RX Overrun Error */ | ||
| 28 | #define LEON_REG_UART_STATUS_PE 0x00000020 /* RX Parity Error */ | ||
| 29 | #define LEON_REG_UART_STATUS_FE 0x00000040 /* RX Framing Error */ | ||
| 30 | #define LEON_REG_UART_STATUS_ERR 0x00000078 /* Error Mask */ | ||
| 31 | |||
| 32 | /* | ||
| 33 | * The following defines the bits in the LEON UART Ctrl Registers. | ||
| 34 | */ | ||
| 35 | |||
| 36 | #define LEON_REG_UART_CTRL_RE 0x00000001 /* Receiver enable */ | ||
| 37 | #define LEON_REG_UART_CTRL_TE 0x00000002 /* Transmitter enable */ | ||
| 38 | #define LEON_REG_UART_CTRL_RI 0x00000004 /* Receiver interrupt enable */ | ||
| 39 | #define LEON_REG_UART_CTRL_TI 0x00000008 /* Transmitter irq */ | ||
| 40 | #define LEON_REG_UART_CTRL_PS 0x00000010 /* Parity select */ | ||
| 41 | #define LEON_REG_UART_CTRL_PE 0x00000020 /* Parity enable */ | ||
| 42 | #define LEON_REG_UART_CTRL_FL 0x00000040 /* Flow control enable */ | ||
| 43 | #define LEON_REG_UART_CTRL_LB 0x00000080 /* Loop Back enable */ | ||
| 44 | |||
| 45 | #define LEON3_GPTIMER_EN 1 | ||
| 46 | #define LEON3_GPTIMER_RL 2 | ||
| 47 | #define LEON3_GPTIMER_LD 4 | ||
| 48 | #define LEON3_GPTIMER_IRQEN 8 | ||
| 49 | #define LEON3_GPTIMER_SEPIRQ 8 | ||
| 50 | |||
| 51 | #define LEON23_REG_TIMER_CONTROL_EN 0x00000001 /* 1 = enable counting */ | ||
| 52 | /* 0 = hold scalar and counter */ | ||
| 53 | #define LEON23_REG_TIMER_CONTROL_RL 0x00000002 /* 1 = reload at 0 */ | ||
| 54 | /* 0 = stop at 0 */ | ||
| 55 | #define LEON23_REG_TIMER_CONTROL_LD 0x00000004 /* 1 = load counter */ | ||
| 56 | /* 0 = no function */ | ||
| 57 | #define LEON23_REG_TIMER_CONTROL_IQ 0x00000008 /* 1 = irq enable */ | ||
| 58 | /* 0 = no function */ | ||
| 59 | |||
| 60 | /* | ||
| 61 | * The following defines the bits in the LEON PS/2 Status Registers. | ||
| 62 | */ | ||
| 63 | |||
| 64 | #define LEON_REG_PS2_STATUS_DR 0x00000001 /* Data Ready */ | ||
| 65 | #define LEON_REG_PS2_STATUS_PE 0x00000002 /* Parity error */ | ||
| 66 | #define LEON_REG_PS2_STATUS_FE 0x00000004 /* Framing error */ | ||
| 67 | #define LEON_REG_PS2_STATUS_KI 0x00000008 /* Keyboard inhibit */ | ||
| 68 | #define LEON_REG_PS2_STATUS_RF 0x00000010 /* RX buffer full */ | ||
| 69 | #define LEON_REG_PS2_STATUS_TF 0x00000020 /* TX buffer full */ | ||
| 70 | |||
| 71 | /* | ||
| 72 | * The following defines the bits in the LEON PS/2 Ctrl Registers. | ||
| 73 | */ | ||
| 74 | |||
| 75 | #define LEON_REG_PS2_CTRL_RE 0x00000001 /* Receiver enable */ | ||
| 76 | #define LEON_REG_PS2_CTRL_TE 0x00000002 /* Transmitter enable */ | ||
| 77 | #define LEON_REG_PS2_CTRL_RI 0x00000004 /* Keyboard receive irq */ | ||
| 78 | #define LEON_REG_PS2_CTRL_TI 0x00000008 /* Keyboard transmit irq */ | ||
| 79 | |||
| 80 | #define LEON3_IRQMPSTATUS_CPUNR 28 | ||
| 81 | #define LEON3_IRQMPSTATUS_BROADCAST 27 | ||
| 82 | |||
| 83 | #define GPTIMER_CONFIG_IRQNT(a) (((a) >> 3) & 0x1f) | ||
| 84 | #define GPTIMER_CONFIG_ISSEP(a) ((a) & (1 << 8)) | ||
| 85 | #define GPTIMER_CONFIG_NTIMERS(a) ((a) & (0x7)) | ||
| 86 | #define LEON3_GPTIMER_CTRL_PENDING 0x10 | ||
| 87 | #define LEON3_GPTIMER_CONFIG_NRTIMERS(c) ((c)->config & 0x7) | ||
| 88 | #define LEON3_GPTIMER_CTRL_ISPENDING(r) (((r)&LEON3_GPTIMER_CTRL_PENDING) ? 1 : 0) | ||
| 89 | |||
| 90 | #ifdef CONFIG_SPARC_LEON | ||
| 91 | |||
| 92 | #ifndef __ASSEMBLY__ | ||
| 93 | |||
| 94 | struct leon3_irqctrl_regs_map { | ||
| 95 | u32 ilevel; | ||
| 96 | u32 ipend; | ||
| 97 | u32 iforce; | ||
| 98 | u32 iclear; | ||
| 99 | u32 mpstatus; | ||
| 100 | u32 mpbroadcast; | ||
| 101 | u32 notused02; | ||
| 102 | u32 notused03; | ||
| 103 | u32 notused10; | ||
| 104 | u32 notused11; | ||
| 105 | u32 notused12; | ||
| 106 | u32 notused13; | ||
| 107 | u32 notused20; | ||
| 108 | u32 notused21; | ||
| 109 | u32 notused22; | ||
| 110 | u32 notused23; | ||
| 111 | u32 mask[16]; | ||
| 112 | u32 force[16]; | ||
| 113 | /* Extended IRQ registers */ | ||
| 114 | u32 intid[16]; /* 0xc0 */ | ||
| 115 | }; | ||
| 116 | |||
| 117 | struct leon3_apbuart_regs_map { | ||
| 118 | u32 data; | ||
| 119 | u32 status; | ||
| 120 | u32 ctrl; | ||
| 121 | u32 scaler; | ||
| 122 | }; | ||
| 123 | |||
| 124 | struct leon3_gptimerelem_regs_map { | ||
| 125 | u32 val; | ||
| 126 | u32 rld; | ||
| 127 | u32 ctrl; | ||
| 128 | u32 unused; | ||
| 129 | }; | ||
| 130 | |||
| 131 | struct leon3_gptimer_regs_map { | ||
| 132 | u32 scalar; | ||
| 133 | u32 scalar_reload; | ||
| 134 | u32 config; | ||
| 135 | u32 unused; | ||
| 136 | struct leon3_gptimerelem_regs_map e[8]; | ||
| 137 | }; | ||
| 138 | |||
| 139 | /* | ||
| 140 | * Types and structure used for AMBA Plug & Play bus scanning | ||
| 141 | */ | ||
| 142 | |||
| 143 | #define AMBA_MAXAPB_DEVS 64 | ||
| 144 | #define AMBA_MAXAPB_DEVS_PERBUS 16 | ||
| 145 | |||
| 146 | struct amba_device_table { | ||
| 147 | int devnr; /* number of devices on AHB or APB bus */ | ||
| 148 | unsigned int *addr[16]; /* addresses to the devices configuration tables */ | ||
| 149 | unsigned int allocbits[1]; /* 0=unallocated, 1=allocated driver */ | ||
| 150 | }; | ||
| 151 | |||
| 152 | struct amba_apbslv_device_table { | ||
| 153 | int devnr; /* number of devices on AHB or APB bus */ | ||
| 154 | unsigned int *addr[AMBA_MAXAPB_DEVS]; /* addresses to the devices configuration tables */ | ||
| 155 | unsigned int apbmst[AMBA_MAXAPB_DEVS]; /* apb master if a entry is a apb slave */ | ||
| 156 | unsigned int apbmstidx[AMBA_MAXAPB_DEVS]; /* apb master idx if a entry is a apb slave */ | ||
| 157 | unsigned int allocbits[4]; /* 0=unallocated, 1=allocated driver */ | ||
| 158 | }; | ||
| 159 | |||
| 160 | struct amba_confarea_type { | ||
| 161 | struct amba_confarea_type *next;/* next bus in chain */ | ||
| 162 | struct amba_device_table ahbmst; | ||
| 163 | struct amba_device_table ahbslv; | ||
| 164 | struct amba_apbslv_device_table apbslv; | ||
| 165 | unsigned int apbmst; | ||
| 166 | }; | ||
| 167 | |||
| 168 | /* collect apb slaves */ | ||
| 169 | struct amba_apb_device { | ||
| 170 | unsigned int start, irq, bus_id; | ||
| 171 | struct amba_confarea_type *bus; | ||
| 172 | }; | ||
| 173 | |||
| 174 | /* collect ahb slaves */ | ||
| 175 | struct amba_ahb_device { | ||
| 176 | unsigned int start[4], irq, bus_id; | ||
| 177 | struct amba_confarea_type *bus; | ||
| 178 | }; | ||
| 179 | |||
| 180 | struct device_node; | ||
| 181 | void _amba_init(struct device_node *dp, struct device_node ***nextp); | ||
| 182 | |||
| 183 | extern struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; | ||
| 184 | extern struct leon3_gptimer_regs_map *leon3_gptimer_regs; | ||
| 185 | extern struct amba_apb_device leon_percpu_timer_dev[16]; | ||
| 186 | extern int leondebug_irq_disable; | ||
| 187 | extern int leon_debug_irqout; | ||
| 188 | extern unsigned long leon3_gptimer_irq; | ||
| 189 | extern unsigned int sparc_leon_eirq; | ||
| 190 | |||
| 191 | #endif /* __ASSEMBLY__ */ | ||
| 192 | |||
| 193 | #define LEON3_IO_AREA 0xfff00000 | ||
| 194 | #define LEON3_CONF_AREA 0xff000 | ||
| 195 | #define LEON3_AHB_SLAVE_CONF_AREA (1 << 11) | ||
| 196 | |||
| 197 | #define LEON3_AHB_CONF_WORDS 8 | ||
| 198 | #define LEON3_APB_CONF_WORDS 2 | ||
| 199 | #define LEON3_AHB_MASTERS 16 | ||
| 200 | #define LEON3_AHB_SLAVES 16 | ||
| 201 | #define LEON3_APB_SLAVES 16 | ||
| 202 | #define LEON3_APBUARTS 8 | ||
| 203 | |||
| 204 | /* Vendor codes */ | ||
| 205 | #define VENDOR_GAISLER 1 | ||
| 206 | #define VENDOR_PENDER 2 | ||
| 207 | #define VENDOR_ESA 4 | ||
| 208 | #define VENDOR_OPENCORES 8 | ||
| 209 | |||
| 210 | /* Gaisler Research device id's */ | ||
| 211 | #define GAISLER_LEON3 0x003 | ||
| 212 | #define GAISLER_LEON3DSU 0x004 | ||
| 213 | #define GAISLER_ETHAHB 0x005 | ||
| 214 | #define GAISLER_APBMST 0x006 | ||
| 215 | #define GAISLER_AHBUART 0x007 | ||
| 216 | #define GAISLER_SRCTRL 0x008 | ||
| 217 | #define GAISLER_SDCTRL 0x009 | ||
| 218 | #define GAISLER_APBUART 0x00C | ||
| 219 | #define GAISLER_IRQMP 0x00D | ||
| 220 | #define GAISLER_AHBRAM 0x00E | ||
| 221 | #define GAISLER_GPTIMER 0x011 | ||
| 222 | #define GAISLER_PCITRG 0x012 | ||
| 223 | #define GAISLER_PCISBRG 0x013 | ||
| 224 | #define GAISLER_PCIFBRG 0x014 | ||
| 225 | #define GAISLER_PCITRACE 0x015 | ||
| 226 | #define GAISLER_PCIDMA 0x016 | ||
| 227 | #define GAISLER_AHBTRACE 0x017 | ||
| 228 | #define GAISLER_ETHDSU 0x018 | ||
| 229 | #define GAISLER_PIOPORT 0x01A | ||
| 230 | #define GAISLER_GRGPIO 0x01A | ||
| 231 | #define GAISLER_AHBJTAG 0x01c | ||
| 232 | #define GAISLER_ETHMAC 0x01D | ||
| 233 | #define GAISLER_AHB2AHB 0x020 | ||
| 234 | #define GAISLER_USBDC 0x021 | ||
| 235 | #define GAISLER_ATACTRL 0x024 | ||
| 236 | #define GAISLER_DDRSPA 0x025 | ||
| 237 | #define GAISLER_USBEHC 0x026 | ||
| 238 | #define GAISLER_USBUHC 0x027 | ||
| 239 | #define GAISLER_I2CMST 0x028 | ||
| 240 | #define GAISLER_SPICTRL 0x02D | ||
| 241 | #define GAISLER_DDR2SPA 0x02E | ||
| 242 | #define GAISLER_SPIMCTRL 0x045 | ||
| 243 | #define GAISLER_LEON4 0x048 | ||
| 244 | #define GAISLER_LEON4DSU 0x049 | ||
| 245 | #define GAISLER_AHBSTAT 0x052 | ||
| 246 | #define GAISLER_FTMCTRL 0x054 | ||
| 247 | #define GAISLER_KBD 0x060 | ||
| 248 | #define GAISLER_VGA 0x061 | ||
| 249 | #define GAISLER_SVGA 0x063 | ||
| 250 | #define GAISLER_GRSYSMON 0x066 | ||
| 251 | #define GAISLER_GRACECTRL 0x067 | ||
| 252 | |||
| 253 | #define GAISLER_L2TIME 0xffd /* internal device: leon2 timer */ | ||
| 254 | #define GAISLER_L2C 0xffe /* internal device: leon2compat */ | ||
| 255 | #define GAISLER_PLUGPLAY 0xfff /* internal device: plug & play configarea */ | ||
| 256 | |||
| 257 | #define amba_vendor(x) (((x) >> 24) & 0xff) | ||
| 258 | |||
| 259 | #define amba_device(x) (((x) >> 12) & 0xfff) | ||
| 260 | |||
| 261 | #endif /* !defined(CONFIG_SPARC_LEON) */ | ||
| 262 | |||
| 263 | #endif | ||
diff --git a/arch/sparc/include/asm/machines.h b/arch/sparc/include/asm/machines.h index c28c2f248794..cd9c099567e4 100644 --- a/arch/sparc/include/asm/machines.h +++ b/arch/sparc/include/asm/machines.h | |||
| @@ -15,7 +15,7 @@ struct Sun_Machine_Models { | |||
| 15 | /* Current number of machines we know about that has an IDPROM | 15 | /* Current number of machines we know about that has an IDPROM |
| 16 | * machtype entry including one entry for the 0x80 OBP machines. | 16 | * machtype entry including one entry for the 0x80 OBP machines. |
| 17 | */ | 17 | */ |
| 18 | #define NUM_SUN_MACHINES 15 | 18 | #define NUM_SUN_MACHINES 16 |
| 19 | 19 | ||
| 20 | /* The machine type in the idprom area looks like this: | 20 | /* The machine type in the idprom area looks like this: |
| 21 | * | 21 | * |
| @@ -30,6 +30,7 @@ struct Sun_Machine_Models { | |||
| 30 | 30 | ||
| 31 | #define SM_ARCH_MASK 0xf0 | 31 | #define SM_ARCH_MASK 0xf0 |
| 32 | #define SM_SUN4 0x20 | 32 | #define SM_SUN4 0x20 |
| 33 | #define M_LEON 0x30 | ||
| 33 | #define SM_SUN4C 0x50 | 34 | #define SM_SUN4C 0x50 |
| 34 | #define SM_SUN4M 0x70 | 35 | #define SM_SUN4M 0x70 |
| 35 | #define SM_SUN4M_OBP 0x80 | 36 | #define SM_SUN4M_OBP 0x80 |
| @@ -41,6 +42,9 @@ struct Sun_Machine_Models { | |||
| 41 | #define SM_4_330 0x03 /* Sun 4/300 series */ | 42 | #define SM_4_330 0x03 /* Sun 4/300 series */ |
| 42 | #define SM_4_470 0x04 /* Sun 4/400 series */ | 43 | #define SM_4_470 0x04 /* Sun 4/400 series */ |
| 43 | 44 | ||
| 45 | /* Leon machines */ | ||
| 46 | #define M_LEON3_SOC 0x02 /* Leon3 SoC */ | ||
| 47 | |||
| 44 | /* Sun4c machines Full Name - PROM NAME */ | 48 | /* Sun4c machines Full Name - PROM NAME */ |
| 45 | #define SM_4C_SS1 0x01 /* Sun4c SparcStation 1 - Sun 4/60 */ | 49 | #define SM_4C_SS1 0x01 /* Sun4c SparcStation 1 - Sun 4/60 */ |
| 46 | #define SM_4C_IPC 0x02 /* Sun4c SparcStation IPC - Sun 4/40 */ | 50 | #define SM_4C_IPC 0x02 /* Sun4c SparcStation IPC - Sun 4/40 */ |
diff --git a/arch/sparc/include/asm/nmi.h b/arch/sparc/include/asm/nmi.h index fbd546dd4feb..72e6500e7ab0 100644 --- a/arch/sparc/include/asm/nmi.h +++ b/arch/sparc/include/asm/nmi.h | |||
| @@ -5,6 +5,9 @@ extern int __init nmi_init(void); | |||
| 5 | extern void perfctr_irq(int irq, struct pt_regs *regs); | 5 | extern void perfctr_irq(int irq, struct pt_regs *regs); |
| 6 | extern void nmi_adjust_hz(unsigned int new_hz); | 6 | extern void nmi_adjust_hz(unsigned int new_hz); |
| 7 | 7 | ||
| 8 | extern int nmi_usable; | 8 | extern atomic_t nmi_active; |
| 9 | |||
| 10 | extern void start_nmi_watchdog(void *unused); | ||
| 11 | extern void stop_nmi_watchdog(void *unused); | ||
| 9 | 12 | ||
| 10 | #endif /* __NMI_H */ | 13 | #endif /* __NMI_H */ |
diff --git a/arch/sparc/include/asm/pci.h b/arch/sparc/include/asm/pci.h index 6e14fd179335..d9c031f9910f 100644 --- a/arch/sparc/include/asm/pci.h +++ b/arch/sparc/include/asm/pci.h | |||
| @@ -5,4 +5,7 @@ | |||
| 5 | #else | 5 | #else |
| 6 | #include <asm/pci_32.h> | 6 | #include <asm/pci_32.h> |
| 7 | #endif | 7 | #endif |
| 8 | |||
| 9 | #include <asm-generic/pci-dma-compat.h> | ||
| 10 | |||
| 8 | #endif | 11 | #endif |
diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h index b41c4c198159..ac0e8369fd97 100644 --- a/arch/sparc/include/asm/pci_32.h +++ b/arch/sparc/include/asm/pci_32.h | |||
| @@ -31,42 +31,8 @@ static inline void pcibios_penalize_isa_irq(int irq, int active) | |||
| 31 | */ | 31 | */ |
| 32 | #define PCI_DMA_BUS_IS_PHYS (0) | 32 | #define PCI_DMA_BUS_IS_PHYS (0) |
| 33 | 33 | ||
| 34 | #include <asm/scatterlist.h> | ||
| 35 | |||
| 36 | struct pci_dev; | 34 | struct pci_dev; |
| 37 | 35 | ||
| 38 | /* Allocate and map kernel buffer using consistent mode DMA for a device. | ||
| 39 | * hwdev should be valid struct pci_dev pointer for PCI devices. | ||
| 40 | */ | ||
| 41 | extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle); | ||
| 42 | |||
| 43 | /* Free and unmap a consistent DMA buffer. | ||
| 44 | * cpu_addr is what was returned from pci_alloc_consistent, | ||
| 45 | * size must be the same as what as passed into pci_alloc_consistent, | ||
| 46 | * and likewise dma_addr must be the same as what *dma_addrp was set to. | ||
| 47 | * | ||
| 48 | * References to the memory and mappings assosciated with cpu_addr/dma_addr | ||
| 49 | * past this call are illegal. | ||
| 50 | */ | ||
| 51 | extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); | ||
| 52 | |||
| 53 | /* Map a single buffer of the indicated size for DMA in streaming mode. | ||
| 54 | * The 32-bit bus address to use is returned. | ||
| 55 | * | ||
| 56 | * Once the device is given the dma address, the device owns this memory | ||
| 57 | * until either pci_unmap_single or pci_dma_sync_single_for_cpu is performed. | ||
| 58 | */ | ||
| 59 | extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction); | ||
| 60 | |||
| 61 | /* Unmap a single streaming mode DMA translation. The dma_addr and size | ||
| 62 | * must match what was provided for in a previous pci_map_single call. All | ||
| 63 | * other usages are undefined. | ||
| 64 | * | ||
| 65 | * After this call, reads by the cpu to the buffer are guaranteed to see | ||
| 66 | * whatever the device wrote there. | ||
| 67 | */ | ||
| 68 | extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction); | ||
| 69 | |||
| 70 | /* pci_unmap_{single,page} is not a nop, thus... */ | 36 | /* pci_unmap_{single,page} is not a nop, thus... */ |
| 71 | #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ | 37 | #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ |
| 72 | dma_addr_t ADDR_NAME; | 38 | dma_addr_t ADDR_NAME; |
| @@ -81,69 +47,6 @@ extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t | |||
| 81 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ | 47 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ |
| 82 | (((PTR)->LEN_NAME) = (VAL)) | 48 | (((PTR)->LEN_NAME) = (VAL)) |
| 83 | 49 | ||
| 84 | /* | ||
| 85 | * Same as above, only with pages instead of mapped addresses. | ||
| 86 | */ | ||
| 87 | extern dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, | ||
| 88 | unsigned long offset, size_t size, int direction); | ||
| 89 | extern void pci_unmap_page(struct pci_dev *hwdev, | ||
| 90 | dma_addr_t dma_address, size_t size, int direction); | ||
| 91 | |||
| 92 | /* Map a set of buffers described by scatterlist in streaming | ||
| 93 | * mode for DMA. This is the scather-gather version of the | ||
| 94 | * above pci_map_single interface. Here the scatter gather list | ||
| 95 | * elements are each tagged with the appropriate dma address | ||
| 96 | * and length. They are obtained via sg_dma_{address,length}(SG). | ||
| 97 | * | ||
| 98 | * NOTE: An implementation may be able to use a smaller number of | ||
| 99 | * DMA address/length pairs than there are SG table elements. | ||
| 100 | * (for example via virtual mapping capabilities) | ||
| 101 | * The routine returns the number of addr/length pairs actually | ||
| 102 | * used, at most nents. | ||
| 103 | * | ||
| 104 | * Device ownership issues as mentioned above for pci_map_single are | ||
| 105 | * the same here. | ||
| 106 | */ | ||
| 107 | extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction); | ||
| 108 | |||
| 109 | /* Unmap a set of streaming mode DMA translations. | ||
| 110 | * Again, cpu read rules concerning calls here are the same as for | ||
| 111 | * pci_unmap_single() above. | ||
| 112 | */ | ||
| 113 | extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nhwents, int direction); | ||
| 114 | |||
| 115 | /* Make physical memory consistent for a single | ||
| 116 | * streaming mode DMA translation after a transfer. | ||
| 117 | * | ||
| 118 | * If you perform a pci_map_single() but wish to interrogate the | ||
| 119 | * buffer using the cpu, yet do not wish to teardown the PCI dma | ||
| 120 | * mapping, you must call this function before doing so. At the | ||
| 121 | * next point you give the PCI dma address back to the card, you | ||
| 122 | * must first perform a pci_dma_sync_for_device, and then the device | ||
| 123 | * again owns the buffer. | ||
| 124 | */ | ||
| 125 | extern void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction); | ||
| 126 | extern void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction); | ||
| 127 | |||
| 128 | /* Make physical memory consistent for a set of streaming | ||
| 129 | * mode DMA translations after a transfer. | ||
| 130 | * | ||
| 131 | * The same as pci_dma_sync_single_* but for a scatter-gather list, | ||
| 132 | * same rules and usage. | ||
| 133 | */ | ||
| 134 | extern void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction); | ||
| 135 | extern void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction); | ||
| 136 | |||
| 137 | /* Return whether the given PCI device DMA address mask can | ||
| 138 | * be supported properly. For example, if your device can | ||
| 139 | * only drive the low 24-bits during PCI bus mastering, then | ||
| 140 | * you would pass 0x00ffffff as the mask to this function. | ||
| 141 | */ | ||
| 142 | static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) | ||
| 143 | { | ||
| 144 | return 1; | ||
| 145 | } | ||
| 146 | |||
| 147 | #ifdef CONFIG_PCI | 50 | #ifdef CONFIG_PCI |
| 148 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | 51 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, |
| 149 | enum pci_dma_burst_strategy *strat, | 52 | enum pci_dma_burst_strategy *strat, |
| @@ -154,14 +57,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, | |||
| 154 | } | 57 | } |
| 155 | #endif | 58 | #endif |
| 156 | 59 | ||
| 157 | #define PCI_DMA_ERROR_CODE (~(dma_addr_t)0x0) | ||
| 158 | |||
| 159 | static inline int pci_dma_mapping_error(struct pci_dev *pdev, | ||
| 160 | dma_addr_t dma_addr) | ||
| 161 | { | ||
| 162 | return (dma_addr == PCI_DMA_ERROR_CODE); | ||
| 163 | } | ||
| 164 | |||
| 165 | struct device_node; | 60 | struct device_node; |
| 166 | extern struct device_node *pci_device_to_OF_node(struct pci_dev *pdev); | 61 | extern struct device_node *pci_device_to_OF_node(struct pci_dev *pdev); |
| 167 | 62 | ||
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h index 7a1e3566e59c..5cc9f6aa5494 100644 --- a/arch/sparc/include/asm/pci_64.h +++ b/arch/sparc/include/asm/pci_64.h | |||
| @@ -35,37 +35,6 @@ static inline void pcibios_penalize_isa_irq(int irq, int active) | |||
| 35 | */ | 35 | */ |
| 36 | #define PCI_DMA_BUS_IS_PHYS (0) | 36 | #define PCI_DMA_BUS_IS_PHYS (0) |
| 37 | 37 | ||
| 38 | static inline void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, | ||
| 39 | dma_addr_t *dma_handle) | ||
| 40 | { | ||
| 41 | return dma_alloc_coherent(&pdev->dev, size, dma_handle, GFP_ATOMIC); | ||
| 42 | } | ||
| 43 | |||
| 44 | static inline void pci_free_consistent(struct pci_dev *pdev, size_t size, | ||
| 45 | void *vaddr, dma_addr_t dma_handle) | ||
| 46 | { | ||
| 47 | return dma_free_coherent(&pdev->dev, size, vaddr, dma_handle); | ||
| 48 | } | ||
| 49 | |||
| 50 | static inline dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, | ||
| 51 | size_t size, int direction) | ||
| 52 | { | ||
| 53 | return dma_map_single(&pdev->dev, ptr, size, | ||
| 54 | (enum dma_data_direction) direction); | ||
| 55 | } | ||
| 56 | |||
| 57 | static inline void pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, | ||
| 58 | size_t size, int direction) | ||
| 59 | { | ||
| 60 | dma_unmap_single(&pdev->dev, dma_addr, size, | ||
| 61 | (enum dma_data_direction) direction); | ||
| 62 | } | ||
| 63 | |||
| 64 | #define pci_map_page(dev, page, off, size, dir) \ | ||
| 65 | pci_map_single(dev, (page_address(page) + (off)), size, dir) | ||
| 66 | #define pci_unmap_page(dev,addr,sz,dir) \ | ||
| 67 | pci_unmap_single(dev,addr,sz,dir) | ||
| 68 | |||
| 69 | /* pci_unmap_{single,page} is not a nop, thus... */ | 38 | /* pci_unmap_{single,page} is not a nop, thus... */ |
| 70 | #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ | 39 | #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ |
| 71 | dma_addr_t ADDR_NAME; | 40 | dma_addr_t ADDR_NAME; |
| @@ -80,57 +49,6 @@ static inline void pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, | |||
| 80 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ | 49 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ |
| 81 | (((PTR)->LEN_NAME) = (VAL)) | 50 | (((PTR)->LEN_NAME) = (VAL)) |
| 82 | 51 | ||
| 83 | static inline int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, | ||
| 84 | int nents, int direction) | ||
| 85 | { | ||
| 86 | return dma_map_sg(&pdev->dev, sg, nents, | ||
| 87 | (enum dma_data_direction) direction); | ||
| 88 | } | ||
| 89 | |||
| 90 | static inline void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, | ||
| 91 | int nents, int direction) | ||
| 92 | { | ||
| 93 | dma_unmap_sg(&pdev->dev, sg, nents, | ||
| 94 | (enum dma_data_direction) direction); | ||
| 95 | } | ||
| 96 | |||
| 97 | static inline void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, | ||
| 98 | dma_addr_t dma_handle, | ||
| 99 | size_t size, int direction) | ||
| 100 | { | ||
| 101 | dma_sync_single_for_cpu(&pdev->dev, dma_handle, size, | ||
| 102 | (enum dma_data_direction) direction); | ||
| 103 | } | ||
| 104 | |||
| 105 | static inline void pci_dma_sync_single_for_device(struct pci_dev *pdev, | ||
| 106 | dma_addr_t dma_handle, | ||
| 107 | size_t size, int direction) | ||
| 108 | { | ||
| 109 | /* No flushing needed to sync cpu writes to the device. */ | ||
| 110 | } | ||
| 111 | |||
| 112 | static inline void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, | ||
| 113 | struct scatterlist *sg, | ||
| 114 | int nents, int direction) | ||
| 115 | { | ||
| 116 | dma_sync_sg_for_cpu(&pdev->dev, sg, nents, | ||
| 117 | (enum dma_data_direction) direction); | ||
| 118 | } | ||
| 119 | |||
| 120 | static inline void pci_dma_sync_sg_for_device(struct pci_dev *pdev, | ||
| 121 | struct scatterlist *sg, | ||
| 122 | int nelems, int direction) | ||
| 123 | { | ||
| 124 | /* No flushing needed to sync cpu writes to the device. */ | ||
| 125 | } | ||
| 126 | |||
| 127 | /* Return whether the given PCI device DMA address mask can | ||
| 128 | * be supported properly. For example, if your device can | ||
| 129 | * only drive the low 24-bits during PCI bus mastering, then | ||
| 130 | * you would pass 0x00ffffff as the mask to this function. | ||
| 131 | */ | ||
| 132 | extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask); | ||
| 133 | |||
| 134 | /* PCI IOMMU mapping bypass support. */ | 52 | /* PCI IOMMU mapping bypass support. */ |
| 135 | 53 | ||
| 136 | /* PCI 64-bit addressing works for all slots on all controller | 54 | /* PCI 64-bit addressing works for all slots on all controller |
| @@ -140,12 +58,6 @@ extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask); | |||
| 140 | #define PCI64_REQUIRED_MASK (~(dma64_addr_t)0) | 58 | #define PCI64_REQUIRED_MASK (~(dma64_addr_t)0) |
| 141 | #define PCI64_ADDR_BASE 0xfffc000000000000UL | 59 | #define PCI64_ADDR_BASE 0xfffc000000000000UL |
| 142 | 60 | ||
| 143 | static inline int pci_dma_mapping_error(struct pci_dev *pdev, | ||
| 144 | dma_addr_t dma_addr) | ||
| 145 | { | ||
| 146 | return dma_mapping_error(&pdev->dev, dma_addr); | ||
| 147 | } | ||
| 148 | |||
| 149 | #ifdef CONFIG_PCI | 61 | #ifdef CONFIG_PCI |
| 150 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | 62 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, |
| 151 | enum pci_dma_burst_strategy *strat, | 63 | enum pci_dma_burst_strategy *strat, |
diff --git a/arch/sparc/include/asm/perf_counter.h b/arch/sparc/include/asm/perf_counter.h new file mode 100644 index 000000000000..5d7a8ca0e491 --- /dev/null +++ b/arch/sparc/include/asm/perf_counter.h | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | #ifndef __ASM_SPARC_PERF_COUNTER_H | ||
| 2 | #define __ASM_SPARC_PERF_COUNTER_H | ||
| 3 | |||
| 4 | extern void set_perf_counter_pending(void); | ||
| 5 | |||
| 6 | #define PERF_COUNTER_INDEX_OFFSET 0 | ||
| 7 | |||
| 8 | #ifdef CONFIG_PERF_COUNTERS | ||
| 9 | extern void init_hw_perf_counters(void); | ||
| 10 | #else | ||
| 11 | static inline void init_hw_perf_counters(void) { } | ||
| 12 | #endif | ||
| 13 | |||
| 14 | #endif | ||
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index b049abf9902f..0ff92fa22064 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h | |||
| @@ -726,11 +726,17 @@ extern unsigned long pte_file(pte_t); | |||
| 726 | extern pte_t pgoff_to_pte(unsigned long); | 726 | extern pte_t pgoff_to_pte(unsigned long); |
| 727 | #define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL) | 727 | #define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL) |
| 728 | 728 | ||
| 729 | extern unsigned long *sparc64_valid_addr_bitmap; | 729 | extern unsigned long sparc64_valid_addr_bitmap[]; |
| 730 | 730 | ||
| 731 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ | 731 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ |
| 732 | #define kern_addr_valid(addr) \ | 732 | static inline bool kern_addr_valid(unsigned long addr) |
| 733 | (test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap)) | 733 | { |
| 734 | unsigned long paddr = __pa(addr); | ||
| 735 | |||
| 736 | if ((paddr >> 41UL) != 0UL) | ||
| 737 | return false; | ||
| 738 | return test_bit(paddr >> 22, sparc64_valid_addr_bitmap); | ||
| 739 | } | ||
| 734 | 740 | ||
| 735 | extern int page_in_phys_avail(unsigned long paddr); | 741 | extern int page_in_phys_avail(unsigned long paddr); |
| 736 | 742 | ||
diff --git a/arch/sparc/include/asm/pgtsrmmu.h b/arch/sparc/include/asm/pgtsrmmu.h index 808555fc1d58..1407c07bdade 100644 --- a/arch/sparc/include/asm/pgtsrmmu.h +++ b/arch/sparc/include/asm/pgtsrmmu.h | |||
| @@ -267,6 +267,7 @@ static inline void srmmu_flush_tlb_page(unsigned long page) | |||
| 267 | 267 | ||
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | #ifndef CONFIG_SPARC_LEON | ||
| 270 | static inline unsigned long srmmu_hwprobe(unsigned long vaddr) | 271 | static inline unsigned long srmmu_hwprobe(unsigned long vaddr) |
| 271 | { | 272 | { |
| 272 | unsigned long retval; | 273 | unsigned long retval; |
| @@ -278,6 +279,9 @@ static inline unsigned long srmmu_hwprobe(unsigned long vaddr) | |||
| 278 | 279 | ||
| 279 | return retval; | 280 | return retval; |
| 280 | } | 281 | } |
| 282 | #else | ||
| 283 | #define srmmu_hwprobe(addr) (srmmu_swprobe(addr, 0) & SRMMU_PTE_PMASK) | ||
| 284 | #endif | ||
| 281 | 285 | ||
| 282 | static inline int | 286 | static inline int |
| 283 | srmmu_get_pte (unsigned long addr) | 287 | srmmu_get_pte (unsigned long addr) |
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index be8d7aaeb60d..82a190d7efc1 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h | |||
| @@ -118,5 +118,8 @@ extern struct device_node *of_console_device; | |||
| 118 | extern char *of_console_path; | 118 | extern char *of_console_path; |
| 119 | extern char *of_console_options; | 119 | extern char *of_console_options; |
| 120 | 120 | ||
| 121 | extern void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp); | ||
| 122 | extern char *build_full_name(struct device_node *dp); | ||
| 123 | |||
| 121 | #endif /* __KERNEL__ */ | 124 | #endif /* __KERNEL__ */ |
| 122 | #endif /* _SPARC_PROM_H */ | 125 | #endif /* _SPARC_PROM_H */ |
diff --git a/arch/sparc/include/asm/socket.h b/arch/sparc/include/asm/socket.h index 982a12f959f4..3a5ae3d12088 100644 --- a/arch/sparc/include/asm/socket.h +++ b/arch/sparc/include/asm/socket.h | |||
| @@ -29,6 +29,9 @@ | |||
| 29 | #define SO_RCVBUFFORCE 0x100b | 29 | #define SO_RCVBUFFORCE 0x100b |
| 30 | #define SO_ERROR 0x1007 | 30 | #define SO_ERROR 0x1007 |
| 31 | #define SO_TYPE 0x1008 | 31 | #define SO_TYPE 0x1008 |
| 32 | #define SO_PROTOCOL 0x1028 | ||
| 33 | #define SO_DOMAIN 0x1029 | ||
| 34 | |||
| 32 | 35 | ||
| 33 | /* Linux specific, keep the same. */ | 36 | /* Linux specific, keep the same. */ |
| 34 | #define SO_NO_CHECK 0x000b | 37 | #define SO_NO_CHECK 0x000b |
diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h index 46f91ab66a50..857630cff636 100644 --- a/arch/sparc/include/asm/spinlock_32.h +++ b/arch/sparc/include/asm/spinlock_32.h | |||
| @@ -76,7 +76,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock) | |||
| 76 | * | 76 | * |
| 77 | * Unfortunately this scheme limits us to ~16,000,000 cpus. | 77 | * Unfortunately this scheme limits us to ~16,000,000 cpus. |
| 78 | */ | 78 | */ |
| 79 | static inline void __read_lock(raw_rwlock_t *rw) | 79 | static inline void arch_read_lock(raw_rwlock_t *rw) |
| 80 | { | 80 | { |
| 81 | register raw_rwlock_t *lp asm("g1"); | 81 | register raw_rwlock_t *lp asm("g1"); |
| 82 | lp = rw; | 82 | lp = rw; |
| @@ -92,11 +92,11 @@ static inline void __read_lock(raw_rwlock_t *rw) | |||
| 92 | #define __raw_read_lock(lock) \ | 92 | #define __raw_read_lock(lock) \ |
| 93 | do { unsigned long flags; \ | 93 | do { unsigned long flags; \ |
| 94 | local_irq_save(flags); \ | 94 | local_irq_save(flags); \ |
| 95 | __read_lock(lock); \ | 95 | arch_read_lock(lock); \ |
| 96 | local_irq_restore(flags); \ | 96 | local_irq_restore(flags); \ |
| 97 | } while(0) | 97 | } while(0) |
| 98 | 98 | ||
| 99 | static inline void __read_unlock(raw_rwlock_t *rw) | 99 | static inline void arch_read_unlock(raw_rwlock_t *rw) |
| 100 | { | 100 | { |
| 101 | register raw_rwlock_t *lp asm("g1"); | 101 | register raw_rwlock_t *lp asm("g1"); |
| 102 | lp = rw; | 102 | lp = rw; |
| @@ -112,7 +112,7 @@ static inline void __read_unlock(raw_rwlock_t *rw) | |||
| 112 | #define __raw_read_unlock(lock) \ | 112 | #define __raw_read_unlock(lock) \ |
| 113 | do { unsigned long flags; \ | 113 | do { unsigned long flags; \ |
| 114 | local_irq_save(flags); \ | 114 | local_irq_save(flags); \ |
| 115 | __read_unlock(lock); \ | 115 | arch_read_unlock(lock); \ |
| 116 | local_irq_restore(flags); \ | 116 | local_irq_restore(flags); \ |
| 117 | } while(0) | 117 | } while(0) |
| 118 | 118 | ||
| @@ -150,7 +150,7 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) | |||
| 150 | return (val == 0); | 150 | return (val == 0); |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | static inline int __read_trylock(raw_rwlock_t *rw) | 153 | static inline int arch_read_trylock(raw_rwlock_t *rw) |
| 154 | { | 154 | { |
| 155 | register raw_rwlock_t *lp asm("g1"); | 155 | register raw_rwlock_t *lp asm("g1"); |
| 156 | register int res asm("o0"); | 156 | register int res asm("o0"); |
| @@ -169,7 +169,7 @@ static inline int __read_trylock(raw_rwlock_t *rw) | |||
| 169 | ({ unsigned long flags; \ | 169 | ({ unsigned long flags; \ |
| 170 | int res; \ | 170 | int res; \ |
| 171 | local_irq_save(flags); \ | 171 | local_irq_save(flags); \ |
| 172 | res = __read_trylock(lock); \ | 172 | res = arch_read_trylock(lock); \ |
| 173 | local_irq_restore(flags); \ | 173 | local_irq_restore(flags); \ |
| 174 | res; \ | 174 | res; \ |
| 175 | }) | 175 | }) |
diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h index f6b2b92ad8d2..43e514783582 100644 --- a/arch/sparc/include/asm/spinlock_64.h +++ b/arch/sparc/include/asm/spinlock_64.h | |||
| @@ -92,7 +92,7 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long fla | |||
| 92 | 92 | ||
| 93 | /* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */ | 93 | /* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */ |
| 94 | 94 | ||
| 95 | static void inline __read_lock(raw_rwlock_t *lock) | 95 | static void inline arch_read_lock(raw_rwlock_t *lock) |
| 96 | { | 96 | { |
| 97 | unsigned long tmp1, tmp2; | 97 | unsigned long tmp1, tmp2; |
| 98 | 98 | ||
| @@ -115,7 +115,7 @@ static void inline __read_lock(raw_rwlock_t *lock) | |||
| 115 | : "memory"); | 115 | : "memory"); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | static int inline __read_trylock(raw_rwlock_t *lock) | 118 | static int inline arch_read_trylock(raw_rwlock_t *lock) |
| 119 | { | 119 | { |
| 120 | int tmp1, tmp2; | 120 | int tmp1, tmp2; |
| 121 | 121 | ||
| @@ -136,7 +136,7 @@ static int inline __read_trylock(raw_rwlock_t *lock) | |||
| 136 | return tmp1; | 136 | return tmp1; |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | static void inline __read_unlock(raw_rwlock_t *lock) | 139 | static void inline arch_read_unlock(raw_rwlock_t *lock) |
| 140 | { | 140 | { |
| 141 | unsigned long tmp1, tmp2; | 141 | unsigned long tmp1, tmp2; |
| 142 | 142 | ||
| @@ -152,7 +152,7 @@ static void inline __read_unlock(raw_rwlock_t *lock) | |||
| 152 | : "memory"); | 152 | : "memory"); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static void inline __write_lock(raw_rwlock_t *lock) | 155 | static void inline arch_write_lock(raw_rwlock_t *lock) |
| 156 | { | 156 | { |
| 157 | unsigned long mask, tmp1, tmp2; | 157 | unsigned long mask, tmp1, tmp2; |
| 158 | 158 | ||
| @@ -177,7 +177,7 @@ static void inline __write_lock(raw_rwlock_t *lock) | |||
| 177 | : "memory"); | 177 | : "memory"); |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | static void inline __write_unlock(raw_rwlock_t *lock) | 180 | static void inline arch_write_unlock(raw_rwlock_t *lock) |
| 181 | { | 181 | { |
| 182 | __asm__ __volatile__( | 182 | __asm__ __volatile__( |
| 183 | " stw %%g0, [%0]" | 183 | " stw %%g0, [%0]" |
| @@ -186,7 +186,7 @@ static void inline __write_unlock(raw_rwlock_t *lock) | |||
| 186 | : "memory"); | 186 | : "memory"); |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | static int inline __write_trylock(raw_rwlock_t *lock) | 189 | static int inline arch_write_trylock(raw_rwlock_t *lock) |
| 190 | { | 190 | { |
| 191 | unsigned long mask, tmp1, tmp2, result; | 191 | unsigned long mask, tmp1, tmp2, result; |
| 192 | 192 | ||
| @@ -210,14 +210,14 @@ static int inline __write_trylock(raw_rwlock_t *lock) | |||
| 210 | return result; | 210 | return result; |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | #define __raw_read_lock(p) __read_lock(p) | 213 | #define __raw_read_lock(p) arch_read_lock(p) |
| 214 | #define __raw_read_lock_flags(p, f) __read_lock(p) | 214 | #define __raw_read_lock_flags(p, f) arch_read_lock(p) |
| 215 | #define __raw_read_trylock(p) __read_trylock(p) | 215 | #define __raw_read_trylock(p) arch_read_trylock(p) |
| 216 | #define __raw_read_unlock(p) __read_unlock(p) | 216 | #define __raw_read_unlock(p) arch_read_unlock(p) |
| 217 | #define __raw_write_lock(p) __write_lock(p) | 217 | #define __raw_write_lock(p) arch_write_lock(p) |
| 218 | #define __raw_write_lock_flags(p, f) __write_lock(p) | 218 | #define __raw_write_lock_flags(p, f) arch_write_lock(p) |
| 219 | #define __raw_write_unlock(p) __write_unlock(p) | 219 | #define __raw_write_unlock(p) arch_write_unlock(p) |
| 220 | #define __raw_write_trylock(p) __write_trylock(p) | 220 | #define __raw_write_trylock(p) arch_write_trylock(p) |
| 221 | 221 | ||
| 222 | #define __raw_read_can_lock(rw) (!((rw)->lock & 0x80000000UL)) | 222 | #define __raw_read_can_lock(rw) (!((rw)->lock & 0x80000000UL)) |
| 223 | #define __raw_write_can_lock(rw) (!(rw)->lock) | 223 | #define __raw_write_can_lock(rw) (!(rw)->lock) |
diff --git a/arch/sparc/include/asm/system_32.h b/arch/sparc/include/asm/system_32.h index 751c8c17f5a0..890036b3689a 100644 --- a/arch/sparc/include/asm/system_32.h +++ b/arch/sparc/include/asm/system_32.h | |||
| @@ -32,6 +32,7 @@ enum sparc_cpu { | |||
| 32 | sun4u = 0x05, /* V8 ploos ploos */ | 32 | sun4u = 0x05, /* V8 ploos ploos */ |
| 33 | sun_unknown = 0x06, | 33 | sun_unknown = 0x06, |
| 34 | ap1000 = 0x07, /* almost a sun4m */ | 34 | ap1000 = 0x07, /* almost a sun4m */ |
| 35 | sparc_leon = 0x08, /* Leon SoC */ | ||
| 35 | }; | 36 | }; |
| 36 | 37 | ||
| 37 | /* Really, userland should not be looking at any of this... */ | 38 | /* Really, userland should not be looking at any of this... */ |
diff --git a/arch/sparc/include/asm/system_64.h b/arch/sparc/include/asm/system_64.h index 6c077816ab28..25e848f0cad7 100644 --- a/arch/sparc/include/asm/system_64.h +++ b/arch/sparc/include/asm/system_64.h | |||
| @@ -29,6 +29,10 @@ enum sparc_cpu { | |||
| 29 | /* This cannot ever be a sun4c :) That's just history. */ | 29 | /* This cannot ever be a sun4c :) That's just history. */ |
| 30 | #define ARCH_SUN4C 0 | 30 | #define ARCH_SUN4C 0 |
| 31 | 31 | ||
| 32 | extern const char *sparc_cpu_type; | ||
| 33 | extern const char *sparc_fpu_type; | ||
| 34 | extern const char *sparc_pmu_type; | ||
| 35 | |||
| 32 | extern char reboot_command[]; | 36 | extern char reboot_command[]; |
| 33 | 37 | ||
| 34 | /* These are here in an effort to more fully work around Spitfire Errata | 38 | /* These are here in an effort to more fully work around Spitfire Errata |
diff --git a/arch/sparc/include/asm/types.h b/arch/sparc/include/asm/types.h index de671d73baed..09c79a9c8516 100644 --- a/arch/sparc/include/asm/types.h +++ b/arch/sparc/include/asm/types.h | |||
| @@ -8,9 +8,8 @@ | |||
| 8 | * need to be careful to avoid a name clashes. | 8 | * need to be careful to avoid a name clashes. |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #if defined(__sparc__) && defined(__arch64__) | 11 | #if defined(__sparc__) |
| 12 | 12 | ||
| 13 | /*** SPARC 64 bit ***/ | ||
| 14 | #include <asm-generic/int-ll64.h> | 13 | #include <asm-generic/int-ll64.h> |
| 15 | 14 | ||
| 16 | #ifndef __ASSEMBLY__ | 15 | #ifndef __ASSEMBLY__ |
| @@ -26,33 +25,21 @@ typedef unsigned short umode_t; | |||
| 26 | /* Dma addresses come in generic and 64-bit flavours. */ | 25 | /* Dma addresses come in generic and 64-bit flavours. */ |
| 27 | 26 | ||
| 28 | typedef u32 dma_addr_t; | 27 | typedef u32 dma_addr_t; |
| 29 | typedef u64 dma64_addr_t; | ||
| 30 | 28 | ||
| 31 | #endif /* __ASSEMBLY__ */ | 29 | #if defined(__arch64__) |
| 32 | 30 | ||
| 33 | #endif /* __KERNEL__ */ | 31 | /*** SPARC 64 bit ***/ |
| 32 | typedef u64 dma64_addr_t; | ||
| 34 | #else | 33 | #else |
| 35 | |||
| 36 | /*** SPARC 32 bit ***/ | 34 | /*** SPARC 32 bit ***/ |
| 37 | #include <asm-generic/int-ll64.h> | ||
| 38 | |||
| 39 | #ifndef __ASSEMBLY__ | ||
| 40 | |||
| 41 | typedef unsigned short umode_t; | ||
| 42 | |||
| 43 | #endif /* __ASSEMBLY__ */ | ||
| 44 | |||
| 45 | #ifdef __KERNEL__ | ||
| 46 | |||
| 47 | #ifndef __ASSEMBLY__ | ||
| 48 | |||
| 49 | typedef u32 dma_addr_t; | ||
| 50 | typedef u32 dma64_addr_t; | 35 | typedef u32 dma64_addr_t; |
| 51 | 36 | ||
| 37 | #endif /* defined(__arch64__) */ | ||
| 38 | |||
| 52 | #endif /* __ASSEMBLY__ */ | 39 | #endif /* __ASSEMBLY__ */ |
| 53 | 40 | ||
| 54 | #endif /* __KERNEL__ */ | 41 | #endif /* __KERNEL__ */ |
| 55 | 42 | ||
| 56 | #endif /* defined(__sparc__) && defined(__arch64__) */ | 43 | #endif /* defined(__sparc__) */ |
| 57 | 44 | ||
| 58 | #endif /* defined(_SPARC_TYPES_H) */ | 45 | #endif /* defined(_SPARC_TYPES_H) */ |
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h index a38c03238918..9ea271e19c70 100644 --- a/arch/sparc/include/asm/uaccess_64.h +++ b/arch/sparc/include/asm/uaccess_64.h | |||
| @@ -7,8 +7,8 @@ | |||
| 7 | 7 | ||
| 8 | #ifdef __KERNEL__ | 8 | #ifdef __KERNEL__ |
| 9 | #include <linux/compiler.h> | 9 | #include <linux/compiler.h> |
| 10 | #include <linux/sched.h> | ||
| 11 | #include <linux/string.h> | 10 | #include <linux/string.h> |
| 11 | #include <linux/thread_info.h> | ||
| 12 | #include <asm/asi.h> | 12 | #include <asm/asi.h> |
| 13 | #include <asm/system.h> | 13 | #include <asm/system.h> |
| 14 | #include <asm/spitfire.h> | 14 | #include <asm/spitfire.h> |
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index b2c406de7d4f..706df669f3b8 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h | |||
| @@ -395,8 +395,9 @@ | |||
| 395 | #define __NR_preadv 324 | 395 | #define __NR_preadv 324 |
| 396 | #define __NR_pwritev 325 | 396 | #define __NR_pwritev 325 |
| 397 | #define __NR_rt_tgsigqueueinfo 326 | 397 | #define __NR_rt_tgsigqueueinfo 326 |
| 398 | #define __NR_perf_counter_open 327 | ||
| 398 | 399 | ||
| 399 | #define NR_SYSCALLS 327 | 400 | #define NR_SYSCALLS 328 |
| 400 | 401 | ||
| 401 | #ifdef __32bit_syscall_numbers__ | 402 | #ifdef __32bit_syscall_numbers__ |
| 402 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, | 403 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, |
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 475ce4696acd..247cc620cee5 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile | |||
| @@ -41,6 +41,8 @@ obj-y += of_device_common.o | |||
| 41 | obj-y += of_device_$(BITS).o | 41 | obj-y += of_device_$(BITS).o |
| 42 | obj-$(CONFIG_SPARC64) += prom_irqtrans.o | 42 | obj-$(CONFIG_SPARC64) += prom_irqtrans.o |
| 43 | 43 | ||
| 44 | obj-$(CONFIG_SPARC_LEON)+= leon_kernel.o | ||
| 45 | |||
| 44 | obj-$(CONFIG_SPARC64) += reboot.o | 46 | obj-$(CONFIG_SPARC64) += reboot.o |
| 45 | obj-$(CONFIG_SPARC64) += sysfs.o | 47 | obj-$(CONFIG_SPARC64) += sysfs.o |
| 46 | obj-$(CONFIG_SPARC64) += iommu.o | 48 | obj-$(CONFIG_SPARC64) += iommu.o |
| @@ -61,7 +63,7 @@ obj-$(CONFIG_SPARC64_SMP) += cpumap.o | |||
| 61 | obj-$(CONFIG_SPARC32) += devres.o | 63 | obj-$(CONFIG_SPARC32) += devres.o |
| 62 | devres-y := ../../../kernel/irq/devres.o | 64 | devres-y := ../../../kernel/irq/devres.o |
| 63 | 65 | ||
| 64 | obj-$(CONFIG_SPARC32) += dma.o | 66 | obj-y += dma.o |
| 65 | 67 | ||
| 66 | obj-$(CONFIG_SPARC32_PCI) += pcic.o | 68 | obj-$(CONFIG_SPARC32_PCI) += pcic.o |
| 67 | 69 | ||
| @@ -101,3 +103,6 @@ obj-$(CONFIG_SUN_LDOMS) += ldc.o vio.o viohs.o ds.o | |||
| 101 | obj-$(CONFIG_AUDIT) += audit.o | 103 | obj-$(CONFIG_AUDIT) += audit.o |
| 102 | audit--$(CONFIG_AUDIT) := compat_audit.o | 104 | audit--$(CONFIG_AUDIT) := compat_audit.o |
| 103 | obj-$(CONFIG_COMPAT) += $(audit--y) | 105 | obj-$(CONFIG_COMPAT) += $(audit--y) |
| 106 | |||
| 107 | pc--$(CONFIG_PERF_COUNTERS) := perf_counter.o | ||
| 108 | obj-$(CONFIG_SPARC64) += $(pc--y) | ||
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index d85c3dc4953a..1446df90ef85 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c | |||
| @@ -312,7 +312,12 @@ void __cpuinit cpu_probe(void) | |||
| 312 | 312 | ||
| 313 | psr = get_psr(); | 313 | psr = get_psr(); |
| 314 | put_psr(psr | PSR_EF); | 314 | put_psr(psr | PSR_EF); |
| 315 | #ifdef CONFIG_SPARC_LEON | ||
| 316 | fpu_vers = 7; | ||
| 317 | #else | ||
| 315 | fpu_vers = ((get_fsr() >> 17) & 0x7); | 318 | fpu_vers = ((get_fsr() >> 17) & 0x7); |
| 319 | #endif | ||
| 320 | |||
| 316 | put_psr(psr); | 321 | put_psr(psr); |
| 317 | 322 | ||
| 318 | set_cpu_and_fpu(psr_impl, psr_vers, fpu_vers); | 323 | set_cpu_and_fpu(psr_impl, psr_vers, fpu_vers); |
diff --git a/arch/sparc/kernel/dma.c b/arch/sparc/kernel/dma.c index 524c32f97c55..e1ba8ee21b9a 100644 --- a/arch/sparc/kernel/dma.c +++ b/arch/sparc/kernel/dma.c | |||
| @@ -1,178 +1,13 @@ | |||
| 1 | /* dma.c: PCI and SBUS DMA accessors for 32-bit sparc. | ||
| 2 | * | ||
| 3 | * Copyright (C) 2008 David S. Miller <davem@davemloft.net> | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <linux/kernel.h> | 1 | #include <linux/kernel.h> |
| 7 | #include <linux/module.h> | 2 | #include <linux/module.h> |
| 8 | #include <linux/dma-mapping.h> | 3 | #include <linux/dma-mapping.h> |
| 9 | #include <linux/scatterlist.h> | 4 | #include <linux/dma-debug.h> |
| 10 | #include <linux/mm.h> | ||
| 11 | |||
| 12 | #ifdef CONFIG_PCI | ||
| 13 | #include <linux/pci.h> | ||
| 14 | #endif | ||
| 15 | 5 | ||
| 16 | #include "dma.h" | 6 | #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 15) |
| 17 | 7 | ||
| 18 | int dma_supported(struct device *dev, u64 mask) | 8 | static int __init dma_init(void) |
| 19 | { | 9 | { |
| 20 | #ifdef CONFIG_PCI | 10 | dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); |
| 21 | if (dev->bus == &pci_bus_type) | ||
| 22 | return pci_dma_supported(to_pci_dev(dev), mask); | ||
| 23 | #endif | ||
| 24 | return 0; | 11 | return 0; |
| 25 | } | 12 | } |
| 26 | EXPORT_SYMBOL(dma_supported); | 13 | fs_initcall(dma_init); |
| 27 | |||
| 28 | int dma_set_mask(struct device *dev, u64 dma_mask) | ||
| 29 | { | ||
| 30 | #ifdef CONFIG_PCI | ||
| 31 | if (dev->bus == &pci_bus_type) | ||
| 32 | return pci_set_dma_mask(to_pci_dev(dev), dma_mask); | ||
| 33 | #endif | ||
| 34 | return -EOPNOTSUPP; | ||
| 35 | } | ||
| 36 | EXPORT_SYMBOL(dma_set_mask); | ||
| 37 | |||
| 38 | static void *dma32_alloc_coherent(struct device *dev, size_t size, | ||
| 39 | dma_addr_t *dma_handle, gfp_t flag) | ||
| 40 | { | ||
| 41 | #ifdef CONFIG_PCI | ||
| 42 | if (dev->bus == &pci_bus_type) | ||
| 43 | return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle); | ||
| 44 | #endif | ||
| 45 | return sbus_alloc_consistent(dev, size, dma_handle); | ||
| 46 | } | ||
| 47 | |||
| 48 | static void dma32_free_coherent(struct device *dev, size_t size, | ||
| 49 | void *cpu_addr, dma_addr_t dma_handle) | ||
| 50 | { | ||
| 51 | #ifdef CONFIG_PCI | ||
| 52 | if (dev->bus == &pci_bus_type) { | ||
| 53 | pci_free_consistent(to_pci_dev(dev), size, | ||
| 54 | cpu_addr, dma_handle); | ||
| 55 | return; | ||
| 56 | } | ||
| 57 | #endif | ||
| 58 | sbus_free_consistent(dev, size, cpu_addr, dma_handle); | ||
| 59 | } | ||
| 60 | |||
| 61 | static dma_addr_t dma32_map_page(struct device *dev, struct page *page, | ||
| 62 | unsigned long offset, size_t size, | ||
| 63 | enum dma_data_direction direction) | ||
| 64 | { | ||
| 65 | #ifdef CONFIG_PCI | ||
| 66 | if (dev->bus == &pci_bus_type) | ||
| 67 | return pci_map_page(to_pci_dev(dev), page, offset, | ||
| 68 | size, (int)direction); | ||
| 69 | #endif | ||
| 70 | return sbus_map_single(dev, page_address(page) + offset, | ||
| 71 | size, (int)direction); | ||
| 72 | } | ||
| 73 | |||
| 74 | static void dma32_unmap_page(struct device *dev, dma_addr_t dma_address, | ||
| 75 | size_t size, enum dma_data_direction direction) | ||
| 76 | { | ||
| 77 | #ifdef CONFIG_PCI | ||
| 78 | if (dev->bus == &pci_bus_type) { | ||
| 79 | pci_unmap_page(to_pci_dev(dev), dma_address, | ||
| 80 | size, (int)direction); | ||
| 81 | return; | ||
| 82 | } | ||
| 83 | #endif | ||
| 84 | sbus_unmap_single(dev, dma_address, size, (int)direction); | ||
| 85 | } | ||
| 86 | |||
| 87 | static int dma32_map_sg(struct device *dev, struct scatterlist *sg, | ||
| 88 | int nents, enum dma_data_direction direction) | ||
| 89 | { | ||
| 90 | #ifdef CONFIG_PCI | ||
| 91 | if (dev->bus == &pci_bus_type) | ||
| 92 | return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction); | ||
| 93 | #endif | ||
| 94 | return sbus_map_sg(dev, sg, nents, direction); | ||
| 95 | } | ||
| 96 | |||
| 97 | void dma32_unmap_sg(struct device *dev, struct scatterlist *sg, | ||
| 98 | int nents, enum dma_data_direction direction) | ||
| 99 | { | ||
| 100 | #ifdef CONFIG_PCI | ||
| 101 | if (dev->bus == &pci_bus_type) { | ||
| 102 | pci_unmap_sg(to_pci_dev(dev), sg, nents, (int)direction); | ||
| 103 | return; | ||
| 104 | } | ||
| 105 | #endif | ||
| 106 | sbus_unmap_sg(dev, sg, nents, (int)direction); | ||
| 107 | } | ||
| 108 | |||
| 109 | static void dma32_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, | ||
| 110 | size_t size, | ||
| 111 | enum dma_data_direction direction) | ||
| 112 | { | ||
| 113 | #ifdef CONFIG_PCI | ||
| 114 | if (dev->bus == &pci_bus_type) { | ||
| 115 | pci_dma_sync_single_for_cpu(to_pci_dev(dev), dma_handle, | ||
| 116 | size, (int)direction); | ||
| 117 | return; | ||
| 118 | } | ||
| 119 | #endif | ||
| 120 | sbus_dma_sync_single_for_cpu(dev, dma_handle, size, (int) direction); | ||
| 121 | } | ||
| 122 | |||
| 123 | static void dma32_sync_single_for_device(struct device *dev, | ||
| 124 | dma_addr_t dma_handle, size_t size, | ||
| 125 | enum dma_data_direction direction) | ||
| 126 | { | ||
| 127 | #ifdef CONFIG_PCI | ||
| 128 | if (dev->bus == &pci_bus_type) { | ||
| 129 | pci_dma_sync_single_for_device(to_pci_dev(dev), dma_handle, | ||
| 130 | size, (int)direction); | ||
| 131 | return; | ||
| 132 | } | ||
| 133 | #endif | ||
| 134 | sbus_dma_sync_single_for_device(dev, dma_handle, size, (int) direction); | ||
| 135 | } | ||
| 136 | |||
| 137 | static void dma32_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, | ||
| 138 | int nelems, enum dma_data_direction direction) | ||
| 139 | { | ||
| 140 | #ifdef CONFIG_PCI | ||
| 141 | if (dev->bus == &pci_bus_type) { | ||
| 142 | pci_dma_sync_sg_for_cpu(to_pci_dev(dev), sg, | ||
| 143 | nelems, (int)direction); | ||
| 144 | return; | ||
| 145 | } | ||
| 146 | #endif | ||
| 147 | BUG(); | ||
| 148 | } | ||
| 149 | |||
| 150 | static void dma32_sync_sg_for_device(struct device *dev, | ||
| 151 | struct scatterlist *sg, int nelems, | ||
| 152 | enum dma_data_direction direction) | ||
| 153 | { | ||
| 154 | #ifdef CONFIG_PCI | ||
| 155 | if (dev->bus == &pci_bus_type) { | ||
| 156 | pci_dma_sync_sg_for_device(to_pci_dev(dev), sg, | ||
| 157 | nelems, (int)direction); | ||
| 158 | return; | ||
| 159 | } | ||
| 160 | #endif | ||
| 161 | BUG(); | ||
| 162 | } | ||
| 163 | |||
| 164 | static const struct dma_ops dma32_dma_ops = { | ||
| 165 | .alloc_coherent = dma32_alloc_coherent, | ||
| 166 | .free_coherent = dma32_free_coherent, | ||
| 167 | .map_page = dma32_map_page, | ||
| 168 | .unmap_page = dma32_unmap_page, | ||
| 169 | .map_sg = dma32_map_sg, | ||
| 170 | .unmap_sg = dma32_unmap_sg, | ||
| 171 | .sync_single_for_cpu = dma32_sync_single_for_cpu, | ||
| 172 | .sync_single_for_device = dma32_sync_single_for_device, | ||
| 173 | .sync_sg_for_cpu = dma32_sync_sg_for_cpu, | ||
| 174 | .sync_sg_for_device = dma32_sync_sg_for_device, | ||
| 175 | }; | ||
| 176 | |||
| 177 | const struct dma_ops *dma_ops = &dma32_dma_ops; | ||
| 178 | EXPORT_SYMBOL(dma_ops); | ||
diff --git a/arch/sparc/kernel/dma.h b/arch/sparc/kernel/dma.h deleted file mode 100644 index f8d8951adb53..000000000000 --- a/arch/sparc/kernel/dma.h +++ /dev/null | |||
| @@ -1,14 +0,0 @@ | |||
| 1 | void *sbus_alloc_consistent(struct device *dev, long len, u32 *dma_addrp); | ||
| 2 | void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba); | ||
| 3 | dma_addr_t sbus_map_single(struct device *dev, void *va, | ||
| 4 | size_t len, int direction); | ||
| 5 | void sbus_unmap_single(struct device *dev, dma_addr_t ba, | ||
| 6 | size_t n, int direction); | ||
| 7 | int sbus_map_sg(struct device *dev, struct scatterlist *sg, | ||
| 8 | int n, int direction); | ||
| 9 | void sbus_unmap_sg(struct device *dev, struct scatterlist *sg, | ||
| 10 | int n, int direction); | ||
| 11 | void sbus_dma_sync_single_for_cpu(struct device *dev, dma_addr_t ba, | ||
| 12 | size_t size, int direction); | ||
| 13 | void sbus_dma_sync_single_for_device(struct device *dev, dma_addr_t ba, | ||
| 14 | size_t size, int direction); | ||
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S index 6b4d8acc4c83..439d82a95ac9 100644 --- a/arch/sparc/kernel/head_32.S +++ b/arch/sparc/kernel/head_32.S | |||
| @@ -809,6 +809,11 @@ found_version: | |||
| 809 | nop | 809 | nop |
| 810 | 810 | ||
| 811 | got_prop: | 811 | got_prop: |
| 812 | #ifdef CONFIG_SPARC_LEON | ||
| 813 | /* no cpu-type check is needed, it is a SPARC-LEON */ | ||
| 814 | ba sun4c_continue_boot | ||
| 815 | nop | ||
| 816 | #endif | ||
| 812 | set cputypval, %o2 | 817 | set cputypval, %o2 |
| 813 | ldub [%o2 + 0x4], %l1 | 818 | ldub [%o2 + 0x4], %l1 |
| 814 | 819 | ||
diff --git a/arch/sparc/kernel/idprom.c b/arch/sparc/kernel/idprom.c index 57922f69c3f7..52a15fe2db19 100644 --- a/arch/sparc/kernel/idprom.c +++ b/arch/sparc/kernel/idprom.c | |||
| @@ -31,6 +31,8 @@ static struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = { | |||
| 31 | { .name = "Sun 4/200 Series", .id_machtype = (SM_SUN4 | SM_4_260) }, | 31 | { .name = "Sun 4/200 Series", .id_machtype = (SM_SUN4 | SM_4_260) }, |
| 32 | { .name = "Sun 4/300 Series", .id_machtype = (SM_SUN4 | SM_4_330) }, | 32 | { .name = "Sun 4/300 Series", .id_machtype = (SM_SUN4 | SM_4_330) }, |
| 33 | { .name = "Sun 4/400 Series", .id_machtype = (SM_SUN4 | SM_4_470) }, | 33 | { .name = "Sun 4/400 Series", .id_machtype = (SM_SUN4 | SM_4_470) }, |
| 34 | /* Now Leon */ | ||
| 35 | { .name = "Leon3 System-on-a-Chip", .id_machtype = (M_LEON | M_LEON3_SOC) }, | ||
| 34 | /* Now, Sun4c's */ | 36 | /* Now, Sun4c's */ |
| 35 | { .name = "Sun4c SparcStation 1", .id_machtype = (SM_SUN4C | SM_4C_SS1) }, | 37 | { .name = "Sun4c SparcStation 1", .id_machtype = (SM_SUN4C | SM_4C_SS1) }, |
| 36 | { .name = "Sun4c SparcStation IPC", .id_machtype = (SM_SUN4C | SM_4C_IPC) }, | 38 | { .name = "Sun4c SparcStation IPC", .id_machtype = (SM_SUN4C | SM_4C_IPC) }, |
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index 0aeaefe696b9..7690cc219ecc 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c | |||
| @@ -353,7 +353,8 @@ static void dma_4u_free_coherent(struct device *dev, size_t size, | |||
| 353 | 353 | ||
| 354 | static dma_addr_t dma_4u_map_page(struct device *dev, struct page *page, | 354 | static dma_addr_t dma_4u_map_page(struct device *dev, struct page *page, |
| 355 | unsigned long offset, size_t sz, | 355 | unsigned long offset, size_t sz, |
| 356 | enum dma_data_direction direction) | 356 | enum dma_data_direction direction, |
| 357 | struct dma_attrs *attrs) | ||
| 357 | { | 358 | { |
| 358 | struct iommu *iommu; | 359 | struct iommu *iommu; |
| 359 | struct strbuf *strbuf; | 360 | struct strbuf *strbuf; |
| @@ -474,7 +475,8 @@ do_flush_sync: | |||
| 474 | } | 475 | } |
| 475 | 476 | ||
| 476 | static void dma_4u_unmap_page(struct device *dev, dma_addr_t bus_addr, | 477 | static void dma_4u_unmap_page(struct device *dev, dma_addr_t bus_addr, |
| 477 | size_t sz, enum dma_data_direction direction) | 478 | size_t sz, enum dma_data_direction direction, |
| 479 | struct dma_attrs *attrs) | ||
| 478 | { | 480 | { |
| 479 | struct iommu *iommu; | 481 | struct iommu *iommu; |
| 480 | struct strbuf *strbuf; | 482 | struct strbuf *strbuf; |
| @@ -520,7 +522,8 @@ static void dma_4u_unmap_page(struct device *dev, dma_addr_t bus_addr, | |||
| 520 | } | 522 | } |
| 521 | 523 | ||
| 522 | static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, | 524 | static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, |
| 523 | int nelems, enum dma_data_direction direction) | 525 | int nelems, enum dma_data_direction direction, |
| 526 | struct dma_attrs *attrs) | ||
| 524 | { | 527 | { |
| 525 | struct scatterlist *s, *outs, *segstart; | 528 | struct scatterlist *s, *outs, *segstart; |
| 526 | unsigned long flags, handle, prot, ctx; | 529 | unsigned long flags, handle, prot, ctx; |
| @@ -691,7 +694,8 @@ static unsigned long fetch_sg_ctx(struct iommu *iommu, struct scatterlist *sg) | |||
| 691 | } | 694 | } |
| 692 | 695 | ||
| 693 | static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, | 696 | static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, |
| 694 | int nelems, enum dma_data_direction direction) | 697 | int nelems, enum dma_data_direction direction, |
| 698 | struct dma_attrs *attrs) | ||
| 695 | { | 699 | { |
| 696 | unsigned long flags, ctx; | 700 | unsigned long flags, ctx; |
| 697 | struct scatterlist *sg; | 701 | struct scatterlist *sg; |
| @@ -822,7 +826,7 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev, | |||
| 822 | spin_unlock_irqrestore(&iommu->lock, flags); | 826 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 823 | } | 827 | } |
| 824 | 828 | ||
| 825 | static const struct dma_ops sun4u_dma_ops = { | 829 | static struct dma_map_ops sun4u_dma_ops = { |
| 826 | .alloc_coherent = dma_4u_alloc_coherent, | 830 | .alloc_coherent = dma_4u_alloc_coherent, |
| 827 | .free_coherent = dma_4u_free_coherent, | 831 | .free_coherent = dma_4u_free_coherent, |
| 828 | .map_page = dma_4u_map_page, | 832 | .map_page = dma_4u_map_page, |
| @@ -833,9 +837,11 @@ static const struct dma_ops sun4u_dma_ops = { | |||
| 833 | .sync_sg_for_cpu = dma_4u_sync_sg_for_cpu, | 837 | .sync_sg_for_cpu = dma_4u_sync_sg_for_cpu, |
| 834 | }; | 838 | }; |
| 835 | 839 | ||
| 836 | const struct dma_ops *dma_ops = &sun4u_dma_ops; | 840 | struct dma_map_ops *dma_ops = &sun4u_dma_ops; |
| 837 | EXPORT_SYMBOL(dma_ops); | 841 | EXPORT_SYMBOL(dma_ops); |
| 838 | 842 | ||
| 843 | extern int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask); | ||
| 844 | |||
| 839 | int dma_supported(struct device *dev, u64 device_mask) | 845 | int dma_supported(struct device *dev, u64 device_mask) |
| 840 | { | 846 | { |
| 841 | struct iommu *iommu = dev->archdata.iommu; | 847 | struct iommu *iommu = dev->archdata.iommu; |
| @@ -849,7 +855,7 @@ int dma_supported(struct device *dev, u64 device_mask) | |||
| 849 | 855 | ||
| 850 | #ifdef CONFIG_PCI | 856 | #ifdef CONFIG_PCI |
| 851 | if (dev->bus == &pci_bus_type) | 857 | if (dev->bus == &pci_bus_type) |
| 852 | return pci_dma_supported(to_pci_dev(dev), device_mask); | 858 | return pci64_dma_supported(to_pci_dev(dev), device_mask); |
| 853 | #endif | 859 | #endif |
| 854 | 860 | ||
| 855 | return 0; | 861 | return 0; |
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 87ea0d03d975..9f61fd8cbb7b 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 36 | #include <linux/pci.h> /* struct pci_dev */ | 36 | #include <linux/pci.h> /* struct pci_dev */ |
| 37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
| 38 | #include <linux/seq_file.h> | ||
| 38 | #include <linux/scatterlist.h> | 39 | #include <linux/scatterlist.h> |
| 39 | #include <linux/of_device.h> | 40 | #include <linux/of_device.h> |
| 40 | 41 | ||
| @@ -48,8 +49,6 @@ | |||
| 48 | #include <asm/iommu.h> | 49 | #include <asm/iommu.h> |
| 49 | #include <asm/io-unit.h> | 50 | #include <asm/io-unit.h> |
| 50 | 51 | ||
| 51 | #include "dma.h" | ||
| 52 | |||
| 53 | #define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */ | 52 | #define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */ |
| 54 | 53 | ||
| 55 | static struct resource *_sparc_find_resource(struct resource *r, | 54 | static struct resource *_sparc_find_resource(struct resource *r, |
| @@ -246,7 +245,8 @@ EXPORT_SYMBOL(sbus_set_sbus64); | |||
| 246 | * Typically devices use them for control blocks. | 245 | * Typically devices use them for control blocks. |
| 247 | * CPU may access them without any explicit flushing. | 246 | * CPU may access them without any explicit flushing. |
| 248 | */ | 247 | */ |
| 249 | void *sbus_alloc_consistent(struct device *dev, long len, u32 *dma_addrp) | 248 | static void *sbus_alloc_coherent(struct device *dev, size_t len, |
| 249 | dma_addr_t *dma_addrp, gfp_t gfp) | ||
| 250 | { | 250 | { |
| 251 | struct of_device *op = to_of_device(dev); | 251 | struct of_device *op = to_of_device(dev); |
| 252 | unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK; | 252 | unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK; |
| @@ -299,7 +299,8 @@ err_nopages: | |||
| 299 | return NULL; | 299 | return NULL; |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba) | 302 | static void sbus_free_coherent(struct device *dev, size_t n, void *p, |
| 303 | dma_addr_t ba) | ||
| 303 | { | 304 | { |
| 304 | struct resource *res; | 305 | struct resource *res; |
| 305 | struct page *pgv; | 306 | struct page *pgv; |
| @@ -317,7 +318,7 @@ void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba) | |||
| 317 | 318 | ||
| 318 | n = (n + PAGE_SIZE-1) & PAGE_MASK; | 319 | n = (n + PAGE_SIZE-1) & PAGE_MASK; |
| 319 | if ((res->end-res->start)+1 != n) { | 320 | if ((res->end-res->start)+1 != n) { |
| 320 | printk("sbus_free_consistent: region 0x%lx asked 0x%lx\n", | 321 | printk("sbus_free_consistent: region 0x%lx asked 0x%zx\n", |
| 321 | (long)((res->end-res->start)+1), n); | 322 | (long)((res->end-res->start)+1), n); |
| 322 | return; | 323 | return; |
| 323 | } | 324 | } |
| @@ -337,8 +338,13 @@ void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba) | |||
| 337 | * CPU view of this memory may be inconsistent with | 338 | * CPU view of this memory may be inconsistent with |
| 338 | * a device view and explicit flushing is necessary. | 339 | * a device view and explicit flushing is necessary. |
| 339 | */ | 340 | */ |
| 340 | dma_addr_t sbus_map_single(struct device *dev, void *va, size_t len, int direction) | 341 | static dma_addr_t sbus_map_page(struct device *dev, struct page *page, |
| 342 | unsigned long offset, size_t len, | ||
| 343 | enum dma_data_direction dir, | ||
| 344 | struct dma_attrs *attrs) | ||
| 341 | { | 345 | { |
| 346 | void *va = page_address(page) + offset; | ||
| 347 | |||
| 342 | /* XXX why are some lengths signed, others unsigned? */ | 348 | /* XXX why are some lengths signed, others unsigned? */ |
| 343 | if (len <= 0) { | 349 | if (len <= 0) { |
| 344 | return 0; | 350 | return 0; |
| @@ -350,12 +356,14 @@ dma_addr_t sbus_map_single(struct device *dev, void *va, size_t len, int directi | |||
| 350 | return mmu_get_scsi_one(dev, va, len); | 356 | return mmu_get_scsi_one(dev, va, len); |
| 351 | } | 357 | } |
| 352 | 358 | ||
| 353 | void sbus_unmap_single(struct device *dev, dma_addr_t ba, size_t n, int direction) | 359 | static void sbus_unmap_page(struct device *dev, dma_addr_t ba, size_t n, |
| 360 | enum dma_data_direction dir, struct dma_attrs *attrs) | ||
| 354 | { | 361 | { |
| 355 | mmu_release_scsi_one(dev, ba, n); | 362 | mmu_release_scsi_one(dev, ba, n); |
| 356 | } | 363 | } |
| 357 | 364 | ||
| 358 | int sbus_map_sg(struct device *dev, struct scatterlist *sg, int n, int direction) | 365 | static int sbus_map_sg(struct device *dev, struct scatterlist *sg, int n, |
| 366 | enum dma_data_direction dir, struct dma_attrs *attrs) | ||
| 359 | { | 367 | { |
| 360 | mmu_get_scsi_sgl(dev, sg, n); | 368 | mmu_get_scsi_sgl(dev, sg, n); |
| 361 | 369 | ||
| @@ -366,19 +374,38 @@ int sbus_map_sg(struct device *dev, struct scatterlist *sg, int n, int direction | |||
| 366 | return n; | 374 | return n; |
| 367 | } | 375 | } |
| 368 | 376 | ||
| 369 | void sbus_unmap_sg(struct device *dev, struct scatterlist *sg, int n, int direction) | 377 | static void sbus_unmap_sg(struct device *dev, struct scatterlist *sg, int n, |
| 378 | enum dma_data_direction dir, struct dma_attrs *attrs) | ||
| 370 | { | 379 | { |
| 371 | mmu_release_scsi_sgl(dev, sg, n); | 380 | mmu_release_scsi_sgl(dev, sg, n); |
| 372 | } | 381 | } |
| 373 | 382 | ||
| 374 | void sbus_dma_sync_single_for_cpu(struct device *dev, dma_addr_t ba, size_t size, int direction) | 383 | static void sbus_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, |
| 384 | int n, enum dma_data_direction dir) | ||
| 375 | { | 385 | { |
| 386 | BUG(); | ||
| 376 | } | 387 | } |
| 377 | 388 | ||
| 378 | void sbus_dma_sync_single_for_device(struct device *dev, dma_addr_t ba, size_t size, int direction) | 389 | static void sbus_sync_sg_for_device(struct device *dev, struct scatterlist *sg, |
| 390 | int n, enum dma_data_direction dir) | ||
| 379 | { | 391 | { |
| 392 | BUG(); | ||
| 380 | } | 393 | } |
| 381 | 394 | ||
| 395 | struct dma_map_ops sbus_dma_ops = { | ||
| 396 | .alloc_coherent = sbus_alloc_coherent, | ||
| 397 | .free_coherent = sbus_free_coherent, | ||
| 398 | .map_page = sbus_map_page, | ||
| 399 | .unmap_page = sbus_unmap_page, | ||
| 400 | .map_sg = sbus_map_sg, | ||
| 401 | .unmap_sg = sbus_unmap_sg, | ||
| 402 | .sync_sg_for_cpu = sbus_sync_sg_for_cpu, | ||
| 403 | .sync_sg_for_device = sbus_sync_sg_for_device, | ||
| 404 | }; | ||
| 405 | |||
| 406 | struct dma_map_ops *dma_ops = &sbus_dma_ops; | ||
| 407 | EXPORT_SYMBOL(dma_ops); | ||
| 408 | |||
| 382 | static int __init sparc_register_ioport(void) | 409 | static int __init sparc_register_ioport(void) |
| 383 | { | 410 | { |
| 384 | register_proc_sparc_ioport(); | 411 | register_proc_sparc_ioport(); |
| @@ -395,7 +422,8 @@ arch_initcall(sparc_register_ioport); | |||
| 395 | /* Allocate and map kernel buffer using consistent mode DMA for a device. | 422 | /* Allocate and map kernel buffer using consistent mode DMA for a device. |
| 396 | * hwdev should be valid struct pci_dev pointer for PCI devices. | 423 | * hwdev should be valid struct pci_dev pointer for PCI devices. |
| 397 | */ | 424 | */ |
| 398 | void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba) | 425 | static void *pci32_alloc_coherent(struct device *dev, size_t len, |
| 426 | dma_addr_t *pba, gfp_t gfp) | ||
| 399 | { | 427 | { |
| 400 | unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK; | 428 | unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK; |
| 401 | unsigned long va; | 429 | unsigned long va; |
| @@ -439,7 +467,6 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba) | |||
| 439 | *pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */ | 467 | *pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */ |
| 440 | return (void *) res->start; | 468 | return (void *) res->start; |
| 441 | } | 469 | } |
| 442 | EXPORT_SYMBOL(pci_alloc_consistent); | ||
| 443 | 470 | ||
| 444 | /* Free and unmap a consistent DMA buffer. | 471 | /* Free and unmap a consistent DMA buffer. |
| 445 | * cpu_addr is what was returned from pci_alloc_consistent, | 472 | * cpu_addr is what was returned from pci_alloc_consistent, |
| @@ -449,7 +476,8 @@ EXPORT_SYMBOL(pci_alloc_consistent); | |||
| 449 | * References to the memory and mappings associated with cpu_addr/dma_addr | 476 | * References to the memory and mappings associated with cpu_addr/dma_addr |
| 450 | * past this call are illegal. | 477 | * past this call are illegal. |
| 451 | */ | 478 | */ |
| 452 | void pci_free_consistent(struct pci_dev *pdev, size_t n, void *p, dma_addr_t ba) | 479 | static void pci32_free_coherent(struct device *dev, size_t n, void *p, |
| 480 | dma_addr_t ba) | ||
| 453 | { | 481 | { |
| 454 | struct resource *res; | 482 | struct resource *res; |
| 455 | unsigned long pgp; | 483 | unsigned long pgp; |
| @@ -481,60 +509,18 @@ void pci_free_consistent(struct pci_dev *pdev, size_t n, void *p, dma_addr_t ba) | |||
| 481 | 509 | ||
| 482 | free_pages(pgp, get_order(n)); | 510 | free_pages(pgp, get_order(n)); |
| 483 | } | 511 | } |
| 484 | EXPORT_SYMBOL(pci_free_consistent); | ||
| 485 | |||
| 486 | /* Map a single buffer of the indicated size for DMA in streaming mode. | ||
| 487 | * The 32-bit bus address to use is returned. | ||
| 488 | * | ||
| 489 | * Once the device is given the dma address, the device owns this memory | ||
| 490 | * until either pci_unmap_single or pci_dma_sync_single_* is performed. | ||
| 491 | */ | ||
| 492 | dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, | ||
| 493 | int direction) | ||
| 494 | { | ||
| 495 | BUG_ON(direction == PCI_DMA_NONE); | ||
| 496 | /* IIep is write-through, not flushing. */ | ||
| 497 | return virt_to_phys(ptr); | ||
| 498 | } | ||
| 499 | EXPORT_SYMBOL(pci_map_single); | ||
| 500 | |||
| 501 | /* Unmap a single streaming mode DMA translation. The dma_addr and size | ||
| 502 | * must match what was provided for in a previous pci_map_single call. All | ||
| 503 | * other usages are undefined. | ||
| 504 | * | ||
| 505 | * After this call, reads by the cpu to the buffer are guaranteed to see | ||
| 506 | * whatever the device wrote there. | ||
| 507 | */ | ||
| 508 | void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t ba, size_t size, | ||
| 509 | int direction) | ||
| 510 | { | ||
| 511 | BUG_ON(direction == PCI_DMA_NONE); | ||
| 512 | if (direction != PCI_DMA_TODEVICE) { | ||
| 513 | mmu_inval_dma_area((unsigned long)phys_to_virt(ba), | ||
| 514 | (size + PAGE_SIZE-1) & PAGE_MASK); | ||
| 515 | } | ||
| 516 | } | ||
| 517 | EXPORT_SYMBOL(pci_unmap_single); | ||
| 518 | 512 | ||
| 519 | /* | 513 | /* |
| 520 | * Same as pci_map_single, but with pages. | 514 | * Same as pci_map_single, but with pages. |
| 521 | */ | 515 | */ |
| 522 | dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, | 516 | static dma_addr_t pci32_map_page(struct device *dev, struct page *page, |
| 523 | unsigned long offset, size_t size, int direction) | 517 | unsigned long offset, size_t size, |
| 518 | enum dma_data_direction dir, | ||
| 519 | struct dma_attrs *attrs) | ||
| 524 | { | 520 | { |
| 525 | BUG_ON(direction == PCI_DMA_NONE); | ||
| 526 | /* IIep is write-through, not flushing. */ | 521 | /* IIep is write-through, not flushing. */ |
| 527 | return page_to_phys(page) + offset; | 522 | return page_to_phys(page) + offset; |
| 528 | } | 523 | } |
| 529 | EXPORT_SYMBOL(pci_map_page); | ||
| 530 | |||
| 531 | void pci_unmap_page(struct pci_dev *hwdev, | ||
| 532 | dma_addr_t dma_address, size_t size, int direction) | ||
| 533 | { | ||
| 534 | BUG_ON(direction == PCI_DMA_NONE); | ||
| 535 | /* mmu_inval_dma_area XXX */ | ||
| 536 | } | ||
| 537 | EXPORT_SYMBOL(pci_unmap_page); | ||
| 538 | 524 | ||
| 539 | /* Map a set of buffers described by scatterlist in streaming | 525 | /* Map a set of buffers described by scatterlist in streaming |
| 540 | * mode for DMA. This is the scather-gather version of the | 526 | * mode for DMA. This is the scather-gather version of the |
| @@ -551,13 +537,13 @@ EXPORT_SYMBOL(pci_unmap_page); | |||
| 551 | * Device ownership issues as mentioned above for pci_map_single are | 537 | * Device ownership issues as mentioned above for pci_map_single are |
| 552 | * the same here. | 538 | * the same here. |
| 553 | */ | 539 | */ |
| 554 | int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, | 540 | static int pci32_map_sg(struct device *device, struct scatterlist *sgl, |
| 555 | int direction) | 541 | int nents, enum dma_data_direction dir, |
| 542 | struct dma_attrs *attrs) | ||
| 556 | { | 543 | { |
| 557 | struct scatterlist *sg; | 544 | struct scatterlist *sg; |
| 558 | int n; | 545 | int n; |
| 559 | 546 | ||
| 560 | BUG_ON(direction == PCI_DMA_NONE); | ||
| 561 | /* IIep is write-through, not flushing. */ | 547 | /* IIep is write-through, not flushing. */ |
| 562 | for_each_sg(sgl, sg, nents, n) { | 548 | for_each_sg(sgl, sg, nents, n) { |
| 563 | BUG_ON(page_address(sg_page(sg)) == NULL); | 549 | BUG_ON(page_address(sg_page(sg)) == NULL); |
| @@ -566,20 +552,19 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, | |||
| 566 | } | 552 | } |
| 567 | return nents; | 553 | return nents; |
| 568 | } | 554 | } |
| 569 | EXPORT_SYMBOL(pci_map_sg); | ||
| 570 | 555 | ||
| 571 | /* Unmap a set of streaming mode DMA translations. | 556 | /* Unmap a set of streaming mode DMA translations. |
| 572 | * Again, cpu read rules concerning calls here are the same as for | 557 | * Again, cpu read rules concerning calls here are the same as for |
| 573 | * pci_unmap_single() above. | 558 | * pci_unmap_single() above. |
| 574 | */ | 559 | */ |
| 575 | void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, | 560 | static void pci32_unmap_sg(struct device *dev, struct scatterlist *sgl, |
| 576 | int direction) | 561 | int nents, enum dma_data_direction dir, |
| 562 | struct dma_attrs *attrs) | ||
| 577 | { | 563 | { |
| 578 | struct scatterlist *sg; | 564 | struct scatterlist *sg; |
| 579 | int n; | 565 | int n; |
| 580 | 566 | ||
| 581 | BUG_ON(direction == PCI_DMA_NONE); | 567 | if (dir != PCI_DMA_TODEVICE) { |
| 582 | if (direction != PCI_DMA_TODEVICE) { | ||
| 583 | for_each_sg(sgl, sg, nents, n) { | 568 | for_each_sg(sgl, sg, nents, n) { |
| 584 | BUG_ON(page_address(sg_page(sg)) == NULL); | 569 | BUG_ON(page_address(sg_page(sg)) == NULL); |
| 585 | mmu_inval_dma_area( | 570 | mmu_inval_dma_area( |
| @@ -588,7 +573,6 @@ void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, | |||
| 588 | } | 573 | } |
| 589 | } | 574 | } |
| 590 | } | 575 | } |
| 591 | EXPORT_SYMBOL(pci_unmap_sg); | ||
| 592 | 576 | ||
| 593 | /* Make physical memory consistent for a single | 577 | /* Make physical memory consistent for a single |
| 594 | * streaming mode DMA translation before or after a transfer. | 578 | * streaming mode DMA translation before or after a transfer. |
| @@ -600,25 +584,23 @@ EXPORT_SYMBOL(pci_unmap_sg); | |||
| 600 | * must first perform a pci_dma_sync_for_device, and then the | 584 | * must first perform a pci_dma_sync_for_device, and then the |
| 601 | * device again owns the buffer. | 585 | * device again owns the buffer. |
| 602 | */ | 586 | */ |
| 603 | void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t ba, size_t size, int direction) | 587 | static void pci32_sync_single_for_cpu(struct device *dev, dma_addr_t ba, |
| 588 | size_t size, enum dma_data_direction dir) | ||
| 604 | { | 589 | { |
| 605 | BUG_ON(direction == PCI_DMA_NONE); | 590 | if (dir != PCI_DMA_TODEVICE) { |
| 606 | if (direction != PCI_DMA_TODEVICE) { | ||
| 607 | mmu_inval_dma_area((unsigned long)phys_to_virt(ba), | 591 | mmu_inval_dma_area((unsigned long)phys_to_virt(ba), |
| 608 | (size + PAGE_SIZE-1) & PAGE_MASK); | 592 | (size + PAGE_SIZE-1) & PAGE_MASK); |
| 609 | } | 593 | } |
| 610 | } | 594 | } |
| 611 | EXPORT_SYMBOL(pci_dma_sync_single_for_cpu); | ||
| 612 | 595 | ||
| 613 | void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t ba, size_t size, int direction) | 596 | static void pci32_sync_single_for_device(struct device *dev, dma_addr_t ba, |
| 597 | size_t size, enum dma_data_direction dir) | ||
| 614 | { | 598 | { |
| 615 | BUG_ON(direction == PCI_DMA_NONE); | 599 | if (dir != PCI_DMA_TODEVICE) { |
| 616 | if (direction != PCI_DMA_TODEVICE) { | ||
| 617 | mmu_inval_dma_area((unsigned long)phys_to_virt(ba), | 600 | mmu_inval_dma_area((unsigned long)phys_to_virt(ba), |
| 618 | (size + PAGE_SIZE-1) & PAGE_MASK); | 601 | (size + PAGE_SIZE-1) & PAGE_MASK); |
| 619 | } | 602 | } |
| 620 | } | 603 | } |
| 621 | EXPORT_SYMBOL(pci_dma_sync_single_for_device); | ||
| 622 | 604 | ||
| 623 | /* Make physical memory consistent for a set of streaming | 605 | /* Make physical memory consistent for a set of streaming |
| 624 | * mode DMA translations after a transfer. | 606 | * mode DMA translations after a transfer. |
| @@ -626,13 +608,13 @@ EXPORT_SYMBOL(pci_dma_sync_single_for_device); | |||
| 626 | * The same as pci_dma_sync_single_* but for a scatter-gather list, | 608 | * The same as pci_dma_sync_single_* but for a scatter-gather list, |
| 627 | * same rules and usage. | 609 | * same rules and usage. |
| 628 | */ | 610 | */ |
| 629 | void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction) | 611 | static void pci32_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl, |
| 612 | int nents, enum dma_data_direction dir) | ||
| 630 | { | 613 | { |
| 631 | struct scatterlist *sg; | 614 | struct scatterlist *sg; |
| 632 | int n; | 615 | int n; |
| 633 | 616 | ||
| 634 | BUG_ON(direction == PCI_DMA_NONE); | 617 | if (dir != PCI_DMA_TODEVICE) { |
| 635 | if (direction != PCI_DMA_TODEVICE) { | ||
| 636 | for_each_sg(sgl, sg, nents, n) { | 618 | for_each_sg(sgl, sg, nents, n) { |
| 637 | BUG_ON(page_address(sg_page(sg)) == NULL); | 619 | BUG_ON(page_address(sg_page(sg)) == NULL); |
| 638 | mmu_inval_dma_area( | 620 | mmu_inval_dma_area( |
| @@ -641,15 +623,14 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int | |||
| 641 | } | 623 | } |
| 642 | } | 624 | } |
| 643 | } | 625 | } |
| 644 | EXPORT_SYMBOL(pci_dma_sync_sg_for_cpu); | ||
| 645 | 626 | ||
| 646 | void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction) | 627 | static void pci32_sync_sg_for_device(struct device *device, struct scatterlist *sgl, |
| 628 | int nents, enum dma_data_direction dir) | ||
| 647 | { | 629 | { |
| 648 | struct scatterlist *sg; | 630 | struct scatterlist *sg; |
| 649 | int n; | 631 | int n; |
| 650 | 632 | ||
| 651 | BUG_ON(direction == PCI_DMA_NONE); | 633 | if (dir != PCI_DMA_TODEVICE) { |
| 652 | if (direction != PCI_DMA_TODEVICE) { | ||
| 653 | for_each_sg(sgl, sg, nents, n) { | 634 | for_each_sg(sgl, sg, nents, n) { |
| 654 | BUG_ON(page_address(sg_page(sg)) == NULL); | 635 | BUG_ON(page_address(sg_page(sg)) == NULL); |
| 655 | mmu_inval_dma_area( | 636 | mmu_inval_dma_area( |
| @@ -658,31 +639,78 @@ void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl, | |||
| 658 | } | 639 | } |
| 659 | } | 640 | } |
| 660 | } | 641 | } |
| 661 | EXPORT_SYMBOL(pci_dma_sync_sg_for_device); | 642 | |
| 643 | struct dma_map_ops pci32_dma_ops = { | ||
| 644 | .alloc_coherent = pci32_alloc_coherent, | ||
| 645 | .free_coherent = pci32_free_coherent, | ||
| 646 | .map_page = pci32_map_page, | ||
| 647 | .map_sg = pci32_map_sg, | ||
| 648 | .unmap_sg = pci32_unmap_sg, | ||
| 649 | .sync_single_for_cpu = pci32_sync_single_for_cpu, | ||
| 650 | .sync_single_for_device = pci32_sync_single_for_device, | ||
| 651 | .sync_sg_for_cpu = pci32_sync_sg_for_cpu, | ||
| 652 | .sync_sg_for_device = pci32_sync_sg_for_device, | ||
| 653 | }; | ||
| 654 | EXPORT_SYMBOL(pci32_dma_ops); | ||
| 655 | |||
| 662 | #endif /* CONFIG_PCI */ | 656 | #endif /* CONFIG_PCI */ |
| 663 | 657 | ||
| 658 | /* | ||
| 659 | * Return whether the given PCI device DMA address mask can be | ||
| 660 | * supported properly. For example, if your device can only drive the | ||
| 661 | * low 24-bits during PCI bus mastering, then you would pass | ||
| 662 | * 0x00ffffff as the mask to this function. | ||
| 663 | */ | ||
| 664 | int dma_supported(struct device *dev, u64 mask) | ||
| 665 | { | ||
| 666 | #ifdef CONFIG_PCI | ||
| 667 | if (dev->bus == &pci_bus_type) | ||
| 668 | return 1; | ||
| 669 | #endif | ||
| 670 | return 0; | ||
| 671 | } | ||
| 672 | EXPORT_SYMBOL(dma_supported); | ||
| 673 | |||
| 674 | int dma_set_mask(struct device *dev, u64 dma_mask) | ||
| 675 | { | ||
| 676 | #ifdef CONFIG_PCI | ||
| 677 | if (dev->bus == &pci_bus_type) | ||
| 678 | return pci_set_dma_mask(to_pci_dev(dev), dma_mask); | ||
| 679 | #endif | ||
| 680 | return -EOPNOTSUPP; | ||
| 681 | } | ||
| 682 | EXPORT_SYMBOL(dma_set_mask); | ||
| 683 | |||
| 684 | |||
| 664 | #ifdef CONFIG_PROC_FS | 685 | #ifdef CONFIG_PROC_FS |
| 665 | 686 | ||
| 666 | static int | 687 | static int sparc_io_proc_show(struct seq_file *m, void *v) |
| 667 | _sparc_io_get_info(char *buf, char **start, off_t fpos, int length, int *eof, | ||
| 668 | void *data) | ||
| 669 | { | 688 | { |
| 670 | char *p = buf, *e = buf + length; | 689 | struct resource *root = m->private, *r; |
| 671 | struct resource *r; | ||
| 672 | const char *nm; | 690 | const char *nm; |
| 673 | 691 | ||
| 674 | for (r = ((struct resource *)data)->child; r != NULL; r = r->sibling) { | 692 | for (r = root->child; r != NULL; r = r->sibling) { |
| 675 | if (p + 32 >= e) /* Better than nothing */ | ||
| 676 | break; | ||
| 677 | if ((nm = r->name) == 0) nm = "???"; | 693 | if ((nm = r->name) == 0) nm = "???"; |
| 678 | p += sprintf(p, "%016llx-%016llx: %s\n", | 694 | seq_printf(m, "%016llx-%016llx: %s\n", |
| 679 | (unsigned long long)r->start, | 695 | (unsigned long long)r->start, |
| 680 | (unsigned long long)r->end, nm); | 696 | (unsigned long long)r->end, nm); |
| 681 | } | 697 | } |
| 682 | 698 | ||
| 683 | return p-buf; | 699 | return 0; |
| 684 | } | 700 | } |
| 685 | 701 | ||
| 702 | static int sparc_io_proc_open(struct inode *inode, struct file *file) | ||
| 703 | { | ||
| 704 | return single_open(file, sparc_io_proc_show, PDE(inode)->data); | ||
| 705 | } | ||
| 706 | |||
| 707 | static const struct file_operations sparc_io_proc_fops = { | ||
| 708 | .owner = THIS_MODULE, | ||
| 709 | .open = sparc_io_proc_open, | ||
| 710 | .read = seq_read, | ||
| 711 | .llseek = seq_lseek, | ||
| 712 | .release = single_release, | ||
| 713 | }; | ||
| 686 | #endif /* CONFIG_PROC_FS */ | 714 | #endif /* CONFIG_PROC_FS */ |
| 687 | 715 | ||
| 688 | /* | 716 | /* |
| @@ -707,7 +735,7 @@ static struct resource *_sparc_find_resource(struct resource *root, | |||
| 707 | static void register_proc_sparc_ioport(void) | 735 | static void register_proc_sparc_ioport(void) |
| 708 | { | 736 | { |
| 709 | #ifdef CONFIG_PROC_FS | 737 | #ifdef CONFIG_PROC_FS |
| 710 | create_proc_read_entry("io_map",0,NULL,_sparc_io_get_info,&sparc_iomap); | 738 | proc_create_data("io_map", 0, NULL, &sparc_io_proc_fops, &sparc_iomap); |
| 711 | create_proc_read_entry("dvma_map",0,NULL,_sparc_io_get_info,&_sparc_dvma); | 739 | proc_create_data("dvma_map", 0, NULL, &sparc_io_proc_fops, &_sparc_dvma); |
| 712 | #endif | 740 | #endif |
| 713 | } | 741 | } |
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index ad800b80c718..e1af43728329 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #include <asm/pcic.h> | 45 | #include <asm/pcic.h> |
| 46 | #include <asm/cacheflush.h> | 46 | #include <asm/cacheflush.h> |
| 47 | #include <asm/irq_regs.h> | 47 | #include <asm/irq_regs.h> |
| 48 | #include <asm/leon.h> | ||
| 48 | 49 | ||
| 49 | #include "kernel.h" | 50 | #include "kernel.h" |
| 50 | #include "irq.h" | 51 | #include "irq.h" |
| @@ -661,6 +662,10 @@ void __init init_IRQ(void) | |||
| 661 | sun4d_init_IRQ(); | 662 | sun4d_init_IRQ(); |
| 662 | break; | 663 | break; |
| 663 | 664 | ||
| 665 | case sparc_leon: | ||
| 666 | leon_init_IRQ(); | ||
| 667 | break; | ||
| 668 | |||
| 664 | default: | 669 | default: |
| 665 | prom_printf("Cannot initialize IRQs on this Sun machine..."); | 670 | prom_printf("Cannot initialize IRQs on this Sun machine..."); |
| 666 | break; | 671 | break; |
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index f0ee79055409..8daab33fc17d 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c | |||
| @@ -886,7 +886,7 @@ void notrace init_irqwork_curcpu(void) | |||
| 886 | * Therefore you cannot make any OBP calls, not even prom_printf, | 886 | * Therefore you cannot make any OBP calls, not even prom_printf, |
| 887 | * from these two routines. | 887 | * from these two routines. |
| 888 | */ | 888 | */ |
| 889 | static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type, unsigned long qmask) | 889 | static void __cpuinit notrace register_one_mondo(unsigned long paddr, unsigned long type, unsigned long qmask) |
| 890 | { | 890 | { |
| 891 | unsigned long num_entries = (qmask + 1) / 64; | 891 | unsigned long num_entries = (qmask + 1) / 64; |
| 892 | unsigned long status; | 892 | unsigned long status; |
diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S index cef8defcd7a9..3ea6e8cde8c5 100644 --- a/arch/sparc/kernel/ktlb.S +++ b/arch/sparc/kernel/ktlb.S | |||
| @@ -151,12 +151,46 @@ kvmap_dtlb_4v: | |||
| 151 | * Must preserve %g1 and %g6 (TAG). | 151 | * Must preserve %g1 and %g6 (TAG). |
| 152 | */ | 152 | */ |
| 153 | kvmap_dtlb_tsb4m_miss: | 153 | kvmap_dtlb_tsb4m_miss: |
| 154 | sethi %hi(kpte_linear_bitmap), %g2 | 154 | /* Clear the PAGE_OFFSET top virtual bits, shift |
| 155 | or %g2, %lo(kpte_linear_bitmap), %g2 | 155 | * down to get PFN, and make sure PFN is in range. |
| 156 | */ | ||
| 157 | sllx %g4, 21, %g5 | ||
| 156 | 158 | ||
| 157 | /* Clear the PAGE_OFFSET top virtual bits, then shift | 159 | /* Check to see if we know about valid memory at the 4MB |
| 158 | * down to get a 256MB physical address index. | 160 | * chunk this physical address will reside within. |
| 159 | */ | 161 | */ |
| 162 | srlx %g5, 21 + 41, %g2 | ||
| 163 | brnz,pn %g2, kvmap_dtlb_longpath | ||
| 164 | nop | ||
| 165 | |||
| 166 | /* This unconditional branch and delay-slot nop gets patched | ||
| 167 | * by the sethi sequence once the bitmap is properly setup. | ||
| 168 | */ | ||
| 169 | .globl valid_addr_bitmap_insn | ||
| 170 | valid_addr_bitmap_insn: | ||
| 171 | ba,pt %xcc, 2f | ||
| 172 | nop | ||
| 173 | .subsection 2 | ||
| 174 | .globl valid_addr_bitmap_patch | ||
| 175 | valid_addr_bitmap_patch: | ||
| 176 | sethi %hi(sparc64_valid_addr_bitmap), %g7 | ||
| 177 | or %g7, %lo(sparc64_valid_addr_bitmap), %g7 | ||
| 178 | .previous | ||
| 179 | |||
| 180 | srlx %g5, 21 + 22, %g2 | ||
| 181 | srlx %g2, 6, %g5 | ||
| 182 | and %g2, 63, %g2 | ||
| 183 | sllx %g5, 3, %g5 | ||
| 184 | ldx [%g7 + %g5], %g5 | ||
| 185 | mov 1, %g7 | ||
| 186 | sllx %g7, %g2, %g7 | ||
| 187 | andcc %g5, %g7, %g0 | ||
| 188 | be,pn %xcc, kvmap_dtlb_longpath | ||
| 189 | |||
| 190 | 2: sethi %hi(kpte_linear_bitmap), %g2 | ||
| 191 | or %g2, %lo(kpte_linear_bitmap), %g2 | ||
| 192 | |||
| 193 | /* Get the 256MB physical address index. */ | ||
| 160 | sllx %g4, 21, %g5 | 194 | sllx %g4, 21, %g5 |
| 161 | mov 1, %g7 | 195 | mov 1, %g7 |
| 162 | srlx %g5, 21 + 28, %g5 | 196 | srlx %g5, 21 + 28, %g5 |
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c new file mode 100644 index 000000000000..54d8a5bd4824 --- /dev/null +++ b/arch/sparc/kernel/leon_kernel.c | |||
| @@ -0,0 +1,203 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB | ||
| 3 | * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <linux/kernel.h> | ||
| 7 | #include <linux/module.h> | ||
| 8 | #include <linux/errno.h> | ||
| 9 | #include <linux/mutex.h> | ||
| 10 | #include <linux/slab.h> | ||
| 11 | #include <linux/of.h> | ||
| 12 | #include <linux/of_platform.h> | ||
| 13 | #include <linux/interrupt.h> | ||
| 14 | #include <linux/of_device.h> | ||
| 15 | #include <asm/oplib.h> | ||
| 16 | #include <asm/timer.h> | ||
| 17 | #include <asm/prom.h> | ||
| 18 | #include <asm/leon.h> | ||
| 19 | #include <asm/leon_amba.h> | ||
| 20 | |||
| 21 | #include "prom.h" | ||
| 22 | #include "irq.h" | ||
| 23 | |||
| 24 | struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; /* interrupt controller base address, initialized by amba_init() */ | ||
| 25 | struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base address, initialized by amba_init() */ | ||
| 26 | struct amba_apb_device leon_percpu_timer_dev[16]; | ||
| 27 | |||
| 28 | int leondebug_irq_disable; | ||
| 29 | int leon_debug_irqout; | ||
| 30 | static int dummy_master_l10_counter; | ||
| 31 | |||
| 32 | unsigned long leon3_gptimer_irq; /* interrupt controller irq number, initialized by amba_init() */ | ||
| 33 | unsigned int sparc_leon_eirq; | ||
| 34 | #define LEON_IMASK ((&leon3_irqctrl_regs->mask[0])) | ||
| 35 | |||
| 36 | /* Return the IRQ of the pending IRQ on the extended IRQ controller */ | ||
| 37 | int sparc_leon_eirq_get(int eirq, int cpu) | ||
| 38 | { | ||
| 39 | return LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->intid[cpu]) & 0x1f; | ||
| 40 | } | ||
| 41 | |||
| 42 | irqreturn_t sparc_leon_eirq_isr(int dummy, void *dev_id) | ||
| 43 | { | ||
| 44 | printk(KERN_ERR "sparc_leon_eirq_isr: ERROR EXTENDED IRQ\n"); | ||
| 45 | return IRQ_HANDLED; | ||
| 46 | } | ||
| 47 | |||
| 48 | /* The extended IRQ controller has been found, this function registers it */ | ||
| 49 | void sparc_leon_eirq_register(int eirq) | ||
| 50 | { | ||
| 51 | int irq; | ||
| 52 | |||
| 53 | /* Register a "BAD" handler for this interrupt, it should never happen */ | ||
| 54 | irq = request_irq(eirq, sparc_leon_eirq_isr, | ||
| 55 | (IRQF_DISABLED | SA_STATIC_ALLOC), "extirq", NULL); | ||
| 56 | |||
| 57 | if (irq) { | ||
| 58 | printk(KERN_ERR | ||
| 59 | "sparc_leon_eirq_register: unable to attach IRQ%d\n", | ||
| 60 | eirq); | ||
| 61 | } else { | ||
| 62 | sparc_leon_eirq = eirq; | ||
| 63 | } | ||
| 64 | |||
| 65 | } | ||
| 66 | |||
| 67 | static inline unsigned long get_irqmask(unsigned int irq) | ||
| 68 | { | ||
| 69 | unsigned long mask; | ||
| 70 | |||
| 71 | if (!irq || ((irq > 0xf) && !sparc_leon_eirq) | ||
| 72 | || ((irq > 0x1f) && sparc_leon_eirq)) { | ||
| 73 | printk(KERN_ERR | ||
| 74 | "leon_get_irqmask: false irq number: %d\n", irq); | ||
| 75 | mask = 0; | ||
| 76 | } else { | ||
| 77 | mask = LEON_HARD_INT(irq); | ||
| 78 | } | ||
| 79 | return mask; | ||
| 80 | } | ||
| 81 | |||
| 82 | static void leon_enable_irq(unsigned int irq_nr) | ||
| 83 | { | ||
| 84 | unsigned long mask, flags; | ||
| 85 | mask = get_irqmask(irq_nr); | ||
| 86 | local_irq_save(flags); | ||
| 87 | LEON3_BYPASS_STORE_PA(LEON_IMASK, | ||
| 88 | (LEON3_BYPASS_LOAD_PA(LEON_IMASK) | (mask))); | ||
| 89 | local_irq_restore(flags); | ||
| 90 | } | ||
| 91 | |||
| 92 | static void leon_disable_irq(unsigned int irq_nr) | ||
| 93 | { | ||
| 94 | unsigned long mask, flags; | ||
| 95 | mask = get_irqmask(irq_nr); | ||
| 96 | local_irq_save(flags); | ||
| 97 | LEON3_BYPASS_STORE_PA(LEON_IMASK, | ||
| 98 | (LEON3_BYPASS_LOAD_PA(LEON_IMASK) & ~(mask))); | ||
| 99 | local_irq_restore(flags); | ||
| 100 | |||
| 101 | } | ||
| 102 | |||
| 103 | void __init leon_init_timers(irq_handler_t counter_fn) | ||
| 104 | { | ||
| 105 | int irq; | ||
| 106 | |||
| 107 | leondebug_irq_disable = 0; | ||
| 108 | leon_debug_irqout = 0; | ||
| 109 | master_l10_counter = (unsigned int *)&dummy_master_l10_counter; | ||
| 110 | dummy_master_l10_counter = 0; | ||
| 111 | |||
| 112 | if (leon3_gptimer_regs && leon3_irqctrl_regs) { | ||
| 113 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0); | ||
| 114 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld, | ||
| 115 | (((1000000 / 100) - 1))); | ||
| 116 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0); | ||
| 117 | |||
| 118 | } else { | ||
| 119 | printk(KERN_ERR "No Timer/irqctrl found\n"); | ||
| 120 | BUG(); | ||
| 121 | } | ||
| 122 | |||
| 123 | irq = request_irq(leon3_gptimer_irq, | ||
| 124 | counter_fn, | ||
| 125 | (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL); | ||
| 126 | |||
| 127 | if (irq) { | ||
| 128 | printk(KERN_ERR "leon_time_init: unable to attach IRQ%d\n", | ||
| 129 | LEON_INTERRUPT_TIMER1); | ||
| 130 | prom_halt(); | ||
| 131 | } | ||
| 132 | |||
| 133 | if (leon3_gptimer_regs) { | ||
| 134 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, | ||
| 135 | LEON3_GPTIMER_EN | | ||
| 136 | LEON3_GPTIMER_RL | | ||
| 137 | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN); | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 | void leon_clear_clock_irq(void) | ||
| 142 | { | ||
| 143 | } | ||
| 144 | |||
| 145 | void leon_load_profile_irq(int cpu, unsigned int limit) | ||
| 146 | { | ||
| 147 | BUG(); | ||
| 148 | } | ||
| 149 | |||
| 150 | |||
| 151 | |||
| 152 | |||
| 153 | void __init leon_trans_init(struct device_node *dp) | ||
| 154 | { | ||
| 155 | if (strcmp(dp->type, "cpu") == 0 && strcmp(dp->name, "<NULL>") == 0) { | ||
| 156 | struct property *p; | ||
| 157 | p = of_find_property(dp, "mid", (void *)0); | ||
| 158 | if (p) { | ||
| 159 | int mid; | ||
| 160 | dp->name = prom_early_alloc(5 + 1); | ||
| 161 | memcpy(&mid, p->value, p->length); | ||
| 162 | sprintf((char *)dp->name, "cpu%.2d", mid); | ||
| 163 | } | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | void __initdata (*prom_amba_init)(struct device_node *dp, struct device_node ***nextp) = 0; | ||
| 168 | |||
| 169 | void __init leon_node_init(struct device_node *dp, struct device_node ***nextp) | ||
| 170 | { | ||
| 171 | if (prom_amba_init && | ||
| 172 | strcmp(dp->type, "ambapp") == 0 && | ||
| 173 | strcmp(dp->name, "ambapp0") == 0) { | ||
| 174 | prom_amba_init(dp, nextp); | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | void __init leon_init_IRQ(void) | ||
| 179 | { | ||
| 180 | sparc_init_timers = leon_init_timers; | ||
| 181 | |||
| 182 | BTFIXUPSET_CALL(enable_irq, leon_enable_irq, BTFIXUPCALL_NORM); | ||
| 183 | BTFIXUPSET_CALL(disable_irq, leon_disable_irq, BTFIXUPCALL_NORM); | ||
| 184 | BTFIXUPSET_CALL(enable_pil_irq, leon_enable_irq, BTFIXUPCALL_NORM); | ||
| 185 | BTFIXUPSET_CALL(disable_pil_irq, leon_disable_irq, BTFIXUPCALL_NORM); | ||
| 186 | |||
| 187 | BTFIXUPSET_CALL(clear_clock_irq, leon_clear_clock_irq, | ||
| 188 | BTFIXUPCALL_NORM); | ||
| 189 | BTFIXUPSET_CALL(load_profile_irq, leon_load_profile_irq, | ||
| 190 | BTFIXUPCALL_NOP); | ||
| 191 | |||
| 192 | #ifdef CONFIG_SMP | ||
| 193 | BTFIXUPSET_CALL(set_cpu_int, leon_set_cpu_int, BTFIXUPCALL_NORM); | ||
| 194 | BTFIXUPSET_CALL(clear_cpu_int, leon_clear_ipi, BTFIXUPCALL_NORM); | ||
| 195 | BTFIXUPSET_CALL(set_irq_udt, leon_set_udt, BTFIXUPCALL_NORM); | ||
| 196 | #endif | ||
| 197 | |||
| 198 | } | ||
| 199 | |||
| 200 | void __init leon_init(void) | ||
| 201 | { | ||
| 202 | prom_build_more = &leon_node_init; | ||
| 203 | } | ||
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c index 2c0cc72d295b..378eb53e0776 100644 --- a/arch/sparc/kernel/nmi.c +++ b/arch/sparc/kernel/nmi.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
| 20 | #include <linux/smp.h> | 20 | #include <linux/smp.h> |
| 21 | 21 | ||
| 22 | #include <asm/perf_counter.h> | ||
| 22 | #include <asm/ptrace.h> | 23 | #include <asm/ptrace.h> |
| 23 | #include <asm/local.h> | 24 | #include <asm/local.h> |
| 24 | #include <asm/pcr.h> | 25 | #include <asm/pcr.h> |
| @@ -31,13 +32,19 @@ | |||
| 31 | * level 14 as our IRQ off level. | 32 | * level 14 as our IRQ off level. |
| 32 | */ | 33 | */ |
| 33 | 34 | ||
| 34 | static int nmi_watchdog_active; | ||
| 35 | static int panic_on_timeout; | 35 | static int panic_on_timeout; |
| 36 | 36 | ||
| 37 | int nmi_usable; | 37 | /* nmi_active: |
| 38 | EXPORT_SYMBOL_GPL(nmi_usable); | 38 | * >0: the NMI watchdog is active, but can be disabled |
| 39 | * <0: the NMI watchdog has not been set up, and cannot be enabled | ||
| 40 | * 0: the NMI watchdog is disabled, but can be enabled | ||
| 41 | */ | ||
| 42 | atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ | ||
| 43 | EXPORT_SYMBOL(nmi_active); | ||
| 39 | 44 | ||
| 40 | static unsigned int nmi_hz = HZ; | 45 | static unsigned int nmi_hz = HZ; |
| 46 | static DEFINE_PER_CPU(short, wd_enabled); | ||
| 47 | static int endflag __initdata; | ||
| 41 | 48 | ||
| 42 | static DEFINE_PER_CPU(unsigned int, last_irq_sum); | 49 | static DEFINE_PER_CPU(unsigned int, last_irq_sum); |
| 43 | static DEFINE_PER_CPU(local_t, alert_counter); | 50 | static DEFINE_PER_CPU(local_t, alert_counter); |
| @@ -45,7 +52,7 @@ static DEFINE_PER_CPU(int, nmi_touch); | |||
| 45 | 52 | ||
| 46 | void touch_nmi_watchdog(void) | 53 | void touch_nmi_watchdog(void) |
| 47 | { | 54 | { |
| 48 | if (nmi_watchdog_active) { | 55 | if (atomic_read(&nmi_active)) { |
| 49 | int cpu; | 56 | int cpu; |
| 50 | 57 | ||
| 51 | for_each_present_cpu(cpu) { | 58 | for_each_present_cpu(cpu) { |
| @@ -78,6 +85,7 @@ static void die_nmi(const char *str, struct pt_regs *regs, int do_panic) | |||
| 78 | if (do_panic || panic_on_oops) | 85 | if (do_panic || panic_on_oops) |
| 79 | panic("Non maskable interrupt"); | 86 | panic("Non maskable interrupt"); |
| 80 | 87 | ||
| 88 | nmi_exit(); | ||
| 81 | local_irq_enable(); | 89 | local_irq_enable(); |
| 82 | do_exit(SIGBUS); | 90 | do_exit(SIGBUS); |
| 83 | } | 91 | } |
| @@ -92,6 +100,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) | |||
| 92 | 100 | ||
| 93 | local_cpu_data().__nmi_count++; | 101 | local_cpu_data().__nmi_count++; |
| 94 | 102 | ||
| 103 | nmi_enter(); | ||
| 104 | |||
| 95 | if (notify_die(DIE_NMI, "nmi", regs, 0, | 105 | if (notify_die(DIE_NMI, "nmi", regs, 0, |
| 96 | pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) | 106 | pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) |
| 97 | touched = 1; | 107 | touched = 1; |
| @@ -103,17 +113,19 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) | |||
| 103 | } | 113 | } |
| 104 | if (!touched && __get_cpu_var(last_irq_sum) == sum) { | 114 | if (!touched && __get_cpu_var(last_irq_sum) == sum) { |
| 105 | local_inc(&__get_cpu_var(alert_counter)); | 115 | local_inc(&__get_cpu_var(alert_counter)); |
| 106 | if (local_read(&__get_cpu_var(alert_counter)) == 5 * nmi_hz) | 116 | if (local_read(&__get_cpu_var(alert_counter)) == 30 * nmi_hz) |
| 107 | die_nmi("BUG: NMI Watchdog detected LOCKUP", | 117 | die_nmi("BUG: NMI Watchdog detected LOCKUP", |
| 108 | regs, panic_on_timeout); | 118 | regs, panic_on_timeout); |
| 109 | } else { | 119 | } else { |
| 110 | __get_cpu_var(last_irq_sum) = sum; | 120 | __get_cpu_var(last_irq_sum) = sum; |
| 111 | local_set(&__get_cpu_var(alert_counter), 0); | 121 | local_set(&__get_cpu_var(alert_counter), 0); |
| 112 | } | 122 | } |
| 113 | if (nmi_usable) { | 123 | if (__get_cpu_var(wd_enabled)) { |
| 114 | write_pic(picl_value(nmi_hz)); | 124 | write_pic(picl_value(nmi_hz)); |
| 115 | pcr_ops->write(pcr_enable); | 125 | pcr_ops->write(pcr_enable); |
| 116 | } | 126 | } |
| 127 | |||
| 128 | nmi_exit(); | ||
| 117 | } | 129 | } |
| 118 | 130 | ||
| 119 | static inline unsigned int get_nmi_count(int cpu) | 131 | static inline unsigned int get_nmi_count(int cpu) |
| @@ -121,8 +133,6 @@ static inline unsigned int get_nmi_count(int cpu) | |||
| 121 | return cpu_data(cpu).__nmi_count; | 133 | return cpu_data(cpu).__nmi_count; |
| 122 | } | 134 | } |
| 123 | 135 | ||
| 124 | static int endflag __initdata; | ||
| 125 | |||
| 126 | static __init void nmi_cpu_busy(void *data) | 136 | static __init void nmi_cpu_busy(void *data) |
| 127 | { | 137 | { |
| 128 | local_irq_enable_in_hardirq(); | 138 | local_irq_enable_in_hardirq(); |
| @@ -143,12 +153,15 @@ static void report_broken_nmi(int cpu, int *prev_nmi_count) | |||
| 143 | printk(KERN_WARNING | 153 | printk(KERN_WARNING |
| 144 | "and attach the output of the 'dmesg' command.\n"); | 154 | "and attach the output of the 'dmesg' command.\n"); |
| 145 | 155 | ||
| 146 | nmi_usable = 0; | 156 | per_cpu(wd_enabled, cpu) = 0; |
| 157 | atomic_dec(&nmi_active); | ||
| 147 | } | 158 | } |
| 148 | 159 | ||
| 149 | static void stop_watchdog(void *unused) | 160 | void stop_nmi_watchdog(void *unused) |
| 150 | { | 161 | { |
| 151 | pcr_ops->write(PCR_PIC_PRIV); | 162 | pcr_ops->write(PCR_PIC_PRIV); |
| 163 | __get_cpu_var(wd_enabled) = 0; | ||
| 164 | atomic_dec(&nmi_active); | ||
| 152 | } | 165 | } |
| 153 | 166 | ||
| 154 | static int __init check_nmi_watchdog(void) | 167 | static int __init check_nmi_watchdog(void) |
| @@ -156,6 +169,9 @@ static int __init check_nmi_watchdog(void) | |||
| 156 | unsigned int *prev_nmi_count; | 169 | unsigned int *prev_nmi_count; |
| 157 | int cpu, err; | 170 | int cpu, err; |
| 158 | 171 | ||
| 172 | if (!atomic_read(&nmi_active)) | ||
| 173 | return 0; | ||
| 174 | |||
| 159 | prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(unsigned int), GFP_KERNEL); | 175 | prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(unsigned int), GFP_KERNEL); |
| 160 | if (!prev_nmi_count) { | 176 | if (!prev_nmi_count) { |
| 161 | err = -ENOMEM; | 177 | err = -ENOMEM; |
| @@ -172,12 +188,15 @@ static int __init check_nmi_watchdog(void) | |||
| 172 | mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */ | 188 | mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */ |
| 173 | 189 | ||
| 174 | for_each_online_cpu(cpu) { | 190 | for_each_online_cpu(cpu) { |
| 191 | if (!per_cpu(wd_enabled, cpu)) | ||
| 192 | continue; | ||
| 175 | if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5) | 193 | if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5) |
| 176 | report_broken_nmi(cpu, prev_nmi_count); | 194 | report_broken_nmi(cpu, prev_nmi_count); |
| 177 | } | 195 | } |
| 178 | endflag = 1; | 196 | endflag = 1; |
| 179 | if (!nmi_usable) { | 197 | if (!atomic_read(&nmi_active)) { |
| 180 | kfree(prev_nmi_count); | 198 | kfree(prev_nmi_count); |
| 199 | atomic_set(&nmi_active, -1); | ||
| 181 | err = -ENODEV; | 200 | err = -ENODEV; |
| 182 | goto error; | 201 | goto error; |
| 183 | } | 202 | } |
| @@ -188,12 +207,26 @@ static int __init check_nmi_watchdog(void) | |||
| 188 | kfree(prev_nmi_count); | 207 | kfree(prev_nmi_count); |
| 189 | return 0; | 208 | return 0; |
| 190 | error: | 209 | error: |
| 191 | on_each_cpu(stop_watchdog, NULL, 1); | 210 | on_each_cpu(stop_nmi_watchdog, NULL, 1); |
| 192 | return err; | 211 | return err; |
| 193 | } | 212 | } |
| 194 | 213 | ||
| 195 | static void start_watchdog(void *unused) | 214 | void start_nmi_watchdog(void *unused) |
| 196 | { | 215 | { |
| 216 | __get_cpu_var(wd_enabled) = 1; | ||
| 217 | atomic_inc(&nmi_active); | ||
| 218 | |||
| 219 | pcr_ops->write(PCR_PIC_PRIV); | ||
| 220 | write_pic(picl_value(nmi_hz)); | ||
| 221 | |||
| 222 | pcr_ops->write(pcr_enable); | ||
| 223 | } | ||
| 224 | |||
| 225 | static void nmi_adjust_hz_one(void *unused) | ||
| 226 | { | ||
| 227 | if (!__get_cpu_var(wd_enabled)) | ||
| 228 | return; | ||
| 229 | |||
| 197 | pcr_ops->write(PCR_PIC_PRIV); | 230 | pcr_ops->write(PCR_PIC_PRIV); |
| 198 | write_pic(picl_value(nmi_hz)); | 231 | write_pic(picl_value(nmi_hz)); |
| 199 | 232 | ||
| @@ -203,13 +236,13 @@ static void start_watchdog(void *unused) | |||
| 203 | void nmi_adjust_hz(unsigned int new_hz) | 236 | void nmi_adjust_hz(unsigned int new_hz) |
| 204 | { | 237 | { |
| 205 | nmi_hz = new_hz; | 238 | nmi_hz = new_hz; |
| 206 | on_each_cpu(start_watchdog, NULL, 1); | 239 | on_each_cpu(nmi_adjust_hz_one, NULL, 1); |
| 207 | } | 240 | } |
| 208 | EXPORT_SYMBOL_GPL(nmi_adjust_hz); | 241 | EXPORT_SYMBOL_GPL(nmi_adjust_hz); |
| 209 | 242 | ||
| 210 | static int nmi_shutdown(struct notifier_block *nb, unsigned long cmd, void *p) | 243 | static int nmi_shutdown(struct notifier_block *nb, unsigned long cmd, void *p) |
| 211 | { | 244 | { |
| 212 | on_each_cpu(stop_watchdog, NULL, 1); | 245 | on_each_cpu(stop_nmi_watchdog, NULL, 1); |
| 213 | return 0; | 246 | return 0; |
| 214 | } | 247 | } |
| 215 | 248 | ||
| @@ -221,18 +254,19 @@ int __init nmi_init(void) | |||
| 221 | { | 254 | { |
| 222 | int err; | 255 | int err; |
| 223 | 256 | ||
| 224 | nmi_usable = 1; | 257 | on_each_cpu(start_nmi_watchdog, NULL, 1); |
| 225 | |||
| 226 | on_each_cpu(start_watchdog, NULL, 1); | ||
| 227 | 258 | ||
| 228 | err = check_nmi_watchdog(); | 259 | err = check_nmi_watchdog(); |
| 229 | if (!err) { | 260 | if (!err) { |
| 230 | err = register_reboot_notifier(&nmi_reboot_notifier); | 261 | err = register_reboot_notifier(&nmi_reboot_notifier); |
| 231 | if (err) { | 262 | if (err) { |
| 232 | nmi_usable = 0; | 263 | on_each_cpu(stop_nmi_watchdog, NULL, 1); |
| 233 | on_each_cpu(stop_watchdog, NULL, 1); | 264 | atomic_set(&nmi_active, -1); |
| 234 | } | 265 | } |
| 235 | } | 266 | } |
| 267 | if (!err) | ||
| 268 | init_hw_perf_counters(); | ||
| 269 | |||
| 236 | return err; | 270 | return err; |
| 237 | } | 271 | } |
| 238 | 272 | ||
diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 90396702ea2c..4c26eb59e742 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c | |||
| @@ -9,6 +9,8 @@ | |||
| 9 | #include <linux/irq.h> | 9 | #include <linux/irq.h> |
| 10 | #include <linux/of_device.h> | 10 | #include <linux/of_device.h> |
| 11 | #include <linux/of_platform.h> | 11 | #include <linux/of_platform.h> |
| 12 | #include <asm/leon.h> | ||
| 13 | #include <asm/leon_amba.h> | ||
| 12 | 14 | ||
| 13 | #include "of_device_common.h" | 15 | #include "of_device_common.h" |
| 14 | 16 | ||
| @@ -97,6 +99,35 @@ static unsigned long of_bus_sbus_get_flags(const u32 *addr, unsigned long flags) | |||
| 97 | return IORESOURCE_MEM; | 99 | return IORESOURCE_MEM; |
| 98 | } | 100 | } |
| 99 | 101 | ||
| 102 | /* | ||
| 103 | * AMBAPP bus specific translator | ||
| 104 | */ | ||
| 105 | |||
| 106 | static int of_bus_ambapp_match(struct device_node *np) | ||
| 107 | { | ||
| 108 | return !strcmp(np->name, "ambapp"); | ||
| 109 | } | ||
| 110 | |||
| 111 | static void of_bus_ambapp_count_cells(struct device_node *child, | ||
| 112 | int *addrc, int *sizec) | ||
| 113 | { | ||
| 114 | if (addrc) | ||
| 115 | *addrc = 1; | ||
| 116 | if (sizec) | ||
| 117 | *sizec = 1; | ||
| 118 | } | ||
| 119 | |||
| 120 | static int of_bus_ambapp_map(u32 *addr, const u32 *range, | ||
| 121 | int na, int ns, int pna) | ||
| 122 | { | ||
| 123 | return of_bus_default_map(addr, range, na, ns, pna); | ||
| 124 | } | ||
| 125 | |||
| 126 | static unsigned long of_bus_ambapp_get_flags(const u32 *addr, | ||
| 127 | unsigned long flags) | ||
| 128 | { | ||
| 129 | return IORESOURCE_MEM; | ||
| 130 | } | ||
| 100 | 131 | ||
| 101 | /* | 132 | /* |
| 102 | * Array of bus specific translators | 133 | * Array of bus specific translators |
| @@ -121,6 +152,15 @@ static struct of_bus of_busses[] = { | |||
| 121 | .map = of_bus_default_map, | 152 | .map = of_bus_default_map, |
| 122 | .get_flags = of_bus_sbus_get_flags, | 153 | .get_flags = of_bus_sbus_get_flags, |
| 123 | }, | 154 | }, |
| 155 | /* AMBA */ | ||
| 156 | { | ||
| 157 | .name = "ambapp", | ||
| 158 | .addr_prop_name = "reg", | ||
| 159 | .match = of_bus_ambapp_match, | ||
| 160 | .count_cells = of_bus_ambapp_count_cells, | ||
| 161 | .map = of_bus_ambapp_map, | ||
| 162 | .get_flags = of_bus_ambapp_get_flags, | ||
| 163 | }, | ||
| 124 | /* Default */ | 164 | /* Default */ |
| 125 | { | 165 | { |
| 126 | .name = "default", | 166 | .name = "default", |
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 57859ad23547..c68648662802 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
| @@ -1039,7 +1039,7 @@ static void ali_sound_dma_hack(struct pci_dev *pdev, int set_bit) | |||
| 1039 | pci_dev_put(ali_isa_bridge); | 1039 | pci_dev_put(ali_isa_bridge); |
| 1040 | } | 1040 | } |
| 1041 | 1041 | ||
| 1042 | int pci_dma_supported(struct pci_dev *pdev, u64 device_mask) | 1042 | int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask) |
| 1043 | { | 1043 | { |
| 1044 | u64 dma_addr_mask; | 1044 | u64 dma_addr_mask; |
| 1045 | 1045 | ||
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 2485eaa23101..23c33ff9c31e 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c | |||
| @@ -232,7 +232,8 @@ static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu, | |||
| 232 | 232 | ||
| 233 | static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, | 233 | static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, |
| 234 | unsigned long offset, size_t sz, | 234 | unsigned long offset, size_t sz, |
| 235 | enum dma_data_direction direction) | 235 | enum dma_data_direction direction, |
| 236 | struct dma_attrs *attrs) | ||
| 236 | { | 237 | { |
| 237 | struct iommu *iommu; | 238 | struct iommu *iommu; |
| 238 | unsigned long flags, npages, oaddr; | 239 | unsigned long flags, npages, oaddr; |
| @@ -296,7 +297,8 @@ iommu_map_fail: | |||
| 296 | } | 297 | } |
| 297 | 298 | ||
| 298 | static void dma_4v_unmap_page(struct device *dev, dma_addr_t bus_addr, | 299 | static void dma_4v_unmap_page(struct device *dev, dma_addr_t bus_addr, |
| 299 | size_t sz, enum dma_data_direction direction) | 300 | size_t sz, enum dma_data_direction direction, |
| 301 | struct dma_attrs *attrs) | ||
| 300 | { | 302 | { |
| 301 | struct pci_pbm_info *pbm; | 303 | struct pci_pbm_info *pbm; |
| 302 | struct iommu *iommu; | 304 | struct iommu *iommu; |
| @@ -336,7 +338,8 @@ static void dma_4v_unmap_page(struct device *dev, dma_addr_t bus_addr, | |||
| 336 | } | 338 | } |
| 337 | 339 | ||
| 338 | static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, | 340 | static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, |
| 339 | int nelems, enum dma_data_direction direction) | 341 | int nelems, enum dma_data_direction direction, |
| 342 | struct dma_attrs *attrs) | ||
| 340 | { | 343 | { |
| 341 | struct scatterlist *s, *outs, *segstart; | 344 | struct scatterlist *s, *outs, *segstart; |
| 342 | unsigned long flags, handle, prot; | 345 | unsigned long flags, handle, prot; |
| @@ -478,7 +481,8 @@ iommu_map_failed: | |||
| 478 | } | 481 | } |
| 479 | 482 | ||
| 480 | static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, | 483 | static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, |
| 481 | int nelems, enum dma_data_direction direction) | 484 | int nelems, enum dma_data_direction direction, |
| 485 | struct dma_attrs *attrs) | ||
| 482 | { | 486 | { |
| 483 | struct pci_pbm_info *pbm; | 487 | struct pci_pbm_info *pbm; |
| 484 | struct scatterlist *sg; | 488 | struct scatterlist *sg; |
| @@ -521,29 +525,13 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, | |||
| 521 | spin_unlock_irqrestore(&iommu->lock, flags); | 525 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 522 | } | 526 | } |
| 523 | 527 | ||
| 524 | static void dma_4v_sync_single_for_cpu(struct device *dev, | 528 | static struct dma_map_ops sun4v_dma_ops = { |
| 525 | dma_addr_t bus_addr, size_t sz, | ||
| 526 | enum dma_data_direction direction) | ||
| 527 | { | ||
| 528 | /* Nothing to do... */ | ||
| 529 | } | ||
| 530 | |||
| 531 | static void dma_4v_sync_sg_for_cpu(struct device *dev, | ||
| 532 | struct scatterlist *sglist, int nelems, | ||
| 533 | enum dma_data_direction direction) | ||
| 534 | { | ||
| 535 | /* Nothing to do... */ | ||
| 536 | } | ||
| 537 | |||
| 538 | static const struct dma_ops sun4v_dma_ops = { | ||
| 539 | .alloc_coherent = dma_4v_alloc_coherent, | 529 | .alloc_coherent = dma_4v_alloc_coherent, |
| 540 | .free_coherent = dma_4v_free_coherent, | 530 | .free_coherent = dma_4v_free_coherent, |
| 541 | .map_page = dma_4v_map_page, | 531 | .map_page = dma_4v_map_page, |
| 542 | .unmap_page = dma_4v_unmap_page, | 532 | .unmap_page = dma_4v_unmap_page, |
| 543 | .map_sg = dma_4v_map_sg, | 533 | .map_sg = dma_4v_map_sg, |
| 544 | .unmap_sg = dma_4v_unmap_sg, | 534 | .unmap_sg = dma_4v_unmap_sg, |
| 545 | .sync_single_for_cpu = dma_4v_sync_single_for_cpu, | ||
| 546 | .sync_sg_for_cpu = dma_4v_sync_sg_for_cpu, | ||
| 547 | }; | 535 | }; |
| 548 | 536 | ||
| 549 | static void __devinit pci_sun4v_scan_bus(struct pci_pbm_info *pbm, | 537 | static void __devinit pci_sun4v_scan_bus(struct pci_pbm_info *pbm, |
diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c index 1ae8cdd7e703..68ff00107073 100644 --- a/arch/sparc/kernel/pcr.c +++ b/arch/sparc/kernel/pcr.c | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
| 8 | #include <linux/irq.h> | 8 | #include <linux/irq.h> |
| 9 | 9 | ||
| 10 | #include <linux/perf_counter.h> | ||
| 11 | |||
| 10 | #include <asm/pil.h> | 12 | #include <asm/pil.h> |
| 11 | #include <asm/pcr.h> | 13 | #include <asm/pcr.h> |
| 12 | #include <asm/nmi.h> | 14 | #include <asm/nmi.h> |
| @@ -34,10 +36,20 @@ unsigned int picl_shift; | |||
| 34 | */ | 36 | */ |
| 35 | void deferred_pcr_work_irq(int irq, struct pt_regs *regs) | 37 | void deferred_pcr_work_irq(int irq, struct pt_regs *regs) |
| 36 | { | 38 | { |
| 39 | struct pt_regs *old_regs; | ||
| 40 | |||
| 37 | clear_softint(1 << PIL_DEFERRED_PCR_WORK); | 41 | clear_softint(1 << PIL_DEFERRED_PCR_WORK); |
| 42 | |||
| 43 | old_regs = set_irq_regs(regs); | ||
| 44 | irq_enter(); | ||
| 45 | #ifdef CONFIG_PERF_COUNTERS | ||
| 46 | perf_counter_do_pending(); | ||
| 47 | #endif | ||
| 48 | irq_exit(); | ||
| 49 | set_irq_regs(old_regs); | ||
| 38 | } | 50 | } |
| 39 | 51 | ||
| 40 | void schedule_deferred_pcr_work(void) | 52 | void set_perf_counter_pending(void) |
| 41 | { | 53 | { |
| 42 | set_softint(1 << PIL_DEFERRED_PCR_WORK); | 54 | set_softint(1 << PIL_DEFERRED_PCR_WORK); |
| 43 | } | 55 | } |
diff --git a/arch/sparc/kernel/perf_counter.c b/arch/sparc/kernel/perf_counter.c new file mode 100644 index 000000000000..09de4035eaa9 --- /dev/null +++ b/arch/sparc/kernel/perf_counter.c | |||
| @@ -0,0 +1,557 @@ | |||
| 1 | /* Performance counter support for sparc64. | ||
| 2 | * | ||
| 3 | * Copyright (C) 2009 David S. Miller <davem@davemloft.net> | ||
| 4 | * | ||
| 5 | * This code is based almost entirely upon the x86 perf counter | ||
| 6 | * code, which is: | ||
| 7 | * | ||
| 8 | * Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de> | ||
| 9 | * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar | ||
| 10 | * Copyright (C) 2009 Jaswinder Singh Rajput | ||
| 11 | * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter | ||
| 12 | * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com> | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/perf_counter.h> | ||
| 16 | #include <linux/kprobes.h> | ||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/kdebug.h> | ||
| 19 | #include <linux/mutex.h> | ||
| 20 | |||
| 21 | #include <asm/cpudata.h> | ||
| 22 | #include <asm/atomic.h> | ||
| 23 | #include <asm/nmi.h> | ||
| 24 | #include <asm/pcr.h> | ||
| 25 | |||
| 26 | /* Sparc64 chips have two performance counters, 32-bits each, with | ||
| 27 | * overflow interrupts generated on transition from 0xffffffff to 0. | ||
| 28 | * The counters are accessed in one go using a 64-bit register. | ||
| 29 | * | ||
| 30 | * Both counters are controlled using a single control register. The | ||
| 31 | * only way to stop all sampling is to clear all of the context (user, | ||
| 32 | * supervisor, hypervisor) sampling enable bits. But these bits apply | ||
| 33 | * to both counters, thus the two counters can't be enabled/disabled | ||
| 34 | * individually. | ||
| 35 | * | ||
| 36 | * The control register has two event fields, one for each of the two | ||
| 37 | * counters. It's thus nearly impossible to have one counter going | ||
| 38 | * while keeping the other one stopped. Therefore it is possible to | ||
| 39 | * get overflow interrupts for counters not currently "in use" and | ||
| 40 | * that condition must be checked in the overflow interrupt handler. | ||
| 41 | * | ||
| 42 | * So we use a hack, in that we program inactive counters with the | ||
| 43 | * "sw_count0" and "sw_count1" events. These count how many times | ||
| 44 | * the instruction "sethi %hi(0xfc000), %g0" is executed. It's an | ||
| 45 | * unusual way to encode a NOP and therefore will not trigger in | ||
| 46 | * normal code. | ||
| 47 | */ | ||
| 48 | |||
| 49 | #define MAX_HWCOUNTERS 2 | ||
| 50 | #define MAX_PERIOD ((1UL << 32) - 1) | ||
| 51 | |||
| 52 | #define PIC_UPPER_INDEX 0 | ||
| 53 | #define PIC_LOWER_INDEX 1 | ||
| 54 | |||
| 55 | struct cpu_hw_counters { | ||
| 56 | struct perf_counter *counters[MAX_HWCOUNTERS]; | ||
| 57 | unsigned long used_mask[BITS_TO_LONGS(MAX_HWCOUNTERS)]; | ||
| 58 | unsigned long active_mask[BITS_TO_LONGS(MAX_HWCOUNTERS)]; | ||
| 59 | int enabled; | ||
| 60 | }; | ||
| 61 | DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters) = { .enabled = 1, }; | ||
| 62 | |||
| 63 | struct perf_event_map { | ||
| 64 | u16 encoding; | ||
| 65 | u8 pic_mask; | ||
| 66 | #define PIC_NONE 0x00 | ||
| 67 | #define PIC_UPPER 0x01 | ||
| 68 | #define PIC_LOWER 0x02 | ||
| 69 | }; | ||
| 70 | |||
| 71 | struct sparc_pmu { | ||
| 72 | const struct perf_event_map *(*event_map)(int); | ||
| 73 | int max_events; | ||
| 74 | int upper_shift; | ||
| 75 | int lower_shift; | ||
| 76 | int event_mask; | ||
| 77 | int hv_bit; | ||
| 78 | int irq_bit; | ||
| 79 | int upper_nop; | ||
| 80 | int lower_nop; | ||
| 81 | }; | ||
| 82 | |||
| 83 | static const struct perf_event_map ultra3i_perfmon_event_map[] = { | ||
| 84 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x0000, PIC_UPPER | PIC_LOWER }, | ||
| 85 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x0001, PIC_UPPER | PIC_LOWER }, | ||
| 86 | [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0009, PIC_LOWER }, | ||
| 87 | [PERF_COUNT_HW_CACHE_MISSES] = { 0x0009, PIC_UPPER }, | ||
| 88 | }; | ||
| 89 | |||
| 90 | static const struct perf_event_map *ultra3i_event_map(int event) | ||
| 91 | { | ||
| 92 | return &ultra3i_perfmon_event_map[event]; | ||
| 93 | } | ||
| 94 | |||
| 95 | static const struct sparc_pmu ultra3i_pmu = { | ||
| 96 | .event_map = ultra3i_event_map, | ||
| 97 | .max_events = ARRAY_SIZE(ultra3i_perfmon_event_map), | ||
| 98 | .upper_shift = 11, | ||
| 99 | .lower_shift = 4, | ||
| 100 | .event_mask = 0x3f, | ||
| 101 | .upper_nop = 0x1c, | ||
| 102 | .lower_nop = 0x14, | ||
| 103 | }; | ||
| 104 | |||
| 105 | static const struct perf_event_map niagara2_perfmon_event_map[] = { | ||
| 106 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x02ff, PIC_UPPER | PIC_LOWER }, | ||
| 107 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x02ff, PIC_UPPER | PIC_LOWER }, | ||
| 108 | [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0208, PIC_UPPER | PIC_LOWER }, | ||
| 109 | [PERF_COUNT_HW_CACHE_MISSES] = { 0x0302, PIC_UPPER | PIC_LOWER }, | ||
| 110 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x0201, PIC_UPPER | PIC_LOWER }, | ||
| 111 | [PERF_COUNT_HW_BRANCH_MISSES] = { 0x0202, PIC_UPPER | PIC_LOWER }, | ||
| 112 | }; | ||
| 113 | |||
| 114 | static const struct perf_event_map *niagara2_event_map(int event) | ||
| 115 | { | ||
| 116 | return &niagara2_perfmon_event_map[event]; | ||
| 117 | } | ||
| 118 | |||
| 119 | static const struct sparc_pmu niagara2_pmu = { | ||
| 120 | .event_map = niagara2_event_map, | ||
| 121 | .max_events = ARRAY_SIZE(niagara2_perfmon_event_map), | ||
| 122 | .upper_shift = 19, | ||
| 123 | .lower_shift = 6, | ||
| 124 | .event_mask = 0xfff, | ||
| 125 | .hv_bit = 0x8, | ||
| 126 | .irq_bit = 0x03, | ||
| 127 | .upper_nop = 0x220, | ||
| 128 | .lower_nop = 0x220, | ||
| 129 | }; | ||
| 130 | |||
| 131 | static const struct sparc_pmu *sparc_pmu __read_mostly; | ||
| 132 | |||
| 133 | static u64 event_encoding(u64 event, int idx) | ||
| 134 | { | ||
| 135 | if (idx == PIC_UPPER_INDEX) | ||
| 136 | event <<= sparc_pmu->upper_shift; | ||
| 137 | else | ||
| 138 | event <<= sparc_pmu->lower_shift; | ||
| 139 | return event; | ||
| 140 | } | ||
| 141 | |||
| 142 | static u64 mask_for_index(int idx) | ||
| 143 | { | ||
| 144 | return event_encoding(sparc_pmu->event_mask, idx); | ||
| 145 | } | ||
| 146 | |||
| 147 | static u64 nop_for_index(int idx) | ||
| 148 | { | ||
| 149 | return event_encoding(idx == PIC_UPPER_INDEX ? | ||
| 150 | sparc_pmu->upper_nop : | ||
| 151 | sparc_pmu->lower_nop, idx); | ||
| 152 | } | ||
| 153 | |||
| 154 | static inline void sparc_pmu_enable_counter(struct hw_perf_counter *hwc, | ||
| 155 | int idx) | ||
| 156 | { | ||
| 157 | u64 val, mask = mask_for_index(idx); | ||
| 158 | |||
| 159 | val = pcr_ops->read(); | ||
| 160 | pcr_ops->write((val & ~mask) | hwc->config); | ||
| 161 | } | ||
| 162 | |||
| 163 | static inline void sparc_pmu_disable_counter(struct hw_perf_counter *hwc, | ||
| 164 | int idx) | ||
| 165 | { | ||
| 166 | u64 mask = mask_for_index(idx); | ||
| 167 | u64 nop = nop_for_index(idx); | ||
| 168 | u64 val = pcr_ops->read(); | ||
| 169 | |||
| 170 | pcr_ops->write((val & ~mask) | nop); | ||
| 171 | } | ||
| 172 | |||
| 173 | void hw_perf_enable(void) | ||
| 174 | { | ||
| 175 | struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); | ||
| 176 | u64 val; | ||
| 177 | int i; | ||
| 178 | |||
| 179 | if (cpuc->enabled) | ||
| 180 | return; | ||
| 181 | |||
| 182 | cpuc->enabled = 1; | ||
| 183 | barrier(); | ||
| 184 | |||
| 185 | val = pcr_ops->read(); | ||
| 186 | |||
| 187 | for (i = 0; i < MAX_HWCOUNTERS; i++) { | ||
| 188 | struct perf_counter *cp = cpuc->counters[i]; | ||
| 189 | struct hw_perf_counter *hwc; | ||
| 190 | |||
| 191 | if (!cp) | ||
| 192 | continue; | ||
| 193 | hwc = &cp->hw; | ||
| 194 | val |= hwc->config_base; | ||
| 195 | } | ||
| 196 | |||
| 197 | pcr_ops->write(val); | ||
| 198 | } | ||
| 199 | |||
| 200 | void hw_perf_disable(void) | ||
| 201 | { | ||
| 202 | struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); | ||
| 203 | u64 val; | ||
| 204 | |||
| 205 | if (!cpuc->enabled) | ||
| 206 | return; | ||
| 207 | |||
| 208 | cpuc->enabled = 0; | ||
| 209 | |||
| 210 | val = pcr_ops->read(); | ||
| 211 | val &= ~(PCR_UTRACE | PCR_STRACE | | ||
| 212 | sparc_pmu->hv_bit | sparc_pmu->irq_bit); | ||
| 213 | pcr_ops->write(val); | ||
| 214 | } | ||
| 215 | |||
| 216 | static u32 read_pmc(int idx) | ||
| 217 | { | ||
| 218 | u64 val; | ||
| 219 | |||
| 220 | read_pic(val); | ||
| 221 | if (idx == PIC_UPPER_INDEX) | ||
| 222 | val >>= 32; | ||
| 223 | |||
| 224 | return val & 0xffffffff; | ||
| 225 | } | ||
| 226 | |||
| 227 | static void write_pmc(int idx, u64 val) | ||
| 228 | { | ||
| 229 | u64 shift, mask, pic; | ||
| 230 | |||
| 231 | shift = 0; | ||
| 232 | if (idx == PIC_UPPER_INDEX) | ||
| 233 | shift = 32; | ||
| 234 | |||
| 235 | mask = ((u64) 0xffffffff) << shift; | ||
| 236 | val <<= shift; | ||
| 237 | |||
| 238 | read_pic(pic); | ||
| 239 | pic &= ~mask; | ||
| 240 | pic |= val; | ||
| 241 | write_pic(pic); | ||
| 242 | } | ||
| 243 | |||
| 244 | static int sparc_perf_counter_set_period(struct perf_counter *counter, | ||
| 245 | struct hw_perf_counter *hwc, int idx) | ||
| 246 | { | ||
| 247 | s64 left = atomic64_read(&hwc->period_left); | ||
| 248 | s64 period = hwc->sample_period; | ||
| 249 | int ret = 0; | ||
| 250 | |||
| 251 | if (unlikely(left <= -period)) { | ||
| 252 | left = period; | ||
| 253 | atomic64_set(&hwc->period_left, left); | ||
| 254 | hwc->last_period = period; | ||
| 255 | ret = 1; | ||
| 256 | } | ||
| 257 | |||
| 258 | if (unlikely(left <= 0)) { | ||
| 259 | left += period; | ||
| 260 | atomic64_set(&hwc->period_left, left); | ||
| 261 | hwc->last_period = period; | ||
| 262 | ret = 1; | ||
| 263 | } | ||
| 264 | if (left > MAX_PERIOD) | ||
| 265 | left = MAX_PERIOD; | ||
| 266 | |||
| 267 | atomic64_set(&hwc->prev_count, (u64)-left); | ||
| 268 | |||
| 269 | write_pmc(idx, (u64)(-left) & 0xffffffff); | ||
| 270 | |||
| 271 | perf_counter_update_userpage(counter); | ||
| 272 | |||
| 273 | return ret; | ||
| 274 | } | ||
| 275 | |||
| 276 | static int sparc_pmu_enable(struct perf_counter *counter) | ||
| 277 | { | ||
| 278 | struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); | ||
| 279 | struct hw_perf_counter *hwc = &counter->hw; | ||
| 280 | int idx = hwc->idx; | ||
| 281 | |||
| 282 | if (test_and_set_bit(idx, cpuc->used_mask)) | ||
| 283 | return -EAGAIN; | ||
| 284 | |||
| 285 | sparc_pmu_disable_counter(hwc, idx); | ||
| 286 | |||
| 287 | cpuc->counters[idx] = counter; | ||
| 288 | set_bit(idx, cpuc->active_mask); | ||
| 289 | |||
| 290 | sparc_perf_counter_set_period(counter, hwc, idx); | ||
| 291 | sparc_pmu_enable_counter(hwc, idx); | ||
| 292 | perf_counter_update_userpage(counter); | ||
| 293 | return 0; | ||
| 294 | } | ||
| 295 | |||
| 296 | static u64 sparc_perf_counter_update(struct perf_counter *counter, | ||
| 297 | struct hw_perf_counter *hwc, int idx) | ||
| 298 | { | ||
| 299 | int shift = 64 - 32; | ||
| 300 | u64 prev_raw_count, new_raw_count; | ||
| 301 | s64 delta; | ||
| 302 | |||
| 303 | again: | ||
| 304 | prev_raw_count = atomic64_read(&hwc->prev_count); | ||
| 305 | new_raw_count = read_pmc(idx); | ||
| 306 | |||
| 307 | if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count, | ||
| 308 | new_raw_count) != prev_raw_count) | ||
| 309 | goto again; | ||
| 310 | |||
| 311 | delta = (new_raw_count << shift) - (prev_raw_count << shift); | ||
| 312 | delta >>= shift; | ||
| 313 | |||
| 314 | atomic64_add(delta, &counter->count); | ||
| 315 | atomic64_sub(delta, &hwc->period_left); | ||
| 316 | |||
| 317 | return new_raw_count; | ||
| 318 | } | ||
| 319 | |||
| 320 | static void sparc_pmu_disable(struct perf_counter *counter) | ||
| 321 | { | ||
| 322 | struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); | ||
| 323 | struct hw_perf_counter *hwc = &counter->hw; | ||
| 324 | int idx = hwc->idx; | ||
| 325 | |||
| 326 | clear_bit(idx, cpuc->active_mask); | ||
| 327 | sparc_pmu_disable_counter(hwc, idx); | ||
| 328 | |||
| 329 | barrier(); | ||
| 330 | |||
| 331 | sparc_perf_counter_update(counter, hwc, idx); | ||
| 332 | cpuc->counters[idx] = NULL; | ||
| 333 | clear_bit(idx, cpuc->used_mask); | ||
| 334 | |||
| 335 | perf_counter_update_userpage(counter); | ||
| 336 | } | ||
| 337 | |||
| 338 | static void sparc_pmu_read(struct perf_counter *counter) | ||
| 339 | { | ||
| 340 | struct hw_perf_counter *hwc = &counter->hw; | ||
| 341 | sparc_perf_counter_update(counter, hwc, hwc->idx); | ||
| 342 | } | ||
| 343 | |||
| 344 | static void sparc_pmu_unthrottle(struct perf_counter *counter) | ||
| 345 | { | ||
| 346 | struct hw_perf_counter *hwc = &counter->hw; | ||
| 347 | sparc_pmu_enable_counter(hwc, hwc->idx); | ||
| 348 | } | ||
| 349 | |||
| 350 | static atomic_t active_counters = ATOMIC_INIT(0); | ||
| 351 | static DEFINE_MUTEX(pmc_grab_mutex); | ||
| 352 | |||
| 353 | void perf_counter_grab_pmc(void) | ||
| 354 | { | ||
| 355 | if (atomic_inc_not_zero(&active_counters)) | ||
| 356 | return; | ||
| 357 | |||
| 358 | mutex_lock(&pmc_grab_mutex); | ||
| 359 | if (atomic_read(&active_counters) == 0) { | ||
| 360 | if (atomic_read(&nmi_active) > 0) { | ||
| 361 | on_each_cpu(stop_nmi_watchdog, NULL, 1); | ||
| 362 | BUG_ON(atomic_read(&nmi_active) != 0); | ||
| 363 | } | ||
| 364 | atomic_inc(&active_counters); | ||
| 365 | } | ||
| 366 | mutex_unlock(&pmc_grab_mutex); | ||
| 367 | } | ||
| 368 | |||
| 369 | void perf_counter_release_pmc(void) | ||
| 370 | { | ||
| 371 | if (atomic_dec_and_mutex_lock(&active_counters, &pmc_grab_mutex)) { | ||
| 372 | if (atomic_read(&nmi_active) == 0) | ||
| 373 | on_each_cpu(start_nmi_watchdog, NULL, 1); | ||
| 374 | mutex_unlock(&pmc_grab_mutex); | ||
| 375 | } | ||
| 376 | } | ||
| 377 | |||
| 378 | static void hw_perf_counter_destroy(struct perf_counter *counter) | ||
| 379 | { | ||
| 380 | perf_counter_release_pmc(); | ||
| 381 | } | ||
| 382 | |||
| 383 | static int __hw_perf_counter_init(struct perf_counter *counter) | ||
| 384 | { | ||
| 385 | struct perf_counter_attr *attr = &counter->attr; | ||
| 386 | struct hw_perf_counter *hwc = &counter->hw; | ||
| 387 | const struct perf_event_map *pmap; | ||
| 388 | u64 enc; | ||
| 389 | |||
| 390 | if (atomic_read(&nmi_active) < 0) | ||
| 391 | return -ENODEV; | ||
| 392 | |||
| 393 | if (attr->type != PERF_TYPE_HARDWARE) | ||
| 394 | return -EOPNOTSUPP; | ||
| 395 | |||
| 396 | if (attr->config >= sparc_pmu->max_events) | ||
| 397 | return -EINVAL; | ||
| 398 | |||
| 399 | perf_counter_grab_pmc(); | ||
| 400 | counter->destroy = hw_perf_counter_destroy; | ||
| 401 | |||
| 402 | /* We save the enable bits in the config_base. So to | ||
| 403 | * turn off sampling just write 'config', and to enable | ||
| 404 | * things write 'config | config_base'. | ||
| 405 | */ | ||
| 406 | hwc->config_base = sparc_pmu->irq_bit; | ||
| 407 | if (!attr->exclude_user) | ||
| 408 | hwc->config_base |= PCR_UTRACE; | ||
| 409 | if (!attr->exclude_kernel) | ||
| 410 | hwc->config_base |= PCR_STRACE; | ||
| 411 | if (!attr->exclude_hv) | ||
| 412 | hwc->config_base |= sparc_pmu->hv_bit; | ||
| 413 | |||
| 414 | if (!hwc->sample_period) { | ||
| 415 | hwc->sample_period = MAX_PERIOD; | ||
| 416 | hwc->last_period = hwc->sample_period; | ||
| 417 | atomic64_set(&hwc->period_left, hwc->sample_period); | ||
| 418 | } | ||
| 419 | |||
| 420 | pmap = sparc_pmu->event_map(attr->config); | ||
| 421 | |||
| 422 | enc = pmap->encoding; | ||
| 423 | if (pmap->pic_mask & PIC_UPPER) { | ||
| 424 | hwc->idx = PIC_UPPER_INDEX; | ||
| 425 | enc <<= sparc_pmu->upper_shift; | ||
| 426 | } else { | ||
| 427 | hwc->idx = PIC_LOWER_INDEX; | ||
| 428 | enc <<= sparc_pmu->lower_shift; | ||
| 429 | } | ||
| 430 | |||
| 431 | hwc->config |= enc; | ||
| 432 | return 0; | ||
| 433 | } | ||
| 434 | |||
| 435 | static const struct pmu pmu = { | ||
| 436 | .enable = sparc_pmu_enable, | ||
| 437 | .disable = sparc_pmu_disable, | ||
| 438 | .read = sparc_pmu_read, | ||
| 439 | .unthrottle = sparc_pmu_unthrottle, | ||
| 440 | }; | ||
| 441 | |||
| 442 | const struct pmu *hw_perf_counter_init(struct perf_counter *counter) | ||
| 443 | { | ||
| 444 | int err = __hw_perf_counter_init(counter); | ||
| 445 | |||
| 446 | if (err) | ||
| 447 | return ERR_PTR(err); | ||
| 448 | return &pmu; | ||
| 449 | } | ||
| 450 | |||
| 451 | void perf_counter_print_debug(void) | ||
| 452 | { | ||
| 453 | unsigned long flags; | ||
| 454 | u64 pcr, pic; | ||
| 455 | int cpu; | ||
| 456 | |||
| 457 | if (!sparc_pmu) | ||
| 458 | return; | ||
| 459 | |||
| 460 | local_irq_save(flags); | ||
| 461 | |||
| 462 | cpu = smp_processor_id(); | ||
| 463 | |||
| 464 | pcr = pcr_ops->read(); | ||
| 465 | read_pic(pic); | ||
| 466 | |||
| 467 | pr_info("\n"); | ||
| 468 | pr_info("CPU#%d: PCR[%016llx] PIC[%016llx]\n", | ||
| 469 | cpu, pcr, pic); | ||
| 470 | |||
| 471 | local_irq_restore(flags); | ||
| 472 | } | ||
| 473 | |||
| 474 | static int __kprobes perf_counter_nmi_handler(struct notifier_block *self, | ||
| 475 | unsigned long cmd, void *__args) | ||
| 476 | { | ||
| 477 | struct die_args *args = __args; | ||
| 478 | struct perf_sample_data data; | ||
| 479 | struct cpu_hw_counters *cpuc; | ||
| 480 | struct pt_regs *regs; | ||
| 481 | int idx; | ||
| 482 | |||
| 483 | if (!atomic_read(&active_counters)) | ||
| 484 | return NOTIFY_DONE; | ||
| 485 | |||
| 486 | switch (cmd) { | ||
| 487 | case DIE_NMI: | ||
| 488 | break; | ||
| 489 | |||
| 490 | default: | ||
| 491 | return NOTIFY_DONE; | ||
| 492 | } | ||
| 493 | |||
| 494 | regs = args->regs; | ||
| 495 | |||
| 496 | data.regs = regs; | ||
| 497 | data.addr = 0; | ||
| 498 | |||
| 499 | cpuc = &__get_cpu_var(cpu_hw_counters); | ||
| 500 | for (idx = 0; idx < MAX_HWCOUNTERS; idx++) { | ||
| 501 | struct perf_counter *counter = cpuc->counters[idx]; | ||
| 502 | struct hw_perf_counter *hwc; | ||
| 503 | u64 val; | ||
| 504 | |||
| 505 | if (!test_bit(idx, cpuc->active_mask)) | ||
| 506 | continue; | ||
| 507 | hwc = &counter->hw; | ||
| 508 | val = sparc_perf_counter_update(counter, hwc, idx); | ||
| 509 | if (val & (1ULL << 31)) | ||
| 510 | continue; | ||
| 511 | |||
| 512 | data.period = counter->hw.last_period; | ||
| 513 | if (!sparc_perf_counter_set_period(counter, hwc, idx)) | ||
| 514 | continue; | ||
| 515 | |||
| 516 | if (perf_counter_overflow(counter, 1, &data)) | ||
| 517 | sparc_pmu_disable_counter(hwc, idx); | ||
| 518 | } | ||
| 519 | |||
| 520 | return NOTIFY_STOP; | ||
| 521 | } | ||
| 522 | |||
| 523 | static __read_mostly struct notifier_block perf_counter_nmi_notifier = { | ||
| 524 | .notifier_call = perf_counter_nmi_handler, | ||
| 525 | }; | ||
| 526 | |||
| 527 | static bool __init supported_pmu(void) | ||
| 528 | { | ||
| 529 | if (!strcmp(sparc_pmu_type, "ultra3i")) { | ||
| 530 | sparc_pmu = &ultra3i_pmu; | ||
| 531 | return true; | ||
| 532 | } | ||
| 533 | if (!strcmp(sparc_pmu_type, "niagara2")) { | ||
| 534 | sparc_pmu = &niagara2_pmu; | ||
| 535 | return true; | ||
| 536 | } | ||
| 537 | return false; | ||
| 538 | } | ||
| 539 | |||
| 540 | void __init init_hw_perf_counters(void) | ||
| 541 | { | ||
| 542 | pr_info("Performance counters: "); | ||
| 543 | |||
| 544 | if (!supported_pmu()) { | ||
| 545 | pr_cont("No support for PMU type '%s'\n", sparc_pmu_type); | ||
| 546 | return; | ||
| 547 | } | ||
| 548 | |||
| 549 | pr_cont("Supported PMU type is '%s'\n", sparc_pmu_type); | ||
| 550 | |||
| 551 | /* All sparc64 PMUs currently have 2 counters. But this simple | ||
| 552 | * driver only supports one active counter at a time. | ||
| 553 | */ | ||
| 554 | perf_max_counters = 1; | ||
| 555 | |||
| 556 | register_die_notifier(&perf_counter_nmi_notifier); | ||
| 557 | } | ||
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index 4041f94e7724..18d67854a1b8 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
| @@ -251,7 +251,7 @@ static void __global_reg_poll(struct global_reg_snapshot *gp) | |||
| 251 | } | 251 | } |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | void __trigger_all_cpu_backtrace(void) | 254 | void arch_trigger_all_cpu_backtrace(void) |
| 255 | { | 255 | { |
| 256 | struct thread_info *tp = current_thread_info(); | 256 | struct thread_info *tp = current_thread_info(); |
| 257 | struct pt_regs *regs = get_irq_regs(); | 257 | struct pt_regs *regs = get_irq_regs(); |
| @@ -304,7 +304,7 @@ void __trigger_all_cpu_backtrace(void) | |||
| 304 | 304 | ||
| 305 | static void sysrq_handle_globreg(int key, struct tty_struct *tty) | 305 | static void sysrq_handle_globreg(int key, struct tty_struct *tty) |
| 306 | { | 306 | { |
| 307 | __trigger_all_cpu_backtrace(); | 307 | arch_trigger_all_cpu_backtrace(); |
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | static struct sysrq_key_op sparc_globalreg_op = { | 310 | static struct sysrq_key_op sparc_globalreg_op = { |
diff --git a/arch/sparc/kernel/prom_32.c b/arch/sparc/kernel/prom_32.c index fe43e80772db..0a37e8cfd160 100644 --- a/arch/sparc/kernel/prom_32.c +++ b/arch/sparc/kernel/prom_32.c | |||
| @@ -24,6 +24,8 @@ | |||
| 24 | 24 | ||
| 25 | #include <asm/prom.h> | 25 | #include <asm/prom.h> |
| 26 | #include <asm/oplib.h> | 26 | #include <asm/oplib.h> |
| 27 | #include <asm/leon.h> | ||
| 28 | #include <asm/leon_amba.h> | ||
| 27 | 29 | ||
| 28 | #include "prom.h" | 30 | #include "prom.h" |
| 29 | 31 | ||
| @@ -131,6 +133,35 @@ static void __init ebus_path_component(struct device_node *dp, char *tmp_buf) | |||
| 131 | regs->which_io, regs->phys_addr); | 133 | regs->which_io, regs->phys_addr); |
| 132 | } | 134 | } |
| 133 | 135 | ||
| 136 | /* "name:vendor:device@irq,addrlo" */ | ||
| 137 | static void __init ambapp_path_component(struct device_node *dp, char *tmp_buf) | ||
| 138 | { | ||
| 139 | struct amba_prom_registers *regs; unsigned int *intr; | ||
| 140 | unsigned int *device, *vendor; | ||
| 141 | struct property *prop; | ||
| 142 | |||
| 143 | prop = of_find_property(dp, "reg", NULL); | ||
| 144 | if (!prop) | ||
| 145 | return; | ||
| 146 | regs = prop->value; | ||
| 147 | prop = of_find_property(dp, "interrupts", NULL); | ||
| 148 | if (!prop) | ||
| 149 | return; | ||
| 150 | intr = prop->value; | ||
| 151 | prop = of_find_property(dp, "vendor", NULL); | ||
| 152 | if (!prop) | ||
| 153 | return; | ||
| 154 | vendor = prop->value; | ||
| 155 | prop = of_find_property(dp, "device", NULL); | ||
| 156 | if (!prop) | ||
| 157 | return; | ||
| 158 | device = prop->value; | ||
| 159 | |||
| 160 | sprintf(tmp_buf, "%s:%d:%d@%x,%x", | ||
| 161 | dp->name, *vendor, *device, | ||
| 162 | *intr, regs->phys_addr); | ||
| 163 | } | ||
| 164 | |||
| 134 | static void __init __build_path_component(struct device_node *dp, char *tmp_buf) | 165 | static void __init __build_path_component(struct device_node *dp, char *tmp_buf) |
| 135 | { | 166 | { |
| 136 | struct device_node *parent = dp->parent; | 167 | struct device_node *parent = dp->parent; |
| @@ -143,6 +174,8 @@ static void __init __build_path_component(struct device_node *dp, char *tmp_buf) | |||
| 143 | return sbus_path_component(dp, tmp_buf); | 174 | return sbus_path_component(dp, tmp_buf); |
| 144 | if (!strcmp(parent->type, "ebus")) | 175 | if (!strcmp(parent->type, "ebus")) |
| 145 | return ebus_path_component(dp, tmp_buf); | 176 | return ebus_path_component(dp, tmp_buf); |
| 177 | if (!strcmp(parent->type, "ambapp")) | ||
| 178 | return ambapp_path_component(dp, tmp_buf); | ||
| 146 | 179 | ||
| 147 | /* "isa" is handled with platform naming */ | 180 | /* "isa" is handled with platform naming */ |
| 148 | } | 181 | } |
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c index 0fb5789d43c8..138910c67206 100644 --- a/arch/sparc/kernel/prom_common.c +++ b/arch/sparc/kernel/prom_common.c | |||
| @@ -22,9 +22,12 @@ | |||
| 22 | #include <linux/of.h> | 22 | #include <linux/of.h> |
| 23 | #include <asm/prom.h> | 23 | #include <asm/prom.h> |
| 24 | #include <asm/oplib.h> | 24 | #include <asm/oplib.h> |
| 25 | #include <asm/leon.h> | ||
| 25 | 26 | ||
| 26 | #include "prom.h" | 27 | #include "prom.h" |
| 27 | 28 | ||
| 29 | void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp); | ||
| 30 | |||
| 28 | struct device_node *of_console_device; | 31 | struct device_node *of_console_device; |
| 29 | EXPORT_SYMBOL(of_console_device); | 32 | EXPORT_SYMBOL(of_console_device); |
| 30 | 33 | ||
| @@ -161,7 +164,7 @@ static struct property * __init build_one_prop(phandle node, char *prev, | |||
| 161 | name = prom_nextprop(node, prev, p->name); | 164 | name = prom_nextprop(node, prev, p->name); |
| 162 | } | 165 | } |
| 163 | 166 | ||
| 164 | if (strlen(name) == 0) { | 167 | if (!name || strlen(name) == 0) { |
| 165 | tmp = p; | 168 | tmp = p; |
| 166 | return NULL; | 169 | return NULL; |
| 167 | } | 170 | } |
| @@ -242,7 +245,7 @@ static struct device_node * __init prom_create_node(phandle node, | |||
| 242 | return dp; | 245 | return dp; |
| 243 | } | 246 | } |
| 244 | 247 | ||
| 245 | static char * __init build_full_name(struct device_node *dp) | 248 | char * __init build_full_name(struct device_node *dp) |
| 246 | { | 249 | { |
| 247 | int len, ourlen, plen; | 250 | int len, ourlen, plen; |
| 248 | char *n; | 251 | char *n; |
| @@ -289,6 +292,9 @@ static struct device_node * __init prom_build_tree(struct device_node *parent, | |||
| 289 | 292 | ||
| 290 | dp->child = prom_build_tree(dp, prom_getchild(node), nextp); | 293 | dp->child = prom_build_tree(dp, prom_getchild(node), nextp); |
| 291 | 294 | ||
| 295 | if (prom_build_more) | ||
| 296 | prom_build_more(dp, nextp); | ||
| 297 | |||
| 292 | node = prom_getsibling(node); | 298 | node = prom_getsibling(node); |
| 293 | } | 299 | } |
| 294 | 300 | ||
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 998cadb4e7f2..16a47ffe03c1 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c | |||
| @@ -235,6 +235,8 @@ void __init setup_arch(char **cmdline_p) | |||
| 235 | sparc_cpu_model = sun4e; | 235 | sparc_cpu_model = sun4e; |
| 236 | if (!strcmp(&cputypval,"sun4u")) | 236 | if (!strcmp(&cputypval,"sun4u")) |
| 237 | sparc_cpu_model = sun4u; | 237 | sparc_cpu_model = sun4u; |
| 238 | if (!strncmp(&cputypval, "leon" , 4)) | ||
| 239 | sparc_cpu_model = sparc_leon; | ||
| 238 | 240 | ||
| 239 | printk("ARCH: "); | 241 | printk("ARCH: "); |
| 240 | switch(sparc_cpu_model) { | 242 | switch(sparc_cpu_model) { |
| @@ -256,6 +258,9 @@ void __init setup_arch(char **cmdline_p) | |||
| 256 | case sun4u: | 258 | case sun4u: |
| 257 | printk("SUN4U\n"); | 259 | printk("SUN4U\n"); |
| 258 | break; | 260 | break; |
| 261 | case sparc_leon: | ||
| 262 | printk("LEON\n"); | ||
| 263 | break; | ||
| 259 | default: | 264 | default: |
| 260 | printk("UNKNOWN!\n"); | 265 | printk("UNKNOWN!\n"); |
| 261 | break; | 266 | break; |
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 181d069a2d44..7ce1a1005b1d 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c | |||
| @@ -590,6 +590,8 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, | |||
| 590 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 590 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
| 591 | clear_thread_flag(TIF_NOTIFY_RESUME); | 591 | clear_thread_flag(TIF_NOTIFY_RESUME); |
| 592 | tracehook_notify_resume(regs); | 592 | tracehook_notify_resume(regs); |
| 593 | if (current->replacement_session_keyring) | ||
| 594 | key_replace_session_keyring(); | ||
| 593 | } | 595 | } |
| 594 | } | 596 | } |
| 595 | 597 | ||
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index ec82d76dc6f2..647afbda7ae1 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c | |||
| @@ -613,5 +613,8 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long | |||
| 613 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 613 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
| 614 | clear_thread_flag(TIF_NOTIFY_RESUME); | 614 | clear_thread_flag(TIF_NOTIFY_RESUME); |
| 615 | tracehook_notify_resume(regs); | 615 | tracehook_notify_resume(regs); |
| 616 | if (current->replacement_session_keyring) | ||
| 617 | key_replace_session_keyring(); | ||
| 616 | } | 618 | } |
| 617 | } | 619 | } |
| 620 | |||
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index 54fb02468f0d..68791cad7b74 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c | |||
| @@ -162,9 +162,6 @@ extern void cpu_panic(void); | |||
| 162 | */ | 162 | */ |
| 163 | 163 | ||
| 164 | extern struct linux_prom_registers smp_penguin_ctable; | 164 | extern struct linux_prom_registers smp_penguin_ctable; |
| 165 | extern unsigned long trapbase_cpu1[]; | ||
| 166 | extern unsigned long trapbase_cpu2[]; | ||
| 167 | extern unsigned long trapbase_cpu3[]; | ||
| 168 | 165 | ||
| 169 | void __init smp4d_boot_cpus(void) | 166 | void __init smp4d_boot_cpus(void) |
| 170 | { | 167 | { |
| @@ -235,25 +232,6 @@ void __init smp4d_smp_done(void) | |||
| 235 | *prev = first; | 232 | *prev = first; |
| 236 | local_flush_cache_all(); | 233 | local_flush_cache_all(); |
| 237 | 234 | ||
| 238 | /* Free unneeded trap tables */ | ||
| 239 | ClearPageReserved(virt_to_page(trapbase_cpu1)); | ||
| 240 | init_page_count(virt_to_page(trapbase_cpu1)); | ||
| 241 | free_page((unsigned long)trapbase_cpu1); | ||
| 242 | totalram_pages++; | ||
| 243 | num_physpages++; | ||
| 244 | |||
| 245 | ClearPageReserved(virt_to_page(trapbase_cpu2)); | ||
| 246 | init_page_count(virt_to_page(trapbase_cpu2)); | ||
| 247 | free_page((unsigned long)trapbase_cpu2); | ||
| 248 | totalram_pages++; | ||
| 249 | num_physpages++; | ||
| 250 | |||
| 251 | ClearPageReserved(virt_to_page(trapbase_cpu3)); | ||
| 252 | init_page_count(virt_to_page(trapbase_cpu3)); | ||
| 253 | free_page((unsigned long)trapbase_cpu3); | ||
| 254 | totalram_pages++; | ||
| 255 | num_physpages++; | ||
| 256 | |||
| 257 | /* Ok, they are spinning and ready to go. */ | 235 | /* Ok, they are spinning and ready to go. */ |
| 258 | smp_processors_ready = 1; | 236 | smp_processors_ready = 1; |
| 259 | sun4d_distribute_irqs(); | 237 | sun4d_distribute_irqs(); |
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index 960b113d0006..762d6eedd944 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c | |||
| @@ -121,9 +121,6 @@ void __cpuinit smp4m_callin(void) | |||
| 121 | */ | 121 | */ |
| 122 | 122 | ||
| 123 | extern struct linux_prom_registers smp_penguin_ctable; | 123 | extern struct linux_prom_registers smp_penguin_ctable; |
| 124 | extern unsigned long trapbase_cpu1[]; | ||
| 125 | extern unsigned long trapbase_cpu2[]; | ||
| 126 | extern unsigned long trapbase_cpu3[]; | ||
| 127 | 124 | ||
| 128 | void __init smp4m_boot_cpus(void) | 125 | void __init smp4m_boot_cpus(void) |
| 129 | { | 126 | { |
| @@ -193,29 +190,6 @@ void __init smp4m_smp_done(void) | |||
| 193 | *prev = first; | 190 | *prev = first; |
| 194 | local_flush_cache_all(); | 191 | local_flush_cache_all(); |
| 195 | 192 | ||
| 196 | /* Free unneeded trap tables */ | ||
| 197 | if (!cpu_isset(1, cpu_present_map)) { | ||
| 198 | ClearPageReserved(virt_to_page(trapbase_cpu1)); | ||
| 199 | init_page_count(virt_to_page(trapbase_cpu1)); | ||
| 200 | free_page((unsigned long)trapbase_cpu1); | ||
| 201 | totalram_pages++; | ||
| 202 | num_physpages++; | ||
| 203 | } | ||
| 204 | if (!cpu_isset(2, cpu_present_map)) { | ||
| 205 | ClearPageReserved(virt_to_page(trapbase_cpu2)); | ||
| 206 | init_page_count(virt_to_page(trapbase_cpu2)); | ||
| 207 | free_page((unsigned long)trapbase_cpu2); | ||
| 208 | totalram_pages++; | ||
| 209 | num_physpages++; | ||
| 210 | } | ||
| 211 | if (!cpu_isset(3, cpu_present_map)) { | ||
| 212 | ClearPageReserved(virt_to_page(trapbase_cpu3)); | ||
| 213 | init_page_count(virt_to_page(trapbase_cpu3)); | ||
| 214 | free_page((unsigned long)trapbase_cpu3); | ||
| 215 | totalram_pages++; | ||
| 216 | num_physpages++; | ||
| 217 | } | ||
| 218 | |||
| 219 | /* Ok, they are spinning and ready to go. */ | 193 | /* Ok, they are spinning and ready to go. */ |
| 220 | } | 194 | } |
| 221 | 195 | ||
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index f061c4dda9ef..e7061138c98a 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S | |||
| @@ -121,7 +121,7 @@ SIGN2(sys32_syslog, sys_syslog, %o0, %o2) | |||
| 121 | SIGN1(sys32_umask, sys_umask, %o0) | 121 | SIGN1(sys32_umask, sys_umask, %o0) |
| 122 | SIGN3(sys32_tgkill, sys_tgkill, %o0, %o1, %o2) | 122 | SIGN3(sys32_tgkill, sys_tgkill, %o0, %o1, %o2) |
| 123 | SIGN1(sys32_sendto, sys_sendto, %o0) | 123 | SIGN1(sys32_sendto, sys_sendto, %o0) |
| 124 | SIGN1(sys32_recvfrom, sys_recvfrom, %o0) | 124 | SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0) |
| 125 | SIGN3(sys32_socket, sys_socket, %o0, %o1, %o2) | 125 | SIGN3(sys32_socket, sys_socket, %o0, %o1, %o2) |
| 126 | SIGN2(sys32_connect, sys_connect, %o0, %o2) | 126 | SIGN2(sys32_connect, sys_connect, %o0, %o2) |
| 127 | SIGN2(sys32_bind, sys_bind, %o0, %o2) | 127 | SIGN2(sys32_bind, sys_bind, %o0, %o2) |
| @@ -134,10 +134,12 @@ SIGN1(sys32_getpeername, sys_getpeername, %o0) | |||
| 134 | SIGN1(sys32_getsockname, sys_getsockname, %o0) | 134 | SIGN1(sys32_getsockname, sys_getsockname, %o0) |
| 135 | SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1) | 135 | SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1) |
| 136 | SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2) | 136 | SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2) |
| 137 | SIGN2(sys32_splice, sys_splice, %o0, %o1) | 137 | SIGN2(sys32_splice, sys_splice, %o0, %o2) |
| 138 | SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5) | 138 | SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5) |
| 139 | SIGN2(sys32_tee, sys_tee, %o0, %o1) | 139 | SIGN2(sys32_tee, sys_tee, %o0, %o1) |
| 140 | SIGN1(sys32_vmsplice, compat_sys_vmsplice, %o0) | 140 | SIGN1(sys32_vmsplice, compat_sys_vmsplice, %o0) |
| 141 | SIGN1(sys32_truncate, sys_truncate, %o1) | ||
| 142 | SIGN1(sys32_ftruncate, sys_ftruncate, %o1) | ||
| 141 | 143 | ||
| 142 | .globl sys32_mmap2 | 144 | .globl sys32_mmap2 |
| 143 | sys32_mmap2: | 145 | sys32_mmap2: |
diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c index d28f496f4669..ca39c606fe8e 100644 --- a/arch/sparc/kernel/sysfs.c +++ b/arch/sparc/kernel/sysfs.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * | 2 | * |
| 3 | * Copyright (C) 2007 David S. Miller <davem@davemloft.net> | 3 | * Copyright (C) 2007 David S. Miller <davem@davemloft.net> |
| 4 | */ | 4 | */ |
| 5 | #include <linux/sched.h> | ||
| 5 | #include <linux/sysdev.h> | 6 | #include <linux/sysdev.h> |
| 6 | #include <linux/cpu.h> | 7 | #include <linux/cpu.h> |
| 7 | #include <linux/smp.h> | 8 | #include <linux/smp.h> |
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 690901657291..04181577cb65 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S | |||
| @@ -82,5 +82,5 @@ sys_call_table: | |||
| 82 | /*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate | 82 | /*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate |
| 83 | /*315*/ .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 | 83 | /*315*/ .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 |
| 84 | /*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv | 84 | /*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv |
| 85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo | 85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_counter_open |
| 86 | 86 | ||
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 6b3ee88e253c..91b06b7f7acf 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S | |||
| @@ -43,8 +43,8 @@ sys_call_table32: | |||
| 43 | /*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall | 43 | /*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall |
| 44 | .word sys32_getgroups, compat_sys_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd | 44 | .word sys32_getgroups, compat_sys_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd |
| 45 | /*120*/ .word compat_sys_readv, compat_sys_writev, compat_sys_settimeofday, sys_fchown16, sys_fchmod | 45 | /*120*/ .word compat_sys_readv, compat_sys_writev, compat_sys_settimeofday, sys_fchown16, sys_fchmod |
| 46 | .word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate | 46 | .word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys32_truncate |
| 47 | /*130*/ .word sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall | 47 | /*130*/ .word sys32_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall |
| 48 | .word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64 | 48 | .word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64 |
| 49 | /*140*/ .word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit | 49 | /*140*/ .word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit |
| 50 | .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write | 50 | .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write |
| @@ -83,7 +83,7 @@ sys_call_table32: | |||
| 83 | /*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate | 83 | /*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate |
| 84 | .word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1 | 84 | .word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1 |
| 85 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv | 85 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv |
| 86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo | 86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_counter_open |
| 87 | 87 | ||
| 88 | #endif /* CONFIG_COMPAT */ | 88 | #endif /* CONFIG_COMPAT */ |
| 89 | 89 | ||
| @@ -158,4 +158,4 @@ sys_call_table: | |||
| 158 | /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate | 158 | /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate |
| 159 | .word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 | 159 | .word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 |
| 160 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv | 160 | /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv |
| 161 | .word sys_pwritev, sys_rt_tgsigqueueinfo | 161 | .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_counter_open |
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile index 681abe0a4594..79836a7dd00c 100644 --- a/arch/sparc/mm/Makefile +++ b/arch/sparc/mm/Makefile | |||
| @@ -11,6 +11,7 @@ obj-$(CONFIG_SPARC32) += loadmmu.o | |||
| 11 | obj-y += generic_$(BITS).o | 11 | obj-y += generic_$(BITS).o |
| 12 | obj-$(CONFIG_SPARC32) += extable.o btfixup.o srmmu.o iommu.o io-unit.o | 12 | obj-$(CONFIG_SPARC32) += extable.o btfixup.o srmmu.o iommu.o io-unit.o |
| 13 | obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o | 13 | obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o |
| 14 | obj-$(CONFIG_SPARC_LEON)+= leon_mm.o | ||
| 14 | 15 | ||
| 15 | # Only used by sparc64 | 16 | # Only used by sparc64 |
| 16 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 17 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c index a5e30c642ee3..b99f81c4906f 100644 --- a/arch/sparc/mm/fault_32.c +++ b/arch/sparc/mm/fault_32.c | |||
| @@ -319,9 +319,10 @@ no_context: | |||
| 319 | */ | 319 | */ |
| 320 | out_of_memory: | 320 | out_of_memory: |
| 321 | up_read(&mm->mmap_sem); | 321 | up_read(&mm->mmap_sem); |
| 322 | printk("VM: killing process %s\n", tsk->comm); | 322 | if (from_user) { |
| 323 | if (from_user) | 323 | pagefault_out_of_memory(); |
| 324 | do_group_exit(SIGKILL); | 324 | return; |
| 325 | } | ||
| 325 | goto no_context; | 326 | goto no_context; |
| 326 | 327 | ||
| 327 | do_sigbus: | 328 | do_sigbus: |
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index e5620b27c8bf..43b0da96a4fb 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c | |||
| @@ -447,9 +447,10 @@ handle_kernel_fault: | |||
| 447 | out_of_memory: | 447 | out_of_memory: |
| 448 | insn = get_fault_insn(regs, insn); | 448 | insn = get_fault_insn(regs, insn); |
| 449 | up_read(&mm->mmap_sem); | 449 | up_read(&mm->mmap_sem); |
| 450 | printk("VM: killing process %s\n", current->comm); | 450 | if (!(regs->tstate & TSTATE_PRIV)) { |
| 451 | if (!(regs->tstate & TSTATE_PRIV)) | 451 | pagefault_out_of_memory(); |
| 452 | do_group_exit(SIGKILL); | 452 | return; |
| 453 | } | ||
| 453 | goto handle_kernel_fault; | 454 | goto handle_kernel_fault; |
| 454 | 455 | ||
| 455 | intr_or_no_mm: | 456 | intr_or_no_mm: |
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c index 26bb3919ff1f..54114ad0bdee 100644 --- a/arch/sparc/mm/init_32.c +++ b/arch/sparc/mm/init_32.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <asm/pgalloc.h> /* bug in asm-generic/tlb.h: check_pgt_cache */ | 34 | #include <asm/pgalloc.h> /* bug in asm-generic/tlb.h: check_pgt_cache */ |
| 35 | #include <asm/tlb.h> | 35 | #include <asm/tlb.h> |
| 36 | #include <asm/prom.h> | 36 | #include <asm/prom.h> |
| 37 | #include <asm/leon.h> | ||
| 37 | 38 | ||
| 38 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 39 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); |
| 39 | 40 | ||
| @@ -326,6 +327,9 @@ void __init paging_init(void) | |||
| 326 | sparc_unmapped_base = 0xe0000000; | 327 | sparc_unmapped_base = 0xe0000000; |
| 327 | BTFIXUPSET_SETHI(sparc_unmapped_base, 0xe0000000); | 328 | BTFIXUPSET_SETHI(sparc_unmapped_base, 0xe0000000); |
| 328 | break; | 329 | break; |
| 330 | case sparc_leon: | ||
| 331 | leon_init(); | ||
| 332 | /* fall through */ | ||
| 329 | case sun4m: | 333 | case sun4m: |
| 330 | case sun4d: | 334 | case sun4d: |
| 331 | srmmu_paging_init(); | 335 | srmmu_paging_init(); |
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index ed6be6ba2f4e..a70a5e1904d9 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
| @@ -145,7 +145,8 @@ static void __init read_obp_memory(const char *property, | |||
| 145 | cmp_p64, NULL); | 145 | cmp_p64, NULL); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | unsigned long *sparc64_valid_addr_bitmap __read_mostly; | 148 | unsigned long sparc64_valid_addr_bitmap[VALID_ADDR_BITMAP_BYTES / |
| 149 | sizeof(unsigned long)]; | ||
| 149 | EXPORT_SYMBOL(sparc64_valid_addr_bitmap); | 150 | EXPORT_SYMBOL(sparc64_valid_addr_bitmap); |
| 150 | 151 | ||
| 151 | /* Kernel physical address base and size in bytes. */ | 152 | /* Kernel physical address base and size in bytes. */ |
| @@ -1874,7 +1875,7 @@ static int pavail_rescan_ents __initdata; | |||
| 1874 | * memory list again, and make sure it provides at least as much | 1875 | * memory list again, and make sure it provides at least as much |
| 1875 | * memory as 'pavail' does. | 1876 | * memory as 'pavail' does. |
| 1876 | */ | 1877 | */ |
| 1877 | static void __init setup_valid_addr_bitmap_from_pavail(void) | 1878 | static void __init setup_valid_addr_bitmap_from_pavail(unsigned long *bitmap) |
| 1878 | { | 1879 | { |
| 1879 | int i; | 1880 | int i; |
| 1880 | 1881 | ||
| @@ -1897,8 +1898,7 @@ static void __init setup_valid_addr_bitmap_from_pavail(void) | |||
| 1897 | 1898 | ||
| 1898 | if (new_start <= old_start && | 1899 | if (new_start <= old_start && |
| 1899 | new_end >= (old_start + PAGE_SIZE)) { | 1900 | new_end >= (old_start + PAGE_SIZE)) { |
| 1900 | set_bit(old_start >> 22, | 1901 | set_bit(old_start >> 22, bitmap); |
| 1901 | sparc64_valid_addr_bitmap); | ||
| 1902 | goto do_next_page; | 1902 | goto do_next_page; |
| 1903 | } | 1903 | } |
| 1904 | } | 1904 | } |
| @@ -1919,20 +1919,21 @@ static void __init setup_valid_addr_bitmap_from_pavail(void) | |||
| 1919 | } | 1919 | } |
| 1920 | } | 1920 | } |
| 1921 | 1921 | ||
| 1922 | static void __init patch_tlb_miss_handler_bitmap(void) | ||
| 1923 | { | ||
| 1924 | extern unsigned int valid_addr_bitmap_insn[]; | ||
| 1925 | extern unsigned int valid_addr_bitmap_patch[]; | ||
| 1926 | |||
| 1927 | valid_addr_bitmap_insn[1] = valid_addr_bitmap_patch[1]; | ||
| 1928 | mb(); | ||
| 1929 | valid_addr_bitmap_insn[0] = valid_addr_bitmap_patch[0]; | ||
| 1930 | flushi(&valid_addr_bitmap_insn[0]); | ||
| 1931 | } | ||
| 1932 | |||
| 1922 | void __init mem_init(void) | 1933 | void __init mem_init(void) |
| 1923 | { | 1934 | { |
| 1924 | unsigned long codepages, datapages, initpages; | 1935 | unsigned long codepages, datapages, initpages; |
| 1925 | unsigned long addr, last; | 1936 | unsigned long addr, last; |
| 1926 | int i; | ||
| 1927 | |||
| 1928 | i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6); | ||
| 1929 | i += 1; | ||
| 1930 | sparc64_valid_addr_bitmap = (unsigned long *) alloc_bootmem(i << 3); | ||
| 1931 | if (sparc64_valid_addr_bitmap == NULL) { | ||
| 1932 | prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n"); | ||
| 1933 | prom_halt(); | ||
| 1934 | } | ||
| 1935 | memset(sparc64_valid_addr_bitmap, 0, i << 3); | ||
| 1936 | 1937 | ||
| 1937 | addr = PAGE_OFFSET + kern_base; | 1938 | addr = PAGE_OFFSET + kern_base; |
| 1938 | last = PAGE_ALIGN(kern_size) + addr; | 1939 | last = PAGE_ALIGN(kern_size) + addr; |
| @@ -1941,15 +1942,19 @@ void __init mem_init(void) | |||
| 1941 | addr += PAGE_SIZE; | 1942 | addr += PAGE_SIZE; |
| 1942 | } | 1943 | } |
| 1943 | 1944 | ||
| 1944 | setup_valid_addr_bitmap_from_pavail(); | 1945 | setup_valid_addr_bitmap_from_pavail(sparc64_valid_addr_bitmap); |
| 1946 | patch_tlb_miss_handler_bitmap(); | ||
| 1945 | 1947 | ||
| 1946 | high_memory = __va(last_valid_pfn << PAGE_SHIFT); | 1948 | high_memory = __va(last_valid_pfn << PAGE_SHIFT); |
| 1947 | 1949 | ||
| 1948 | #ifdef CONFIG_NEED_MULTIPLE_NODES | 1950 | #ifdef CONFIG_NEED_MULTIPLE_NODES |
| 1949 | for_each_online_node(i) { | 1951 | { |
| 1950 | if (NODE_DATA(i)->node_spanned_pages != 0) { | 1952 | int i; |
| 1951 | totalram_pages += | 1953 | for_each_online_node(i) { |
| 1952 | free_all_bootmem_node(NODE_DATA(i)); | 1954 | if (NODE_DATA(i)->node_spanned_pages != 0) { |
| 1955 | totalram_pages += | ||
| 1956 | free_all_bootmem_node(NODE_DATA(i)); | ||
| 1957 | } | ||
| 1953 | } | 1958 | } |
| 1954 | } | 1959 | } |
| 1955 | #else | 1960 | #else |
diff --git a/arch/sparc/mm/init_64.h b/arch/sparc/mm/init_64.h index 16063870a489..c2f772dbd556 100644 --- a/arch/sparc/mm/init_64.h +++ b/arch/sparc/mm/init_64.h | |||
| @@ -5,10 +5,13 @@ | |||
| 5 | * marked non-static so that assembler code can get at them. | 5 | * marked non-static so that assembler code can get at them. |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #define MAX_PHYS_ADDRESS (1UL << 42UL) | 8 | #define MAX_PHYS_ADDRESS (1UL << 41UL) |
| 9 | #define KPTE_BITMAP_CHUNK_SZ (256UL * 1024UL * 1024UL) | 9 | #define KPTE_BITMAP_CHUNK_SZ (256UL * 1024UL * 1024UL) |
| 10 | #define KPTE_BITMAP_BYTES \ | 10 | #define KPTE_BITMAP_BYTES \ |
| 11 | ((MAX_PHYS_ADDRESS / KPTE_BITMAP_CHUNK_SZ) / 8) | 11 | ((MAX_PHYS_ADDRESS / KPTE_BITMAP_CHUNK_SZ) / 8) |
| 12 | #define VALID_ADDR_BITMAP_CHUNK_SZ (4UL * 1024UL * 1024UL) | ||
| 13 | #define VALID_ADDR_BITMAP_BYTES \ | ||
| 14 | ((MAX_PHYS_ADDRESS / VALID_ADDR_BITMAP_CHUNK_SZ) / 8) | ||
| 12 | 15 | ||
| 13 | extern unsigned long kern_linear_pte_xor[2]; | 16 | extern unsigned long kern_linear_pte_xor[2]; |
| 14 | extern unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)]; | 17 | extern unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)]; |
diff --git a/arch/sparc/mm/leon_mm.c b/arch/sparc/mm/leon_mm.c new file mode 100644 index 000000000000..c0e01297e64e --- /dev/null +++ b/arch/sparc/mm/leon_mm.c | |||
| @@ -0,0 +1,260 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/sparc/mm/leon_m.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2004 Konrad Eisele (eiselekd@web.de, konrad@gaisler.com) Gaisler Research | ||
| 5 | * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB | ||
| 6 | * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB | ||
| 7 | * | ||
| 8 | * do srmmu probe in software | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/mm.h> | ||
| 14 | #include <asm/asi.h> | ||
| 15 | #include <asm/leon.h> | ||
| 16 | #include <asm/tlbflush.h> | ||
| 17 | |||
| 18 | int leon_flush_during_switch = 1; | ||
| 19 | int srmmu_swprobe_trace; | ||
| 20 | |||
| 21 | unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr) | ||
| 22 | { | ||
| 23 | |||
| 24 | unsigned int ctxtbl; | ||
| 25 | unsigned int pgd, pmd, ped; | ||
| 26 | unsigned int ptr; | ||
| 27 | unsigned int lvl, pte, paddrbase; | ||
| 28 | unsigned int ctx; | ||
| 29 | unsigned int paddr_calc; | ||
| 30 | |||
| 31 | paddrbase = 0; | ||
| 32 | |||
| 33 | if (srmmu_swprobe_trace) | ||
| 34 | printk(KERN_INFO "swprobe: trace on\n"); | ||
| 35 | |||
| 36 | ctxtbl = srmmu_get_ctable_ptr(); | ||
| 37 | if (!(ctxtbl)) { | ||
| 38 | if (srmmu_swprobe_trace) | ||
| 39 | printk(KERN_INFO "swprobe: srmmu_get_ctable_ptr returned 0=>0\n"); | ||
| 40 | return 0; | ||
| 41 | } | ||
| 42 | if (!_pfn_valid(PFN(ctxtbl))) { | ||
| 43 | if (srmmu_swprobe_trace) | ||
| 44 | printk(KERN_INFO | ||
| 45 | "swprobe: !_pfn_valid(%x)=>0\n", | ||
| 46 | PFN(ctxtbl)); | ||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | ctx = srmmu_get_context(); | ||
| 51 | if (srmmu_swprobe_trace) | ||
| 52 | printk(KERN_INFO "swprobe: --- ctx (%x) ---\n", ctx); | ||
| 53 | |||
| 54 | pgd = LEON_BYPASS_LOAD_PA(ctxtbl + (ctx * 4)); | ||
| 55 | |||
| 56 | if (((pgd & SRMMU_ET_MASK) == SRMMU_ET_PTE)) { | ||
| 57 | if (srmmu_swprobe_trace) | ||
| 58 | printk(KERN_INFO "swprobe: pgd is entry level 3\n"); | ||
| 59 | lvl = 3; | ||
| 60 | pte = pgd; | ||
| 61 | paddrbase = pgd & _SRMMU_PTE_PMASK_LEON; | ||
| 62 | goto ready; | ||
| 63 | } | ||
| 64 | if (((pgd & SRMMU_ET_MASK) != SRMMU_ET_PTD)) { | ||
| 65 | if (srmmu_swprobe_trace) | ||
| 66 | printk(KERN_INFO "swprobe: pgd is invalid => 0\n"); | ||
| 67 | return 0; | ||
| 68 | } | ||
| 69 | |||
| 70 | if (srmmu_swprobe_trace) | ||
| 71 | printk(KERN_INFO "swprobe: --- pgd (%x) ---\n", pgd); | ||
| 72 | |||
| 73 | ptr = (pgd & SRMMU_PTD_PMASK) << 4; | ||
| 74 | ptr += ((((vaddr) >> LEON_PGD_SH) & LEON_PGD_M) * 4); | ||
| 75 | if (!_pfn_valid(PFN(ptr))) | ||
| 76 | return 0; | ||
| 77 | |||
| 78 | pmd = LEON_BYPASS_LOAD_PA(ptr); | ||
| 79 | if (((pmd & SRMMU_ET_MASK) == SRMMU_ET_PTE)) { | ||
| 80 | if (srmmu_swprobe_trace) | ||
| 81 | printk(KERN_INFO "swprobe: pmd is entry level 2\n"); | ||
| 82 | lvl = 2; | ||
| 83 | pte = pmd; | ||
| 84 | paddrbase = pmd & _SRMMU_PTE_PMASK_LEON; | ||
| 85 | goto ready; | ||
| 86 | } | ||
| 87 | if (((pmd & SRMMU_ET_MASK) != SRMMU_ET_PTD)) { | ||
| 88 | if (srmmu_swprobe_trace) | ||
| 89 | printk(KERN_INFO "swprobe: pmd is invalid => 0\n"); | ||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | if (srmmu_swprobe_trace) | ||
| 94 | printk(KERN_INFO "swprobe: --- pmd (%x) ---\n", pmd); | ||
| 95 | |||
| 96 | ptr = (pmd & SRMMU_PTD_PMASK) << 4; | ||
| 97 | ptr += (((vaddr >> LEON_PMD_SH) & LEON_PMD_M) * 4); | ||
| 98 | if (!_pfn_valid(PFN(ptr))) { | ||
| 99 | if (srmmu_swprobe_trace) | ||
| 100 | printk(KERN_INFO "swprobe: !_pfn_valid(%x)=>0\n", | ||
| 101 | PFN(ptr)); | ||
| 102 | return 0; | ||
| 103 | } | ||
| 104 | |||
| 105 | ped = LEON_BYPASS_LOAD_PA(ptr); | ||
| 106 | |||
| 107 | if (((ped & SRMMU_ET_MASK) == SRMMU_ET_PTE)) { | ||
| 108 | if (srmmu_swprobe_trace) | ||
| 109 | printk(KERN_INFO "swprobe: ped is entry level 1\n"); | ||
| 110 | lvl = 1; | ||
| 111 | pte = ped; | ||
| 112 | paddrbase = ped & _SRMMU_PTE_PMASK_LEON; | ||
| 113 | goto ready; | ||
| 114 | } | ||
| 115 | if (((ped & SRMMU_ET_MASK) != SRMMU_ET_PTD)) { | ||
| 116 | if (srmmu_swprobe_trace) | ||
| 117 | printk(KERN_INFO "swprobe: ped is invalid => 0\n"); | ||
| 118 | return 0; | ||
| 119 | } | ||
| 120 | |||
| 121 | if (srmmu_swprobe_trace) | ||
| 122 | printk(KERN_INFO "swprobe: --- ped (%x) ---\n", ped); | ||
| 123 | |||
| 124 | ptr = (ped & SRMMU_PTD_PMASK) << 4; | ||
| 125 | ptr += (((vaddr >> LEON_PTE_SH) & LEON_PTE_M) * 4); | ||
| 126 | if (!_pfn_valid(PFN(ptr))) | ||
| 127 | return 0; | ||
| 128 | |||
| 129 | ptr = LEON_BYPASS_LOAD_PA(ptr); | ||
| 130 | if (((ptr & SRMMU_ET_MASK) == SRMMU_ET_PTE)) { | ||
| 131 | if (srmmu_swprobe_trace) | ||
| 132 | printk(KERN_INFO "swprobe: ptr is entry level 0\n"); | ||
| 133 | lvl = 0; | ||
| 134 | pte = ptr; | ||
| 135 | paddrbase = ptr & _SRMMU_PTE_PMASK_LEON; | ||
| 136 | goto ready; | ||
| 137 | } | ||
| 138 | if (srmmu_swprobe_trace) | ||
| 139 | printk(KERN_INFO "swprobe: ptr is invalid => 0\n"); | ||
| 140 | return 0; | ||
| 141 | |||
| 142 | ready: | ||
| 143 | switch (lvl) { | ||
| 144 | case 0: | ||
| 145 | paddr_calc = | ||
| 146 | (vaddr & ~(-1 << LEON_PTE_SH)) | ((pte & ~0xff) << 4); | ||
| 147 | break; | ||
| 148 | case 1: | ||
| 149 | paddr_calc = | ||
| 150 | (vaddr & ~(-1 << LEON_PMD_SH)) | ((pte & ~0xff) << 4); | ||
| 151 | break; | ||
| 152 | case 2: | ||
| 153 | paddr_calc = | ||
| 154 | (vaddr & ~(-1 << LEON_PGD_SH)) | ((pte & ~0xff) << 4); | ||
| 155 | break; | ||
| 156 | default: | ||
| 157 | case 3: | ||
| 158 | paddr_calc = vaddr; | ||
| 159 | break; | ||
| 160 | } | ||
| 161 | if (srmmu_swprobe_trace) | ||
| 162 | printk(KERN_INFO "swprobe: padde %x\n", paddr_calc); | ||
| 163 | if (paddr) | ||
| 164 | *paddr = paddr_calc; | ||
| 165 | return paddrbase; | ||
| 166 | } | ||
| 167 | |||
| 168 | void leon_flush_icache_all(void) | ||
| 169 | { | ||
| 170 | __asm__ __volatile__(" flush "); /*iflush*/ | ||
| 171 | } | ||
| 172 | |||
| 173 | void leon_flush_dcache_all(void) | ||
| 174 | { | ||
| 175 | __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : | ||
| 176 | "i"(ASI_LEON_DFLUSH) : "memory"); | ||
| 177 | } | ||
| 178 | |||
| 179 | void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page) | ||
| 180 | { | ||
| 181 | if (vma->vm_flags & VM_EXEC) | ||
| 182 | leon_flush_icache_all(); | ||
| 183 | leon_flush_dcache_all(); | ||
| 184 | } | ||
| 185 | |||
| 186 | void leon_flush_cache_all(void) | ||
| 187 | { | ||
| 188 | __asm__ __volatile__(" flush "); /*iflush*/ | ||
| 189 | __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : : | ||
| 190 | "i"(ASI_LEON_DFLUSH) : "memory"); | ||
| 191 | } | ||
| 192 | |||
| 193 | void leon_flush_tlb_all(void) | ||
| 194 | { | ||
| 195 | leon_flush_cache_all(); | ||
| 196 | __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : "r"(0x400), | ||
| 197 | "i"(ASI_LEON_MMUFLUSH) : "memory"); | ||
| 198 | } | ||
| 199 | |||
| 200 | /* get all cache regs */ | ||
| 201 | void leon3_getCacheRegs(struct leon3_cacheregs *regs) | ||
| 202 | { | ||
| 203 | unsigned long ccr, iccr, dccr; | ||
| 204 | |||
| 205 | if (!regs) | ||
| 206 | return; | ||
| 207 | /* Get Cache regs from "Cache ASI" address 0x0, 0x8 and 0xC */ | ||
| 208 | __asm__ __volatile__("lda [%%g0] %3, %0\n\t" | ||
| 209 | "mov 0x08, %%g1\n\t" | ||
| 210 | "lda [%%g1] %3, %1\n\t" | ||
| 211 | "mov 0x0c, %%g1\n\t" | ||
| 212 | "lda [%%g1] %3, %2\n\t" | ||
| 213 | : "=r"(ccr), "=r"(iccr), "=r"(dccr) | ||
| 214 | /* output */ | ||
| 215 | : "i"(ASI_LEON_CACHEREGS) /* input */ | ||
| 216 | : "g1" /* clobber list */ | ||
| 217 | ); | ||
| 218 | regs->ccr = ccr; | ||
| 219 | regs->iccr = iccr; | ||
| 220 | regs->dccr = dccr; | ||
| 221 | } | ||
| 222 | |||
| 223 | /* Due to virtual cache we need to check cache configuration if | ||
| 224 | * it is possible to skip flushing in some cases. | ||
| 225 | * | ||
| 226 | * Leon2 and Leon3 differ in their way of telling cache information | ||
| 227 | * | ||
| 228 | */ | ||
| 229 | int leon_flush_needed(void) | ||
| 230 | { | ||
| 231 | int flush_needed = -1; | ||
| 232 | unsigned int ssize, sets; | ||
| 233 | char *setStr[4] = | ||
| 234 | { "direct mapped", "2-way associative", "3-way associative", | ||
| 235 | "4-way associative" | ||
| 236 | }; | ||
| 237 | /* leon 3 */ | ||
| 238 | struct leon3_cacheregs cregs; | ||
| 239 | leon3_getCacheRegs(&cregs); | ||
| 240 | sets = (cregs.dccr & LEON3_XCCR_SETS_MASK) >> 24; | ||
| 241 | /* (ssize=>realsize) 0=>1k, 1=>2k, 2=>4k, 3=>8k ... */ | ||
| 242 | ssize = 1 << ((cregs.dccr & LEON3_XCCR_SSIZE_MASK) >> 20); | ||
| 243 | |||
| 244 | printk(KERN_INFO "CACHE: %s cache, set size %dk\n", | ||
| 245 | sets > 3 ? "unknown" : setStr[sets], ssize); | ||
| 246 | if ((ssize <= (PAGE_SIZE / 1024)) && (sets == 0)) { | ||
| 247 | /* Set Size <= Page size ==> | ||
| 248 | flush on every context switch not needed. */ | ||
| 249 | flush_needed = 0; | ||
| 250 | printk(KERN_INFO "CACHE: not flushing on every context switch\n"); | ||
| 251 | } | ||
| 252 | return flush_needed; | ||
| 253 | } | ||
| 254 | |||
| 255 | void leon_switch_mm(void) | ||
| 256 | { | ||
| 257 | flush_tlb_mm((void *)0); | ||
| 258 | if (leon_flush_during_switch) | ||
| 259 | leon_flush_cache_all(); | ||
| 260 | } | ||
diff --git a/arch/sparc/mm/loadmmu.c b/arch/sparc/mm/loadmmu.c index 652be05acbea..82ec8f666036 100644 --- a/arch/sparc/mm/loadmmu.c +++ b/arch/sparc/mm/loadmmu.c | |||
| @@ -33,6 +33,7 @@ void __init load_mmu(void) | |||
| 33 | break; | 33 | break; |
| 34 | case sun4m: | 34 | case sun4m: |
| 35 | case sun4d: | 35 | case sun4d: |
| 36 | case sparc_leon: | ||
| 36 | ld_mmu_srmmu(); | 37 | ld_mmu_srmmu(); |
| 37 | break; | 38 | break; |
| 38 | default: | 39 | default: |
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index ade4eb373bdd..509b1ffeba66 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | #include <asm/tsunami.h> | 46 | #include <asm/tsunami.h> |
| 47 | #include <asm/swift.h> | 47 | #include <asm/swift.h> |
| 48 | #include <asm/turbosparc.h> | 48 | #include <asm/turbosparc.h> |
| 49 | #include <asm/leon.h> | ||
| 49 | 50 | ||
| 50 | #include <asm/btfixup.h> | 51 | #include <asm/btfixup.h> |
| 51 | 52 | ||
| @@ -569,6 +570,9 @@ static void srmmu_switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, | |||
| 569 | srmmu_ctxd_set(&srmmu_context_table[mm->context], mm->pgd); | 570 | srmmu_ctxd_set(&srmmu_context_table[mm->context], mm->pgd); |
| 570 | } | 571 | } |
| 571 | 572 | ||
| 573 | if (sparc_cpu_model == sparc_leon) | ||
| 574 | leon_switch_mm(); | ||
| 575 | |||
| 572 | if (is_hypersparc) | 576 | if (is_hypersparc) |
| 573 | hyper_flush_whole_icache(); | 577 | hyper_flush_whole_icache(); |
| 574 | 578 | ||
| @@ -1977,6 +1981,45 @@ static void __init init_viking(void) | |||
| 1977 | poke_srmmu = poke_viking; | 1981 | poke_srmmu = poke_viking; |
| 1978 | } | 1982 | } |
| 1979 | 1983 | ||
| 1984 | #ifdef CONFIG_SPARC_LEON | ||
| 1985 | |||
| 1986 | void __init poke_leonsparc(void) | ||
| 1987 | { | ||
| 1988 | } | ||
| 1989 | |||
| 1990 | void __init init_leon(void) | ||
| 1991 | { | ||
| 1992 | |||
| 1993 | srmmu_name = "Leon"; | ||
| 1994 | |||
| 1995 | BTFIXUPSET_CALL(flush_cache_all, leon_flush_cache_all, | ||
| 1996 | BTFIXUPCALL_NORM); | ||
| 1997 | BTFIXUPSET_CALL(flush_cache_mm, leon_flush_cache_all, | ||
| 1998 | BTFIXUPCALL_NORM); | ||
| 1999 | BTFIXUPSET_CALL(flush_cache_page, leon_flush_pcache_all, | ||
| 2000 | BTFIXUPCALL_NORM); | ||
| 2001 | BTFIXUPSET_CALL(flush_cache_range, leon_flush_cache_all, | ||
| 2002 | BTFIXUPCALL_NORM); | ||
| 2003 | BTFIXUPSET_CALL(flush_page_for_dma, leon_flush_dcache_all, | ||
| 2004 | BTFIXUPCALL_NORM); | ||
| 2005 | |||
| 2006 | BTFIXUPSET_CALL(flush_tlb_all, leon_flush_tlb_all, BTFIXUPCALL_NORM); | ||
| 2007 | BTFIXUPSET_CALL(flush_tlb_mm, leon_flush_tlb_all, BTFIXUPCALL_NORM); | ||
| 2008 | BTFIXUPSET_CALL(flush_tlb_page, leon_flush_tlb_all, BTFIXUPCALL_NORM); | ||
| 2009 | BTFIXUPSET_CALL(flush_tlb_range, leon_flush_tlb_all, BTFIXUPCALL_NORM); | ||
| 2010 | |||
| 2011 | BTFIXUPSET_CALL(__flush_page_to_ram, leon_flush_cache_all, | ||
| 2012 | BTFIXUPCALL_NOP); | ||
| 2013 | BTFIXUPSET_CALL(flush_sig_insns, leon_flush_cache_all, BTFIXUPCALL_NOP); | ||
| 2014 | |||
| 2015 | poke_srmmu = poke_leonsparc; | ||
| 2016 | |||
| 2017 | srmmu_cache_pagetables = 0; | ||
| 2018 | |||
| 2019 | leon_flush_during_switch = leon_flush_needed(); | ||
| 2020 | } | ||
| 2021 | #endif | ||
| 2022 | |||
| 1980 | /* Probe for the srmmu chip version. */ | 2023 | /* Probe for the srmmu chip version. */ |
| 1981 | static void __init get_srmmu_type(void) | 2024 | static void __init get_srmmu_type(void) |
| 1982 | { | 2025 | { |
| @@ -1992,7 +2035,15 @@ static void __init get_srmmu_type(void) | |||
| 1992 | psr_typ = (psr >> 28) & 0xf; | 2035 | psr_typ = (psr >> 28) & 0xf; |
| 1993 | psr_vers = (psr >> 24) & 0xf; | 2036 | psr_vers = (psr >> 24) & 0xf; |
| 1994 | 2037 | ||
| 1995 | /* First, check for HyperSparc or Cypress. */ | 2038 | /* First, check for sparc-leon. */ |
| 2039 | if (sparc_cpu_model == sparc_leon) { | ||
| 2040 | psr_typ = 0xf; /* hardcoded ids for older models/simulators */ | ||
| 2041 | psr_vers = 2; | ||
| 2042 | init_leon(); | ||
| 2043 | return; | ||
| 2044 | } | ||
| 2045 | |||
| 2046 | /* Second, check for HyperSparc or Cypress. */ | ||
| 1996 | if(mod_typ == 1) { | 2047 | if(mod_typ == 1) { |
| 1997 | switch(mod_rev) { | 2048 | switch(mod_rev) { |
| 1998 | case 7: | 2049 | case 7: |
diff --git a/arch/sparc/oprofile/init.c b/arch/sparc/oprofile/init.c index d172f86439b1..f97cb8b6ee5f 100644 --- a/arch/sparc/oprofile/init.c +++ b/arch/sparc/oprofile/init.c | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | static int profile_timer_exceptions_notify(struct notifier_block *self, | 21 | static int profile_timer_exceptions_notify(struct notifier_block *self, |
| 22 | unsigned long val, void *data) | 22 | unsigned long val, void *data) |
| 23 | { | 23 | { |
| 24 | struct die_args *args = (struct die_args *)data; | 24 | struct die_args *args = data; |
| 25 | int ret = NOTIFY_DONE; | 25 | int ret = NOTIFY_DONE; |
| 26 | 26 | ||
| 27 | switch (val) { | 27 | switch (val) { |
| @@ -57,7 +57,7 @@ static void timer_stop(void) | |||
| 57 | 57 | ||
| 58 | static int op_nmi_timer_init(struct oprofile_operations *ops) | 58 | static int op_nmi_timer_init(struct oprofile_operations *ops) |
| 59 | { | 59 | { |
| 60 | if (!nmi_usable) | 60 | if (atomic_read(&nmi_active) <= 0) |
| 61 | return -ENODEV; | 61 | return -ENODEV; |
| 62 | 62 | ||
| 63 | ops->start = timer_start; | 63 | ops->start = timer_start; |
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c index eedffb4fec2d..39fc6af21b7c 100644 --- a/arch/sparc/prom/misc_64.c +++ b/arch/sparc/prom/misc_64.c | |||
| @@ -88,7 +88,7 @@ void prom_cmdline(void) | |||
| 88 | /* Drop into the prom, but completely terminate the program. | 88 | /* Drop into the prom, but completely terminate the program. |
| 89 | * No chance of continuing. | 89 | * No chance of continuing. |
| 90 | */ | 90 | */ |
| 91 | void prom_halt(void) | 91 | void notrace prom_halt(void) |
| 92 | { | 92 | { |
| 93 | #ifdef CONFIG_SUN_LDOMS | 93 | #ifdef CONFIG_SUN_LDOMS |
| 94 | if (ldom_domaining_enabled) | 94 | if (ldom_domaining_enabled) |
diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c index 660943ee4c2a..ca869266b9f3 100644 --- a/arch/sparc/prom/printf.c +++ b/arch/sparc/prom/printf.c | |||
| @@ -14,14 +14,14 @@ | |||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/compiler.h> | ||
| 17 | 18 | ||
| 18 | #include <asm/openprom.h> | 19 | #include <asm/openprom.h> |
| 19 | #include <asm/oplib.h> | 20 | #include <asm/oplib.h> |
| 20 | 21 | ||
| 21 | static char ppbuf[1024]; | 22 | static char ppbuf[1024]; |
| 22 | 23 | ||
| 23 | void | 24 | void notrace prom_write(const char *buf, unsigned int n) |
| 24 | prom_write(const char *buf, unsigned int n) | ||
| 25 | { | 25 | { |
| 26 | char ch; | 26 | char ch; |
| 27 | 27 | ||
| @@ -33,8 +33,7 @@ prom_write(const char *buf, unsigned int n) | |||
| 33 | } | 33 | } |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | void | 36 | void notrace prom_printf(const char *fmt, ...) |
| 37 | prom_printf(const char *fmt, ...) | ||
| 38 | { | 37 | { |
| 39 | va_list args; | 38 | va_list args; |
| 40 | int i; | 39 | int i; |
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 3b44b47c7e1d..f114813ae258 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c | |||
| @@ -245,7 +245,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 245 | 245 | ||
| 246 | dev_kfree_skb(skb); | 246 | dev_kfree_skb(skb); |
| 247 | 247 | ||
| 248 | return 0; | 248 | return NETDEV_TX_OK; |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | static void uml_net_set_multicast_list(struct net_device *dev) | 251 | static void uml_net_set_multicast_list(struct net_device *dev) |
| @@ -285,7 +285,7 @@ static void uml_net_get_drvinfo(struct net_device *dev, | |||
| 285 | strcpy(info->version, "42"); | 285 | strcpy(info->version, "42"); |
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | static struct ethtool_ops uml_net_ethtool_ops = { | 288 | static const struct ethtool_ops uml_net_ethtool_ops = { |
| 289 | .get_drvinfo = uml_net_get_drvinfo, | 289 | .get_drvinfo = uml_net_get_drvinfo, |
| 290 | .get_link = ethtool_op_get_link, | 290 | .get_link = ethtool_op_get_link, |
| 291 | }; | 291 | }; |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 13ffa5df37d7..fc20fdc0f7f2 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -38,7 +38,7 @@ config X86 | |||
| 38 | select HAVE_FUNCTION_GRAPH_FP_TEST | 38 | select HAVE_FUNCTION_GRAPH_FP_TEST |
| 39 | select HAVE_FUNCTION_TRACE_MCOUNT_TEST | 39 | select HAVE_FUNCTION_TRACE_MCOUNT_TEST |
| 40 | select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE | 40 | select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE |
| 41 | select HAVE_FTRACE_SYSCALLS | 41 | select HAVE_SYSCALL_TRACEPOINTS |
| 42 | select HAVE_KVM | 42 | select HAVE_KVM |
| 43 | select HAVE_ARCH_KGDB | 43 | select HAVE_ARCH_KGDB |
| 44 | select HAVE_ARCH_TRACEHOOK | 44 | select HAVE_ARCH_TRACEHOOK |
| @@ -586,7 +586,6 @@ config GART_IOMMU | |||
| 586 | bool "GART IOMMU support" if EMBEDDED | 586 | bool "GART IOMMU support" if EMBEDDED |
| 587 | default y | 587 | default y |
| 588 | select SWIOTLB | 588 | select SWIOTLB |
| 589 | select AGP | ||
| 590 | depends on X86_64 && PCI | 589 | depends on X86_64 && PCI |
| 591 | ---help--- | 590 | ---help--- |
| 592 | Support for full DMA access of devices with 32bit memory access only | 591 | Support for full DMA access of devices with 32bit memory access only |
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index 8130334329c0..527519b8a9f9 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu | |||
| @@ -262,6 +262,15 @@ config MCORE2 | |||
| 262 | family in /proc/cpuinfo. Newer ones have 6 and older ones 15 | 262 | family in /proc/cpuinfo. Newer ones have 6 and older ones 15 |
| 263 | (not a typo) | 263 | (not a typo) |
| 264 | 264 | ||
| 265 | config MATOM | ||
| 266 | bool "Intel Atom" | ||
| 267 | ---help--- | ||
| 268 | |||
| 269 | Select this for the Intel Atom platform. Intel Atom CPUs have an | ||
| 270 | in-order pipelining architecture and thus can benefit from | ||
| 271 | accordingly optimized code. Use a recent GCC with specific Atom | ||
| 272 | support in order to fully benefit from selecting this option. | ||
| 273 | |||
| 265 | config GENERIC_CPU | 274 | config GENERIC_CPU |
| 266 | bool "Generic-x86-64" | 275 | bool "Generic-x86-64" |
| 267 | depends on X86_64 | 276 | depends on X86_64 |
| @@ -295,7 +304,7 @@ config X86_CPU | |||
| 295 | config X86_L1_CACHE_BYTES | 304 | config X86_L1_CACHE_BYTES |
| 296 | int | 305 | int |
| 297 | default "128" if MPSC | 306 | default "128" if MPSC |
| 298 | default "64" if GENERIC_CPU || MK8 || MCORE2 || X86_32 | 307 | default "64" if GENERIC_CPU || MK8 || MCORE2 || MATOM || X86_32 |
| 299 | 308 | ||
| 300 | config X86_INTERNODE_CACHE_BYTES | 309 | config X86_INTERNODE_CACHE_BYTES |
| 301 | int | 310 | int |
| @@ -310,7 +319,7 @@ config X86_L1_CACHE_SHIFT | |||
| 310 | default "7" if MPENTIUM4 || MPSC | 319 | default "7" if MPENTIUM4 || MPSC |
| 311 | default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 | 320 | default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 |
| 312 | default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX | 321 | default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX |
| 313 | default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 || X86_GENERIC || GENERIC_CPU | 322 | default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU |
| 314 | 323 | ||
| 315 | config X86_XADD | 324 | config X86_XADD |
| 316 | def_bool y | 325 | def_bool y |
| @@ -359,7 +368,7 @@ config X86_INTEL_USERCOPY | |||
| 359 | 368 | ||
| 360 | config X86_USE_PPRO_CHECKSUM | 369 | config X86_USE_PPRO_CHECKSUM |
| 361 | def_bool y | 370 | def_bool y |
| 362 | depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2 | 371 | depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM |
| 363 | 372 | ||
| 364 | config X86_USE_3DNOW | 373 | config X86_USE_3DNOW |
| 365 | def_bool y | 374 | def_bool y |
| @@ -387,7 +396,7 @@ config X86_P6_NOP | |||
| 387 | 396 | ||
| 388 | config X86_TSC | 397 | config X86_TSC |
| 389 | def_bool y | 398 | def_bool y |
| 390 | depends on ((MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64 | 399 | depends on ((MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) && !X86_NUMAQ) || X86_64 |
| 391 | 400 | ||
| 392 | config X86_CMPXCHG64 | 401 | config X86_CMPXCHG64 |
| 393 | def_bool y | 402 | def_bool y |
| @@ -397,7 +406,7 @@ config X86_CMPXCHG64 | |||
| 397 | # generates cmov. | 406 | # generates cmov. |
| 398 | config X86_CMOV | 407 | config X86_CMOV |
| 399 | def_bool y | 408 | def_bool y |
| 400 | depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64) | 409 | depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM) |
| 401 | 410 | ||
| 402 | config X86_MINIMUM_CPU_FAMILY | 411 | config X86_MINIMUM_CPU_FAMILY |
| 403 | int | 412 | int |
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 1b68659c41b4..7983c420eaf2 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
| @@ -32,8 +32,8 @@ ifeq ($(CONFIG_X86_32),y) | |||
| 32 | 32 | ||
| 33 | # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use | 33 | # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use |
| 34 | # a lot more stack due to the lack of sharing of stacklots: | 34 | # a lot more stack due to the lack of sharing of stacklots: |
| 35 | KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \ | 35 | KBUILD_CFLAGS += $(call cc-ifversion, -lt, 0400, \ |
| 36 | echo $(call cc-option,-fno-unit-at-a-time); fi ;) | 36 | $(call cc-option,-fno-unit-at-a-time)) |
| 37 | 37 | ||
| 38 | # CPU-specific tuning. Anything which can be shared with UML should go here. | 38 | # CPU-specific tuning. Anything which can be shared with UML should go here. |
| 39 | include $(srctree)/arch/x86/Makefile_32.cpu | 39 | include $(srctree)/arch/x86/Makefile_32.cpu |
| @@ -55,6 +55,8 @@ else | |||
| 55 | 55 | ||
| 56 | cflags-$(CONFIG_MCORE2) += \ | 56 | cflags-$(CONFIG_MCORE2) += \ |
| 57 | $(call cc-option,-march=core2,$(call cc-option,-mtune=generic)) | 57 | $(call cc-option,-march=core2,$(call cc-option,-mtune=generic)) |
| 58 | cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom) \ | ||
| 59 | $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic)) | ||
| 58 | cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) | 60 | cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) |
| 59 | KBUILD_CFLAGS += $(cflags-y) | 61 | KBUILD_CFLAGS += $(cflags-y) |
| 60 | 62 | ||
| @@ -72,7 +74,7 @@ endif | |||
| 72 | 74 | ||
| 73 | ifdef CONFIG_CC_STACKPROTECTOR | 75 | ifdef CONFIG_CC_STACKPROTECTOR |
| 74 | cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh | 76 | cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh |
| 75 | ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC)),y) | 77 | ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(biarch)),y) |
| 76 | stackp-y := -fstack-protector | 78 | stackp-y := -fstack-protector |
| 77 | stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += -fstack-protector-all | 79 | stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += -fstack-protector-all |
| 78 | KBUILD_CFLAGS += $(stackp-y) | 80 | KBUILD_CFLAGS += $(stackp-y) |
diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu index 80177ec052f0..30e9a264f69d 100644 --- a/arch/x86/Makefile_32.cpu +++ b/arch/x86/Makefile_32.cpu | |||
| @@ -33,6 +33,8 @@ cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-f | |||
| 33 | cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) | 33 | cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) |
| 34 | cflags-$(CONFIG_MVIAC7) += -march=i686 | 34 | cflags-$(CONFIG_MVIAC7) += -march=i686 |
| 35 | cflags-$(CONFIG_MCORE2) += -march=i686 $(call tune,core2) | 35 | cflags-$(CONFIG_MCORE2) += -march=i686 $(call tune,core2) |
| 36 | cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom,$(call cc-option,-march=core2,-march=i686)) \ | ||
| 37 | $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic)) | ||
| 36 | 38 | ||
| 37 | # AMD Elan support | 39 | # AMD Elan support |
| 38 | cflags-$(CONFIG_X86_ELAN) += -march=i486 | 40 | cflags-$(CONFIG_X86_ELAN) += -march=i486 |
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index e2ff504b4ddc..f8ed0658404c 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | # create a compressed vmlinux image from the original vmlinux | 4 | # create a compressed vmlinux image from the original vmlinux |
| 5 | # | 5 | # |
| 6 | 6 | ||
| 7 | targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o | 7 | targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o |
| 8 | 8 | ||
| 9 | KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 | 9 | KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 |
| 10 | KBUILD_CFLAGS += -fno-strict-aliasing -fPIC | 10 | KBUILD_CFLAGS += -fno-strict-aliasing -fPIC |
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c index 275dd177f198..11e8c6eb80a1 100644 --- a/arch/x86/boot/video-vesa.c +++ b/arch/x86/boot/video-vesa.c | |||
| @@ -31,7 +31,6 @@ static inline void vesa_store_mode_params_graphics(void) {} | |||
| 31 | 31 | ||
| 32 | static int vesa_probe(void) | 32 | static int vesa_probe(void) |
| 33 | { | 33 | { |
| 34 | #if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID) | ||
| 35 | struct biosregs ireg, oreg; | 34 | struct biosregs ireg, oreg; |
| 36 | u16 mode; | 35 | u16 mode; |
| 37 | addr_t mode_ptr; | 36 | addr_t mode_ptr; |
| @@ -49,8 +48,7 @@ static int vesa_probe(void) | |||
| 49 | vginfo.signature != VESA_MAGIC || | 48 | vginfo.signature != VESA_MAGIC || |
| 50 | vginfo.version < 0x0102) | 49 | vginfo.version < 0x0102) |
| 51 | return 0; /* Not present */ | 50 | return 0; /* Not present */ |
| 52 | #endif /* CONFIG_VIDEO_VESA || CONFIG_FIRMWARE_EDID */ | 51 | |
| 53 | #ifdef CONFIG_VIDEO_VESA | ||
| 54 | set_fs(vginfo.video_mode_ptr.seg); | 52 | set_fs(vginfo.video_mode_ptr.seg); |
| 55 | mode_ptr = vginfo.video_mode_ptr.off; | 53 | mode_ptr = vginfo.video_mode_ptr.off; |
| 56 | 54 | ||
| @@ -102,9 +100,6 @@ static int vesa_probe(void) | |||
| 102 | } | 100 | } |
| 103 | 101 | ||
| 104 | return nmodes; | 102 | return nmodes; |
| 105 | #else | ||
| 106 | return 0; | ||
| 107 | #endif /* CONFIG_VIDEO_VESA */ | ||
| 108 | } | 103 | } |
| 109 | 104 | ||
| 110 | static int vesa_set_mode(struct mode_info *mode) | 105 | static int vesa_set_mode(struct mode_info *mode) |
diff --git a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c index 8f8d827e254d..819caa1f2008 100644 --- a/arch/x86/boot/video-vga.c +++ b/arch/x86/boot/video-vga.c | |||
| @@ -47,14 +47,6 @@ static u8 vga_set_basic_mode(void) | |||
| 47 | 47 | ||
| 48 | initregs(&ireg); | 48 | initregs(&ireg); |
| 49 | 49 | ||
| 50 | #ifdef CONFIG_VIDEO_400_HACK | ||
| 51 | if (adapter >= ADAPTER_VGA) { | ||
| 52 | ireg.ax = 0x1202; | ||
| 53 | ireg.bx = 0x0030; | ||
| 54 | intcall(0x10, &ireg, NULL); | ||
| 55 | } | ||
| 56 | #endif | ||
| 57 | |||
| 58 | ax = 0x0f00; | 50 | ax = 0x0f00; |
| 59 | intcall(0x10, &ireg, &oreg); | 51 | intcall(0x10, &ireg, &oreg); |
| 60 | mode = oreg.al; | 52 | mode = oreg.al; |
| @@ -62,11 +54,9 @@ static u8 vga_set_basic_mode(void) | |||
| 62 | set_fs(0); | 54 | set_fs(0); |
| 63 | rows = rdfs8(0x484); /* rows minus one */ | 55 | rows = rdfs8(0x484); /* rows minus one */ |
| 64 | 56 | ||
| 65 | #ifndef CONFIG_VIDEO_400_HACK | ||
| 66 | if ((oreg.ax == 0x5003 || oreg.ax == 0x5007) && | 57 | if ((oreg.ax == 0x5003 || oreg.ax == 0x5007) && |
| 67 | (rows == 0 || rows == 24)) | 58 | (rows == 0 || rows == 24)) |
| 68 | return mode; | 59 | return mode; |
| 69 | #endif | ||
| 70 | 60 | ||
| 71 | if (mode != 3 && mode != 7) | 61 | if (mode != 3 && mode != 7) |
| 72 | mode = 3; | 62 | mode = 3; |
diff --git a/arch/x86/boot/video.c b/arch/x86/boot/video.c index bad728b76fc2..d42da3802499 100644 --- a/arch/x86/boot/video.c +++ b/arch/x86/boot/video.c | |||
| @@ -221,7 +221,6 @@ static unsigned int mode_menu(void) | |||
| 221 | } | 221 | } |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | #ifdef CONFIG_VIDEO_RETAIN | ||
| 225 | /* Save screen content to the heap */ | 224 | /* Save screen content to the heap */ |
| 226 | static struct saved_screen { | 225 | static struct saved_screen { |
| 227 | int x, y; | 226 | int x, y; |
| @@ -299,10 +298,6 @@ static void restore_screen(void) | |||
| 299 | ireg.dl = saved.curx; | 298 | ireg.dl = saved.curx; |
| 300 | intcall(0x10, &ireg, NULL); | 299 | intcall(0x10, &ireg, NULL); |
| 301 | } | 300 | } |
| 302 | #else | ||
| 303 | #define save_screen() ((void)0) | ||
| 304 | #define restore_screen() ((void)0) | ||
| 305 | #endif | ||
| 306 | 301 | ||
| 307 | void set_video(void) | 302 | void set_video(void) |
| 308 | { | 303 | { |
diff --git a/arch/x86/boot/video.h b/arch/x86/boot/video.h index 5bb174a997fc..ff339c5db311 100644 --- a/arch/x86/boot/video.h +++ b/arch/x86/boot/video.h | |||
| @@ -17,19 +17,8 @@ | |||
| 17 | 17 | ||
| 18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
| 19 | 19 | ||
| 20 | /* Enable autodetection of SVGA adapters and modes. */ | 20 | /* |
| 21 | #undef CONFIG_VIDEO_SVGA | 21 | * This code uses an extended set of video mode numbers. These include: |
| 22 | |||
| 23 | /* Enable autodetection of VESA modes */ | ||
| 24 | #define CONFIG_VIDEO_VESA | ||
| 25 | |||
| 26 | /* Retain screen contents when switching modes */ | ||
| 27 | #define CONFIG_VIDEO_RETAIN | ||
| 28 | |||
| 29 | /* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */ | ||
| 30 | #undef CONFIG_VIDEO_400_HACK | ||
| 31 | |||
| 32 | /* This code uses an extended set of video mode numbers. These include: | ||
| 33 | * Aliases for standard modes | 22 | * Aliases for standard modes |
| 34 | * NORMAL_VGA (-1) | 23 | * NORMAL_VGA (-1) |
| 35 | * EXTENDED_VGA (-2) | 24 | * EXTENDED_VGA (-2) |
| @@ -67,13 +56,8 @@ | |||
| 67 | /* The "recalculate timings" flag */ | 56 | /* The "recalculate timings" flag */ |
| 68 | #define VIDEO_RECALC 0x8000 | 57 | #define VIDEO_RECALC 0x8000 |
| 69 | 58 | ||
| 70 | /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ | ||
| 71 | #ifdef CONFIG_VIDEO_RETAIN | ||
| 72 | void store_screen(void); | 59 | void store_screen(void); |
| 73 | #define DO_STORE() store_screen() | 60 | #define DO_STORE() store_screen() |
| 74 | #else | ||
| 75 | #define DO_STORE() ((void)0) | ||
| 76 | #endif /* CONFIG_VIDEO_RETAIN */ | ||
| 77 | 61 | ||
| 78 | /* | 62 | /* |
| 79 | * Mode table structures | 63 | * Mode table structures |
diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index edb992ebef92..d28fad19654a 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig | |||
| @@ -2355,7 +2355,7 @@ CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y | |||
| 2355 | CONFIG_HAVE_DYNAMIC_FTRACE=y | 2355 | CONFIG_HAVE_DYNAMIC_FTRACE=y |
| 2356 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y | 2356 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y |
| 2357 | CONFIG_HAVE_HW_BRANCH_TRACER=y | 2357 | CONFIG_HAVE_HW_BRANCH_TRACER=y |
| 2358 | CONFIG_HAVE_FTRACE_SYSCALLS=y | 2358 | CONFIG_HAVE_SYSCALL_TRACEPOINTS=y |
| 2359 | CONFIG_RING_BUFFER=y | 2359 | CONFIG_RING_BUFFER=y |
| 2360 | CONFIG_TRACING=y | 2360 | CONFIG_TRACING=y |
| 2361 | CONFIG_TRACING_SUPPORT=y | 2361 | CONFIG_TRACING_SUPPORT=y |
diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index cee1dd2e69b2..6c86acd847a4 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig | |||
| @@ -2329,7 +2329,7 @@ CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y | |||
| 2329 | CONFIG_HAVE_DYNAMIC_FTRACE=y | 2329 | CONFIG_HAVE_DYNAMIC_FTRACE=y |
| 2330 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y | 2330 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y |
| 2331 | CONFIG_HAVE_HW_BRANCH_TRACER=y | 2331 | CONFIG_HAVE_HW_BRANCH_TRACER=y |
| 2332 | CONFIG_HAVE_FTRACE_SYSCALLS=y | 2332 | CONFIG_HAVE_SYSCALL_TRACEPOINTS=y |
| 2333 | CONFIG_RING_BUFFER=y | 2333 | CONFIG_RING_BUFFER=y |
| 2334 | CONFIG_TRACING=y | 2334 | CONFIG_TRACING=y |
| 2335 | CONFIG_TRACING_SUPPORT=y | 2335 | CONFIG_TRACING_SUPPORT=y |
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index c580c5ec1cad..585edebe12cf 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c | |||
| @@ -59,13 +59,6 @@ asmlinkage void aesni_cbc_enc(struct crypto_aes_ctx *ctx, u8 *out, | |||
| 59 | asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out, | 59 | asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out, |
| 60 | const u8 *in, unsigned int len, u8 *iv); | 60 | const u8 *in, unsigned int len, u8 *iv); |
| 61 | 61 | ||
| 62 | static inline int kernel_fpu_using(void) | ||
| 63 | { | ||
| 64 | if (in_interrupt() && !(read_cr0() & X86_CR0_TS)) | ||
| 65 | return 1; | ||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx) | 62 | static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx) |
| 70 | { | 63 | { |
| 71 | unsigned long addr = (unsigned long)raw_ctx; | 64 | unsigned long addr = (unsigned long)raw_ctx; |
| @@ -89,7 +82,7 @@ static int aes_set_key_common(struct crypto_tfm *tfm, void *raw_ctx, | |||
| 89 | return -EINVAL; | 82 | return -EINVAL; |
| 90 | } | 83 | } |
| 91 | 84 | ||
| 92 | if (kernel_fpu_using()) | 85 | if (irq_fpu_usable()) |
| 93 | err = crypto_aes_expand_key(ctx, in_key, key_len); | 86 | err = crypto_aes_expand_key(ctx, in_key, key_len); |
| 94 | else { | 87 | else { |
| 95 | kernel_fpu_begin(); | 88 | kernel_fpu_begin(); |
| @@ -110,7 +103,7 @@ static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | |||
| 110 | { | 103 | { |
| 111 | struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm)); | 104 | struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm)); |
| 112 | 105 | ||
| 113 | if (kernel_fpu_using()) | 106 | if (irq_fpu_usable()) |
| 114 | crypto_aes_encrypt_x86(ctx, dst, src); | 107 | crypto_aes_encrypt_x86(ctx, dst, src); |
| 115 | else { | 108 | else { |
| 116 | kernel_fpu_begin(); | 109 | kernel_fpu_begin(); |
| @@ -123,7 +116,7 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | |||
| 123 | { | 116 | { |
| 124 | struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm)); | 117 | struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm)); |
| 125 | 118 | ||
| 126 | if (kernel_fpu_using()) | 119 | if (irq_fpu_usable()) |
| 127 | crypto_aes_decrypt_x86(ctx, dst, src); | 120 | crypto_aes_decrypt_x86(ctx, dst, src); |
| 128 | else { | 121 | else { |
| 129 | kernel_fpu_begin(); | 122 | kernel_fpu_begin(); |
| @@ -349,7 +342,7 @@ static int ablk_encrypt(struct ablkcipher_request *req) | |||
| 349 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); | 342 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); |
| 350 | struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); | 343 | struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); |
| 351 | 344 | ||
| 352 | if (kernel_fpu_using()) { | 345 | if (irq_fpu_usable()) { |
| 353 | struct ablkcipher_request *cryptd_req = | 346 | struct ablkcipher_request *cryptd_req = |
| 354 | ablkcipher_request_ctx(req); | 347 | ablkcipher_request_ctx(req); |
| 355 | memcpy(cryptd_req, req, sizeof(*req)); | 348 | memcpy(cryptd_req, req, sizeof(*req)); |
| @@ -370,7 +363,7 @@ static int ablk_decrypt(struct ablkcipher_request *req) | |||
| 370 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); | 363 | struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); |
| 371 | struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); | 364 | struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); |
| 372 | 365 | ||
| 373 | if (kernel_fpu_using()) { | 366 | if (irq_fpu_usable()) { |
| 374 | struct ablkcipher_request *cryptd_req = | 367 | struct ablkcipher_request *cryptd_req = |
| 375 | ablkcipher_request_ctx(req); | 368 | ablkcipher_request_ctx(req); |
| 376 | memcpy(cryptd_req, req, sizeof(*req)); | 369 | memcpy(cryptd_req, req, sizeof(*req)); |
| @@ -636,7 +629,7 @@ static int __init aesni_init(void) | |||
| 636 | int err; | 629 | int err; |
| 637 | 630 | ||
| 638 | if (!cpu_has_aes) { | 631 | if (!cpu_has_aes) { |
| 639 | printk(KERN_ERR "Intel AES-NI instructions are not detected.\n"); | 632 | printk(KERN_INFO "Intel AES-NI instructions are not detected.\n"); |
| 640 | return -ENODEV; | 633 | return -ENODEV; |
| 641 | } | 634 | } |
| 642 | if ((err = crypto_register_alg(&aesni_alg))) | 635 | if ((err = crypto_register_alg(&aesni_alg))) |
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index e590261ba059..ba331bfd1112 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S | |||
| @@ -537,7 +537,7 @@ ia32_sys_call_table: | |||
| 537 | .quad sys_mkdir | 537 | .quad sys_mkdir |
| 538 | .quad sys_rmdir /* 40 */ | 538 | .quad sys_rmdir /* 40 */ |
| 539 | .quad sys_dup | 539 | .quad sys_dup |
| 540 | .quad sys32_pipe | 540 | .quad sys_pipe |
| 541 | .quad compat_sys_times | 541 | .quad compat_sys_times |
| 542 | .quad quiet_ni_syscall /* old prof syscall holder */ | 542 | .quad quiet_ni_syscall /* old prof syscall holder */ |
| 543 | .quad sys_brk /* 45 */ | 543 | .quad sys_brk /* 45 */ |
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index 085a8c35f149..9f5527198825 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c | |||
| @@ -189,20 +189,6 @@ asmlinkage long sys32_mprotect(unsigned long start, size_t len, | |||
| 189 | return sys_mprotect(start, len, prot); | 189 | return sys_mprotect(start, len, prot); |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | asmlinkage long sys32_pipe(int __user *fd) | ||
| 193 | { | ||
| 194 | int retval; | ||
| 195 | int fds[2]; | ||
| 196 | |||
| 197 | retval = do_pipe_flags(fds, 0); | ||
| 198 | if (retval) | ||
| 199 | goto out; | ||
| 200 | if (copy_to_user(fd, fds, sizeof(fds))) | ||
| 201 | retval = -EFAULT; | ||
| 202 | out: | ||
| 203 | return retval; | ||
| 204 | } | ||
| 205 | |||
| 206 | asmlinkage long sys32_rt_sigaction(int sig, struct sigaction32 __user *act, | 192 | asmlinkage long sys32_rt_sigaction(int sig, struct sigaction32 __user *act, |
| 207 | struct sigaction32 __user *oact, | 193 | struct sigaction32 __user *oact, |
| 208 | unsigned int sigsetsize) | 194 | unsigned int sigsetsize) |
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 1a37bcdc8606..c240efc74e00 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h | |||
| @@ -73,8 +73,6 @@ static inline void alternatives_smp_module_del(struct module *mod) {} | |||
| 73 | static inline void alternatives_smp_switch(int smp) {} | 73 | static inline void alternatives_smp_switch(int smp) {} |
| 74 | #endif /* CONFIG_SMP */ | 74 | #endif /* CONFIG_SMP */ |
| 75 | 75 | ||
| 76 | const unsigned char *const *find_nop_table(void); | ||
| 77 | |||
| 78 | /* alternative assembly primitive: */ | 76 | /* alternative assembly primitive: */ |
| 79 | #define ALTERNATIVE(oldinstr, newinstr, feature) \ | 77 | #define ALTERNATIVE(oldinstr, newinstr, feature) \ |
| 80 | \ | 78 | \ |
| @@ -144,8 +142,6 @@ static inline void apply_paravirt(struct paravirt_patch_site *start, | |||
| 144 | #define __parainstructions_end NULL | 142 | #define __parainstructions_end NULL |
| 145 | #endif | 143 | #endif |
| 146 | 144 | ||
| 147 | extern void add_nops(void *insns, unsigned int len); | ||
| 148 | |||
| 149 | /* | 145 | /* |
| 150 | * Clear and restore the kernel write-protection flag on the local CPU. | 146 | * Clear and restore the kernel write-protection flag on the local CPU. |
| 151 | * Allows the kernel to edit read-only pages. | 147 | * Allows the kernel to edit read-only pages. |
| @@ -161,10 +157,7 @@ extern void add_nops(void *insns, unsigned int len); | |||
| 161 | * Intel's errata. | 157 | * Intel's errata. |
| 162 | * On the local CPU you need to be protected again NMI or MCE handlers seeing an | 158 | * On the local CPU you need to be protected again NMI or MCE handlers seeing an |
| 163 | * inconsistent instruction while you patch. | 159 | * inconsistent instruction while you patch. |
| 164 | * The _early version expects the memory to already be RW. | ||
| 165 | */ | 160 | */ |
| 166 | |||
| 167 | extern void *text_poke(void *addr, const void *opcode, size_t len); | 161 | extern void *text_poke(void *addr, const void *opcode, size_t len); |
| 168 | extern void *text_poke_early(void *addr, const void *opcode, size_t len); | ||
| 169 | 162 | ||
| 170 | #endif /* _ASM_X86_ALTERNATIVE_H */ | 163 | #endif /* _ASM_X86_ALTERNATIVE_H */ |
diff --git a/arch/x86/include/asm/amd_iommu.h b/arch/x86/include/asm/amd_iommu.h index bdf96f119f06..ac95995b7bad 100644 --- a/arch/x86/include/asm/amd_iommu.h +++ b/arch/x86/include/asm/amd_iommu.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #ifdef CONFIG_AMD_IOMMU | 25 | #ifdef CONFIG_AMD_IOMMU |
| 26 | extern int amd_iommu_init(void); | 26 | extern int amd_iommu_init(void); |
| 27 | extern int amd_iommu_init_dma_ops(void); | 27 | extern int amd_iommu_init_dma_ops(void); |
| 28 | extern int amd_iommu_init_passthrough(void); | ||
| 28 | extern void amd_iommu_detect(void); | 29 | extern void amd_iommu_detect(void); |
| 29 | extern irqreturn_t amd_iommu_int_handler(int irq, void *data); | 30 | extern irqreturn_t amd_iommu_int_handler(int irq, void *data); |
| 30 | extern void amd_iommu_flush_all_domains(void); | 31 | extern void amd_iommu_flush_all_domains(void); |
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index 0c878caaa0a2..2a2cc7a78a81 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h | |||
| @@ -143,22 +143,29 @@ | |||
| 143 | #define EVT_BUFFER_SIZE 8192 /* 512 entries */ | 143 | #define EVT_BUFFER_SIZE 8192 /* 512 entries */ |
| 144 | #define EVT_LEN_MASK (0x9ULL << 56) | 144 | #define EVT_LEN_MASK (0x9ULL << 56) |
| 145 | 145 | ||
| 146 | #define PAGE_MODE_NONE 0x00 | ||
| 146 | #define PAGE_MODE_1_LEVEL 0x01 | 147 | #define PAGE_MODE_1_LEVEL 0x01 |
| 147 | #define PAGE_MODE_2_LEVEL 0x02 | 148 | #define PAGE_MODE_2_LEVEL 0x02 |
| 148 | #define PAGE_MODE_3_LEVEL 0x03 | 149 | #define PAGE_MODE_3_LEVEL 0x03 |
| 149 | 150 | #define PAGE_MODE_4_LEVEL 0x04 | |
| 150 | #define IOMMU_PDE_NL_0 0x000ULL | 151 | #define PAGE_MODE_5_LEVEL 0x05 |
| 151 | #define IOMMU_PDE_NL_1 0x200ULL | 152 | #define PAGE_MODE_6_LEVEL 0x06 |
| 152 | #define IOMMU_PDE_NL_2 0x400ULL | 153 | |
| 153 | #define IOMMU_PDE_NL_3 0x600ULL | 154 | #define PM_LEVEL_SHIFT(x) (12 + ((x) * 9)) |
| 154 | 155 | #define PM_LEVEL_SIZE(x) (((x) < 6) ? \ | |
| 155 | #define IOMMU_PTE_L2_INDEX(address) (((address) >> 30) & 0x1ffULL) | 156 | ((1ULL << PM_LEVEL_SHIFT((x))) - 1): \ |
| 156 | #define IOMMU_PTE_L1_INDEX(address) (((address) >> 21) & 0x1ffULL) | 157 | (0xffffffffffffffffULL)) |
| 157 | #define IOMMU_PTE_L0_INDEX(address) (((address) >> 12) & 0x1ffULL) | 158 | #define PM_LEVEL_INDEX(x, a) (((a) >> PM_LEVEL_SHIFT((x))) & 0x1ffULL) |
| 158 | 159 | #define PM_LEVEL_ENC(x) (((x) << 9) & 0xe00ULL) | |
| 159 | #define IOMMU_MAP_SIZE_L1 (1ULL << 21) | 160 | #define PM_LEVEL_PDE(x, a) ((a) | PM_LEVEL_ENC((x)) | \ |
| 160 | #define IOMMU_MAP_SIZE_L2 (1ULL << 30) | 161 | IOMMU_PTE_P | IOMMU_PTE_IR | IOMMU_PTE_IW) |
| 161 | #define IOMMU_MAP_SIZE_L3 (1ULL << 39) | 162 | #define PM_PTE_LEVEL(pte) (((pte) >> 9) & 0x7ULL) |
| 163 | |||
| 164 | #define PM_MAP_4k 0 | ||
| 165 | #define PM_ADDR_MASK 0x000ffffffffff000ULL | ||
| 166 | #define PM_MAP_MASK(lvl) (PM_ADDR_MASK & \ | ||
| 167 | (~((1ULL << (12 + ((lvl) * 9))) - 1))) | ||
| 168 | #define PM_ALIGNED(lvl, addr) ((PM_MAP_MASK(lvl) & (addr)) == (addr)) | ||
| 162 | 169 | ||
| 163 | #define IOMMU_PTE_P (1ULL << 0) | 170 | #define IOMMU_PTE_P (1ULL << 0) |
| 164 | #define IOMMU_PTE_TV (1ULL << 1) | 171 | #define IOMMU_PTE_TV (1ULL << 1) |
| @@ -167,11 +174,6 @@ | |||
| 167 | #define IOMMU_PTE_IR (1ULL << 61) | 174 | #define IOMMU_PTE_IR (1ULL << 61) |
| 168 | #define IOMMU_PTE_IW (1ULL << 62) | 175 | #define IOMMU_PTE_IW (1ULL << 62) |
| 169 | 176 | ||
| 170 | #define IOMMU_L1_PDE(address) \ | ||
| 171 | ((address) | IOMMU_PDE_NL_1 | IOMMU_PTE_P | IOMMU_PTE_IR | IOMMU_PTE_IW) | ||
| 172 | #define IOMMU_L2_PDE(address) \ | ||
| 173 | ((address) | IOMMU_PDE_NL_2 | IOMMU_PTE_P | IOMMU_PTE_IR | IOMMU_PTE_IW) | ||
| 174 | |||
| 175 | #define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL) | 177 | #define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL) |
| 176 | #define IOMMU_PTE_PRESENT(pte) ((pte) & IOMMU_PTE_P) | 178 | #define IOMMU_PTE_PRESENT(pte) ((pte) & IOMMU_PTE_P) |
| 177 | #define IOMMU_PTE_PAGE(pte) (phys_to_virt((pte) & IOMMU_PAGE_MASK)) | 179 | #define IOMMU_PTE_PAGE(pte) (phys_to_virt((pte) & IOMMU_PAGE_MASK)) |
| @@ -194,11 +196,14 @@ | |||
| 194 | #define PD_DMA_OPS_MASK (1UL << 0) /* domain used for dma_ops */ | 196 | #define PD_DMA_OPS_MASK (1UL << 0) /* domain used for dma_ops */ |
| 195 | #define PD_DEFAULT_MASK (1UL << 1) /* domain is a default dma_ops | 197 | #define PD_DEFAULT_MASK (1UL << 1) /* domain is a default dma_ops |
| 196 | domain for an IOMMU */ | 198 | domain for an IOMMU */ |
| 199 | #define PD_PASSTHROUGH_MASK (1UL << 2) /* domain has no page | ||
| 200 | translation */ | ||
| 201 | |||
| 197 | extern bool amd_iommu_dump; | 202 | extern bool amd_iommu_dump; |
| 198 | #define DUMP_printk(format, arg...) \ | 203 | #define DUMP_printk(format, arg...) \ |
| 199 | do { \ | 204 | do { \ |
| 200 | if (amd_iommu_dump) \ | 205 | if (amd_iommu_dump) \ |
| 201 | printk(KERN_INFO "AMD IOMMU: " format, ## arg); \ | 206 | printk(KERN_INFO "AMD-Vi: " format, ## arg); \ |
| 202 | } while(0); | 207 | } while(0); |
| 203 | 208 | ||
| 204 | /* | 209 | /* |
| @@ -226,6 +231,7 @@ struct protection_domain { | |||
| 226 | int mode; /* paging mode (0-6 levels) */ | 231 | int mode; /* paging mode (0-6 levels) */ |
| 227 | u64 *pt_root; /* page table root pointer */ | 232 | u64 *pt_root; /* page table root pointer */ |
| 228 | unsigned long flags; /* flags to find out type of domain */ | 233 | unsigned long flags; /* flags to find out type of domain */ |
| 234 | bool updated; /* complete domain flush required */ | ||
| 229 | unsigned dev_cnt; /* devices assigned to this domain */ | 235 | unsigned dev_cnt; /* devices assigned to this domain */ |
| 230 | void *priv; /* private data */ | 236 | void *priv; /* private data */ |
| 231 | }; | 237 | }; |
| @@ -337,6 +343,9 @@ struct amd_iommu { | |||
| 337 | /* if one, we need to send a completion wait command */ | 343 | /* if one, we need to send a completion wait command */ |
| 338 | bool need_sync; | 344 | bool need_sync; |
| 339 | 345 | ||
| 346 | /* becomes true if a command buffer reset is running */ | ||
| 347 | bool reset_in_progress; | ||
| 348 | |||
| 340 | /* default dma_ops domain for that IOMMU */ | 349 | /* default dma_ops domain for that IOMMU */ |
| 341 | struct dma_ops_domain *default_dom; | 350 | struct dma_ops_domain *default_dom; |
| 342 | }; | 351 | }; |
| @@ -457,4 +466,7 @@ static inline void amd_iommu_stats_init(void) { } | |||
| 457 | 466 | ||
| 458 | #endif /* CONFIG_AMD_IOMMU_STATS */ | 467 | #endif /* CONFIG_AMD_IOMMU_STATS */ |
| 459 | 468 | ||
| 469 | /* some function prototypes */ | ||
| 470 | extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu); | ||
| 471 | |||
| 460 | #endif /* _ASM_X86_AMD_IOMMU_TYPES_H */ | 472 | #endif /* _ASM_X86_AMD_IOMMU_TYPES_H */ |
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index bb7d47925847..586b7adb8e53 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
| @@ -183,6 +183,10 @@ static inline int x2apic_enabled(void) | |||
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | #define x2apic_supported() (cpu_has_x2apic) | 185 | #define x2apic_supported() (cpu_has_x2apic) |
| 186 | static inline void x2apic_force_phys(void) | ||
| 187 | { | ||
| 188 | x2apic_phys = 1; | ||
| 189 | } | ||
| 186 | #else | 190 | #else |
| 187 | static inline void check_x2apic(void) | 191 | static inline void check_x2apic(void) |
| 188 | { | 192 | { |
| @@ -194,6 +198,9 @@ static inline int x2apic_enabled(void) | |||
| 194 | { | 198 | { |
| 195 | return 0; | 199 | return 0; |
| 196 | } | 200 | } |
| 201 | static inline void x2apic_force_phys(void) | ||
| 202 | { | ||
| 203 | } | ||
| 197 | 204 | ||
| 198 | #define x2apic_preenabled 0 | 205 | #define x2apic_preenabled 0 |
| 199 | #define x2apic_supported() 0 | 206 | #define x2apic_supported() 0 |
diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h index 7ddb36ab933b..3b62da926de9 100644 --- a/arch/x86/include/asm/apicdef.h +++ b/arch/x86/include/asm/apicdef.h | |||
| @@ -8,12 +8,14 @@ | |||
| 8 | * Ingo Molnar <mingo@redhat.com>, 1999, 2000 | 8 | * Ingo Molnar <mingo@redhat.com>, 1999, 2000 |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #define APIC_DEFAULT_PHYS_BASE 0xfee00000 | 11 | #define IO_APIC_DEFAULT_PHYS_BASE 0xfec00000 |
| 12 | #define APIC_DEFAULT_PHYS_BASE 0xfee00000 | ||
| 12 | 13 | ||
| 13 | #define APIC_ID 0x20 | 14 | #define APIC_ID 0x20 |
| 14 | 15 | ||
| 15 | #define APIC_LVR 0x30 | 16 | #define APIC_LVR 0x30 |
| 16 | #define APIC_LVR_MASK 0xFF00FF | 17 | #define APIC_LVR_MASK 0xFF00FF |
| 18 | #define APIC_LVR_DIRECTED_EOI (1 << 24) | ||
| 17 | #define GET_APIC_VERSION(x) ((x) & 0xFFu) | 19 | #define GET_APIC_VERSION(x) ((x) & 0xFFu) |
| 18 | #define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFFu) | 20 | #define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFFu) |
| 19 | #ifdef CONFIG_X86_32 | 21 | #ifdef CONFIG_X86_32 |
| @@ -40,6 +42,7 @@ | |||
| 40 | #define APIC_DFR_CLUSTER 0x0FFFFFFFul | 42 | #define APIC_DFR_CLUSTER 0x0FFFFFFFul |
| 41 | #define APIC_DFR_FLAT 0xFFFFFFFFul | 43 | #define APIC_DFR_FLAT 0xFFFFFFFFul |
| 42 | #define APIC_SPIV 0xF0 | 44 | #define APIC_SPIV 0xF0 |
| 45 | #define APIC_SPIV_DIRECTED_EOI (1 << 12) | ||
| 43 | #define APIC_SPIV_FOCUS_DISABLED (1 << 9) | 46 | #define APIC_SPIV_FOCUS_DISABLED (1 << 9) |
| 44 | #define APIC_SPIV_APIC_ENABLED (1 << 8) | 47 | #define APIC_SPIV_APIC_ENABLED (1 << 8) |
| 45 | #define APIC_ISR 0x100 | 48 | #define APIC_ISR 0x100 |
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h index 56be78f582f0..b3ed1e1460ff 100644 --- a/arch/x86/include/asm/asm.h +++ b/arch/x86/include/asm/asm.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #ifdef __ASSEMBLY__ | 4 | #ifdef __ASSEMBLY__ |
| 5 | # define __ASM_FORM(x) x | 5 | # define __ASM_FORM(x) x |
| 6 | # define __ASM_EX_SEC .section __ex_table | 6 | # define __ASM_EX_SEC .section __ex_table, "a" |
| 7 | #else | 7 | #else |
| 8 | # define __ASM_FORM(x) " " #x " " | 8 | # define __ASM_FORM(x) " " #x " " |
| 9 | # define __ASM_EX_SEC " .section __ex_table,\"a\"\n" | 9 | # define __ASM_EX_SEC " .section __ex_table,\"a\"\n" |
| @@ -38,10 +38,18 @@ | |||
| 38 | #define _ASM_DI __ASM_REG(di) | 38 | #define _ASM_DI __ASM_REG(di) |
| 39 | 39 | ||
| 40 | /* Exception table entry */ | 40 | /* Exception table entry */ |
| 41 | #ifdef __ASSEMBLY__ | ||
| 42 | # define _ASM_EXTABLE(from,to) \ | ||
| 43 | __ASM_EX_SEC ; \ | ||
| 44 | _ASM_ALIGN ; \ | ||
| 45 | _ASM_PTR from , to ; \ | ||
| 46 | .previous | ||
| 47 | #else | ||
| 41 | # define _ASM_EXTABLE(from,to) \ | 48 | # define _ASM_EXTABLE(from,to) \ |
| 42 | __ASM_EX_SEC \ | 49 | __ASM_EX_SEC \ |
| 43 | _ASM_ALIGN "\n" \ | 50 | _ASM_ALIGN "\n" \ |
| 44 | _ASM_PTR #from "," #to "\n" \ | 51 | _ASM_PTR #from "," #to "\n" \ |
| 45 | " .previous\n" | 52 | " .previous\n" |
| 53 | #endif | ||
| 46 | 54 | ||
| 47 | #endif /* _ASM_X86_ASM_H */ | 55 | #endif /* _ASM_X86_ASM_H */ |
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 4a28d22d4793..847fee6493a2 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
| @@ -95,6 +95,7 @@ | |||
| 95 | #define X86_FEATURE_NONSTOP_TSC (3*32+24) /* TSC does not stop in C states */ | 95 | #define X86_FEATURE_NONSTOP_TSC (3*32+24) /* TSC does not stop in C states */ |
| 96 | #define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */ | 96 | #define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */ |
| 97 | #define X86_FEATURE_EXTD_APICID (3*32+26) /* has extended APICID (8 bits) */ | 97 | #define X86_FEATURE_EXTD_APICID (3*32+26) /* has extended APICID (8 bits) */ |
| 98 | #define X86_FEATURE_AMD_DCM (3*32+27) /* multi-node processor */ | ||
| 98 | 99 | ||
| 99 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ | 100 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ |
| 100 | #define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */ | 101 | #define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */ |
diff --git a/arch/x86/include/asm/current.h b/arch/x86/include/asm/current.h index c68c361697e1..4d447b732d82 100644 --- a/arch/x86/include/asm/current.h +++ b/arch/x86/include/asm/current.h | |||
| @@ -11,7 +11,7 @@ DECLARE_PER_CPU(struct task_struct *, current_task); | |||
| 11 | 11 | ||
| 12 | static __always_inline struct task_struct *get_current(void) | 12 | static __always_inline struct task_struct *get_current(void) |
| 13 | { | 13 | { |
| 14 | return percpu_read(current_task); | 14 | return percpu_read_stable(current_task); |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | #define current get_current() | 17 | #define current get_current() |
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index c993e9e0fed4..e8de2f6f5ca5 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h | |||
| @@ -291,11 +291,24 @@ static inline unsigned long get_desc_base(const struct desc_struct *desc) | |||
| 291 | return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24); | 291 | return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24); |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | static inline void set_desc_base(struct desc_struct *desc, unsigned long base) | ||
| 295 | { | ||
| 296 | desc->base0 = base & 0xffff; | ||
| 297 | desc->base1 = (base >> 16) & 0xff; | ||
| 298 | desc->base2 = (base >> 24) & 0xff; | ||
| 299 | } | ||
| 300 | |||
| 294 | static inline unsigned long get_desc_limit(const struct desc_struct *desc) | 301 | static inline unsigned long get_desc_limit(const struct desc_struct *desc) |
| 295 | { | 302 | { |
| 296 | return desc->limit0 | (desc->limit << 16); | 303 | return desc->limit0 | (desc->limit << 16); |
| 297 | } | 304 | } |
| 298 | 305 | ||
| 306 | static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit) | ||
| 307 | { | ||
| 308 | desc->limit0 = limit & 0xffff; | ||
| 309 | desc->limit = (limit >> 16) & 0xf; | ||
| 310 | } | ||
| 311 | |||
| 299 | static inline void _set_gate(int gate, unsigned type, void *addr, | 312 | static inline void _set_gate(int gate, unsigned type, void *addr, |
| 300 | unsigned dpl, unsigned ist, unsigned seg) | 313 | unsigned dpl, unsigned ist, unsigned seg) |
| 301 | { | 314 | { |
diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h index a6adefa28b94..9d6684849fd9 100644 --- a/arch/x86/include/asm/desc_defs.h +++ b/arch/x86/include/asm/desc_defs.h | |||
| @@ -34,6 +34,12 @@ struct desc_struct { | |||
| 34 | }; | 34 | }; |
| 35 | } __attribute__((packed)); | 35 | } __attribute__((packed)); |
| 36 | 36 | ||
| 37 | #define GDT_ENTRY_INIT(flags, base, limit) { { { \ | ||
| 38 | .a = ((limit) & 0xffff) | (((base) & 0xffff) << 16), \ | ||
| 39 | .b = (((base) & 0xff0000) >> 16) | (((flags) & 0xf0ff) << 8) | \ | ||
| 40 | ((limit) & 0xf0000) | ((base) & 0xff000000), \ | ||
| 41 | } } } | ||
| 42 | |||
| 37 | enum { | 43 | enum { |
| 38 | GATE_INTERRUPT = 0xE, | 44 | GATE_INTERRUPT = 0xE, |
| 39 | GATE_TRAP = 0xF, | 45 | GATE_TRAP = 0xF, |
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index 1c3f9435f1c9..0ee770d23d0e 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h | |||
| @@ -55,6 +55,24 @@ extern int dma_set_mask(struct device *dev, u64 mask); | |||
| 55 | extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, | 55 | extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, |
| 56 | dma_addr_t *dma_addr, gfp_t flag); | 56 | dma_addr_t *dma_addr, gfp_t flag); |
| 57 | 57 | ||
| 58 | static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) | ||
| 59 | { | ||
| 60 | if (!dev->dma_mask) | ||
| 61 | return 0; | ||
| 62 | |||
| 63 | return addr + size <= *dev->dma_mask; | ||
| 64 | } | ||
| 65 | |||
| 66 | static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) | ||
| 67 | { | ||
| 68 | return paddr; | ||
| 69 | } | ||
| 70 | |||
| 71 | static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) | ||
| 72 | { | ||
| 73 | return daddr; | ||
| 74 | } | ||
| 75 | |||
| 58 | static inline void | 76 | static inline void |
| 59 | dma_cache_sync(struct device *dev, void *vaddr, size_t size, | 77 | dma_cache_sync(struct device *dev, void *vaddr, size_t size, |
| 60 | enum dma_data_direction dir) | 78 | enum dma_data_direction dir) |
diff --git a/arch/x86/include/asm/dwarf2.h b/arch/x86/include/asm/dwarf2.h index 3afc5e87cfdd..ae6253ab9029 100644 --- a/arch/x86/include/asm/dwarf2.h +++ b/arch/x86/include/asm/dwarf2.h | |||
| @@ -87,9 +87,25 @@ | |||
| 87 | CFI_RESTORE \reg | 87 | CFI_RESTORE \reg |
| 88 | .endm | 88 | .endm |
| 89 | #else /*!CONFIG_X86_64*/ | 89 | #else /*!CONFIG_X86_64*/ |
| 90 | .macro pushl_cfi reg | ||
| 91 | pushl \reg | ||
| 92 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 93 | .endm | ||
| 90 | 94 | ||
| 91 | /* 32bit defenitions are missed yet */ | 95 | .macro popl_cfi reg |
| 96 | popl \reg | ||
| 97 | CFI_ADJUST_CFA_OFFSET -4 | ||
| 98 | .endm | ||
| 92 | 99 | ||
| 100 | .macro movl_cfi reg offset=0 | ||
| 101 | movl %\reg, \offset(%esp) | ||
| 102 | CFI_REL_OFFSET \reg, \offset | ||
| 103 | .endm | ||
| 104 | |||
| 105 | .macro movl_cfi_restore offset reg | ||
| 106 | movl \offset(%esp), %\reg | ||
| 107 | CFI_RESTORE \reg | ||
| 108 | .endm | ||
| 93 | #endif /*!CONFIG_X86_64*/ | 109 | #endif /*!CONFIG_X86_64*/ |
| 94 | #endif /*__ASSEMBLY__*/ | 110 | #endif /*__ASSEMBLY__*/ |
| 95 | 111 | ||
diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h index bd2c6511c887..db24c2278be0 100644 --- a/arch/x86/include/asm/ftrace.h +++ b/arch/x86/include/asm/ftrace.h | |||
| @@ -28,13 +28,6 @@ | |||
| 28 | 28 | ||
| 29 | #endif | 29 | #endif |
| 30 | 30 | ||
| 31 | /* FIXME: I don't want to stay hardcoded */ | ||
| 32 | #ifdef CONFIG_X86_64 | ||
| 33 | # define FTRACE_SYSCALL_MAX 296 | ||
| 34 | #else | ||
| 35 | # define FTRACE_SYSCALL_MAX 333 | ||
| 36 | #endif | ||
| 37 | |||
| 38 | #ifdef CONFIG_FUNCTION_TRACER | 31 | #ifdef CONFIG_FUNCTION_TRACER |
| 39 | #define MCOUNT_ADDR ((long)(mcount)) | 32 | #define MCOUNT_ADDR ((long)(mcount)) |
| 40 | #define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */ | 33 | #define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */ |
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h index 175adf58dd4f..0b20bbb758f2 100644 --- a/arch/x86/include/asm/i387.h +++ b/arch/x86/include/asm/i387.h | |||
| @@ -26,6 +26,7 @@ extern void fpu_init(void); | |||
| 26 | extern void mxcsr_feature_mask_init(void); | 26 | extern void mxcsr_feature_mask_init(void); |
| 27 | extern int init_fpu(struct task_struct *child); | 27 | extern int init_fpu(struct task_struct *child); |
| 28 | extern asmlinkage void math_state_restore(void); | 28 | extern asmlinkage void math_state_restore(void); |
| 29 | extern void __math_state_restore(void); | ||
| 29 | extern void init_thread_xstate(void); | 30 | extern void init_thread_xstate(void); |
| 30 | extern int dump_fpu(struct pt_regs *, struct user_i387_struct *); | 31 | extern int dump_fpu(struct pt_regs *, struct user_i387_struct *); |
| 31 | 32 | ||
| @@ -301,6 +302,14 @@ static inline void kernel_fpu_end(void) | |||
| 301 | preempt_enable(); | 302 | preempt_enable(); |
| 302 | } | 303 | } |
| 303 | 304 | ||
| 305 | static inline bool irq_fpu_usable(void) | ||
| 306 | { | ||
| 307 | struct pt_regs *regs; | ||
| 308 | |||
| 309 | return !in_interrupt() || !(regs = get_irq_regs()) || \ | ||
| 310 | user_mode(regs) || (read_cr0() & X86_CR0_TS); | ||
| 311 | } | ||
| 312 | |||
| 304 | /* | 313 | /* |
| 305 | * Some instructions like VIA's padlock instructions generate a spurious | 314 | * Some instructions like VIA's padlock instructions generate a spurious |
| 306 | * DNA fault but don't modify SSE registers. And these instructions | 315 | * DNA fault but don't modify SSE registers. And these instructions |
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 330ee807f89e..85232d32fcb8 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h | |||
| @@ -150,11 +150,10 @@ extern int timer_through_8259; | |||
| 150 | #define io_apic_assign_pci_irqs \ | 150 | #define io_apic_assign_pci_irqs \ |
| 151 | (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) | 151 | (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) |
| 152 | 152 | ||
| 153 | #ifdef CONFIG_ACPI | 153 | extern u8 io_apic_unique_id(u8 id); |
| 154 | extern int io_apic_get_unique_id(int ioapic, int apic_id); | 154 | extern int io_apic_get_unique_id(int ioapic, int apic_id); |
| 155 | extern int io_apic_get_version(int ioapic); | 155 | extern int io_apic_get_version(int ioapic); |
| 156 | extern int io_apic_get_redir_entries(int ioapic); | 156 | extern int io_apic_get_redir_entries(int ioapic); |
| 157 | #endif /* CONFIG_ACPI */ | ||
| 158 | 157 | ||
| 159 | struct io_apic_irq_attr; | 158 | struct io_apic_irq_attr; |
| 160 | extern int io_apic_set_pci_routing(struct device *dev, int irq, | 159 | extern int io_apic_set_pci_routing(struct device *dev, int irq, |
| @@ -177,6 +176,16 @@ extern int setup_ioapic_entry(int apic, int irq, | |||
| 177 | int polarity, int vector, int pin); | 176 | int polarity, int vector, int pin); |
| 178 | extern void ioapic_write_entry(int apic, int pin, | 177 | extern void ioapic_write_entry(int apic, int pin, |
| 179 | struct IO_APIC_route_entry e); | 178 | struct IO_APIC_route_entry e); |
| 179 | |||
| 180 | struct mp_ioapic_gsi{ | ||
| 181 | int gsi_base; | ||
| 182 | int gsi_end; | ||
| 183 | }; | ||
| 184 | extern struct mp_ioapic_gsi mp_gsi_routing[]; | ||
| 185 | int mp_find_ioapic(int gsi); | ||
| 186 | int mp_find_ioapic_pin(int ioapic, int gsi); | ||
| 187 | void __init mp_register_ioapic(int id, u32 address, u32 gsi_base); | ||
| 188 | |||
| 180 | #else /* !CONFIG_X86_IO_APIC */ | 189 | #else /* !CONFIG_X86_IO_APIC */ |
| 181 | #define io_apic_assign_pci_irqs 0 | 190 | #define io_apic_assign_pci_irqs 0 |
| 182 | static const int timer_through_8259 = 0; | 191 | static const int timer_through_8259 = 0; |
diff --git a/arch/x86/include/asm/ioctls.h b/arch/x86/include/asm/ioctls.h index 0d5b23b7b06e..ec34c760665e 100644 --- a/arch/x86/include/asm/ioctls.h +++ b/arch/x86/include/asm/ioctls.h | |||
| @@ -1,94 +1 @@ | |||
| 1 | #ifndef _ASM_X86_IOCTLS_H | #include <asm-generic/ioctls.h> | |
| 2 | #define _ASM_X86_IOCTLS_H | ||
| 3 | |||
| 4 | #include <asm/ioctl.h> | ||
| 5 | |||
| 6 | /* 0x54 is just a magic number to make these relatively unique ('T') */ | ||
| 7 | |||
| 8 | #define TCGETS 0x5401 | ||
| 9 | #define TCSETS 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */ | ||
| 10 | #define TCSETSW 0x5403 | ||
| 11 | #define TCSETSF 0x5404 | ||
| 12 | #define TCGETA 0x5405 | ||
| 13 | #define TCSETA 0x5406 | ||
| 14 | #define TCSETAW 0x5407 | ||
| 15 | #define TCSETAF 0x5408 | ||
| 16 | #define TCSBRK 0x5409 | ||
| 17 | #define TCXONC 0x540A | ||
| 18 | #define TCFLSH 0x540B | ||
| 19 | #define TIOCEXCL 0x540C | ||
| 20 | #define TIOCNXCL 0x540D | ||
| 21 | #define TIOCSCTTY 0x540E | ||
| 22 | #define TIOCGPGRP 0x540F | ||
| 23 | #define TIOCSPGRP 0x5410 | ||
| 24 | #define TIOCOUTQ 0x5411 | ||
| 25 | #define TIOCSTI 0x5412 | ||
| 26 | #define TIOCGWINSZ 0x5413 | ||
| 27 | #define TIOCSWINSZ 0x5414 | ||
| 28 | #define TIOCMGET 0x5415 | ||
| 29 | #define TIOCMBIS 0x5416 | ||
| 30 | #define TIOCMBIC 0x5417 | ||
| 31 | #define TIOCMSET 0x5418 | ||
| 32 | #define TIOCGSOFTCAR 0x5419 | ||
| 33 | #define TIOCSSOFTCAR 0x541A | ||
| 34 | #define FIONREAD 0x541B | ||
| 35 | #define TIOCINQ FIONREAD | ||
| 36 | #define TIOCLINUX 0x541C | ||
| 37 | #define TIOCCONS 0x541D | ||
| 38 | #define TIOCGSERIAL 0x541E | ||
| 39 | #define TIOCSSERIAL 0x541F | ||
| 40 | #define TIOCPKT 0x5420 | ||
| 41 | #define FIONBIO 0x5421 | ||
| 42 | #define TIOCNOTTY 0x5422 | ||
| 43 | #define TIOCSETD 0x5423 | ||
| 44 | #define TIOCGETD 0x5424 | ||
| 45 | #define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ | ||
| 46 | /* #define TIOCTTYGSTRUCT 0x5426 - Former debugging-only ioctl */ | ||
| 47 | #define TIOCSBRK 0x5427 /* BSD compatibility */ | ||
| 48 | #define TIOCCBRK 0x5428 /* BSD compatibility */ | ||
| 49 | #define TIOCGSID 0x5429 /* Return the session ID of FD */ | ||
| 50 | #define TCGETS2 _IOR('T', 0x2A, struct termios2) | ||
| 51 | #define TCSETS2 _IOW('T', 0x2B, struct termios2) | ||
| 52 | #define TCSETSW2 _IOW('T', 0x2C, struct termios2) | ||
| 53 | #define TCSETSF2 _IOW('T', 0x2D, struct termios2) | ||
| 54 | #define TIOCGRS485 0x542E | ||
| 55 | #define TIOCSRS485 0x542F | ||
| 56 | #define TIOCGPTN _IOR('T', 0x30, unsigned int) | ||
| 57 | /* Get Pty Number (of pty-mux device) */ | ||
| 58 | #define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ | ||
| 59 | #define TCGETX 0x5432 /* SYS5 TCGETX compatibility */ | ||
| 60 | #define TCSETX 0x5433 | ||
| 61 | #define TCSETXF 0x5434 | ||
| 62 | #define TCSETXW 0x5435 | ||
| 63 | |||
| 64 | #define FIONCLEX 0x5450 | ||
| 65 | #define FIOCLEX 0x5451 | ||
| 66 | #define FIOASYNC 0x5452 | ||
| 67 | #define TIOCSERCONFIG 0x5453 | ||
| 68 | #define TIOCSERGWILD 0x5454 | ||
| 69 | #define TIOCSERSWILD 0x5455 | ||
| 70 | #define TIOCGLCKTRMIOS 0x5456 | ||
| 71 | #define TIOCSLCKTRMIOS 0x5457 | ||
| 72 | #define TIOCSERGSTRUCT 0x5458 /* For debugging only */ | ||
| 73 | #define TIOCSERGETLSR 0x5459 /* Get line status register */ | ||
| 74 | #define TIOCSERGETMULTI 0x545A /* Get multiport config */ | ||
| 75 | #define TIOCSERSETMULTI 0x545B /* Set multiport config */ | ||
| 76 | |||
| 77 | #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ | ||
| 78 | #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ | ||
| 79 | #define TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ | ||
| 80 | #define TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ | ||
| 81 | #define FIOQSIZE 0x5460 | ||
| 82 | |||
| 83 | /* Used for packet mode */ | ||
| 84 | #define TIOCPKT_DATA 0 | ||
| 85 | #define TIOCPKT_FLUSHREAD 1 | ||
| 86 | #define TIOCPKT_FLUSHWRITE 2 | ||
| 87 | #define TIOCPKT_STOP 4 | ||
| 88 | #define TIOCPKT_START 8 | ||
| 89 | #define TIOCPKT_NOSTOP 16 | ||
| 90 | #define TIOCPKT_DOSTOP 32 | ||
| 91 | |||
| 92 | #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ | ||
| 93 | |||
| 94 | #endif /* _ASM_X86_IOCTLS_H */ | ||
diff --git a/arch/x86/include/asm/ipcbuf.h b/arch/x86/include/asm/ipcbuf.h index ee678fd51594..84c7e51cb6d0 100644 --- a/arch/x86/include/asm/ipcbuf.h +++ b/arch/x86/include/asm/ipcbuf.h | |||
| @@ -1,28 +1 @@ | |||
| 1 | #ifndef _ASM_X86_IPCBUF_H | #include <asm-generic/ipcbuf.h> | |
| 2 | #define _ASM_X86_IPCBUF_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * The ipc64_perm structure for x86 architecture. | ||
| 6 | * Note extra padding because this structure is passed back and forth | ||
| 7 | * between kernel and user space. | ||
| 8 | * | ||
| 9 | * Pad space is left for: | ||
| 10 | * - 32-bit mode_t and seq | ||
| 11 | * - 2 miscellaneous 32-bit values | ||
| 12 | */ | ||
| 13 | |||
| 14 | struct ipc64_perm { | ||
| 15 | __kernel_key_t key; | ||
| 16 | __kernel_uid32_t uid; | ||
| 17 | __kernel_gid32_t gid; | ||
| 18 | __kernel_uid32_t cuid; | ||
| 19 | __kernel_gid32_t cgid; | ||
| 20 | __kernel_mode_t mode; | ||
| 21 | unsigned short __pad1; | ||
| 22 | unsigned short seq; | ||
| 23 | unsigned short __pad2; | ||
| 24 | unsigned long __unused1; | ||
| 25 | unsigned long __unused2; | ||
| 26 | }; | ||
| 27 | |||
| 28 | #endif /* _ASM_X86_IPCBUF_H */ | ||
diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h index c6ccbe7e81ad..9e2b952f810a 100644 --- a/arch/x86/include/asm/irqflags.h +++ b/arch/x86/include/asm/irqflags.h | |||
| @@ -13,14 +13,13 @@ static inline unsigned long native_save_fl(void) | |||
| 13 | unsigned long flags; | 13 | unsigned long flags; |
| 14 | 14 | ||
| 15 | /* | 15 | /* |
| 16 | * Note: this needs to be "=r" not "=rm", because we have the | 16 | * "=rm" is safe here, because "pop" adjusts the stack before |
| 17 | * stack offset from what gcc expects at the time the "pop" is | 17 | * it evaluates its effective address -- this is part of the |
| 18 | * executed, and so a memory reference with respect to the stack | 18 | * documented behavior of the "pop" instruction. |
| 19 | * would end up using the wrong address. | ||
| 20 | */ | 19 | */ |
| 21 | asm volatile("# __raw_save_flags\n\t" | 20 | asm volatile("# __raw_save_flags\n\t" |
| 22 | "pushf ; pop %0" | 21 | "pushf ; pop %0" |
| 23 | : "=r" (flags) | 22 | : "=rm" (flags) |
| 24 | : /* no input */ | 23 | : /* no input */ |
| 25 | : "memory"); | 24 | : "memory"); |
| 26 | 25 | ||
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h index 125be8b19568..4a5fe914dc59 100644 --- a/arch/x86/include/asm/kvm.h +++ b/arch/x86/include/asm/kvm.h | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | #define __KVM_HAVE_USER_NMI | 17 | #define __KVM_HAVE_USER_NMI |
| 18 | #define __KVM_HAVE_GUEST_DEBUG | 18 | #define __KVM_HAVE_GUEST_DEBUG |
| 19 | #define __KVM_HAVE_MSIX | 19 | #define __KVM_HAVE_MSIX |
| 20 | #define __KVM_HAVE_MCE | ||
| 21 | #define __KVM_HAVE_PIT_STATE2 | ||
| 20 | 22 | ||
| 21 | /* Architectural interrupt line count. */ | 23 | /* Architectural interrupt line count. */ |
| 22 | #define KVM_NR_INTERRUPTS 256 | 24 | #define KVM_NR_INTERRUPTS 256 |
| @@ -236,6 +238,14 @@ struct kvm_pit_state { | |||
| 236 | struct kvm_pit_channel_state channels[3]; | 238 | struct kvm_pit_channel_state channels[3]; |
| 237 | }; | 239 | }; |
| 238 | 240 | ||
| 241 | #define KVM_PIT_FLAGS_HPET_LEGACY 0x00000001 | ||
| 242 | |||
| 243 | struct kvm_pit_state2 { | ||
| 244 | struct kvm_pit_channel_state channels[3]; | ||
| 245 | __u32 flags; | ||
| 246 | __u32 reserved[9]; | ||
| 247 | }; | ||
| 248 | |||
| 239 | struct kvm_reinject_control { | 249 | struct kvm_reinject_control { |
| 240 | __u8 pit_reinject; | 250 | __u8 pit_reinject; |
| 241 | __u8 reserved[31]; | 251 | __u8 reserved[31]; |
diff --git a/arch/x86/include/asm/kvm_x86_emulate.h b/arch/x86/include/asm/kvm_emulate.h index b7ed2c423116..b7ed2c423116 100644 --- a/arch/x86/include/asm/kvm_x86_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h | |||
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index eabdc1cfab5c..3be000435fad 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
| 15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
| 16 | #include <linux/mmu_notifier.h> | 16 | #include <linux/mmu_notifier.h> |
| 17 | #include <linux/tracepoint.h> | ||
| 17 | 18 | ||
| 18 | #include <linux/kvm.h> | 19 | #include <linux/kvm.h> |
| 19 | #include <linux/kvm_para.h> | 20 | #include <linux/kvm_para.h> |
| @@ -37,12 +38,14 @@ | |||
| 37 | #define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS | \ | 38 | #define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS | \ |
| 38 | 0xFFFFFF0000000000ULL) | 39 | 0xFFFFFF0000000000ULL) |
| 39 | 40 | ||
| 40 | #define KVM_GUEST_CR0_MASK \ | 41 | #define KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST \ |
| 41 | (X86_CR0_PG | X86_CR0_PE | X86_CR0_WP | X86_CR0_NE \ | 42 | (X86_CR0_WP | X86_CR0_NE | X86_CR0_NW | X86_CR0_CD) |
| 42 | | X86_CR0_NW | X86_CR0_CD) | 43 | #define KVM_GUEST_CR0_MASK \ |
| 44 | (KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE) | ||
| 45 | #define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST \ | ||
| 46 | (X86_CR0_WP | X86_CR0_NE | X86_CR0_TS | X86_CR0_MP) | ||
| 43 | #define KVM_VM_CR0_ALWAYS_ON \ | 47 | #define KVM_VM_CR0_ALWAYS_ON \ |
| 44 | (X86_CR0_PG | X86_CR0_PE | X86_CR0_WP | X86_CR0_NE | X86_CR0_TS \ | 48 | (KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE) |
| 45 | | X86_CR0_MP) | ||
| 46 | #define KVM_GUEST_CR4_MASK \ | 49 | #define KVM_GUEST_CR4_MASK \ |
| 47 | (X86_CR4_VME | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE | X86_CR4_VMXE) | 50 | (X86_CR4_VME | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE | X86_CR4_VMXE) |
| 48 | #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE) | 51 | #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE) |
| @@ -51,12 +54,12 @@ | |||
| 51 | #define INVALID_PAGE (~(hpa_t)0) | 54 | #define INVALID_PAGE (~(hpa_t)0) |
| 52 | #define UNMAPPED_GVA (~(gpa_t)0) | 55 | #define UNMAPPED_GVA (~(gpa_t)0) |
| 53 | 56 | ||
| 54 | /* shadow tables are PAE even on non-PAE hosts */ | 57 | /* KVM Hugepage definitions for x86 */ |
| 55 | #define KVM_HPAGE_SHIFT 21 | 58 | #define KVM_NR_PAGE_SIZES 3 |
| 56 | #define KVM_HPAGE_SIZE (1UL << KVM_HPAGE_SHIFT) | 59 | #define KVM_HPAGE_SHIFT(x) (PAGE_SHIFT + (((x) - 1) * 9)) |
| 57 | #define KVM_HPAGE_MASK (~(KVM_HPAGE_SIZE - 1)) | 60 | #define KVM_HPAGE_SIZE(x) (1UL << KVM_HPAGE_SHIFT(x)) |
| 58 | 61 | #define KVM_HPAGE_MASK(x) (~(KVM_HPAGE_SIZE(x) - 1)) | |
| 59 | #define KVM_PAGES_PER_HPAGE (KVM_HPAGE_SIZE / PAGE_SIZE) | 62 | #define KVM_PAGES_PER_HPAGE(x) (KVM_HPAGE_SIZE(x) / PAGE_SIZE) |
| 60 | 63 | ||
| 61 | #define DE_VECTOR 0 | 64 | #define DE_VECTOR 0 |
| 62 | #define DB_VECTOR 1 | 65 | #define DB_VECTOR 1 |
| @@ -120,6 +123,10 @@ enum kvm_reg { | |||
| 120 | NR_VCPU_REGS | 123 | NR_VCPU_REGS |
| 121 | }; | 124 | }; |
| 122 | 125 | ||
| 126 | enum kvm_reg_ex { | ||
| 127 | VCPU_EXREG_PDPTR = NR_VCPU_REGS, | ||
| 128 | }; | ||
| 129 | |||
| 123 | enum { | 130 | enum { |
| 124 | VCPU_SREG_ES, | 131 | VCPU_SREG_ES, |
| 125 | VCPU_SREG_CS, | 132 | VCPU_SREG_CS, |
| @@ -131,7 +138,7 @@ enum { | |||
| 131 | VCPU_SREG_LDTR, | 138 | VCPU_SREG_LDTR, |
| 132 | }; | 139 | }; |
| 133 | 140 | ||
| 134 | #include <asm/kvm_x86_emulate.h> | 141 | #include <asm/kvm_emulate.h> |
| 135 | 142 | ||
| 136 | #define KVM_NR_MEM_OBJS 40 | 143 | #define KVM_NR_MEM_OBJS 40 |
| 137 | 144 | ||
| @@ -308,7 +315,6 @@ struct kvm_vcpu_arch { | |||
| 308 | struct { | 315 | struct { |
| 309 | gfn_t gfn; /* presumed gfn during guest pte update */ | 316 | gfn_t gfn; /* presumed gfn during guest pte update */ |
| 310 | pfn_t pfn; /* pfn corresponding to that gfn */ | 317 | pfn_t pfn; /* pfn corresponding to that gfn */ |
| 311 | int largepage; | ||
| 312 | unsigned long mmu_seq; | 318 | unsigned long mmu_seq; |
| 313 | } update_pte; | 319 | } update_pte; |
| 314 | 320 | ||
| @@ -334,16 +340,6 @@ struct kvm_vcpu_arch { | |||
| 334 | u8 nr; | 340 | u8 nr; |
| 335 | } interrupt; | 341 | } interrupt; |
| 336 | 342 | ||
| 337 | struct { | ||
| 338 | int vm86_active; | ||
| 339 | u8 save_iopl; | ||
| 340 | struct kvm_save_segment { | ||
| 341 | u16 selector; | ||
| 342 | unsigned long base; | ||
| 343 | u32 limit; | ||
| 344 | u32 ar; | ||
| 345 | } tr, es, ds, fs, gs; | ||
| 346 | } rmode; | ||
| 347 | int halt_request; /* real mode on Intel only */ | 343 | int halt_request; /* real mode on Intel only */ |
| 348 | 344 | ||
| 349 | int cpuid_nent; | 345 | int cpuid_nent; |
| @@ -366,13 +362,15 @@ struct kvm_vcpu_arch { | |||
| 366 | u32 pat; | 362 | u32 pat; |
| 367 | 363 | ||
| 368 | int switch_db_regs; | 364 | int switch_db_regs; |
| 369 | unsigned long host_db[KVM_NR_DB_REGS]; | ||
| 370 | unsigned long host_dr6; | ||
| 371 | unsigned long host_dr7; | ||
| 372 | unsigned long db[KVM_NR_DB_REGS]; | 365 | unsigned long db[KVM_NR_DB_REGS]; |
| 373 | unsigned long dr6; | 366 | unsigned long dr6; |
| 374 | unsigned long dr7; | 367 | unsigned long dr7; |
| 375 | unsigned long eff_db[KVM_NR_DB_REGS]; | 368 | unsigned long eff_db[KVM_NR_DB_REGS]; |
| 369 | |||
| 370 | u64 mcg_cap; | ||
| 371 | u64 mcg_status; | ||
| 372 | u64 mcg_ctl; | ||
| 373 | u64 *mce_banks; | ||
| 376 | }; | 374 | }; |
| 377 | 375 | ||
| 378 | struct kvm_mem_alias { | 376 | struct kvm_mem_alias { |
| @@ -409,6 +407,7 @@ struct kvm_arch{ | |||
| 409 | 407 | ||
| 410 | struct page *ept_identity_pagetable; | 408 | struct page *ept_identity_pagetable; |
| 411 | bool ept_identity_pagetable_done; | 409 | bool ept_identity_pagetable_done; |
| 410 | gpa_t ept_identity_map_addr; | ||
| 412 | 411 | ||
| 413 | unsigned long irq_sources_bitmap; | 412 | unsigned long irq_sources_bitmap; |
| 414 | unsigned long irq_states[KVM_IOAPIC_NUM_PINS]; | 413 | unsigned long irq_states[KVM_IOAPIC_NUM_PINS]; |
| @@ -526,6 +525,9 @@ struct kvm_x86_ops { | |||
| 526 | int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); | 525 | int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); |
| 527 | int (*get_tdp_level)(void); | 526 | int (*get_tdp_level)(void); |
| 528 | u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio); | 527 | u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio); |
| 528 | bool (*gb_page_enable)(void); | ||
| 529 | |||
| 530 | const struct trace_print_flags *exit_reasons_str; | ||
| 529 | }; | 531 | }; |
| 530 | 532 | ||
| 531 | extern struct kvm_x86_ops *kvm_x86_ops; | 533 | extern struct kvm_x86_ops *kvm_x86_ops; |
| @@ -618,6 +620,7 @@ void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr); | |||
| 618 | void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); | 620 | void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); |
| 619 | void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2, | 621 | void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2, |
| 620 | u32 error_code); | 622 | u32 error_code); |
| 623 | bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl); | ||
| 621 | 624 | ||
| 622 | int kvm_pic_set_irq(void *opaque, int irq, int level); | 625 | int kvm_pic_set_irq(void *opaque, int irq, int level); |
| 623 | 626 | ||
| @@ -752,8 +755,6 @@ static inline void kvm_inject_gp(struct kvm_vcpu *vcpu, u32 error_code) | |||
| 752 | kvm_queue_exception_e(vcpu, GP_VECTOR, error_code); | 755 | kvm_queue_exception_e(vcpu, GP_VECTOR, error_code); |
| 753 | } | 756 | } |
| 754 | 757 | ||
| 755 | #define MSR_IA32_TIME_STAMP_COUNTER 0x010 | ||
| 756 | |||
| 757 | #define TSS_IOPB_BASE_OFFSET 0x66 | 758 | #define TSS_IOPB_BASE_OFFSET 0x66 |
| 758 | #define TSS_BASE_SIZE 0x68 | 759 | #define TSS_BASE_SIZE 0x68 |
| 759 | #define TSS_IOPB_SIZE (65536 / 8) | 760 | #define TSS_IOPB_SIZE (65536 / 8) |
| @@ -796,5 +797,8 @@ asmlinkage void kvm_handle_fault_on_reboot(void); | |||
| 796 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); | 797 | int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); |
| 797 | int kvm_age_hva(struct kvm *kvm, unsigned long hva); | 798 | int kvm_age_hva(struct kvm *kvm, unsigned long hva); |
| 798 | int cpuid_maxphyaddr(struct kvm_vcpu *vcpu); | 799 | int cpuid_maxphyaddr(struct kvm_vcpu *vcpu); |
| 800 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); | ||
| 801 | int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu); | ||
| 802 | int kvm_cpu_get_interrupt(struct kvm_vcpu *v); | ||
| 799 | 803 | ||
| 800 | #endif /* _ASM_X86_KVM_HOST_H */ | 804 | #endif /* _ASM_X86_KVM_HOST_H */ |
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index b8a3305ae093..c584076a47f4 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #ifndef _ASM_X86_KVM_PARA_H | 1 | #ifndef _ASM_X86_KVM_PARA_H |
| 2 | #define _ASM_X86_KVM_PARA_H | 2 | #define _ASM_X86_KVM_PARA_H |
| 3 | 3 | ||
| 4 | #include <linux/types.h> | ||
| 5 | |||
| 4 | /* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It | 6 | /* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It |
| 5 | * should be used to determine that a VM is running under KVM. | 7 | * should be used to determine that a VM is running under KVM. |
| 6 | */ | 8 | */ |
diff --git a/arch/x86/include/asm/lguest.h b/arch/x86/include/asm/lguest.h index 5136dad57cbb..0d97deba1e35 100644 --- a/arch/x86/include/asm/lguest.h +++ b/arch/x86/include/asm/lguest.h | |||
| @@ -90,8 +90,9 @@ static inline void lguest_set_ts(void) | |||
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | /* Full 4G segment descriptors, suitable for CS and DS. */ | 92 | /* Full 4G segment descriptors, suitable for CS and DS. */ |
| 93 | #define FULL_EXEC_SEGMENT ((struct desc_struct){ { {0x0000ffff, 0x00cf9b00} } }) | 93 | #define FULL_EXEC_SEGMENT \ |
| 94 | #define FULL_SEGMENT ((struct desc_struct){ { {0x0000ffff, 0x00cf9300} } }) | 94 | ((struct desc_struct)GDT_ENTRY_INIT(0xc09b, 0, 0xfffff)) |
| 95 | #define FULL_SEGMENT ((struct desc_struct)GDT_ENTRY_INIT(0xc093, 0, 0xfffff)) | ||
| 95 | 96 | ||
| 96 | #endif /* __ASSEMBLY__ */ | 97 | #endif /* __ASSEMBLY__ */ |
| 97 | 98 | ||
diff --git a/arch/x86/include/asm/mman.h b/arch/x86/include/asm/mman.h index 751af2550ed9..593e51d4643f 100644 --- a/arch/x86/include/asm/mman.h +++ b/arch/x86/include/asm/mman.h | |||
| @@ -1,20 +1,8 @@ | |||
| 1 | #ifndef _ASM_X86_MMAN_H | 1 | #ifndef _ASM_X86_MMAN_H |
| 2 | #define _ASM_X86_MMAN_H | 2 | #define _ASM_X86_MMAN_H |
| 3 | 3 | ||
| 4 | #include <asm-generic/mman-common.h> | ||
| 5 | |||
| 6 | #define MAP_32BIT 0x40 /* only give out 32bit addresses */ | 4 | #define MAP_32BIT 0x40 /* only give out 32bit addresses */ |
| 7 | 5 | ||
| 8 | #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ | 6 | #include <asm-generic/mman.h> |
| 9 | #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ | ||
| 10 | #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ | ||
| 11 | #define MAP_LOCKED 0x2000 /* pages are locked */ | ||
| 12 | #define MAP_NORESERVE 0x4000 /* don't check for reservations */ | ||
| 13 | #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ | ||
| 14 | #define MAP_NONBLOCK 0x10000 /* do not block on IO */ | ||
| 15 | #define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */ | ||
| 16 | |||
| 17 | #define MCL_CURRENT 1 /* lock all current mappings */ | ||
| 18 | #define MCL_FUTURE 2 /* lock all future mappings */ | ||
| 19 | 7 | ||
| 20 | #endif /* _ASM_X86_MMAN_H */ | 8 | #endif /* _ASM_X86_MMAN_H */ |
diff --git a/arch/x86/include/asm/module.h b/arch/x86/include/asm/module.h index 47d62743c4d5..3e2ce58a31a3 100644 --- a/arch/x86/include/asm/module.h +++ b/arch/x86/include/asm/module.h | |||
| @@ -1,18 +1,7 @@ | |||
| 1 | #ifndef _ASM_X86_MODULE_H | 1 | #ifndef _ASM_X86_MODULE_H |
| 2 | #define _ASM_X86_MODULE_H | 2 | #define _ASM_X86_MODULE_H |
| 3 | 3 | ||
| 4 | /* x86_32/64 are simple */ | 4 | #include <asm-generic/module.h> |
| 5 | struct mod_arch_specific {}; | ||
| 6 | |||
| 7 | #ifdef CONFIG_X86_32 | ||
| 8 | # define Elf_Shdr Elf32_Shdr | ||
| 9 | # define Elf_Sym Elf32_Sym | ||
| 10 | # define Elf_Ehdr Elf32_Ehdr | ||
| 11 | #else | ||
| 12 | # define Elf_Shdr Elf64_Shdr | ||
| 13 | # define Elf_Sym Elf64_Sym | ||
| 14 | # define Elf_Ehdr Elf64_Ehdr | ||
| 15 | #endif | ||
| 16 | 5 | ||
| 17 | #ifdef CONFIG_X86_64 | 6 | #ifdef CONFIG_X86_64 |
| 18 | /* X86_64 does not define MODULE_PROC_FAMILY */ | 7 | /* X86_64 does not define MODULE_PROC_FAMILY */ |
| @@ -28,6 +17,8 @@ struct mod_arch_specific {}; | |||
| 28 | #define MODULE_PROC_FAMILY "586MMX " | 17 | #define MODULE_PROC_FAMILY "586MMX " |
| 29 | #elif defined CONFIG_MCORE2 | 18 | #elif defined CONFIG_MCORE2 |
| 30 | #define MODULE_PROC_FAMILY "CORE2 " | 19 | #define MODULE_PROC_FAMILY "CORE2 " |
| 20 | #elif defined CONFIG_MATOM | ||
| 21 | #define MODULE_PROC_FAMILY "ATOM " | ||
| 31 | #elif defined CONFIG_M686 | 22 | #elif defined CONFIG_M686 |
| 32 | #define MODULE_PROC_FAMILY "686 " | 23 | #define MODULE_PROC_FAMILY "686 " |
| 33 | #elif defined CONFIG_MPENTIUMII | 24 | #elif defined CONFIG_MPENTIUMII |
diff --git a/arch/x86/include/asm/msgbuf.h b/arch/x86/include/asm/msgbuf.h index 7e4e9481f51c..809134c644a6 100644 --- a/arch/x86/include/asm/msgbuf.h +++ b/arch/x86/include/asm/msgbuf.h | |||
| @@ -1,39 +1 @@ | |||
| 1 | #ifndef _ASM_X86_MSGBUF_H | #include <asm-generic/msgbuf.h> | |
| 2 | #define _ASM_X86_MSGBUF_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * The msqid64_ds structure for i386 architecture. | ||
| 6 | * Note extra padding because this structure is passed back and forth | ||
| 7 | * between kernel and user space. | ||
| 8 | * | ||
| 9 | * Pad space on i386 is left for: | ||
| 10 | * - 64-bit time_t to solve y2038 problem | ||
| 11 | * - 2 miscellaneous 32-bit values | ||
| 12 | * | ||
| 13 | * Pad space on x8664 is left for: | ||
| 14 | * - 2 miscellaneous 64-bit values | ||
| 15 | */ | ||
| 16 | struct msqid64_ds { | ||
| 17 | struct ipc64_perm msg_perm; | ||
| 18 | __kernel_time_t msg_stime; /* last msgsnd time */ | ||
| 19 | #ifdef __i386__ | ||
| 20 | unsigned long __unused1; | ||
| 21 | #endif | ||
| 22 | __kernel_time_t msg_rtime; /* last msgrcv time */ | ||
| 23 | #ifdef __i386__ | ||
| 24 | unsigned long __unused2; | ||
| 25 | #endif | ||
| 26 | __kernel_time_t msg_ctime; /* last change time */ | ||
| 27 | #ifdef __i386__ | ||
| 28 | unsigned long __unused3; | ||
| 29 | #endif | ||
| 30 | unsigned long msg_cbytes; /* current number of bytes on queue */ | ||
| 31 | unsigned long msg_qnum; /* number of messages in queue */ | ||
| 32 | unsigned long msg_qbytes; /* max number of bytes on queue */ | ||
| 33 | __kernel_pid_t msg_lspid; /* pid of last msgsnd */ | ||
| 34 | __kernel_pid_t msg_lrpid; /* last receive pid */ | ||
| 35 | unsigned long __unused4; | ||
| 36 | unsigned long __unused5; | ||
| 37 | }; | ||
| 38 | |||
| 39 | #endif /* _ASM_X86_MSGBUF_H */ | ||
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 6be7fc254b59..bd5549034a95 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h | |||
| @@ -374,6 +374,7 @@ | |||
| 374 | /* AMD-V MSRs */ | 374 | /* AMD-V MSRs */ |
| 375 | 375 | ||
| 376 | #define MSR_VM_CR 0xc0010114 | 376 | #define MSR_VM_CR 0xc0010114 |
| 377 | #define MSR_VM_IGNNE 0xc0010115 | ||
| 377 | #define MSR_VM_HSAVE_PA 0xc0010117 | 378 | #define MSR_VM_HSAVE_PA 0xc0010117 |
| 378 | 379 | ||
| 379 | #endif /* _ASM_X86_MSR_INDEX_H */ | 380 | #endif /* _ASM_X86_MSR_INDEX_H */ |
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 48ad9d29484a..7e2b6ba962ff 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h | |||
| @@ -3,10 +3,16 @@ | |||
| 3 | 3 | ||
| 4 | #include <asm/msr-index.h> | 4 | #include <asm/msr-index.h> |
| 5 | 5 | ||
| 6 | #ifdef __KERNEL__ | ||
| 7 | #ifndef __ASSEMBLY__ | 6 | #ifndef __ASSEMBLY__ |
| 8 | 7 | ||
| 9 | #include <linux/types.h> | 8 | #include <linux/types.h> |
| 9 | #include <linux/ioctl.h> | ||
| 10 | |||
| 11 | #define X86_IOC_RDMSR_REGS _IOWR('c', 0xA0, __u32[8]) | ||
| 12 | #define X86_IOC_WRMSR_REGS _IOWR('c', 0xA1, __u32[8]) | ||
| 13 | |||
| 14 | #ifdef __KERNEL__ | ||
| 15 | |||
| 10 | #include <asm/asm.h> | 16 | #include <asm/asm.h> |
| 11 | #include <asm/errno.h> | 17 | #include <asm/errno.h> |
| 12 | #include <asm/cpumask.h> | 18 | #include <asm/cpumask.h> |
| @@ -67,23 +73,7 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr, | |||
| 67 | ".previous\n\t" | 73 | ".previous\n\t" |
| 68 | _ASM_EXTABLE(2b, 3b) | 74 | _ASM_EXTABLE(2b, 3b) |
| 69 | : [err] "=r" (*err), EAX_EDX_RET(val, low, high) | 75 | : [err] "=r" (*err), EAX_EDX_RET(val, low, high) |
| 70 | : "c" (msr), [fault] "i" (-EFAULT)); | 76 | : "c" (msr), [fault] "i" (-EIO)); |
| 71 | return EAX_EDX_VAL(val, low, high); | ||
| 72 | } | ||
| 73 | |||
| 74 | static inline unsigned long long native_read_msr_amd_safe(unsigned int msr, | ||
| 75 | int *err) | ||
| 76 | { | ||
| 77 | DECLARE_ARGS(val, low, high); | ||
| 78 | |||
| 79 | asm volatile("2: rdmsr ; xor %0,%0\n" | ||
| 80 | "1:\n\t" | ||
| 81 | ".section .fixup,\"ax\"\n\t" | ||
| 82 | "3: mov %3,%0 ; jmp 1b\n\t" | ||
| 83 | ".previous\n\t" | ||
| 84 | _ASM_EXTABLE(2b, 3b) | ||
| 85 | : "=r" (*err), EAX_EDX_RET(val, low, high) | ||
| 86 | : "c" (msr), "D" (0x9c5a203a), "i" (-EFAULT)); | ||
| 87 | return EAX_EDX_VAL(val, low, high); | 77 | return EAX_EDX_VAL(val, low, high); |
| 88 | } | 78 | } |
| 89 | 79 | ||
| @@ -106,13 +96,16 @@ notrace static inline int native_write_msr_safe(unsigned int msr, | |||
| 106 | _ASM_EXTABLE(2b, 3b) | 96 | _ASM_EXTABLE(2b, 3b) |
| 107 | : [err] "=a" (err) | 97 | : [err] "=a" (err) |
| 108 | : "c" (msr), "0" (low), "d" (high), | 98 | : "c" (msr), "0" (low), "d" (high), |
| 109 | [fault] "i" (-EFAULT) | 99 | [fault] "i" (-EIO) |
| 110 | : "memory"); | 100 | : "memory"); |
| 111 | return err; | 101 | return err; |
| 112 | } | 102 | } |
| 113 | 103 | ||
| 114 | extern unsigned long long native_read_tsc(void); | 104 | extern unsigned long long native_read_tsc(void); |
| 115 | 105 | ||
| 106 | extern int native_rdmsr_safe_regs(u32 regs[8]); | ||
| 107 | extern int native_wrmsr_safe_regs(u32 regs[8]); | ||
| 108 | |||
| 116 | static __always_inline unsigned long long __native_read_tsc(void) | 109 | static __always_inline unsigned long long __native_read_tsc(void) |
| 117 | { | 110 | { |
| 118 | DECLARE_ARGS(val, low, high); | 111 | DECLARE_ARGS(val, low, high); |
| @@ -181,14 +174,44 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) | |||
| 181 | *p = native_read_msr_safe(msr, &err); | 174 | *p = native_read_msr_safe(msr, &err); |
| 182 | return err; | 175 | return err; |
| 183 | } | 176 | } |
| 177 | |||
| 184 | static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) | 178 | static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) |
| 185 | { | 179 | { |
| 180 | u32 gprs[8] = { 0 }; | ||
| 186 | int err; | 181 | int err; |
| 187 | 182 | ||
| 188 | *p = native_read_msr_amd_safe(msr, &err); | 183 | gprs[1] = msr; |
| 184 | gprs[7] = 0x9c5a203a; | ||
| 185 | |||
| 186 | err = native_rdmsr_safe_regs(gprs); | ||
| 187 | |||
| 188 | *p = gprs[0] | ((u64)gprs[2] << 32); | ||
| 189 | |||
| 189 | return err; | 190 | return err; |
| 190 | } | 191 | } |
| 191 | 192 | ||
| 193 | static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) | ||
| 194 | { | ||
| 195 | u32 gprs[8] = { 0 }; | ||
| 196 | |||
| 197 | gprs[0] = (u32)val; | ||
| 198 | gprs[1] = msr; | ||
| 199 | gprs[2] = val >> 32; | ||
| 200 | gprs[7] = 0x9c5a203a; | ||
| 201 | |||
| 202 | return native_wrmsr_safe_regs(gprs); | ||
| 203 | } | ||
| 204 | |||
| 205 | static inline int rdmsr_safe_regs(u32 regs[8]) | ||
| 206 | { | ||
| 207 | return native_rdmsr_safe_regs(regs); | ||
| 208 | } | ||
| 209 | |||
| 210 | static inline int wrmsr_safe_regs(u32 regs[8]) | ||
| 211 | { | ||
| 212 | return native_wrmsr_safe_regs(regs); | ||
| 213 | } | ||
| 214 | |||
| 192 | #define rdtscl(low) \ | 215 | #define rdtscl(low) \ |
| 193 | ((low) = (u32)__native_read_tsc()) | 216 | ((low) = (u32)__native_read_tsc()) |
| 194 | 217 | ||
| @@ -228,6 +251,8 @@ void rdmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs); | |||
| 228 | void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs); | 251 | void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs); |
| 229 | int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); | 252 | int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); |
| 230 | int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); | 253 | int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); |
| 254 | int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); | ||
| 255 | int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); | ||
| 231 | #else /* CONFIG_SMP */ | 256 | #else /* CONFIG_SMP */ |
| 232 | static inline int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) | 257 | static inline int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) |
| 233 | { | 258 | { |
| @@ -258,7 +283,15 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | |||
| 258 | { | 283 | { |
| 259 | return wrmsr_safe(msr_no, l, h); | 284 | return wrmsr_safe(msr_no, l, h); |
| 260 | } | 285 | } |
| 286 | static inline int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]) | ||
| 287 | { | ||
| 288 | return rdmsr_safe_regs(regs); | ||
| 289 | } | ||
| 290 | static inline int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]) | ||
| 291 | { | ||
| 292 | return wrmsr_safe_regs(regs); | ||
| 293 | } | ||
| 261 | #endif /* CONFIG_SMP */ | 294 | #endif /* CONFIG_SMP */ |
| 262 | #endif /* __ASSEMBLY__ */ | ||
| 263 | #endif /* __KERNEL__ */ | 295 | #endif /* __KERNEL__ */ |
| 296 | #endif /* __ASSEMBLY__ */ | ||
| 264 | #endif /* _ASM_X86_MSR_H */ | 297 | #endif /* _ASM_X86_MSR_H */ |
diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h index c86e5ed4af51..e63cf7d441e1 100644 --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h | |||
| @@ -45,8 +45,8 @@ extern int proc_nmi_enabled(struct ctl_table *, int , struct file *, | |||
| 45 | void __user *, size_t *, loff_t *); | 45 | void __user *, size_t *, loff_t *); |
| 46 | extern int unknown_nmi_panic; | 46 | extern int unknown_nmi_panic; |
| 47 | 47 | ||
| 48 | void __trigger_all_cpu_backtrace(void); | 48 | void arch_trigger_all_cpu_backtrace(void); |
| 49 | #define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace() | 49 | #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace |
| 50 | 50 | ||
| 51 | static inline void localise_nmi_watchdog(void) | 51 | static inline void localise_nmi_watchdog(void) |
| 52 | { | 52 | { |
diff --git a/arch/x86/include/asm/param.h b/arch/x86/include/asm/param.h index 6f0d0422f4ca..965d45427975 100644 --- a/arch/x86/include/asm/param.h +++ b/arch/x86/include/asm/param.h | |||
| @@ -1,22 +1 @@ | |||
| 1 | #ifndef _ASM_X86_PARAM_H | #include <asm-generic/param.h> | |
| 2 | #define _ASM_X86_PARAM_H | ||
| 3 | |||
| 4 | #ifdef __KERNEL__ | ||
| 5 | # define HZ CONFIG_HZ /* Internal kernel timer frequency */ | ||
| 6 | # define USER_HZ 100 /* some user interfaces are */ | ||
| 7 | # define CLOCKS_PER_SEC (USER_HZ) /* in "ticks" like times() */ | ||
| 8 | #endif | ||
| 9 | |||
| 10 | #ifndef HZ | ||
| 11 | #define HZ 100 | ||
| 12 | #endif | ||
| 13 | |||
| 14 | #define EXEC_PAGESIZE 4096 | ||
| 15 | |||
| 16 | #ifndef NOGROUP | ||
| 17 | #define NOGROUP (-1) | ||
| 18 | #endif | ||
| 19 | |||
| 20 | #define MAXHOSTNAMELEN 64 /* max length of hostname */ | ||
| 21 | |||
| 22 | #endif /* _ASM_X86_PARAM_H */ | ||
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 4fb37c8a0832..40d6586af25b 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
| @@ -7,689 +7,11 @@ | |||
| 7 | #include <asm/pgtable_types.h> | 7 | #include <asm/pgtable_types.h> |
| 8 | #include <asm/asm.h> | 8 | #include <asm/asm.h> |
| 9 | 9 | ||
| 10 | /* Bitmask of what can be clobbered: usually at least eax. */ | 10 | #include <asm/paravirt_types.h> |
| 11 | #define CLBR_NONE 0 | ||
| 12 | #define CLBR_EAX (1 << 0) | ||
| 13 | #define CLBR_ECX (1 << 1) | ||
| 14 | #define CLBR_EDX (1 << 2) | ||
| 15 | #define CLBR_EDI (1 << 3) | ||
| 16 | |||
| 17 | #ifdef CONFIG_X86_32 | ||
| 18 | /* CLBR_ANY should match all regs platform has. For i386, that's just it */ | ||
| 19 | #define CLBR_ANY ((1 << 4) - 1) | ||
| 20 | |||
| 21 | #define CLBR_ARG_REGS (CLBR_EAX | CLBR_EDX | CLBR_ECX) | ||
| 22 | #define CLBR_RET_REG (CLBR_EAX | CLBR_EDX) | ||
| 23 | #define CLBR_SCRATCH (0) | ||
| 24 | #else | ||
| 25 | #define CLBR_RAX CLBR_EAX | ||
| 26 | #define CLBR_RCX CLBR_ECX | ||
| 27 | #define CLBR_RDX CLBR_EDX | ||
| 28 | #define CLBR_RDI CLBR_EDI | ||
| 29 | #define CLBR_RSI (1 << 4) | ||
| 30 | #define CLBR_R8 (1 << 5) | ||
| 31 | #define CLBR_R9 (1 << 6) | ||
| 32 | #define CLBR_R10 (1 << 7) | ||
| 33 | #define CLBR_R11 (1 << 8) | ||
| 34 | |||
| 35 | #define CLBR_ANY ((1 << 9) - 1) | ||
| 36 | |||
| 37 | #define CLBR_ARG_REGS (CLBR_RDI | CLBR_RSI | CLBR_RDX | \ | ||
| 38 | CLBR_RCX | CLBR_R8 | CLBR_R9) | ||
| 39 | #define CLBR_RET_REG (CLBR_RAX) | ||
| 40 | #define CLBR_SCRATCH (CLBR_R10 | CLBR_R11) | ||
| 41 | |||
| 42 | #include <asm/desc_defs.h> | ||
| 43 | #endif /* X86_64 */ | ||
| 44 | |||
| 45 | #define CLBR_CALLEE_SAVE ((CLBR_ARG_REGS | CLBR_SCRATCH) & ~CLBR_RET_REG) | ||
| 46 | 11 | ||
| 47 | #ifndef __ASSEMBLY__ | 12 | #ifndef __ASSEMBLY__ |
| 48 | #include <linux/types.h> | 13 | #include <linux/types.h> |
| 49 | #include <linux/cpumask.h> | 14 | #include <linux/cpumask.h> |
| 50 | #include <asm/kmap_types.h> | ||
| 51 | #include <asm/desc_defs.h> | ||
| 52 | |||
| 53 | struct page; | ||
| 54 | struct thread_struct; | ||
| 55 | struct desc_ptr; | ||
| 56 | struct tss_struct; | ||
| 57 | struct mm_struct; | ||
| 58 | struct desc_struct; | ||
| 59 | struct task_struct; | ||
| 60 | |||
| 61 | /* | ||
| 62 | * Wrapper type for pointers to code which uses the non-standard | ||
| 63 | * calling convention. See PV_CALL_SAVE_REGS_THUNK below. | ||
| 64 | */ | ||
| 65 | struct paravirt_callee_save { | ||
| 66 | void *func; | ||
| 67 | }; | ||
| 68 | |||
| 69 | /* general info */ | ||
| 70 | struct pv_info { | ||
| 71 | unsigned int kernel_rpl; | ||
| 72 | int shared_kernel_pmd; | ||
| 73 | int paravirt_enabled; | ||
| 74 | const char *name; | ||
| 75 | }; | ||
| 76 | |||
| 77 | struct pv_init_ops { | ||
| 78 | /* | ||
| 79 | * Patch may replace one of the defined code sequences with | ||
| 80 | * arbitrary code, subject to the same register constraints. | ||
| 81 | * This generally means the code is not free to clobber any | ||
| 82 | * registers other than EAX. The patch function should return | ||
| 83 | * the number of bytes of code generated, as we nop pad the | ||
| 84 | * rest in generic code. | ||
| 85 | */ | ||
| 86 | unsigned (*patch)(u8 type, u16 clobber, void *insnbuf, | ||
| 87 | unsigned long addr, unsigned len); | ||
| 88 | |||
| 89 | /* Basic arch-specific setup */ | ||
| 90 | void (*arch_setup)(void); | ||
| 91 | char *(*memory_setup)(void); | ||
| 92 | void (*post_allocator_init)(void); | ||
| 93 | |||
| 94 | /* Print a banner to identify the environment */ | ||
| 95 | void (*banner)(void); | ||
| 96 | }; | ||
| 97 | |||
| 98 | |||
| 99 | struct pv_lazy_ops { | ||
| 100 | /* Set deferred update mode, used for batching operations. */ | ||
| 101 | void (*enter)(void); | ||
| 102 | void (*leave)(void); | ||
| 103 | }; | ||
| 104 | |||
| 105 | struct pv_time_ops { | ||
| 106 | void (*time_init)(void); | ||
| 107 | |||
| 108 | /* Set and set time of day */ | ||
| 109 | unsigned long (*get_wallclock)(void); | ||
| 110 | int (*set_wallclock)(unsigned long); | ||
| 111 | |||
| 112 | unsigned long long (*sched_clock)(void); | ||
| 113 | unsigned long (*get_tsc_khz)(void); | ||
| 114 | }; | ||
| 115 | |||
| 116 | struct pv_cpu_ops { | ||
| 117 | /* hooks for various privileged instructions */ | ||
| 118 | unsigned long (*get_debugreg)(int regno); | ||
| 119 | void (*set_debugreg)(int regno, unsigned long value); | ||
| 120 | |||
| 121 | void (*clts)(void); | ||
| 122 | |||
| 123 | unsigned long (*read_cr0)(void); | ||
| 124 | void (*write_cr0)(unsigned long); | ||
| 125 | |||
| 126 | unsigned long (*read_cr4_safe)(void); | ||
| 127 | unsigned long (*read_cr4)(void); | ||
| 128 | void (*write_cr4)(unsigned long); | ||
| 129 | |||
| 130 | #ifdef CONFIG_X86_64 | ||
| 131 | unsigned long (*read_cr8)(void); | ||
| 132 | void (*write_cr8)(unsigned long); | ||
| 133 | #endif | ||
| 134 | |||
| 135 | /* Segment descriptor handling */ | ||
| 136 | void (*load_tr_desc)(void); | ||
| 137 | void (*load_gdt)(const struct desc_ptr *); | ||
| 138 | void (*load_idt)(const struct desc_ptr *); | ||
| 139 | void (*store_gdt)(struct desc_ptr *); | ||
| 140 | void (*store_idt)(struct desc_ptr *); | ||
| 141 | void (*set_ldt)(const void *desc, unsigned entries); | ||
| 142 | unsigned long (*store_tr)(void); | ||
| 143 | void (*load_tls)(struct thread_struct *t, unsigned int cpu); | ||
| 144 | #ifdef CONFIG_X86_64 | ||
| 145 | void (*load_gs_index)(unsigned int idx); | ||
| 146 | #endif | ||
| 147 | void (*write_ldt_entry)(struct desc_struct *ldt, int entrynum, | ||
| 148 | const void *desc); | ||
| 149 | void (*write_gdt_entry)(struct desc_struct *, | ||
| 150 | int entrynum, const void *desc, int size); | ||
| 151 | void (*write_idt_entry)(gate_desc *, | ||
| 152 | int entrynum, const gate_desc *gate); | ||
| 153 | void (*alloc_ldt)(struct desc_struct *ldt, unsigned entries); | ||
| 154 | void (*free_ldt)(struct desc_struct *ldt, unsigned entries); | ||
| 155 | |||
| 156 | void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t); | ||
| 157 | |||
| 158 | void (*set_iopl_mask)(unsigned mask); | ||
| 159 | |||
| 160 | void (*wbinvd)(void); | ||
| 161 | void (*io_delay)(void); | ||
| 162 | |||
| 163 | /* cpuid emulation, mostly so that caps bits can be disabled */ | ||
| 164 | void (*cpuid)(unsigned int *eax, unsigned int *ebx, | ||
| 165 | unsigned int *ecx, unsigned int *edx); | ||
| 166 | |||
| 167 | /* MSR, PMC and TSR operations. | ||
| 168 | err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */ | ||
| 169 | u64 (*read_msr_amd)(unsigned int msr, int *err); | ||
| 170 | u64 (*read_msr)(unsigned int msr, int *err); | ||
| 171 | int (*write_msr)(unsigned int msr, unsigned low, unsigned high); | ||
| 172 | |||
| 173 | u64 (*read_tsc)(void); | ||
| 174 | u64 (*read_pmc)(int counter); | ||
| 175 | unsigned long long (*read_tscp)(unsigned int *aux); | ||
| 176 | |||
| 177 | /* | ||
| 178 | * Atomically enable interrupts and return to userspace. This | ||
| 179 | * is only ever used to return to 32-bit processes; in a | ||
| 180 | * 64-bit kernel, it's used for 32-on-64 compat processes, but | ||
| 181 | * never native 64-bit processes. (Jump, not call.) | ||
| 182 | */ | ||
| 183 | void (*irq_enable_sysexit)(void); | ||
| 184 | |||
| 185 | /* | ||
| 186 | * Switch to usermode gs and return to 64-bit usermode using | ||
| 187 | * sysret. Only used in 64-bit kernels to return to 64-bit | ||
| 188 | * processes. Usermode register state, including %rsp, must | ||
| 189 | * already be restored. | ||
| 190 | */ | ||
| 191 | void (*usergs_sysret64)(void); | ||
| 192 | |||
| 193 | /* | ||
| 194 | * Switch to usermode gs and return to 32-bit usermode using | ||
| 195 | * sysret. Used to return to 32-on-64 compat processes. | ||
| 196 | * Other usermode register state, including %esp, must already | ||
| 197 | * be restored. | ||
| 198 | */ | ||
| 199 | void (*usergs_sysret32)(void); | ||
| 200 | |||
| 201 | /* Normal iret. Jump to this with the standard iret stack | ||
| 202 | frame set up. */ | ||
| 203 | void (*iret)(void); | ||
| 204 | |||
| 205 | void (*swapgs)(void); | ||
| 206 | |||
| 207 | void (*start_context_switch)(struct task_struct *prev); | ||
| 208 | void (*end_context_switch)(struct task_struct *next); | ||
| 209 | }; | ||
| 210 | |||
| 211 | struct pv_irq_ops { | ||
| 212 | void (*init_IRQ)(void); | ||
| 213 | |||
| 214 | /* | ||
| 215 | * Get/set interrupt state. save_fl and restore_fl are only | ||
| 216 | * expected to use X86_EFLAGS_IF; all other bits | ||
| 217 | * returned from save_fl are undefined, and may be ignored by | ||
| 218 | * restore_fl. | ||
| 219 | * | ||
| 220 | * NOTE: These functions callers expect the callee to preserve | ||
| 221 | * more registers than the standard C calling convention. | ||
| 222 | */ | ||
| 223 | struct paravirt_callee_save save_fl; | ||
| 224 | struct paravirt_callee_save restore_fl; | ||
| 225 | struct paravirt_callee_save irq_disable; | ||
| 226 | struct paravirt_callee_save irq_enable; | ||
| 227 | |||
| 228 | void (*safe_halt)(void); | ||
| 229 | void (*halt)(void); | ||
| 230 | |||
| 231 | #ifdef CONFIG_X86_64 | ||
| 232 | void (*adjust_exception_frame)(void); | ||
| 233 | #endif | ||
| 234 | }; | ||
| 235 | |||
| 236 | struct pv_apic_ops { | ||
| 237 | #ifdef CONFIG_X86_LOCAL_APIC | ||
| 238 | void (*setup_boot_clock)(void); | ||
| 239 | void (*setup_secondary_clock)(void); | ||
| 240 | |||
| 241 | void (*startup_ipi_hook)(int phys_apicid, | ||
| 242 | unsigned long start_eip, | ||
| 243 | unsigned long start_esp); | ||
| 244 | #endif | ||
| 245 | }; | ||
| 246 | |||
| 247 | struct pv_mmu_ops { | ||
| 248 | /* | ||
| 249 | * Called before/after init_mm pagetable setup. setup_start | ||
| 250 | * may reset %cr3, and may pre-install parts of the pagetable; | ||
| 251 | * pagetable setup is expected to preserve any existing | ||
| 252 | * mapping. | ||
| 253 | */ | ||
| 254 | void (*pagetable_setup_start)(pgd_t *pgd_base); | ||
| 255 | void (*pagetable_setup_done)(pgd_t *pgd_base); | ||
| 256 | |||
| 257 | unsigned long (*read_cr2)(void); | ||
| 258 | void (*write_cr2)(unsigned long); | ||
| 259 | |||
| 260 | unsigned long (*read_cr3)(void); | ||
| 261 | void (*write_cr3)(unsigned long); | ||
| 262 | |||
| 263 | /* | ||
| 264 | * Hooks for intercepting the creation/use/destruction of an | ||
| 265 | * mm_struct. | ||
| 266 | */ | ||
| 267 | void (*activate_mm)(struct mm_struct *prev, | ||
| 268 | struct mm_struct *next); | ||
| 269 | void (*dup_mmap)(struct mm_struct *oldmm, | ||
| 270 | struct mm_struct *mm); | ||
| 271 | void (*exit_mmap)(struct mm_struct *mm); | ||
| 272 | |||
| 273 | |||
| 274 | /* TLB operations */ | ||
| 275 | void (*flush_tlb_user)(void); | ||
| 276 | void (*flush_tlb_kernel)(void); | ||
| 277 | void (*flush_tlb_single)(unsigned long addr); | ||
| 278 | void (*flush_tlb_others)(const struct cpumask *cpus, | ||
| 279 | struct mm_struct *mm, | ||
| 280 | unsigned long va); | ||
| 281 | |||
| 282 | /* Hooks for allocating and freeing a pagetable top-level */ | ||
| 283 | int (*pgd_alloc)(struct mm_struct *mm); | ||
| 284 | void (*pgd_free)(struct mm_struct *mm, pgd_t *pgd); | ||
| 285 | |||
| 286 | /* | ||
| 287 | * Hooks for allocating/releasing pagetable pages when they're | ||
| 288 | * attached to a pagetable | ||
| 289 | */ | ||
| 290 | void (*alloc_pte)(struct mm_struct *mm, unsigned long pfn); | ||
| 291 | void (*alloc_pmd)(struct mm_struct *mm, unsigned long pfn); | ||
| 292 | void (*alloc_pmd_clone)(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count); | ||
| 293 | void (*alloc_pud)(struct mm_struct *mm, unsigned long pfn); | ||
| 294 | void (*release_pte)(unsigned long pfn); | ||
| 295 | void (*release_pmd)(unsigned long pfn); | ||
| 296 | void (*release_pud)(unsigned long pfn); | ||
| 297 | |||
| 298 | /* Pagetable manipulation functions */ | ||
| 299 | void (*set_pte)(pte_t *ptep, pte_t pteval); | ||
| 300 | void (*set_pte_at)(struct mm_struct *mm, unsigned long addr, | ||
| 301 | pte_t *ptep, pte_t pteval); | ||
| 302 | void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval); | ||
| 303 | void (*pte_update)(struct mm_struct *mm, unsigned long addr, | ||
| 304 | pte_t *ptep); | ||
| 305 | void (*pte_update_defer)(struct mm_struct *mm, | ||
| 306 | unsigned long addr, pte_t *ptep); | ||
| 307 | |||
| 308 | pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr, | ||
| 309 | pte_t *ptep); | ||
| 310 | void (*ptep_modify_prot_commit)(struct mm_struct *mm, unsigned long addr, | ||
| 311 | pte_t *ptep, pte_t pte); | ||
| 312 | |||
| 313 | struct paravirt_callee_save pte_val; | ||
| 314 | struct paravirt_callee_save make_pte; | ||
| 315 | |||
| 316 | struct paravirt_callee_save pgd_val; | ||
| 317 | struct paravirt_callee_save make_pgd; | ||
| 318 | |||
| 319 | #if PAGETABLE_LEVELS >= 3 | ||
| 320 | #ifdef CONFIG_X86_PAE | ||
| 321 | void (*set_pte_atomic)(pte_t *ptep, pte_t pteval); | ||
| 322 | void (*pte_clear)(struct mm_struct *mm, unsigned long addr, | ||
| 323 | pte_t *ptep); | ||
| 324 | void (*pmd_clear)(pmd_t *pmdp); | ||
| 325 | |||
| 326 | #endif /* CONFIG_X86_PAE */ | ||
| 327 | |||
| 328 | void (*set_pud)(pud_t *pudp, pud_t pudval); | ||
| 329 | |||
| 330 | struct paravirt_callee_save pmd_val; | ||
| 331 | struct paravirt_callee_save make_pmd; | ||
| 332 | |||
| 333 | #if PAGETABLE_LEVELS == 4 | ||
| 334 | struct paravirt_callee_save pud_val; | ||
| 335 | struct paravirt_callee_save make_pud; | ||
| 336 | |||
| 337 | void (*set_pgd)(pgd_t *pudp, pgd_t pgdval); | ||
| 338 | #endif /* PAGETABLE_LEVELS == 4 */ | ||
| 339 | #endif /* PAGETABLE_LEVELS >= 3 */ | ||
| 340 | |||
| 341 | #ifdef CONFIG_HIGHPTE | ||
| 342 | void *(*kmap_atomic_pte)(struct page *page, enum km_type type); | ||
| 343 | #endif | ||
| 344 | |||
| 345 | struct pv_lazy_ops lazy_mode; | ||
| 346 | |||
| 347 | /* dom0 ops */ | ||
| 348 | |||
| 349 | /* Sometimes the physical address is a pfn, and sometimes its | ||
| 350 | an mfn. We can tell which is which from the index. */ | ||
| 351 | void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx, | ||
| 352 | phys_addr_t phys, pgprot_t flags); | ||
| 353 | }; | ||
| 354 | |||
| 355 | struct raw_spinlock; | ||
| 356 | struct pv_lock_ops { | ||
| 357 | int (*spin_is_locked)(struct raw_spinlock *lock); | ||
| 358 | int (*spin_is_contended)(struct raw_spinlock *lock); | ||
| 359 | void (*spin_lock)(struct raw_spinlock *lock); | ||
| 360 | void (*spin_lock_flags)(struct raw_spinlock *lock, unsigned long flags); | ||
| 361 | int (*spin_trylock)(struct raw_spinlock *lock); | ||
| 362 | void (*spin_unlock)(struct raw_spinlock *lock); | ||
| 363 | }; | ||
| 364 | |||
| 365 | /* This contains all the paravirt structures: we get a convenient | ||
| 366 | * number for each function using the offset which we use to indicate | ||
| 367 | * what to patch. */ | ||
| 368 | struct paravirt_patch_template { | ||
| 369 | struct pv_init_ops pv_init_ops; | ||
| 370 | struct pv_time_ops pv_time_ops; | ||
| 371 | struct pv_cpu_ops pv_cpu_ops; | ||
| 372 | struct pv_irq_ops pv_irq_ops; | ||
| 373 | struct pv_apic_ops pv_apic_ops; | ||
| 374 | struct pv_mmu_ops pv_mmu_ops; | ||
| 375 | struct pv_lock_ops pv_lock_ops; | ||
| 376 | }; | ||
| 377 | |||
| 378 | extern struct pv_info pv_info; | ||
| 379 | extern struct pv_init_ops pv_init_ops; | ||
| 380 | extern struct pv_time_ops pv_time_ops; | ||
| 381 | extern struct pv_cpu_ops pv_cpu_ops; | ||
| 382 | extern struct pv_irq_ops pv_irq_ops; | ||
| 383 | extern struct pv_apic_ops pv_apic_ops; | ||
| 384 | extern struct pv_mmu_ops pv_mmu_ops; | ||
| 385 | extern struct pv_lock_ops pv_lock_ops; | ||
| 386 | |||
| 387 | #define PARAVIRT_PATCH(x) \ | ||
| 388 | (offsetof(struct paravirt_patch_template, x) / sizeof(void *)) | ||
| 389 | |||
| 390 | #define paravirt_type(op) \ | ||
| 391 | [paravirt_typenum] "i" (PARAVIRT_PATCH(op)), \ | ||
| 392 | [paravirt_opptr] "i" (&(op)) | ||
| 393 | #define paravirt_clobber(clobber) \ | ||
| 394 | [paravirt_clobber] "i" (clobber) | ||
| 395 | |||
| 396 | /* | ||
| 397 | * Generate some code, and mark it as patchable by the | ||
| 398 | * apply_paravirt() alternate instruction patcher. | ||
| 399 | */ | ||
| 400 | #define _paravirt_alt(insn_string, type, clobber) \ | ||
| 401 | "771:\n\t" insn_string "\n" "772:\n" \ | ||
| 402 | ".pushsection .parainstructions,\"a\"\n" \ | ||
| 403 | _ASM_ALIGN "\n" \ | ||
| 404 | _ASM_PTR " 771b\n" \ | ||
| 405 | " .byte " type "\n" \ | ||
| 406 | " .byte 772b-771b\n" \ | ||
| 407 | " .short " clobber "\n" \ | ||
| 408 | ".popsection\n" | ||
| 409 | |||
| 410 | /* Generate patchable code, with the default asm parameters. */ | ||
| 411 | #define paravirt_alt(insn_string) \ | ||
| 412 | _paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]") | ||
| 413 | |||
| 414 | /* Simple instruction patching code. */ | ||
| 415 | #define DEF_NATIVE(ops, name, code) \ | ||
| 416 | extern const char start_##ops##_##name[], end_##ops##_##name[]; \ | ||
| 417 | asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":") | ||
| 418 | |||
| 419 | unsigned paravirt_patch_nop(void); | ||
| 420 | unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len); | ||
| 421 | unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len); | ||
| 422 | unsigned paravirt_patch_ignore(unsigned len); | ||
| 423 | unsigned paravirt_patch_call(void *insnbuf, | ||
| 424 | const void *target, u16 tgt_clobbers, | ||
| 425 | unsigned long addr, u16 site_clobbers, | ||
| 426 | unsigned len); | ||
| 427 | unsigned paravirt_patch_jmp(void *insnbuf, const void *target, | ||
| 428 | unsigned long addr, unsigned len); | ||
| 429 | unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, | ||
| 430 | unsigned long addr, unsigned len); | ||
| 431 | |||
| 432 | unsigned paravirt_patch_insns(void *insnbuf, unsigned len, | ||
| 433 | const char *start, const char *end); | ||
| 434 | |||
| 435 | unsigned native_patch(u8 type, u16 clobbers, void *ibuf, | ||
| 436 | unsigned long addr, unsigned len); | ||
| 437 | |||
| 438 | int paravirt_disable_iospace(void); | ||
| 439 | |||
| 440 | /* | ||
| 441 | * This generates an indirect call based on the operation type number. | ||
| 442 | * The type number, computed in PARAVIRT_PATCH, is derived from the | ||
| 443 | * offset into the paravirt_patch_template structure, and can therefore be | ||
| 444 | * freely converted back into a structure offset. | ||
| 445 | */ | ||
| 446 | #define PARAVIRT_CALL "call *%c[paravirt_opptr];" | ||
| 447 | |||
| 448 | /* | ||
| 449 | * These macros are intended to wrap calls through one of the paravirt | ||
| 450 | * ops structs, so that they can be later identified and patched at | ||
| 451 | * runtime. | ||
| 452 | * | ||
| 453 | * Normally, a call to a pv_op function is a simple indirect call: | ||
| 454 | * (pv_op_struct.operations)(args...). | ||
| 455 | * | ||
| 456 | * Unfortunately, this is a relatively slow operation for modern CPUs, | ||
| 457 | * because it cannot necessarily determine what the destination | ||
| 458 | * address is. In this case, the address is a runtime constant, so at | ||
| 459 | * the very least we can patch the call to e a simple direct call, or | ||
| 460 | * ideally, patch an inline implementation into the callsite. (Direct | ||
| 461 | * calls are essentially free, because the call and return addresses | ||
| 462 | * are completely predictable.) | ||
| 463 | * | ||
| 464 | * For i386, these macros rely on the standard gcc "regparm(3)" calling | ||
| 465 | * convention, in which the first three arguments are placed in %eax, | ||
| 466 | * %edx, %ecx (in that order), and the remaining arguments are placed | ||
| 467 | * on the stack. All caller-save registers (eax,edx,ecx) are expected | ||
| 468 | * to be modified (either clobbered or used for return values). | ||
| 469 | * X86_64, on the other hand, already specifies a register-based calling | ||
| 470 | * conventions, returning at %rax, with parameteres going on %rdi, %rsi, | ||
| 471 | * %rdx, and %rcx. Note that for this reason, x86_64 does not need any | ||
| 472 | * special handling for dealing with 4 arguments, unlike i386. | ||
| 473 | * However, x86_64 also have to clobber all caller saved registers, which | ||
| 474 | * unfortunately, are quite a bit (r8 - r11) | ||
| 475 | * | ||
| 476 | * The call instruction itself is marked by placing its start address | ||
| 477 | * and size into the .parainstructions section, so that | ||
| 478 | * apply_paravirt() in arch/i386/kernel/alternative.c can do the | ||
| 479 | * appropriate patching under the control of the backend pv_init_ops | ||
| 480 | * implementation. | ||
| 481 | * | ||
| 482 | * Unfortunately there's no way to get gcc to generate the args setup | ||
| 483 | * for the call, and then allow the call itself to be generated by an | ||
| 484 | * inline asm. Because of this, we must do the complete arg setup and | ||
| 485 | * return value handling from within these macros. This is fairly | ||
| 486 | * cumbersome. | ||
| 487 | * | ||
| 488 | * There are 5 sets of PVOP_* macros for dealing with 0-4 arguments. | ||
| 489 | * It could be extended to more arguments, but there would be little | ||
| 490 | * to be gained from that. For each number of arguments, there are | ||
| 491 | * the two VCALL and CALL variants for void and non-void functions. | ||
| 492 | * | ||
| 493 | * When there is a return value, the invoker of the macro must specify | ||
| 494 | * the return type. The macro then uses sizeof() on that type to | ||
| 495 | * determine whether its a 32 or 64 bit value, and places the return | ||
| 496 | * in the right register(s) (just %eax for 32-bit, and %edx:%eax for | ||
| 497 | * 64-bit). For x86_64 machines, it just returns at %rax regardless of | ||
| 498 | * the return value size. | ||
| 499 | * | ||
| 500 | * 64-bit arguments are passed as a pair of adjacent 32-bit arguments | ||
| 501 | * i386 also passes 64-bit arguments as a pair of adjacent 32-bit arguments | ||
| 502 | * in low,high order | ||
| 503 | * | ||
| 504 | * Small structures are passed and returned in registers. The macro | ||
| 505 | * calling convention can't directly deal with this, so the wrapper | ||
| 506 | * functions must do this. | ||
| 507 | * | ||
| 508 | * These PVOP_* macros are only defined within this header. This | ||
| 509 | * means that all uses must be wrapped in inline functions. This also | ||
| 510 | * makes sure the incoming and outgoing types are always correct. | ||
| 511 | */ | ||
| 512 | #ifdef CONFIG_X86_32 | ||
| 513 | #define PVOP_VCALL_ARGS \ | ||
| 514 | unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx | ||
| 515 | #define PVOP_CALL_ARGS PVOP_VCALL_ARGS | ||
| 516 | |||
| 517 | #define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x)) | ||
| 518 | #define PVOP_CALL_ARG2(x) "d" ((unsigned long)(x)) | ||
| 519 | #define PVOP_CALL_ARG3(x) "c" ((unsigned long)(x)) | ||
| 520 | |||
| 521 | #define PVOP_VCALL_CLOBBERS "=a" (__eax), "=d" (__edx), \ | ||
| 522 | "=c" (__ecx) | ||
| 523 | #define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS | ||
| 524 | |||
| 525 | #define PVOP_VCALLEE_CLOBBERS "=a" (__eax), "=d" (__edx) | ||
| 526 | #define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS | ||
| 527 | |||
| 528 | #define EXTRA_CLOBBERS | ||
| 529 | #define VEXTRA_CLOBBERS | ||
| 530 | #else /* CONFIG_X86_64 */ | ||
| 531 | #define PVOP_VCALL_ARGS \ | ||
| 532 | unsigned long __edi = __edi, __esi = __esi, \ | ||
| 533 | __edx = __edx, __ecx = __ecx | ||
| 534 | #define PVOP_CALL_ARGS PVOP_VCALL_ARGS, __eax | ||
| 535 | |||
| 536 | #define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x)) | ||
| 537 | #define PVOP_CALL_ARG2(x) "S" ((unsigned long)(x)) | ||
| 538 | #define PVOP_CALL_ARG3(x) "d" ((unsigned long)(x)) | ||
| 539 | #define PVOP_CALL_ARG4(x) "c" ((unsigned long)(x)) | ||
| 540 | |||
| 541 | #define PVOP_VCALL_CLOBBERS "=D" (__edi), \ | ||
| 542 | "=S" (__esi), "=d" (__edx), \ | ||
| 543 | "=c" (__ecx) | ||
| 544 | #define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax) | ||
| 545 | |||
| 546 | #define PVOP_VCALLEE_CLOBBERS "=a" (__eax) | ||
| 547 | #define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS | ||
| 548 | |||
| 549 | #define EXTRA_CLOBBERS , "r8", "r9", "r10", "r11" | ||
| 550 | #define VEXTRA_CLOBBERS , "rax", "r8", "r9", "r10", "r11" | ||
| 551 | #endif /* CONFIG_X86_32 */ | ||
| 552 | |||
| 553 | #ifdef CONFIG_PARAVIRT_DEBUG | ||
| 554 | #define PVOP_TEST_NULL(op) BUG_ON(op == NULL) | ||
| 555 | #else | ||
| 556 | #define PVOP_TEST_NULL(op) ((void)op) | ||
| 557 | #endif | ||
| 558 | |||
| 559 | #define ____PVOP_CALL(rettype, op, clbr, call_clbr, extra_clbr, \ | ||
| 560 | pre, post, ...) \ | ||
| 561 | ({ \ | ||
| 562 | rettype __ret; \ | ||
| 563 | PVOP_CALL_ARGS; \ | ||
| 564 | PVOP_TEST_NULL(op); \ | ||
| 565 | /* This is 32-bit specific, but is okay in 64-bit */ \ | ||
| 566 | /* since this condition will never hold */ \ | ||
| 567 | if (sizeof(rettype) > sizeof(unsigned long)) { \ | ||
| 568 | asm volatile(pre \ | ||
| 569 | paravirt_alt(PARAVIRT_CALL) \ | ||
| 570 | post \ | ||
| 571 | : call_clbr \ | ||
| 572 | : paravirt_type(op), \ | ||
| 573 | paravirt_clobber(clbr), \ | ||
| 574 | ##__VA_ARGS__ \ | ||
| 575 | : "memory", "cc" extra_clbr); \ | ||
| 576 | __ret = (rettype)((((u64)__edx) << 32) | __eax); \ | ||
| 577 | } else { \ | ||
| 578 | asm volatile(pre \ | ||
| 579 | paravirt_alt(PARAVIRT_CALL) \ | ||
| 580 | post \ | ||
| 581 | : call_clbr \ | ||
| 582 | : paravirt_type(op), \ | ||
| 583 | paravirt_clobber(clbr), \ | ||
| 584 | ##__VA_ARGS__ \ | ||
| 585 | : "memory", "cc" extra_clbr); \ | ||
| 586 | __ret = (rettype)__eax; \ | ||
| 587 | } \ | ||
| 588 | __ret; \ | ||
| 589 | }) | ||
| 590 | |||
| 591 | #define __PVOP_CALL(rettype, op, pre, post, ...) \ | ||
| 592 | ____PVOP_CALL(rettype, op, CLBR_ANY, PVOP_CALL_CLOBBERS, \ | ||
| 593 | EXTRA_CLOBBERS, pre, post, ##__VA_ARGS__) | ||
| 594 | |||
| 595 | #define __PVOP_CALLEESAVE(rettype, op, pre, post, ...) \ | ||
| 596 | ____PVOP_CALL(rettype, op.func, CLBR_RET_REG, \ | ||
| 597 | PVOP_CALLEE_CLOBBERS, , \ | ||
| 598 | pre, post, ##__VA_ARGS__) | ||
| 599 | |||
| 600 | |||
| 601 | #define ____PVOP_VCALL(op, clbr, call_clbr, extra_clbr, pre, post, ...) \ | ||
| 602 | ({ \ | ||
| 603 | PVOP_VCALL_ARGS; \ | ||
| 604 | PVOP_TEST_NULL(op); \ | ||
| 605 | asm volatile(pre \ | ||
| 606 | paravirt_alt(PARAVIRT_CALL) \ | ||
| 607 | post \ | ||
| 608 | : call_clbr \ | ||
| 609 | : paravirt_type(op), \ | ||
| 610 | paravirt_clobber(clbr), \ | ||
| 611 | ##__VA_ARGS__ \ | ||
| 612 | : "memory", "cc" extra_clbr); \ | ||
| 613 | }) | ||
| 614 | |||
| 615 | #define __PVOP_VCALL(op, pre, post, ...) \ | ||
| 616 | ____PVOP_VCALL(op, CLBR_ANY, PVOP_VCALL_CLOBBERS, \ | ||
| 617 | VEXTRA_CLOBBERS, \ | ||
| 618 | pre, post, ##__VA_ARGS__) | ||
| 619 | |||
| 620 | #define __PVOP_VCALLEESAVE(rettype, op, pre, post, ...) \ | ||
| 621 | ____PVOP_CALL(rettype, op.func, CLBR_RET_REG, \ | ||
| 622 | PVOP_VCALLEE_CLOBBERS, , \ | ||
| 623 | pre, post, ##__VA_ARGS__) | ||
| 624 | |||
| 625 | |||
| 626 | |||
| 627 | #define PVOP_CALL0(rettype, op) \ | ||
| 628 | __PVOP_CALL(rettype, op, "", "") | ||
| 629 | #define PVOP_VCALL0(op) \ | ||
| 630 | __PVOP_VCALL(op, "", "") | ||
| 631 | |||
| 632 | #define PVOP_CALLEE0(rettype, op) \ | ||
| 633 | __PVOP_CALLEESAVE(rettype, op, "", "") | ||
| 634 | #define PVOP_VCALLEE0(op) \ | ||
| 635 | __PVOP_VCALLEESAVE(op, "", "") | ||
| 636 | |||
| 637 | |||
| 638 | #define PVOP_CALL1(rettype, op, arg1) \ | ||
| 639 | __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1)) | ||
| 640 | #define PVOP_VCALL1(op, arg1) \ | ||
| 641 | __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1)) | ||
| 642 | |||
| 643 | #define PVOP_CALLEE1(rettype, op, arg1) \ | ||
| 644 | __PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1)) | ||
| 645 | #define PVOP_VCALLEE1(op, arg1) \ | ||
| 646 | __PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1)) | ||
| 647 | |||
| 648 | |||
| 649 | #define PVOP_CALL2(rettype, op, arg1, arg2) \ | ||
| 650 | __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \ | ||
| 651 | PVOP_CALL_ARG2(arg2)) | ||
| 652 | #define PVOP_VCALL2(op, arg1, arg2) \ | ||
| 653 | __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1), \ | ||
| 654 | PVOP_CALL_ARG2(arg2)) | ||
| 655 | |||
| 656 | #define PVOP_CALLEE2(rettype, op, arg1, arg2) \ | ||
| 657 | __PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \ | ||
| 658 | PVOP_CALL_ARG2(arg2)) | ||
| 659 | #define PVOP_VCALLEE2(op, arg1, arg2) \ | ||
| 660 | __PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1), \ | ||
| 661 | PVOP_CALL_ARG2(arg2)) | ||
| 662 | |||
| 663 | |||
| 664 | #define PVOP_CALL3(rettype, op, arg1, arg2, arg3) \ | ||
| 665 | __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \ | ||
| 666 | PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3)) | ||
| 667 | #define PVOP_VCALL3(op, arg1, arg2, arg3) \ | ||
| 668 | __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1), \ | ||
| 669 | PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3)) | ||
| 670 | |||
| 671 | /* This is the only difference in x86_64. We can make it much simpler */ | ||
| 672 | #ifdef CONFIG_X86_32 | ||
| 673 | #define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \ | ||
| 674 | __PVOP_CALL(rettype, op, \ | ||
| 675 | "push %[_arg4];", "lea 4(%%esp),%%esp;", \ | ||
| 676 | PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \ | ||
| 677 | PVOP_CALL_ARG3(arg3), [_arg4] "mr" ((u32)(arg4))) | ||
| 678 | #define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \ | ||
| 679 | __PVOP_VCALL(op, \ | ||
| 680 | "push %[_arg4];", "lea 4(%%esp),%%esp;", \ | ||
| 681 | "0" ((u32)(arg1)), "1" ((u32)(arg2)), \ | ||
| 682 | "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4))) | ||
| 683 | #else | ||
| 684 | #define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \ | ||
| 685 | __PVOP_CALL(rettype, op, "", "", \ | ||
| 686 | PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \ | ||
| 687 | PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4)) | ||
| 688 | #define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \ | ||
| 689 | __PVOP_VCALL(op, "", "", \ | ||
| 690 | PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \ | ||
| 691 | PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4)) | ||
| 692 | #endif | ||
| 693 | 15 | ||
| 694 | static inline int paravirt_enabled(void) | 16 | static inline int paravirt_enabled(void) |
| 695 | { | 17 | { |
| @@ -820,15 +142,22 @@ static inline u64 paravirt_read_msr(unsigned msr, int *err) | |||
| 820 | { | 142 | { |
| 821 | return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err); | 143 | return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err); |
| 822 | } | 144 | } |
| 823 | static inline u64 paravirt_read_msr_amd(unsigned msr, int *err) | 145 | |
| 146 | static inline int paravirt_rdmsr_regs(u32 *regs) | ||
| 824 | { | 147 | { |
| 825 | return PVOP_CALL2(u64, pv_cpu_ops.read_msr_amd, msr, err); | 148 | return PVOP_CALL1(int, pv_cpu_ops.rdmsr_regs, regs); |
| 826 | } | 149 | } |
| 150 | |||
| 827 | static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high) | 151 | static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high) |
| 828 | { | 152 | { |
| 829 | return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high); | 153 | return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high); |
| 830 | } | 154 | } |
| 831 | 155 | ||
| 156 | static inline int paravirt_wrmsr_regs(u32 *regs) | ||
| 157 | { | ||
| 158 | return PVOP_CALL1(int, pv_cpu_ops.wrmsr_regs, regs); | ||
| 159 | } | ||
| 160 | |||
| 832 | /* These should all do BUG_ON(_err), but our headers are too tangled. */ | 161 | /* These should all do BUG_ON(_err), but our headers are too tangled. */ |
| 833 | #define rdmsr(msr, val1, val2) \ | 162 | #define rdmsr(msr, val1, val2) \ |
| 834 | do { \ | 163 | do { \ |
| @@ -862,6 +191,9 @@ do { \ | |||
| 862 | _err; \ | 191 | _err; \ |
| 863 | }) | 192 | }) |
| 864 | 193 | ||
| 194 | #define rdmsr_safe_regs(regs) paravirt_rdmsr_regs(regs) | ||
| 195 | #define wrmsr_safe_regs(regs) paravirt_wrmsr_regs(regs) | ||
| 196 | |||
| 865 | static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) | 197 | static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) |
| 866 | { | 198 | { |
| 867 | int err; | 199 | int err; |
| @@ -871,12 +203,31 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) | |||
| 871 | } | 203 | } |
| 872 | static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) | 204 | static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) |
| 873 | { | 205 | { |
| 206 | u32 gprs[8] = { 0 }; | ||
| 874 | int err; | 207 | int err; |
| 875 | 208 | ||
| 876 | *p = paravirt_read_msr_amd(msr, &err); | 209 | gprs[1] = msr; |
| 210 | gprs[7] = 0x9c5a203a; | ||
| 211 | |||
| 212 | err = paravirt_rdmsr_regs(gprs); | ||
| 213 | |||
| 214 | *p = gprs[0] | ((u64)gprs[2] << 32); | ||
| 215 | |||
| 877 | return err; | 216 | return err; |
| 878 | } | 217 | } |
| 879 | 218 | ||
| 219 | static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) | ||
| 220 | { | ||
| 221 | u32 gprs[8] = { 0 }; | ||
| 222 | |||
| 223 | gprs[0] = (u32)val; | ||
| 224 | gprs[1] = msr; | ||
| 225 | gprs[2] = val >> 32; | ||
| 226 | gprs[7] = 0x9c5a203a; | ||
| 227 | |||
| 228 | return paravirt_wrmsr_regs(gprs); | ||
| 229 | } | ||
| 230 | |||
| 880 | static inline u64 paravirt_read_tsc(void) | 231 | static inline u64 paravirt_read_tsc(void) |
| 881 | { | 232 | { |
| 882 | return PVOP_CALL0(u64, pv_cpu_ops.read_tsc); | 233 | return PVOP_CALL0(u64, pv_cpu_ops.read_tsc); |
| @@ -1393,20 +744,6 @@ static inline void pmd_clear(pmd_t *pmdp) | |||
| 1393 | } | 744 | } |
| 1394 | #endif /* CONFIG_X86_PAE */ | 745 | #endif /* CONFIG_X86_PAE */ |
| 1395 | 746 | ||
| 1396 | /* Lazy mode for batching updates / context switch */ | ||
| 1397 | enum paravirt_lazy_mode { | ||
| 1398 | PARAVIRT_LAZY_NONE, | ||
| 1399 | PARAVIRT_LAZY_MMU, | ||
| 1400 | PARAVIRT_LAZY_CPU, | ||
| 1401 | }; | ||
| 1402 | |||
| 1403 | enum paravirt_lazy_mode paravirt_get_lazy_mode(void); | ||
| 1404 | void paravirt_start_context_switch(struct task_struct *prev); | ||
| 1405 | void paravirt_end_context_switch(struct task_struct *next); | ||
| 1406 | |||
| 1407 | void paravirt_enter_lazy_mmu(void); | ||
| 1408 | void paravirt_leave_lazy_mmu(void); | ||
| 1409 | |||
| 1410 | #define __HAVE_ARCH_START_CONTEXT_SWITCH | 747 | #define __HAVE_ARCH_START_CONTEXT_SWITCH |
| 1411 | static inline void arch_start_context_switch(struct task_struct *prev) | 748 | static inline void arch_start_context_switch(struct task_struct *prev) |
| 1412 | { | 749 | { |
| @@ -1437,12 +774,6 @@ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, | |||
| 1437 | pv_mmu_ops.set_fixmap(idx, phys, flags); | 774 | pv_mmu_ops.set_fixmap(idx, phys, flags); |
| 1438 | } | 775 | } |
| 1439 | 776 | ||
| 1440 | void _paravirt_nop(void); | ||
| 1441 | u32 _paravirt_ident_32(u32); | ||
| 1442 | u64 _paravirt_ident_64(u64); | ||
| 1443 | |||
| 1444 | #define paravirt_nop ((void *)_paravirt_nop) | ||
| 1445 | |||
| 1446 | #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) | 777 | #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) |
| 1447 | 778 | ||
| 1448 | static inline int __raw_spin_is_locked(struct raw_spinlock *lock) | 779 | static inline int __raw_spin_is_locked(struct raw_spinlock *lock) |
| @@ -1479,17 +810,6 @@ static __always_inline void __raw_spin_unlock(struct raw_spinlock *lock) | |||
| 1479 | 810 | ||
| 1480 | #endif | 811 | #endif |
| 1481 | 812 | ||
| 1482 | /* These all sit in the .parainstructions section to tell us what to patch. */ | ||
| 1483 | struct paravirt_patch_site { | ||
| 1484 | u8 *instr; /* original instructions */ | ||
| 1485 | u8 instrtype; /* type of this instruction */ | ||
| 1486 | u8 len; /* length of original instruction */ | ||
| 1487 | u16 clobbers; /* what registers you may clobber */ | ||
| 1488 | }; | ||
| 1489 | |||
| 1490 | extern struct paravirt_patch_site __parainstructions[], | ||
| 1491 | __parainstructions_end[]; | ||
| 1492 | |||
| 1493 | #ifdef CONFIG_X86_32 | 813 | #ifdef CONFIG_X86_32 |
| 1494 | #define PV_SAVE_REGS "pushl %ecx; pushl %edx;" | 814 | #define PV_SAVE_REGS "pushl %ecx; pushl %edx;" |
| 1495 | #define PV_RESTORE_REGS "popl %edx; popl %ecx;" | 815 | #define PV_RESTORE_REGS "popl %edx; popl %ecx;" |
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h new file mode 100644 index 000000000000..25402d0006e7 --- /dev/null +++ b/arch/x86/include/asm/paravirt_types.h | |||
| @@ -0,0 +1,721 @@ | |||
| 1 | #ifndef _ASM_X86_PARAVIRT_TYPES_H | ||
| 2 | #define _ASM_X86_PARAVIRT_TYPES_H | ||
| 3 | |||
| 4 | /* Bitmask of what can be clobbered: usually at least eax. */ | ||
| 5 | #define CLBR_NONE 0 | ||
| 6 | #define CLBR_EAX (1 << 0) | ||
| 7 | #define CLBR_ECX (1 << 1) | ||
| 8 | #define CLBR_EDX (1 << 2) | ||
| 9 | #define CLBR_EDI (1 << 3) | ||
| 10 | |||
| 11 | #ifdef CONFIG_X86_32 | ||
| 12 | /* CLBR_ANY should match all regs platform has. For i386, that's just it */ | ||
| 13 | #define CLBR_ANY ((1 << 4) - 1) | ||
| 14 | |||
| 15 | #define CLBR_ARG_REGS (CLBR_EAX | CLBR_EDX | CLBR_ECX) | ||
| 16 | #define CLBR_RET_REG (CLBR_EAX | CLBR_EDX) | ||
| 17 | #define CLBR_SCRATCH (0) | ||
| 18 | #else | ||
| 19 | #define CLBR_RAX CLBR_EAX | ||
| 20 | #define CLBR_RCX CLBR_ECX | ||
| 21 | #define CLBR_RDX CLBR_EDX | ||
| 22 | #define CLBR_RDI CLBR_EDI | ||
| 23 | #define CLBR_RSI (1 << 4) | ||
| 24 | #define CLBR_R8 (1 << 5) | ||
| 25 | #define CLBR_R9 (1 << 6) | ||
| 26 | #define CLBR_R10 (1 << 7) | ||
| 27 | #define CLBR_R11 (1 << 8) | ||
| 28 | |||
| 29 | #define CLBR_ANY ((1 << 9) - 1) | ||
| 30 | |||
| 31 | #define CLBR_ARG_REGS (CLBR_RDI | CLBR_RSI | CLBR_RDX | \ | ||
| 32 | CLBR_RCX | CLBR_R8 | CLBR_R9) | ||
| 33 | #define CLBR_RET_REG (CLBR_RAX) | ||
| 34 | #define CLBR_SCRATCH (CLBR_R10 | CLBR_R11) | ||
| 35 | |||
| 36 | #endif /* X86_64 */ | ||
| 37 | |||
| 38 | #define CLBR_CALLEE_SAVE ((CLBR_ARG_REGS | CLBR_SCRATCH) & ~CLBR_RET_REG) | ||
| 39 | |||
| 40 | #ifndef __ASSEMBLY__ | ||
| 41 | |||
| 42 | #include <asm/desc_defs.h> | ||
| 43 | #include <asm/kmap_types.h> | ||
| 44 | |||
| 45 | struct page; | ||
| 46 | struct thread_struct; | ||
| 47 | struct desc_ptr; | ||
| 48 | struct tss_struct; | ||
| 49 | struct mm_struct; | ||
| 50 | struct desc_struct; | ||
| 51 | struct task_struct; | ||
| 52 | struct cpumask; | ||
| 53 | |||
| 54 | /* | ||
| 55 | * Wrapper type for pointers to code which uses the non-standard | ||
| 56 | * calling convention. See PV_CALL_SAVE_REGS_THUNK below. | ||
| 57 | */ | ||
| 58 | struct paravirt_callee_save { | ||
| 59 | void *func; | ||
| 60 | }; | ||
| 61 | |||
| 62 | /* general info */ | ||
| 63 | struct pv_info { | ||
| 64 | unsigned int kernel_rpl; | ||
| 65 | int shared_kernel_pmd; | ||
| 66 | int paravirt_enabled; | ||
| 67 | const char *name; | ||
| 68 | }; | ||
| 69 | |||
| 70 | struct pv_init_ops { | ||
| 71 | /* | ||
| 72 | * Patch may replace one of the defined code sequences with | ||
| 73 | * arbitrary code, subject to the same register constraints. | ||
| 74 | * This generally means the code is not free to clobber any | ||
| 75 | * registers other than EAX. The patch function should return | ||
| 76 | * the number of bytes of code generated, as we nop pad the | ||
| 77 | * rest in generic code. | ||
| 78 | */ | ||
| 79 | unsigned (*patch)(u8 type, u16 clobber, void *insnbuf, | ||
| 80 | unsigned long addr, unsigned len); | ||
| 81 | |||
| 82 | /* Basic arch-specific setup */ | ||
| 83 | void (*arch_setup)(void); | ||
| 84 | char *(*memory_setup)(void); | ||
| 85 | void (*post_allocator_init)(void); | ||
| 86 | |||
| 87 | /* Print a banner to identify the environment */ | ||
| 88 | void (*banner)(void); | ||
| 89 | }; | ||
| 90 | |||
| 91 | |||
| 92 | struct pv_lazy_ops { | ||
| 93 | /* Set deferred update mode, used for batching operations. */ | ||
| 94 | void (*enter)(void); | ||
| 95 | void (*leave)(void); | ||
| 96 | }; | ||
| 97 | |||
| 98 | struct pv_time_ops { | ||
| 99 | void (*time_init)(void); | ||
| 100 | |||
| 101 | /* Set and set time of day */ | ||
| 102 | unsigned long (*get_wallclock)(void); | ||
| 103 | int (*set_wallclock)(unsigned long); | ||
| 104 | |||
| 105 | unsigned long long (*sched_clock)(void); | ||
| 106 | unsigned long (*get_tsc_khz)(void); | ||
| 107 | }; | ||
| 108 | |||
| 109 | struct pv_cpu_ops { | ||
| 110 | /* hooks for various privileged instructions */ | ||
| 111 | unsigned long (*get_debugreg)(int regno); | ||
| 112 | void (*set_debugreg)(int regno, unsigned long value); | ||
| 113 | |||
| 114 | void (*clts)(void); | ||
| 115 | |||
| 116 | unsigned long (*read_cr0)(void); | ||
| 117 | void (*write_cr0)(unsigned long); | ||
| 118 | |||
| 119 | unsigned long (*read_cr4_safe)(void); | ||
| 120 | unsigned long (*read_cr4)(void); | ||
| 121 | void (*write_cr4)(unsigned long); | ||
| 122 | |||
| 123 | #ifdef CONFIG_X86_64 | ||
| 124 | unsigned long (*read_cr8)(void); | ||
| 125 | void (*write_cr8)(unsigned long); | ||
| 126 | #endif | ||
| 127 | |||
| 128 | /* Segment descriptor handling */ | ||
| 129 | void (*load_tr_desc)(void); | ||
| 130 | void (*load_gdt)(const struct desc_ptr *); | ||
| 131 | void (*load_idt)(const struct desc_ptr *); | ||
| 132 | void (*store_gdt)(struct desc_ptr *); | ||
| 133 | void (*store_idt)(struct desc_ptr *); | ||
| 134 | void (*set_ldt)(const void *desc, unsigned entries); | ||
| 135 | unsigned long (*store_tr)(void); | ||
| 136 | void (*load_tls)(struct thread_struct *t, unsigned int cpu); | ||
| 137 | #ifdef CONFIG_X86_64 | ||
| 138 | void (*load_gs_index)(unsigned int idx); | ||
| 139 | #endif | ||
| 140 | void (*write_ldt_entry)(struct desc_struct *ldt, int entrynum, | ||
| 141 | const void *desc); | ||
| 142 | void (*write_gdt_entry)(struct desc_struct *, | ||
| 143 | int entrynum, const void *desc, int size); | ||
| 144 | void (*write_idt_entry)(gate_desc *, | ||
| 145 | int entrynum, const gate_desc *gate); | ||
| 146 | void (*alloc_ldt)(struct desc_struct *ldt, unsigned entries); | ||
| 147 | void (*free_ldt)(struct desc_struct *ldt, unsigned entries); | ||
| 148 | |||
| 149 | void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t); | ||
| 150 | |||
| 151 | void (*set_iopl_mask)(unsigned mask); | ||
| 152 | |||
| 153 | void (*wbinvd)(void); | ||
| 154 | void (*io_delay)(void); | ||
| 155 | |||
| 156 | /* cpuid emulation, mostly so that caps bits can be disabled */ | ||
| 157 | void (*cpuid)(unsigned int *eax, unsigned int *ebx, | ||
| 158 | unsigned int *ecx, unsigned int *edx); | ||
| 159 | |||
| 160 | /* MSR, PMC and TSR operations. | ||
| 161 | err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */ | ||
| 162 | u64 (*read_msr)(unsigned int msr, int *err); | ||
| 163 | int (*rdmsr_regs)(u32 *regs); | ||
| 164 | int (*write_msr)(unsigned int msr, unsigned low, unsigned high); | ||
| 165 | int (*wrmsr_regs)(u32 *regs); | ||
| 166 | |||
| 167 | u64 (*read_tsc)(void); | ||
| 168 | u64 (*read_pmc)(int counter); | ||
| 169 | unsigned long long (*read_tscp)(unsigned int *aux); | ||
| 170 | |||
| 171 | /* | ||
| 172 | * Atomically enable interrupts and return to userspace. This | ||
| 173 | * is only ever used to return to 32-bit processes; in a | ||
| 174 | * 64-bit kernel, it's used for 32-on-64 compat processes, but | ||
| 175 | * never native 64-bit processes. (Jump, not call.) | ||
| 176 | */ | ||
| 177 | void (*irq_enable_sysexit)(void); | ||
| 178 | |||
| 179 | /* | ||
| 180 | * Switch to usermode gs and return to 64-bit usermode using | ||
| 181 | * sysret. Only used in 64-bit kernels to return to 64-bit | ||
| 182 | * processes. Usermode register state, including %rsp, must | ||
| 183 | * already be restored. | ||
| 184 | */ | ||
| 185 | void (*usergs_sysret64)(void); | ||
| 186 | |||
| 187 | /* | ||
| 188 | * Switch to usermode gs and return to 32-bit usermode using | ||
| 189 | * sysret. Used to return to 32-on-64 compat processes. | ||
| 190 | * Other usermode register state, including %esp, must already | ||
| 191 | * be restored. | ||
| 192 | */ | ||
| 193 | void (*usergs_sysret32)(void); | ||
| 194 | |||
| 195 | /* Normal iret. Jump to this with the standard iret stack | ||
| 196 | frame set up. */ | ||
| 197 | void (*iret)(void); | ||
| 198 | |||
| 199 | void (*swapgs)(void); | ||
| 200 | |||
| 201 | void (*start_context_switch)(struct task_struct *prev); | ||
| 202 | void (*end_context_switch)(struct task_struct *next); | ||
| 203 | }; | ||
| 204 | |||
| 205 | struct pv_irq_ops { | ||
| 206 | void (*init_IRQ)(void); | ||
| 207 | |||
| 208 | /* | ||
| 209 | * Get/set interrupt state. save_fl and restore_fl are only | ||
| 210 | * expected to use X86_EFLAGS_IF; all other bits | ||
| 211 | * returned from save_fl are undefined, and may be ignored by | ||
| 212 | * restore_fl. | ||
| 213 | * | ||
| 214 | * NOTE: These functions callers expect the callee to preserve | ||
| 215 | * more registers than the standard C calling convention. | ||
| 216 | */ | ||
| 217 | struct paravirt_callee_save save_fl; | ||
| 218 | struct paravirt_callee_save restore_fl; | ||
| 219 | struct paravirt_callee_save irq_disable; | ||
| 220 | struct paravirt_callee_save irq_enable; | ||
| 221 | |||
| 222 | void (*safe_halt)(void); | ||
| 223 | void (*halt)(void); | ||
| 224 | |||
| 225 | #ifdef CONFIG_X86_64 | ||
| 226 | void (*adjust_exception_frame)(void); | ||
| 227 | #endif | ||
| 228 | }; | ||
| 229 | |||
| 230 | struct pv_apic_ops { | ||
| 231 | #ifdef CONFIG_X86_LOCAL_APIC | ||
| 232 | void (*setup_boot_clock)(void); | ||
| 233 | void (*setup_secondary_clock)(void); | ||
| 234 | |||
| 235 | void (*startup_ipi_hook)(int phys_apicid, | ||
| 236 | unsigned long start_eip, | ||
| 237 | unsigned long start_esp); | ||
| 238 | #endif | ||
| 239 | }; | ||
| 240 | |||
| 241 | struct pv_mmu_ops { | ||
| 242 | /* | ||
| 243 | * Called before/after init_mm pagetable setup. setup_start | ||
| 244 | * may reset %cr3, and may pre-install parts of the pagetable; | ||
| 245 | * pagetable setup is expected to preserve any existing | ||
| 246 | * mapping. | ||
| 247 | */ | ||
| 248 | void (*pagetable_setup_start)(pgd_t *pgd_base); | ||
| 249 | void (*pagetable_setup_done)(pgd_t *pgd_base); | ||
| 250 | |||
| 251 | unsigned long (*read_cr2)(void); | ||
| 252 | void (*write_cr2)(unsigned long); | ||
| 253 | |||
| 254 | unsigned long (*read_cr3)(void); | ||
| 255 | void (*write_cr3)(unsigned long); | ||
| 256 | |||
| 257 | /* | ||
| 258 | * Hooks for intercepting the creation/use/destruction of an | ||
| 259 | * mm_struct. | ||
| 260 | */ | ||
| 261 | void (*activate_mm)(struct mm_struct *prev, | ||
| 262 | struct mm_struct *next); | ||
| 263 | void (*dup_mmap)(struct mm_struct *oldmm, | ||
| 264 | struct mm_struct *mm); | ||
| 265 | void (*exit_mmap)(struct mm_struct *mm); | ||
| 266 | |||
| 267 | |||
| 268 | /* TLB operations */ | ||
| 269 | void (*flush_tlb_user)(void); | ||
| 270 | void (*flush_tlb_kernel)(void); | ||
| 271 | void (*flush_tlb_single)(unsigned long addr); | ||
| 272 | void (*flush_tlb_others)(const struct cpumask *cpus, | ||
| 273 | struct mm_struct *mm, | ||
| 274 | unsigned long va); | ||
| 275 | |||
| 276 | /* Hooks for allocating and freeing a pagetable top-level */ | ||
| 277 | int (*pgd_alloc)(struct mm_struct *mm); | ||
| 278 | void (*pgd_free)(struct mm_struct *mm, pgd_t *pgd); | ||
| 279 | |||
| 280 | /* | ||
| 281 | * Hooks for allocating/releasing pagetable pages when they're | ||
| 282 | * attached to a pagetable | ||
| 283 | */ | ||
| 284 | void (*alloc_pte)(struct mm_struct *mm, unsigned long pfn); | ||
| 285 | void (*alloc_pmd)(struct mm_struct *mm, unsigned long pfn); | ||
| 286 | void (*alloc_pmd_clone)(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count); | ||
| 287 | void (*alloc_pud)(struct mm_struct *mm, unsigned long pfn); | ||
| 288 | void (*release_pte)(unsigned long pfn); | ||
| 289 | void (*release_pmd)(unsigned long pfn); | ||
| 290 | void (*release_pud)(unsigned long pfn); | ||
| 291 | |||
| 292 | /* Pagetable manipulation functions */ | ||
| 293 | void (*set_pte)(pte_t *ptep, pte_t pteval); | ||
| 294 | void (*set_pte_at)(struct mm_struct *mm, unsigned long addr, | ||
| 295 | pte_t *ptep, pte_t pteval); | ||
| 296 | void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval); | ||
| 297 | void (*pte_update)(struct mm_struct *mm, unsigned long addr, | ||
| 298 | pte_t *ptep); | ||
| 299 | void (*pte_update_defer)(struct mm_struct *mm, | ||
| 300 | unsigned long addr, pte_t *ptep); | ||
| 301 | |||
| 302 | pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr, | ||
| 303 | pte_t *ptep); | ||
| 304 | void (*ptep_modify_prot_commit)(struct mm_struct *mm, unsigned long addr, | ||
| 305 | pte_t *ptep, pte_t pte); | ||
| 306 | |||
| 307 | struct paravirt_callee_save pte_val; | ||
| 308 | struct paravirt_callee_save make_pte; | ||
| 309 | |||
| 310 | struct paravirt_callee_save pgd_val; | ||
| 311 | struct paravirt_callee_save make_pgd; | ||
| 312 | |||
| 313 | #if PAGETABLE_LEVELS >= 3 | ||
| 314 | #ifdef CONFIG_X86_PAE | ||
| 315 | void (*set_pte_atomic)(pte_t *ptep, pte_t pteval); | ||
| 316 | void (*pte_clear)(struct mm_struct *mm, unsigned long addr, | ||
| 317 | pte_t *ptep); | ||
| 318 | void (*pmd_clear)(pmd_t *pmdp); | ||
| 319 | |||
| 320 | #endif /* CONFIG_X86_PAE */ | ||
| 321 | |||
| 322 | void (*set_pud)(pud_t *pudp, pud_t pudval); | ||
| 323 | |||
| 324 | struct paravirt_callee_save pmd_val; | ||
| 325 | struct paravirt_callee_save make_pmd; | ||
| 326 | |||
| 327 | #if PAGETABLE_LEVELS == 4 | ||
| 328 | struct paravirt_callee_save pud_val; | ||
| 329 | struct paravirt_callee_save make_pud; | ||
| 330 | |||
| 331 | void (*set_pgd)(pgd_t *pudp, pgd_t pgdval); | ||
| 332 | #endif /* PAGETABLE_LEVELS == 4 */ | ||
| 333 | #endif /* PAGETABLE_LEVELS >= 3 */ | ||
| 334 | |||
| 335 | #ifdef CONFIG_HIGHPTE | ||
| 336 | void *(*kmap_atomic_pte)(struct page *page, enum km_type type); | ||
| 337 | #endif | ||
| 338 | |||
| 339 | struct pv_lazy_ops lazy_mode; | ||
| 340 | |||
| 341 | /* dom0 ops */ | ||
| 342 | |||
| 343 | /* Sometimes the physical address is a pfn, and sometimes its | ||
| 344 | an mfn. We can tell which is which from the index. */ | ||
| 345 | void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx, | ||
| 346 | phys_addr_t phys, pgprot_t flags); | ||
| 347 | }; | ||
| 348 | |||
| 349 | struct raw_spinlock; | ||
| 350 | struct pv_lock_ops { | ||
| 351 | int (*spin_is_locked)(struct raw_spinlock *lock); | ||
| 352 | int (*spin_is_contended)(struct raw_spinlock *lock); | ||
| 353 | void (*spin_lock)(struct raw_spinlock *lock); | ||
| 354 | void (*spin_lock_flags)(struct raw_spinlock *lock, unsigned long flags); | ||
| 355 | int (*spin_trylock)(struct raw_spinlock *lock); | ||
| 356 | void (*spin_unlock)(struct raw_spinlock *lock); | ||
| 357 | }; | ||
| 358 | |||
| 359 | /* This contains all the paravirt structures: we get a convenient | ||
| 360 | * number for each function using the offset which we use to indicate | ||
| 361 | * what to patch. */ | ||
| 362 | struct paravirt_patch_template { | ||
| 363 | struct pv_init_ops pv_init_ops; | ||
| 364 | struct pv_time_ops pv_time_ops; | ||
| 365 | struct pv_cpu_ops pv_cpu_ops; | ||
| 366 | struct pv_irq_ops pv_irq_ops; | ||
| 367 | struct pv_apic_ops pv_apic_ops; | ||
| 368 | struct pv_mmu_ops pv_mmu_ops; | ||
| 369 | struct pv_lock_ops pv_lock_ops; | ||
| 370 | }; | ||
| 371 | |||
| 372 | extern struct pv_info pv_info; | ||
| 373 | extern struct pv_init_ops pv_init_ops; | ||
| 374 | extern struct pv_time_ops pv_time_ops; | ||
| 375 | extern struct pv_cpu_ops pv_cpu_ops; | ||
| 376 | extern struct pv_irq_ops pv_irq_ops; | ||
| 377 | extern struct pv_apic_ops pv_apic_ops; | ||
| 378 | extern struct pv_mmu_ops pv_mmu_ops; | ||
| 379 | extern struct pv_lock_ops pv_lock_ops; | ||
| 380 | |||
| 381 | #define PARAVIRT_PATCH(x) \ | ||
| 382 | (offsetof(struct paravirt_patch_template, x) / sizeof(void *)) | ||
| 383 | |||
| 384 | #define paravirt_type(op) \ | ||
| 385 | [paravirt_typenum] "i" (PARAVIRT_PATCH(op)), \ | ||
| 386 | [paravirt_opptr] "i" (&(op)) | ||
| 387 | #define paravirt_clobber(clobber) \ | ||
| 388 | [paravirt_clobber] "i" (clobber) | ||
| 389 | |||
| 390 | /* | ||
| 391 | * Generate some code, and mark it as patchable by the | ||
| 392 | * apply_paravirt() alternate instruction patcher. | ||
| 393 | */ | ||
| 394 | #define _paravirt_alt(insn_string, type, clobber) \ | ||
| 395 | "771:\n\t" insn_string "\n" "772:\n" \ | ||
| 396 | ".pushsection .parainstructions,\"a\"\n" \ | ||
| 397 | _ASM_ALIGN "\n" \ | ||
| 398 | _ASM_PTR " 771b\n" \ | ||
| 399 | " .byte " type "\n" \ | ||
| 400 | " .byte 772b-771b\n" \ | ||
| 401 | " .short " clobber "\n" \ | ||
| 402 | ".popsection\n" | ||
| 403 | |||
| 404 | /* Generate patchable code, with the default asm parameters. */ | ||
| 405 | #define paravirt_alt(insn_string) \ | ||
| 406 | _paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]") | ||
| 407 | |||
| 408 | /* Simple instruction patching code. */ | ||
| 409 | #define DEF_NATIVE(ops, name, code) \ | ||
| 410 | extern const char start_##ops##_##name[], end_##ops##_##name[]; \ | ||
| 411 | asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":") | ||
| 412 | |||
| 413 | unsigned paravirt_patch_nop(void); | ||
| 414 | unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len); | ||
| 415 | unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len); | ||
| 416 | unsigned paravirt_patch_ignore(unsigned len); | ||
| 417 | unsigned paravirt_patch_call(void *insnbuf, | ||
| 418 | const void *target, u16 tgt_clobbers, | ||
| 419 | unsigned long addr, u16 site_clobbers, | ||
| 420 | unsigned len); | ||
| 421 | unsigned paravirt_patch_jmp(void *insnbuf, const void *target, | ||
| 422 | unsigned long addr, unsigned len); | ||
| 423 | unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf, | ||
| 424 | unsigned long addr, unsigned len); | ||
| 425 | |||
| 426 | unsigned paravirt_patch_insns(void *insnbuf, unsigned len, | ||
| 427 | const char *start, const char *end); | ||
| 428 | |||
| 429 | unsigned native_patch(u8 type, u16 clobbers, void *ibuf, | ||
| 430 | unsigned long addr, unsigned len); | ||
| 431 | |||
| 432 | int paravirt_disable_iospace(void); | ||
| 433 | |||
| 434 | /* | ||
| 435 | * This generates an indirect call based on the operation type number. | ||
| 436 | * The type number, computed in PARAVIRT_PATCH, is derived from the | ||
| 437 | * offset into the paravirt_patch_template structure, and can therefore be | ||
| 438 | * freely converted back into a structure offset. | ||
| 439 | */ | ||
| 440 | #define PARAVIRT_CALL "call *%c[paravirt_opptr];" | ||
| 441 | |||
| 442 | /* | ||
| 443 | * These macros are intended to wrap calls through one of the paravirt | ||
| 444 | * ops structs, so that they can be later identified and patched at | ||
| 445 | * runtime. | ||
| 446 | * | ||
| 447 | * Normally, a call to a pv_op function is a simple indirect call: | ||
| 448 | * (pv_op_struct.operations)(args...). | ||
| 449 | * | ||
| 450 | * Unfortunately, this is a relatively slow operation for modern CPUs, | ||
| 451 | * because it cannot necessarily determine what the destination | ||
| 452 | * address is. In this case, the address is a runtime constant, so at | ||
| 453 | * the very least we can patch the call to e a simple direct call, or | ||
| 454 | * ideally, patch an inline implementation into the callsite. (Direct | ||
| 455 | * calls are essentially free, because the call and return addresses | ||
| 456 | * are completely predictable.) | ||
| 457 | * | ||
| 458 | * For i386, these macros rely on the standard gcc "regparm(3)" calling | ||
| 459 | * convention, in which the first three arguments are placed in %eax, | ||
| 460 | * %edx, %ecx (in that order), and the remaining arguments are placed | ||
| 461 | * on the stack. All caller-save registers (eax,edx,ecx) are expected | ||
| 462 | * to be modified (either clobbered or used for return values). | ||
| 463 | * X86_64, on the other hand, already specifies a register-based calling | ||
| 464 | * conventions, returning at %rax, with parameteres going on %rdi, %rsi, | ||
| 465 | * %rdx, and %rcx. Note that for this reason, x86_64 does not need any | ||
| 466 | * special handling for dealing with 4 arguments, unlike i386. | ||
| 467 | * However, x86_64 also have to clobber all caller saved registers, which | ||
| 468 | * unfortunately, are quite a bit (r8 - r11) | ||
| 469 | * | ||
| 470 | * The call instruction itself is marked by placing its start address | ||
| 471 | * and size into the .parainstructions section, so that | ||
| 472 | * apply_paravirt() in arch/i386/kernel/alternative.c can do the | ||
| 473 | * appropriate patching under the control of the backend pv_init_ops | ||
| 474 | * implementation. | ||
| 475 | * | ||
| 476 | * Unfortunately there's no way to get gcc to generate the args setup | ||
| 477 | * for the call, and then allow the call itself to be generated by an | ||
| 478 | * inline asm. Because of this, we must do the complete arg setup and | ||
| 479 | * return value handling from within these macros. This is fairly | ||
| 480 | * cumbersome. | ||
| 481 | * | ||
| 482 | * There are 5 sets of PVOP_* macros for dealing with 0-4 arguments. | ||
| 483 | * It could be extended to more arguments, but there would be little | ||
| 484 | * to be gained from that. For each number of arguments, there are | ||
| 485 | * the two VCALL and CALL variants for void and non-void functions. | ||
| 486 | * | ||
| 487 | * When there is a return value, the invoker of the macro must specify | ||
| 488 | * the return type. The macro then uses sizeof() on that type to | ||
| 489 | * determine whether its a 32 or 64 bit value, and places the return | ||
| 490 | * in the right register(s) (just %eax for 32-bit, and %edx:%eax for | ||
| 491 | * 64-bit). For x86_64 machines, it just returns at %rax regardless of | ||
| 492 | * the return value size. | ||
| 493 | * | ||
| 494 | * 64-bit arguments are passed as a pair of adjacent 32-bit arguments | ||
| 495 | * i386 also passes 64-bit arguments as a pair of adjacent 32-bit arguments | ||
| 496 | * in low,high order | ||
| 497 | * | ||
| 498 | * Small structures are passed and returned in registers. The macro | ||
| 499 | * calling convention can't directly deal with this, so the wrapper | ||
| 500 | * functions must do this. | ||
| 501 | * | ||
| 502 | * These PVOP_* macros are only defined within this header. This | ||
| 503 | * means that all uses must be wrapped in inline functions. This also | ||
| 504 | * makes sure the incoming and outgoing types are always correct. | ||
| 505 | */ | ||
| 506 | #ifdef CONFIG_X86_32 | ||
| 507 | #define PVOP_VCALL_ARGS \ | ||
| 508 | unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx | ||
| 509 | #define PVOP_CALL_ARGS PVOP_VCALL_ARGS | ||
| 510 | |||
| 511 | #define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x)) | ||
| 512 | #define PVOP_CALL_ARG2(x) "d" ((unsigned long)(x)) | ||
| 513 | #define PVOP_CALL_ARG3(x) "c" ((unsigned long)(x)) | ||
| 514 | |||
| 515 | #define PVOP_VCALL_CLOBBERS "=a" (__eax), "=d" (__edx), \ | ||
| 516 | "=c" (__ecx) | ||
| 517 | #define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS | ||
| 518 | |||
| 519 | #define PVOP_VCALLEE_CLOBBERS "=a" (__eax), "=d" (__edx) | ||
| 520 | #define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS | ||
| 521 | |||
| 522 | #define EXTRA_CLOBBERS | ||
| 523 | #define VEXTRA_CLOBBERS | ||
| 524 | #else /* CONFIG_X86_64 */ | ||
| 525 | #define PVOP_VCALL_ARGS \ | ||
| 526 | unsigned long __edi = __edi, __esi = __esi, \ | ||
| 527 | __edx = __edx, __ecx = __ecx | ||
| 528 | #define PVOP_CALL_ARGS PVOP_VCALL_ARGS, __eax | ||
| 529 | |||
| 530 | #define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x)) | ||
| 531 | #define PVOP_CALL_ARG2(x) "S" ((unsigned long)(x)) | ||
| 532 | #define PVOP_CALL_ARG3(x) "d" ((unsigned long)(x)) | ||
| 533 | #define PVOP_CALL_ARG4(x) "c" ((unsigned long)(x)) | ||
| 534 | |||
| 535 | #define PVOP_VCALL_CLOBBERS "=D" (__edi), \ | ||
| 536 | "=S" (__esi), "=d" (__edx), \ | ||
| 537 | "=c" (__ecx) | ||
| 538 | #define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax) | ||
| 539 | |||
| 540 | #define PVOP_VCALLEE_CLOBBERS "=a" (__eax) | ||
| 541 | #define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS | ||
| 542 | |||
| 543 | #define EXTRA_CLOBBERS , "r8", "r9", "r10", "r11" | ||
| 544 | #define VEXTRA_CLOBBERS , "rax", "r8", "r9", "r10", "r11" | ||
| 545 | #endif /* CONFIG_X86_32 */ | ||
| 546 | |||
| 547 | #ifdef CONFIG_PARAVIRT_DEBUG | ||
| 548 | #define PVOP_TEST_NULL(op) BUG_ON(op == NULL) | ||
| 549 | #else | ||
| 550 | #define PVOP_TEST_NULL(op) ((void)op) | ||
| 551 | #endif | ||
| 552 | |||
| 553 | #define ____PVOP_CALL(rettype, op, clbr, call_clbr, extra_clbr, \ | ||
| 554 | pre, post, ...) \ | ||
| 555 | ({ \ | ||
| 556 | rettype __ret; \ | ||
| 557 | PVOP_CALL_ARGS; \ | ||
| 558 | PVOP_TEST_NULL(op); \ | ||
| 559 | /* This is 32-bit specific, but is okay in 64-bit */ \ | ||
| 560 | /* since this condition will never hold */ \ | ||
| 561 | if (sizeof(rettype) > sizeof(unsigned long)) { \ | ||
| 562 | asm volatile(pre \ | ||
| 563 | paravirt_alt(PARAVIRT_CALL) \ | ||
| 564 | post \ | ||
| 565 | : call_clbr \ | ||
| 566 | : paravirt_type(op), \ | ||
| 567 | paravirt_clobber(clbr), \ | ||
| 568 | ##__VA_ARGS__ \ | ||
| 569 | : "memory", "cc" extra_clbr); \ | ||
| 570 | __ret = (rettype)((((u64)__edx) << 32) | __eax); \ | ||
| 571 | } else { \ | ||
| 572 | asm volatile(pre \ | ||
| 573 | paravirt_alt(PARAVIRT_CALL) \ | ||
| 574 | post \ | ||
| 575 | : call_clbr \ | ||
| 576 | : paravirt_type(op), \ | ||
| 577 | paravirt_clobber(clbr), \ | ||
| 578 | ##__VA_ARGS__ \ | ||
| 579 | : "memory", "cc" extra_clbr); \ | ||
| 580 | __ret = (rettype)__eax; \ | ||
| 581 | } \ | ||
| 582 | __ret; \ | ||
| 583 | }) | ||
| 584 | |||
| 585 | #define __PVOP_CALL(rettype, op, pre, post, ...) \ | ||
| 586 | ____PVOP_CALL(rettype, op, CLBR_ANY, PVOP_CALL_CLOBBERS, \ | ||
| 587 | EXTRA_CLOBBERS, pre, post, ##__VA_ARGS__) | ||
| 588 | |||
| 589 | #define __PVOP_CALLEESAVE(rettype, op, pre, post, ...) \ | ||
| 590 | ____PVOP_CALL(rettype, op.func, CLBR_RET_REG, \ | ||
| 591 | PVOP_CALLEE_CLOBBERS, , \ | ||
| 592 | pre, post, ##__VA_ARGS__) | ||
| 593 | |||
| 594 | |||
| 595 | #define ____PVOP_VCALL(op, clbr, call_clbr, extra_clbr, pre, post, ...) \ | ||
| 596 | ({ \ | ||
| 597 | PVOP_VCALL_ARGS; \ | ||
| 598 | PVOP_TEST_NULL(op); \ | ||
| 599 | asm volatile(pre \ | ||
| 600 | paravirt_alt(PARAVIRT_CALL) \ | ||
| 601 | post \ | ||
| 602 | : call_clbr \ | ||
| 603 | : paravirt_type(op), \ | ||
| 604 | paravirt_clobber(clbr), \ | ||
| 605 | ##__VA_ARGS__ \ | ||
| 606 | : "memory", "cc" extra_clbr); \ | ||
| 607 | }) | ||
| 608 | |||
| 609 | #define __PVOP_VCALL(op, pre, post, ...) \ | ||
| 610 | ____PVOP_VCALL(op, CLBR_ANY, PVOP_VCALL_CLOBBERS, \ | ||
| 611 | VEXTRA_CLOBBERS, \ | ||
| 612 | pre, post, ##__VA_ARGS__) | ||
| 613 | |||
| 614 | #define __PVOP_VCALLEESAVE(rettype, op, pre, post, ...) \ | ||
| 615 | ____PVOP_CALL(rettype, op.func, CLBR_RET_REG, \ | ||
| 616 | PVOP_VCALLEE_CLOBBERS, , \ | ||
| 617 | pre, post, ##__VA_ARGS__) | ||
| 618 | |||
| 619 | |||
| 620 | |||
| 621 | #define PVOP_CALL0(rettype, op) \ | ||
| 622 | __PVOP_CALL(rettype, op, "", "") | ||
| 623 | #define PVOP_VCALL0(op) \ | ||
| 624 | __PVOP_VCALL(op, "", "") | ||
| 625 | |||
| 626 | #define PVOP_CALLEE0(rettype, op) \ | ||
| 627 | __PVOP_CALLEESAVE(rettype, op, "", "") | ||
| 628 | #define PVOP_VCALLEE0(op) \ | ||
| 629 | __PVOP_VCALLEESAVE(op, "", "") | ||
| 630 | |||
| 631 | |||
| 632 | #define PVOP_CALL1(rettype, op, arg1) \ | ||
| 633 | __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1)) | ||
| 634 | #define PVOP_VCALL1(op, arg1) \ | ||
| 635 | __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1)) | ||
| 636 | |||
| 637 | #define PVOP_CALLEE1(rettype, op, arg1) \ | ||
| 638 | __PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1)) | ||
| 639 | #define PVOP_VCALLEE1(op, arg1) \ | ||
| 640 | __PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1)) | ||
| 641 | |||
| 642 | |||
| 643 | #define PVOP_CALL2(rettype, op, arg1, arg2) \ | ||
| 644 | __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \ | ||
| 645 | PVOP_CALL_ARG2(arg2)) | ||
| 646 | #define PVOP_VCALL2(op, arg1, arg2) \ | ||
| 647 | __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1), \ | ||
| 648 | PVOP_CALL_ARG2(arg2)) | ||
| 649 | |||
| 650 | #define PVOP_CALLEE2(rettype, op, arg1, arg2) \ | ||
| 651 | __PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \ | ||
| 652 | PVOP_CALL_ARG2(arg2)) | ||
| 653 | #define PVOP_VCALLEE2(op, arg1, arg2) \ | ||
| 654 | __PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1), \ | ||
| 655 | PVOP_CALL_ARG2(arg2)) | ||
| 656 | |||
| 657 | |||
| 658 | #define PVOP_CALL3(rettype, op, arg1, arg2, arg3) \ | ||
| 659 | __PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1), \ | ||
| 660 | PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3)) | ||
| 661 | #define PVOP_VCALL3(op, arg1, arg2, arg3) \ | ||
| 662 | __PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1), \ | ||
| 663 | PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3)) | ||
| 664 | |||
| 665 | /* This is the only difference in x86_64. We can make it much simpler */ | ||
| 666 | #ifdef CONFIG_X86_32 | ||
| 667 | #define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \ | ||
| 668 | __PVOP_CALL(rettype, op, \ | ||
| 669 | "push %[_arg4];", "lea 4(%%esp),%%esp;", \ | ||
| 670 | PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \ | ||
| 671 | PVOP_CALL_ARG3(arg3), [_arg4] "mr" ((u32)(arg4))) | ||
| 672 | #define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \ | ||
| 673 | __PVOP_VCALL(op, \ | ||
| 674 | "push %[_arg4];", "lea 4(%%esp),%%esp;", \ | ||
| 675 | "0" ((u32)(arg1)), "1" ((u32)(arg2)), \ | ||
| 676 | "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4))) | ||
| 677 | #else | ||
| 678 | #define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4) \ | ||
| 679 | __PVOP_CALL(rettype, op, "", "", \ | ||
| 680 | PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \ | ||
| 681 | PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4)) | ||
| 682 | #define PVOP_VCALL4(op, arg1, arg2, arg3, arg4) \ | ||
| 683 | __PVOP_VCALL(op, "", "", \ | ||
| 684 | PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2), \ | ||
| 685 | PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4)) | ||
| 686 | #endif | ||
| 687 | |||
| 688 | /* Lazy mode for batching updates / context switch */ | ||
| 689 | enum paravirt_lazy_mode { | ||
| 690 | PARAVIRT_LAZY_NONE, | ||
| 691 | PARAVIRT_LAZY_MMU, | ||
| 692 | PARAVIRT_LAZY_CPU, | ||
| 693 | }; | ||
| 694 | |||
| 695 | enum paravirt_lazy_mode paravirt_get_lazy_mode(void); | ||
| 696 | void paravirt_start_context_switch(struct task_struct *prev); | ||
| 697 | void paravirt_end_context_switch(struct task_struct *next); | ||
| 698 | |||
| 699 | void paravirt_enter_lazy_mmu(void); | ||
| 700 | void paravirt_leave_lazy_mmu(void); | ||
| 701 | |||
| 702 | void _paravirt_nop(void); | ||
| 703 | u32 _paravirt_ident_32(u32); | ||
| 704 | u64 _paravirt_ident_64(u64); | ||
| 705 | |||
| 706 | #define paravirt_nop ((void *)_paravirt_nop) | ||
| 707 | |||
| 708 | /* These all sit in the .parainstructions section to tell us what to patch. */ | ||
| 709 | struct paravirt_patch_site { | ||
| 710 | u8 *instr; /* original instructions */ | ||
| 711 | u8 instrtype; /* type of this instruction */ | ||
| 712 | u8 len; /* length of original instruction */ | ||
| 713 | u16 clobbers; /* what registers you may clobber */ | ||
| 714 | }; | ||
| 715 | |||
| 716 | extern struct paravirt_patch_site __parainstructions[], | ||
| 717 | __parainstructions_end[]; | ||
| 718 | |||
| 719 | #endif /* __ASSEMBLY__ */ | ||
| 720 | |||
| 721 | #endif /* _ASM_X86_PARAVIRT_TYPES_H */ | ||
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 103f1ddb0d85..04eacefcfd26 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h | |||
| @@ -49,7 +49,7 @@ | |||
| 49 | #define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x | 49 | #define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x |
| 50 | #define __my_cpu_offset percpu_read(this_cpu_off) | 50 | #define __my_cpu_offset percpu_read(this_cpu_off) |
| 51 | #else | 51 | #else |
| 52 | #define __percpu_arg(x) "%" #x | 52 | #define __percpu_arg(x) "%P" #x |
| 53 | #endif | 53 | #endif |
| 54 | 54 | ||
| 55 | /* | 55 | /* |
| @@ -104,36 +104,48 @@ do { \ | |||
| 104 | } \ | 104 | } \ |
| 105 | } while (0) | 105 | } while (0) |
| 106 | 106 | ||
| 107 | #define percpu_from_op(op, var) \ | 107 | #define percpu_from_op(op, var, constraint) \ |
| 108 | ({ \ | 108 | ({ \ |
| 109 | typeof(var) ret__; \ | 109 | typeof(var) ret__; \ |
| 110 | switch (sizeof(var)) { \ | 110 | switch (sizeof(var)) { \ |
| 111 | case 1: \ | 111 | case 1: \ |
| 112 | asm(op "b "__percpu_arg(1)",%0" \ | 112 | asm(op "b "__percpu_arg(1)",%0" \ |
| 113 | : "=q" (ret__) \ | 113 | : "=q" (ret__) \ |
| 114 | : "m" (var)); \ | 114 | : constraint); \ |
| 115 | break; \ | 115 | break; \ |
| 116 | case 2: \ | 116 | case 2: \ |
| 117 | asm(op "w "__percpu_arg(1)",%0" \ | 117 | asm(op "w "__percpu_arg(1)",%0" \ |
| 118 | : "=r" (ret__) \ | 118 | : "=r" (ret__) \ |
| 119 | : "m" (var)); \ | 119 | : constraint); \ |
| 120 | break; \ | 120 | break; \ |
| 121 | case 4: \ | 121 | case 4: \ |
| 122 | asm(op "l "__percpu_arg(1)",%0" \ | 122 | asm(op "l "__percpu_arg(1)",%0" \ |
| 123 | : "=r" (ret__) \ | 123 | : "=r" (ret__) \ |
| 124 | : "m" (var)); \ | 124 | : constraint); \ |
| 125 | break; \ | 125 | break; \ |
| 126 | case 8: \ | 126 | case 8: \ |
| 127 | asm(op "q "__percpu_arg(1)",%0" \ | 127 | asm(op "q "__percpu_arg(1)",%0" \ |
| 128 | : "=r" (ret__) \ | 128 | : "=r" (ret__) \ |
| 129 | : "m" (var)); \ | 129 | : constraint); \ |
| 130 | break; \ | 130 | break; \ |
| 131 | default: __bad_percpu_size(); \ | 131 | default: __bad_percpu_size(); \ |
| 132 | } \ | 132 | } \ |
| 133 | ret__; \ | 133 | ret__; \ |
| 134 | }) | 134 | }) |
| 135 | 135 | ||
| 136 | #define percpu_read(var) percpu_from_op("mov", per_cpu__##var) | 136 | /* |
| 137 | * percpu_read() makes gcc load the percpu variable every time it is | ||
| 138 | * accessed while percpu_read_stable() allows the value to be cached. | ||
| 139 | * percpu_read_stable() is more efficient and can be used if its value | ||
| 140 | * is guaranteed to be valid across cpus. The current users include | ||
| 141 | * get_current() and get_thread_info() both of which are actually | ||
| 142 | * per-thread variables implemented as per-cpu variables and thus | ||
| 143 | * stable for the duration of the respective task. | ||
| 144 | */ | ||
| 145 | #define percpu_read(var) percpu_from_op("mov", per_cpu__##var, \ | ||
| 146 | "m" (per_cpu__##var)) | ||
| 147 | #define percpu_read_stable(var) percpu_from_op("mov", per_cpu__##var, \ | ||
| 148 | "p" (&per_cpu__##var)) | ||
| 137 | #define percpu_write(var, val) percpu_to_op("mov", per_cpu__##var, val) | 149 | #define percpu_write(var, val) percpu_to_op("mov", per_cpu__##var, val) |
| 138 | #define percpu_add(var, val) percpu_to_op("add", per_cpu__##var, val) | 150 | #define percpu_add(var, val) percpu_to_op("add", per_cpu__##var, val) |
| 139 | #define percpu_sub(var, val) percpu_to_op("sub", per_cpu__##var, val) | 151 | #define percpu_sub(var, val) percpu_to_op("sub", per_cpu__##var, val) |
diff --git a/arch/x86/include/asm/perf_counter.h b/arch/x86/include/asm/perf_counter.h index fa64e401589d..e7b7c938ae27 100644 --- a/arch/x86/include/asm/perf_counter.h +++ b/arch/x86/include/asm/perf_counter.h | |||
| @@ -84,6 +84,16 @@ union cpuid10_edx { | |||
| 84 | #define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b | 84 | #define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b |
| 85 | #define X86_PMC_IDX_FIXED_BUS_CYCLES (X86_PMC_IDX_FIXED + 2) | 85 | #define X86_PMC_IDX_FIXED_BUS_CYCLES (X86_PMC_IDX_FIXED + 2) |
| 86 | 86 | ||
| 87 | /* | ||
| 88 | * We model BTS tracing as another fixed-mode PMC. | ||
| 89 | * | ||
| 90 | * We choose a value in the middle of the fixed counter range, since lower | ||
| 91 | * values are used by actual fixed counters and higher values are used | ||
| 92 | * to indicate other overflow conditions in the PERF_GLOBAL_STATUS msr. | ||
| 93 | */ | ||
| 94 | #define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16) | ||
| 95 | |||
| 96 | |||
| 87 | #ifdef CONFIG_PERF_COUNTERS | 97 | #ifdef CONFIG_PERF_COUNTERS |
| 88 | extern void init_hw_perf_counters(void); | 98 | extern void init_hw_perf_counters(void); |
| 89 | extern void perf_counters_lapic_init(void); | 99 | extern void perf_counters_lapic_init(void); |
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 3cc06e3fceb8..4c5b51fdc788 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #define _ASM_X86_PGTABLE_H | 2 | #define _ASM_X86_PGTABLE_H |
| 3 | 3 | ||
| 4 | #include <asm/page.h> | 4 | #include <asm/page.h> |
| 5 | #include <asm/e820.h> | ||
| 5 | 6 | ||
| 6 | #include <asm/pgtable_types.h> | 7 | #include <asm/pgtable_types.h> |
| 7 | 8 | ||
| @@ -134,6 +135,11 @@ static inline unsigned long pte_pfn(pte_t pte) | |||
| 134 | return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT; | 135 | return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT; |
| 135 | } | 136 | } |
| 136 | 137 | ||
| 138 | static inline unsigned long pmd_pfn(pmd_t pmd) | ||
| 139 | { | ||
| 140 | return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT; | ||
| 141 | } | ||
| 142 | |||
| 137 | #define pte_page(pte) pfn_to_page(pte_pfn(pte)) | 143 | #define pte_page(pte) pfn_to_page(pte_pfn(pte)) |
| 138 | 144 | ||
| 139 | static inline int pmd_large(pmd_t pte) | 145 | static inline int pmd_large(pmd_t pte) |
| @@ -269,10 +275,17 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) | |||
| 269 | 275 | ||
| 270 | #define canon_pgprot(p) __pgprot(massage_pgprot(p)) | 276 | #define canon_pgprot(p) __pgprot(massage_pgprot(p)) |
| 271 | 277 | ||
| 272 | static inline int is_new_memtype_allowed(unsigned long flags, | 278 | static inline int is_new_memtype_allowed(u64 paddr, unsigned long size, |
| 273 | unsigned long new_flags) | 279 | unsigned long flags, |
| 280 | unsigned long new_flags) | ||
| 274 | { | 281 | { |
| 275 | /* | 282 | /* |
| 283 | * PAT type is always WB for ISA. So no need to check. | ||
| 284 | */ | ||
| 285 | if (is_ISA_range(paddr, paddr + size - 1)) | ||
| 286 | return 1; | ||
| 287 | |||
| 288 | /* | ||
| 276 | * Certain new memtypes are not allowed with certain | 289 | * Certain new memtypes are not allowed with certain |
| 277 | * requested memtype: | 290 | * requested memtype: |
| 278 | * - request is uncached, return cannot be write-back | 291 | * - request is uncached, return cannot be write-back |
| @@ -351,7 +364,7 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd) | |||
| 351 | * this macro returns the index of the entry in the pmd page which would | 364 | * this macro returns the index of the entry in the pmd page which would |
| 352 | * control the given virtual address | 365 | * control the given virtual address |
| 353 | */ | 366 | */ |
| 354 | static inline unsigned pmd_index(unsigned long address) | 367 | static inline unsigned long pmd_index(unsigned long address) |
| 355 | { | 368 | { |
| 356 | return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); | 369 | return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); |
| 357 | } | 370 | } |
| @@ -371,7 +384,7 @@ static inline unsigned pmd_index(unsigned long address) | |||
| 371 | * this function returns the index of the entry in the pte page which would | 384 | * this function returns the index of the entry in the pte page which would |
| 372 | * control the given virtual address | 385 | * control the given virtual address |
| 373 | */ | 386 | */ |
| 374 | static inline unsigned pte_index(unsigned long address) | 387 | static inline unsigned long pte_index(unsigned long address) |
| 375 | { | 388 | { |
| 376 | return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); | 389 | return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); |
| 377 | } | 390 | } |
| @@ -422,11 +435,6 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) | |||
| 422 | return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address); | 435 | return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address); |
| 423 | } | 436 | } |
| 424 | 437 | ||
| 425 | static inline unsigned long pmd_pfn(pmd_t pmd) | ||
| 426 | { | ||
| 427 | return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT; | ||
| 428 | } | ||
| 429 | |||
| 430 | static inline int pud_large(pud_t pud) | 438 | static inline int pud_large(pud_t pud) |
| 431 | { | 439 | { |
| 432 | return (pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) == | 440 | return (pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) == |
| @@ -462,7 +470,7 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd) | |||
| 462 | #define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT) | 470 | #define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT) |
| 463 | 471 | ||
| 464 | /* to find an entry in a page-table-directory. */ | 472 | /* to find an entry in a page-table-directory. */ |
| 465 | static inline unsigned pud_index(unsigned long address) | 473 | static inline unsigned long pud_index(unsigned long address) |
| 466 | { | 474 | { |
| 467 | return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1); | 475 | return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1); |
| 468 | } | 476 | } |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index c7768269b1cf..e08ea043e085 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
| @@ -403,7 +403,17 @@ extern unsigned long kernel_eflags; | |||
| 403 | extern asmlinkage void ignore_sysret(void); | 403 | extern asmlinkage void ignore_sysret(void); |
| 404 | #else /* X86_64 */ | 404 | #else /* X86_64 */ |
| 405 | #ifdef CONFIG_CC_STACKPROTECTOR | 405 | #ifdef CONFIG_CC_STACKPROTECTOR |
| 406 | DECLARE_PER_CPU(unsigned long, stack_canary); | 406 | /* |
| 407 | * Make sure stack canary segment base is cached-aligned: | ||
| 408 | * "For Intel Atom processors, avoid non zero segment base address | ||
| 409 | * that is not aligned to cache line boundary at all cost." | ||
| 410 | * (Optim Ref Manual Assembly/Compiler Coding Rule 15.) | ||
| 411 | */ | ||
| 412 | struct stack_canary { | ||
| 413 | char __pad[20]; /* canary at %gs:20 */ | ||
| 414 | unsigned long canary; | ||
| 415 | }; | ||
| 416 | DECLARE_PER_CPU_ALIGNED(struct stack_canary, stack_canary); | ||
| 407 | #endif | 417 | #endif |
| 408 | #endif /* X86_64 */ | 418 | #endif /* X86_64 */ |
| 409 | 419 | ||
| @@ -703,13 +713,23 @@ static inline void cpu_relax(void) | |||
| 703 | rep_nop(); | 713 | rep_nop(); |
| 704 | } | 714 | } |
| 705 | 715 | ||
| 706 | /* Stop speculative execution: */ | 716 | /* Stop speculative execution and prefetching of modified code. */ |
| 707 | static inline void sync_core(void) | 717 | static inline void sync_core(void) |
| 708 | { | 718 | { |
| 709 | int tmp; | 719 | int tmp; |
| 710 | 720 | ||
| 711 | asm volatile("cpuid" : "=a" (tmp) : "0" (1) | 721 | #if defined(CONFIG_M386) || defined(CONFIG_M486) |
| 712 | : "ebx", "ecx", "edx", "memory"); | 722 | if (boot_cpu_data.x86 < 5) |
| 723 | /* There is no speculative execution. | ||
| 724 | * jmp is a barrier to prefetching. */ | ||
| 725 | asm volatile("jmp 1f\n1:\n" ::: "memory"); | ||
| 726 | else | ||
| 727 | #endif | ||
| 728 | /* cpuid is a barrier to speculative execution. | ||
| 729 | * Prefetched instructions are automatically | ||
| 730 | * invalidated when modified. */ | ||
| 731 | asm volatile("cpuid" : "=a" (tmp) : "0" (1) | ||
| 732 | : "ebx", "ecx", "edx", "memory"); | ||
| 713 | } | 733 | } |
| 714 | 734 | ||
| 715 | static inline void __monitor(const void *eax, unsigned long ecx, | 735 | static inline void __monitor(const void *eax, unsigned long ecx, |
diff --git a/arch/x86/include/asm/scatterlist.h b/arch/x86/include/asm/scatterlist.h index 263d397d2eef..75af592677ec 100644 --- a/arch/x86/include/asm/scatterlist.h +++ b/arch/x86/include/asm/scatterlist.h | |||
| @@ -1,33 +1,8 @@ | |||
| 1 | #ifndef _ASM_X86_SCATTERLIST_H | 1 | #ifndef _ASM_X86_SCATTERLIST_H |
| 2 | #define _ASM_X86_SCATTERLIST_H | 2 | #define _ASM_X86_SCATTERLIST_H |
| 3 | 3 | ||
| 4 | #include <asm/types.h> | ||
| 5 | |||
| 6 | struct scatterlist { | ||
| 7 | #ifdef CONFIG_DEBUG_SG | ||
| 8 | unsigned long sg_magic; | ||
| 9 | #endif | ||
| 10 | unsigned long page_link; | ||
| 11 | unsigned int offset; | ||
| 12 | unsigned int length; | ||
| 13 | dma_addr_t dma_address; | ||
| 14 | unsigned int dma_length; | ||
| 15 | }; | ||
| 16 | |||
| 17 | #define ARCH_HAS_SG_CHAIN | ||
| 18 | #define ISA_DMA_THRESHOLD (0x00ffffff) | 4 | #define ISA_DMA_THRESHOLD (0x00ffffff) |
| 19 | 5 | ||
| 20 | /* | 6 | #include <asm-generic/scatterlist.h> |
| 21 | * These macros should be used after a pci_map_sg call has been done | ||
| 22 | * to get bus addresses of each of the SG entries and their lengths. | ||
| 23 | * You should only work with the number of sg entries pci_map_sg | ||
| 24 | * returns. | ||
| 25 | */ | ||
| 26 | #define sg_dma_address(sg) ((sg)->dma_address) | ||
| 27 | #ifdef CONFIG_X86_32 | ||
| 28 | # define sg_dma_len(sg) ((sg)->length) | ||
| 29 | #else | ||
| 30 | # define sg_dma_len(sg) ((sg)->dma_length) | ||
| 31 | #endif | ||
| 32 | 7 | ||
| 33 | #endif /* _ASM_X86_SCATTERLIST_H */ | 8 | #endif /* _ASM_X86_SCATTERLIST_H */ |
diff --git a/arch/x86/include/asm/shmbuf.h b/arch/x86/include/asm/shmbuf.h index b51413b74971..83c05fc2de38 100644 --- a/arch/x86/include/asm/shmbuf.h +++ b/arch/x86/include/asm/shmbuf.h | |||
| @@ -1,51 +1 @@ | |||
| 1 | #ifndef _ASM_X86_SHMBUF_H | #include <asm-generic/shmbuf.h> | |
| 2 | #define _ASM_X86_SHMBUF_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * The shmid64_ds structure for x86 architecture. | ||
| 6 | * Note extra padding because this structure is passed back and forth | ||
| 7 | * between kernel and user space. | ||
| 8 | * | ||
| 9 | * Pad space on 32 bit is left for: | ||
| 10 | * - 64-bit time_t to solve y2038 problem | ||
| 11 | * - 2 miscellaneous 32-bit values | ||
| 12 | * | ||
| 13 | * Pad space on 64 bit is left for: | ||
| 14 | * - 2 miscellaneous 64-bit values | ||
| 15 | */ | ||
| 16 | |||
| 17 | struct shmid64_ds { | ||
| 18 | struct ipc64_perm shm_perm; /* operation perms */ | ||
| 19 | size_t shm_segsz; /* size of segment (bytes) */ | ||
| 20 | __kernel_time_t shm_atime; /* last attach time */ | ||
| 21 | #ifdef __i386__ | ||
| 22 | unsigned long __unused1; | ||
| 23 | #endif | ||
| 24 | __kernel_time_t shm_dtime; /* last detach time */ | ||
| 25 | #ifdef __i386__ | ||
| 26 | unsigned long __unused2; | ||
| 27 | #endif | ||
| 28 | __kernel_time_t shm_ctime; /* last change time */ | ||
| 29 | #ifdef __i386__ | ||
| 30 | unsigned long __unused3; | ||
| 31 | #endif | ||
| 32 | __kernel_pid_t shm_cpid; /* pid of creator */ | ||
| 33 | __kernel_pid_t shm_lpid; /* pid of last operator */ | ||
| 34 | unsigned long shm_nattch; /* no. of current attaches */ | ||
| 35 | unsigned long __unused4; | ||
| 36 | unsigned long __unused5; | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct shminfo64 { | ||
| 40 | unsigned long shmmax; | ||
| 41 | unsigned long shmmin; | ||
| 42 | unsigned long shmmni; | ||
| 43 | unsigned long shmseg; | ||
| 44 | unsigned long shmall; | ||
| 45 | unsigned long __unused1; | ||
| 46 | unsigned long __unused2; | ||
| 47 | unsigned long __unused3; | ||
| 48 | unsigned long __unused4; | ||
| 49 | }; | ||
| 50 | |||
| 51 | #endif /* _ASM_X86_SHMBUF_H */ | ||
diff --git a/arch/x86/include/asm/socket.h b/arch/x86/include/asm/socket.h index ca8bf2cd0ba9..6b71384b9d8b 100644 --- a/arch/x86/include/asm/socket.h +++ b/arch/x86/include/asm/socket.h | |||
| @@ -1,60 +1 @@ | |||
| 1 | #ifndef _ASM_X86_SOCKET_H | #include <asm-generic/socket.h> | |
| 2 | #define _ASM_X86_SOCKET_H | ||
| 3 | |||
| 4 | #include <asm/sockios.h> | ||
| 5 | |||
| 6 | /* For setsockopt(2) */ | ||
| 7 | #define SOL_SOCKET 1 | ||
| 8 | |||
| 9 | #define SO_DEBUG 1 | ||
| 10 | #define SO_REUSEADDR 2 | ||
| 11 | #define SO_TYPE 3 | ||
| 12 | #define SO_ERROR 4 | ||
| 13 | #define SO_DONTROUTE 5 | ||
| 14 | #define SO_BROADCAST 6 | ||
| 15 | #define SO_SNDBUF 7 | ||
| 16 | #define SO_RCVBUF 8 | ||
| 17 | #define SO_SNDBUFFORCE 32 | ||
| 18 | #define SO_RCVBUFFORCE 33 | ||
| 19 | #define SO_KEEPALIVE 9 | ||
| 20 | #define SO_OOBINLINE 10 | ||
| 21 | #define SO_NO_CHECK 11 | ||
| 22 | #define SO_PRIORITY 12 | ||
| 23 | #define SO_LINGER 13 | ||
| 24 | #define SO_BSDCOMPAT 14 | ||
| 25 | /* To add :#define SO_REUSEPORT 15 */ | ||
| 26 | #define SO_PASSCRED 16 | ||
| 27 | #define SO_PEERCRED 17 | ||
| 28 | #define SO_RCVLOWAT 18 | ||
| 29 | #define SO_SNDLOWAT 19 | ||
| 30 | #define SO_RCVTIMEO 20 | ||
| 31 | #define SO_SNDTIMEO 21 | ||
| 32 | |||
| 33 | /* Security levels - as per NRL IPv6 - don't actually do anything */ | ||
| 34 | #define SO_SECURITY_AUTHENTICATION 22 | ||
| 35 | #define SO_SECURITY_ENCRYPTION_TRANSPORT 23 | ||
| 36 | #define SO_SECURITY_ENCRYPTION_NETWORK 24 | ||
| 37 | |||
| 38 | #define SO_BINDTODEVICE 25 | ||
| 39 | |||
| 40 | /* Socket filtering */ | ||
| 41 | #define SO_ATTACH_FILTER 26 | ||
| 42 | #define SO_DETACH_FILTER 27 | ||
| 43 | |||
| 44 | #define SO_PEERNAME 28 | ||
| 45 | #define SO_TIMESTAMP 29 | ||
| 46 | #define SCM_TIMESTAMP SO_TIMESTAMP | ||
| 47 | |||
| 48 | #define SO_ACCEPTCONN 30 | ||
| 49 | |||
| 50 | #define SO_PEERSEC 31 | ||
| 51 | #define SO_PASSSEC 34 | ||
| 52 | #define SO_TIMESTAMPNS 35 | ||
| 53 | #define SCM_TIMESTAMPNS SO_TIMESTAMPNS | ||
| 54 | |||
| 55 | #define SO_MARK 36 | ||
| 56 | |||
| 57 | #define SO_TIMESTAMPING 37 | ||
| 58 | #define SCM_TIMESTAMPING SO_TIMESTAMPING | ||
| 59 | |||
| 60 | #endif /* _ASM_X86_SOCKET_H */ | ||
diff --git a/arch/x86/include/asm/sockios.h b/arch/x86/include/asm/sockios.h index 49cc72b5d3c9..def6d4746ee7 100644 --- a/arch/x86/include/asm/sockios.h +++ b/arch/x86/include/asm/sockios.h | |||
| @@ -1,13 +1 @@ | |||
| 1 | #ifndef _ASM_X86_SOCKIOS_H | #include <asm-generic/sockios.h> | |
| 2 | #define _ASM_X86_SOCKIOS_H | ||
| 3 | |||
| 4 | /* Socket-level I/O control calls. */ | ||
| 5 | #define FIOSETOWN 0x8901 | ||
| 6 | #define SIOCSPGRP 0x8902 | ||
| 7 | #define FIOGETOWN 0x8903 | ||
| 8 | #define SIOCGPGRP 0x8904 | ||
| 9 | #define SIOCATMARK 0x8905 | ||
| 10 | #define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ | ||
| 11 | #define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ | ||
| 12 | |||
| 13 | #endif /* _ASM_X86_SOCKIOS_H */ | ||
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h index c2d742c6e15f..157517763565 100644 --- a/arch/x86/include/asm/stackprotector.h +++ b/arch/x86/include/asm/stackprotector.h | |||
| @@ -48,7 +48,7 @@ | |||
| 48 | * head_32 for boot CPU and setup_per_cpu_areas() for others. | 48 | * head_32 for boot CPU and setup_per_cpu_areas() for others. |
| 49 | */ | 49 | */ |
| 50 | #define GDT_STACK_CANARY_INIT \ | 50 | #define GDT_STACK_CANARY_INIT \ |
| 51 | [GDT_ENTRY_STACK_CANARY] = { { { 0x00000018, 0x00409000 } } }, | 51 | [GDT_ENTRY_STACK_CANARY] = GDT_ENTRY_INIT(0x4090, 0, 0x18), |
| 52 | 52 | ||
| 53 | /* | 53 | /* |
| 54 | * Initialize the stackprotector canary value. | 54 | * Initialize the stackprotector canary value. |
| @@ -78,21 +78,19 @@ static __always_inline void boot_init_stack_canary(void) | |||
| 78 | #ifdef CONFIG_X86_64 | 78 | #ifdef CONFIG_X86_64 |
| 79 | percpu_write(irq_stack_union.stack_canary, canary); | 79 | percpu_write(irq_stack_union.stack_canary, canary); |
| 80 | #else | 80 | #else |
| 81 | percpu_write(stack_canary, canary); | 81 | percpu_write(stack_canary.canary, canary); |
| 82 | #endif | 82 | #endif |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | static inline void setup_stack_canary_segment(int cpu) | 85 | static inline void setup_stack_canary_segment(int cpu) |
| 86 | { | 86 | { |
| 87 | #ifdef CONFIG_X86_32 | 87 | #ifdef CONFIG_X86_32 |
| 88 | unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu) - 20; | 88 | unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu); |
| 89 | struct desc_struct *gdt_table = get_cpu_gdt_table(cpu); | 89 | struct desc_struct *gdt_table = get_cpu_gdt_table(cpu); |
| 90 | struct desc_struct desc; | 90 | struct desc_struct desc; |
| 91 | 91 | ||
| 92 | desc = gdt_table[GDT_ENTRY_STACK_CANARY]; | 92 | desc = gdt_table[GDT_ENTRY_STACK_CANARY]; |
| 93 | desc.base0 = canary & 0xffff; | 93 | set_desc_base(&desc, canary); |
| 94 | desc.base1 = (canary >> 16) & 0xff; | ||
| 95 | desc.base2 = (canary >> 24) & 0xff; | ||
| 96 | write_gdt_entry(gdt_table, GDT_ENTRY_STACK_CANARY, &desc, DESCTYPE_S); | 94 | write_gdt_entry(gdt_table, GDT_ENTRY_STACK_CANARY, &desc, DESCTYPE_S); |
| 97 | #endif | 95 | #endif |
| 98 | } | 96 | } |
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index 643c59b4bc6e..f08f97374892 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h | |||
| @@ -31,7 +31,7 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | |||
| 31 | "movl %P[task_canary](%[next]), %%ebx\n\t" \ | 31 | "movl %P[task_canary](%[next]), %%ebx\n\t" \ |
| 32 | "movl %%ebx, "__percpu_arg([stack_canary])"\n\t" | 32 | "movl %%ebx, "__percpu_arg([stack_canary])"\n\t" |
| 33 | #define __switch_canary_oparam \ | 33 | #define __switch_canary_oparam \ |
| 34 | , [stack_canary] "=m" (per_cpu_var(stack_canary)) | 34 | , [stack_canary] "=m" (per_cpu_var(stack_canary.canary)) |
| 35 | #define __switch_canary_iparam \ | 35 | #define __switch_canary_iparam \ |
| 36 | , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) | 36 | , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) |
| 37 | #else /* CC_STACKPROTECTOR */ | 37 | #else /* CC_STACKPROTECTOR */ |
| @@ -150,33 +150,6 @@ do { \ | |||
| 150 | #endif | 150 | #endif |
| 151 | 151 | ||
| 152 | #ifdef __KERNEL__ | 152 | #ifdef __KERNEL__ |
| 153 | #define _set_base(addr, base) do { unsigned long __pr; \ | ||
| 154 | __asm__ __volatile__ ("movw %%dx,%1\n\t" \ | ||
| 155 | "rorl $16,%%edx\n\t" \ | ||
| 156 | "movb %%dl,%2\n\t" \ | ||
| 157 | "movb %%dh,%3" \ | ||
| 158 | :"=&d" (__pr) \ | ||
| 159 | :"m" (*((addr)+2)), \ | ||
| 160 | "m" (*((addr)+4)), \ | ||
| 161 | "m" (*((addr)+7)), \ | ||
| 162 | "0" (base) \ | ||
| 163 | ); } while (0) | ||
| 164 | |||
| 165 | #define _set_limit(addr, limit) do { unsigned long __lr; \ | ||
| 166 | __asm__ __volatile__ ("movw %%dx,%1\n\t" \ | ||
| 167 | "rorl $16,%%edx\n\t" \ | ||
| 168 | "movb %2,%%dh\n\t" \ | ||
| 169 | "andb $0xf0,%%dh\n\t" \ | ||
| 170 | "orb %%dh,%%dl\n\t" \ | ||
| 171 | "movb %%dl,%2" \ | ||
| 172 | :"=&d" (__lr) \ | ||
| 173 | :"m" (*(addr)), \ | ||
| 174 | "m" (*((addr)+6)), \ | ||
| 175 | "0" (limit) \ | ||
| 176 | ); } while (0) | ||
| 177 | |||
| 178 | #define set_base(ldt, base) _set_base(((char *)&(ldt)) , (base)) | ||
| 179 | #define set_limit(ldt, limit) _set_limit(((char *)&(ldt)) , ((limit)-1)) | ||
| 180 | 153 | ||
| 181 | extern void native_load_gs_index(unsigned); | 154 | extern void native_load_gs_index(unsigned); |
| 182 | 155 | ||
diff --git a/arch/x86/include/asm/termbits.h b/arch/x86/include/asm/termbits.h index af1b70ea440f..3935b106de79 100644 --- a/arch/x86/include/asm/termbits.h +++ b/arch/x86/include/asm/termbits.h | |||
| @@ -1,198 +1 @@ | |||
| 1 | #ifndef _ASM_X86_TERMBITS_H | #include <asm-generic/termbits.h> | |
| 2 | #define _ASM_X86_TERMBITS_H | ||
| 3 | |||
| 4 | #include <linux/posix_types.h> | ||
| 5 | |||
| 6 | typedef unsigned char cc_t; | ||
| 7 | typedef unsigned int speed_t; | ||
| 8 | typedef unsigned int tcflag_t; | ||
| 9 | |||
| 10 | #define NCCS 19 | ||
| 11 | struct termios { | ||
| 12 | tcflag_t c_iflag; /* input mode flags */ | ||
| 13 | tcflag_t c_oflag; /* output mode flags */ | ||
| 14 | tcflag_t c_cflag; /* control mode flags */ | ||
| 15 | tcflag_t c_lflag; /* local mode flags */ | ||
| 16 | cc_t c_line; /* line discipline */ | ||
| 17 | cc_t c_cc[NCCS]; /* control characters */ | ||
| 18 | }; | ||
| 19 | |||
| 20 | struct termios2 { | ||
| 21 | tcflag_t c_iflag; /* input mode flags */ | ||
| 22 | tcflag_t c_oflag; /* output mode flags */ | ||
| 23 | tcflag_t c_cflag; /* control mode flags */ | ||
| 24 | tcflag_t c_lflag; /* local mode flags */ | ||
| 25 | cc_t c_line; /* line discipline */ | ||
| 26 | cc_t c_cc[NCCS]; /* control characters */ | ||
| 27 | speed_t c_ispeed; /* input speed */ | ||
| 28 | speed_t c_ospeed; /* output speed */ | ||
| 29 | }; | ||
| 30 | |||
| 31 | struct ktermios { | ||
| 32 | tcflag_t c_iflag; /* input mode flags */ | ||
| 33 | tcflag_t c_oflag; /* output mode flags */ | ||
| 34 | tcflag_t c_cflag; /* control mode flags */ | ||
| 35 | tcflag_t c_lflag; /* local mode flags */ | ||
| 36 | cc_t c_line; /* line discipline */ | ||
| 37 | cc_t c_cc[NCCS]; /* control characters */ | ||
| 38 | speed_t c_ispeed; /* input speed */ | ||
| 39 | speed_t c_ospeed; /* output speed */ | ||
| 40 | }; | ||
| 41 | |||
| 42 | /* c_cc characters */ | ||
| 43 | #define VINTR 0 | ||
| 44 | #define VQUIT 1 | ||
| 45 | #define VERASE 2 | ||
| 46 | #define VKILL 3 | ||
| 47 | #define VEOF 4 | ||
| 48 | #define VTIME 5 | ||
| 49 | #define VMIN 6 | ||
| 50 | #define VSWTC 7 | ||
| 51 | #define VSTART 8 | ||
| 52 | #define VSTOP 9 | ||
| 53 | #define VSUSP 10 | ||
| 54 | #define VEOL 11 | ||
| 55 | #define VREPRINT 12 | ||
| 56 | #define VDISCARD 13 | ||
| 57 | #define VWERASE 14 | ||
| 58 | #define VLNEXT 15 | ||
| 59 | #define VEOL2 16 | ||
| 60 | |||
| 61 | /* c_iflag bits */ | ||
| 62 | #define IGNBRK 0000001 | ||
| 63 | #define BRKINT 0000002 | ||
| 64 | #define IGNPAR 0000004 | ||
| 65 | #define PARMRK 0000010 | ||
| 66 | #define INPCK 0000020 | ||
| 67 | #define ISTRIP 0000040 | ||
| 68 | #define INLCR 0000100 | ||
| 69 | #define IGNCR 0000200 | ||
| 70 | #define ICRNL 0000400 | ||
| 71 | #define IUCLC 0001000 | ||
| 72 | #define IXON 0002000 | ||
| 73 | #define IXANY 0004000 | ||
| 74 | #define IXOFF 0010000 | ||
| 75 | #define IMAXBEL 0020000 | ||
| 76 | #define IUTF8 0040000 | ||
| 77 | |||
| 78 | /* c_oflag bits */ | ||
| 79 | #define OPOST 0000001 | ||
| 80 | #define OLCUC 0000002 | ||
| 81 | #define ONLCR 0000004 | ||
| 82 | #define OCRNL 0000010 | ||
| 83 | #define ONOCR 0000020 | ||
| 84 | #define ONLRET 0000040 | ||
| 85 | #define OFILL 0000100 | ||
| 86 | #define OFDEL 0000200 | ||
| 87 | #define NLDLY 0000400 | ||
| 88 | #define NL0 0000000 | ||
| 89 | #define NL1 0000400 | ||
| 90 | #define CRDLY 0003000 | ||
| 91 | #define CR0 0000000 | ||
| 92 | #define CR1 0001000 | ||
| 93 | #define CR2 0002000 | ||
| 94 | #define CR3 0003000 | ||
| 95 | #define TABDLY 0014000 | ||
| 96 | #define TAB0 0000000 | ||
| 97 | #define TAB1 0004000 | ||
| 98 | #define TAB2 0010000 | ||
| 99 | #define TAB3 0014000 | ||
| 100 | #define XTABS 0014000 | ||
| 101 | #define BSDLY 0020000 | ||
| 102 | #define BS0 0000000 | ||
| 103 | #define BS1 0020000 | ||
| 104 | #define VTDLY 0040000 | ||
| 105 | #define VT0 0000000 | ||
| 106 | #define VT1 0040000 | ||
| 107 | #define FFDLY 0100000 | ||
| 108 | #define FF0 0000000 | ||
| 109 | #define FF1 0100000 | ||
| 110 | |||
| 111 | /* c_cflag bit meaning */ | ||
| 112 | #define CBAUD 0010017 | ||
| 113 | #define B0 0000000 /* hang up */ | ||
| 114 | #define B50 0000001 | ||
| 115 | #define B75 0000002 | ||
| 116 | #define B110 0000003 | ||
| 117 | #define B134 0000004 | ||
| 118 | #define B150 0000005 | ||
| 119 | #define B200 0000006 | ||
| 120 | #define B300 0000007 | ||
| 121 | #define B600 0000010 | ||
| 122 | #define B1200 0000011 | ||
| 123 | #define B1800 0000012 | ||
| 124 | #define B2400 0000013 | ||
| 125 | #define B4800 0000014 | ||
| 126 | #define B9600 0000015 | ||
| 127 | #define B19200 0000016 | ||
| 128 | #define B38400 0000017 | ||
| 129 | #define EXTA B19200 | ||
| 130 | #define EXTB B38400 | ||
| 131 | #define CSIZE 0000060 | ||
| 132 | #define CS5 0000000 | ||
| 133 | #define CS6 0000020 | ||
| 134 | #define CS7 0000040 | ||
| 135 | #define CS8 0000060 | ||
| 136 | #define CSTOPB 0000100 | ||
| 137 | #define CREAD 0000200 | ||
| 138 | #define PARENB 0000400 | ||
| 139 | #define PARODD 0001000 | ||
| 140 | #define HUPCL 0002000 | ||
| 141 | #define CLOCAL 0004000 | ||
| 142 | #define CBAUDEX 0010000 | ||
| 143 | #define BOTHER 0010000 /* non standard rate */ | ||
| 144 | #define B57600 0010001 | ||
| 145 | #define B115200 0010002 | ||
| 146 | #define B230400 0010003 | ||
| 147 | #define B460800 0010004 | ||
| 148 | #define B500000 0010005 | ||
| 149 | #define B576000 0010006 | ||
| 150 | #define B921600 0010007 | ||
| 151 | #define B1000000 0010010 | ||
| 152 | #define B1152000 0010011 | ||
| 153 | #define B1500000 0010012 | ||
| 154 | #define B2000000 0010013 | ||
| 155 | #define B2500000 0010014 | ||
| 156 | #define B3000000 0010015 | ||
| 157 | #define B3500000 0010016 | ||
| 158 | #define B4000000 0010017 | ||
| 159 | #define CIBAUD 002003600000 /* input baud rate */ | ||
| 160 | #define CMSPAR 010000000000 /* mark or space (stick) parity */ | ||
| 161 | #define CRTSCTS 020000000000 /* flow control */ | ||
| 162 | |||
| 163 | #define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ | ||
| 164 | |||
| 165 | /* c_lflag bits */ | ||
| 166 | #define ISIG 0000001 | ||
| 167 | #define ICANON 0000002 | ||
| 168 | #define XCASE 0000004 | ||
| 169 | #define ECHO 0000010 | ||
| 170 | #define ECHOE 0000020 | ||
| 171 | #define ECHOK 0000040 | ||
| 172 | #define ECHONL 0000100 | ||
| 173 | #define NOFLSH 0000200 | ||
| 174 | #define TOSTOP 0000400 | ||
| 175 | #define ECHOCTL 0001000 | ||
| 176 | #define ECHOPRT 0002000 | ||
| 177 | #define ECHOKE 0004000 | ||
| 178 | #define FLUSHO 0010000 | ||
| 179 | #define PENDIN 0040000 | ||
| 180 | #define IEXTEN 0100000 | ||
| 181 | |||
| 182 | /* tcflow() and TCXONC use these */ | ||
| 183 | #define TCOOFF 0 | ||
| 184 | #define TCOON 1 | ||
| 185 | #define TCIOFF 2 | ||
| 186 | #define TCION 3 | ||
| 187 | |||
| 188 | /* tcflush() and TCFLSH use these */ | ||
| 189 | #define TCIFLUSH 0 | ||
| 190 | #define TCOFLUSH 1 | ||
| 191 | #define TCIOFLUSH 2 | ||
| 192 | |||
| 193 | /* tcsetattr uses these */ | ||
| 194 | #define TCSANOW 0 | ||
| 195 | #define TCSADRAIN 1 | ||
| 196 | #define TCSAFLUSH 2 | ||
| 197 | |||
| 198 | #endif /* _ASM_X86_TERMBITS_H */ | ||
diff --git a/arch/x86/include/asm/termios.h b/arch/x86/include/asm/termios.h index c4ee8056baca..280d78a9d966 100644 --- a/arch/x86/include/asm/termios.h +++ b/arch/x86/include/asm/termios.h | |||
| @@ -1,114 +1 @@ | |||
| 1 | #ifndef _ASM_X86_TERMIOS_H | #include <asm-generic/termios.h> | |
| 2 | #define _ASM_X86_TERMIOS_H | ||
| 3 | |||
| 4 | #include <asm/termbits.h> | ||
| 5 | #include <asm/ioctls.h> | ||
| 6 | |||
| 7 | struct winsize { | ||
| 8 | unsigned short ws_row; | ||
| 9 | unsigned short ws_col; | ||
| 10 | unsigned short ws_xpixel; | ||
| 11 | unsigned short ws_ypixel; | ||
| 12 | }; | ||
| 13 | |||
| 14 | #define NCC 8 | ||
| 15 | struct termio { | ||
| 16 | unsigned short c_iflag; /* input mode flags */ | ||
| 17 | unsigned short c_oflag; /* output mode flags */ | ||
| 18 | unsigned short c_cflag; /* control mode flags */ | ||
| 19 | unsigned short c_lflag; /* local mode flags */ | ||
| 20 | unsigned char c_line; /* line discipline */ | ||
| 21 | unsigned char c_cc[NCC]; /* control characters */ | ||
| 22 | }; | ||
| 23 | |||
| 24 | /* modem lines */ | ||
| 25 | #define TIOCM_LE 0x001 | ||
| 26 | #define TIOCM_DTR 0x002 | ||
| 27 | #define TIOCM_RTS 0x004 | ||
| 28 | #define TIOCM_ST 0x008 | ||
| 29 | #define TIOCM_SR 0x010 | ||
| 30 | #define TIOCM_CTS 0x020 | ||
| 31 | #define TIOCM_CAR 0x040 | ||
| 32 | #define TIOCM_RNG 0x080 | ||
| 33 | #define TIOCM_DSR 0x100 | ||
| 34 | #define TIOCM_CD TIOCM_CAR | ||
| 35 | #define TIOCM_RI TIOCM_RNG | ||
| 36 | #define TIOCM_OUT1 0x2000 | ||
| 37 | #define TIOCM_OUT2 0x4000 | ||
| 38 | #define TIOCM_LOOP 0x8000 | ||
| 39 | |||
| 40 | /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ | ||
| 41 | |||
| 42 | #ifdef __KERNEL__ | ||
| 43 | |||
| 44 | #include <asm/uaccess.h> | ||
| 45 | |||
| 46 | /* intr=^C quit=^\ erase=del kill=^U | ||
| 47 | eof=^D vtime=\0 vmin=\1 sxtc=\0 | ||
| 48 | start=^Q stop=^S susp=^Z eol=\0 | ||
| 49 | reprint=^R discard=^U werase=^W lnext=^V | ||
| 50 | eol2=\0 | ||
| 51 | */ | ||
| 52 | #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" | ||
| 53 | |||
| 54 | /* | ||
| 55 | * Translate a "termio" structure into a "termios". Ugh. | ||
| 56 | */ | ||
| 57 | #define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ | ||
| 58 | unsigned short __tmp; \ | ||
| 59 | get_user(__tmp,&(termio)->x); \ | ||
| 60 | *(unsigned short *) &(termios)->x = __tmp; \ | ||
| 61 | } | ||
| 62 | |||
| 63 | static inline int user_termio_to_kernel_termios(struct ktermios *termios, | ||
| 64 | struct termio __user *termio) | ||
| 65 | { | ||
| 66 | SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); | ||
| 67 | SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); | ||
| 68 | SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); | ||
| 69 | SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); | ||
| 70 | get_user(termios->c_line, &termio->c_line); | ||
| 71 | return copy_from_user(termios->c_cc, termio->c_cc, NCC); | ||
| 72 | } | ||
| 73 | |||
| 74 | /* | ||
| 75 | * Translate a "termios" structure into a "termio". Ugh. | ||
| 76 | */ | ||
| 77 | static inline int kernel_termios_to_user_termio(struct termio __user *termio, | ||
| 78 | struct ktermios *termios) | ||
| 79 | { | ||
| 80 | put_user((termios)->c_iflag, &(termio)->c_iflag); | ||
| 81 | put_user((termios)->c_oflag, &(termio)->c_oflag); | ||
| 82 | put_user((termios)->c_cflag, &(termio)->c_cflag); | ||
| 83 | put_user((termios)->c_lflag, &(termio)->c_lflag); | ||
| 84 | put_user((termios)->c_line, &(termio)->c_line); | ||
| 85 | return copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); | ||
| 86 | } | ||
| 87 | |||
| 88 | static inline int user_termios_to_kernel_termios(struct ktermios *k, | ||
| 89 | struct termios2 __user *u) | ||
| 90 | { | ||
| 91 | return copy_from_user(k, u, sizeof(struct termios2)); | ||
| 92 | } | ||
| 93 | |||
| 94 | static inline int kernel_termios_to_user_termios(struct termios2 __user *u, | ||
| 95 | struct ktermios *k) | ||
| 96 | { | ||
| 97 | return copy_to_user(u, k, sizeof(struct termios2)); | ||
| 98 | } | ||
| 99 | |||
| 100 | static inline int user_termios_to_kernel_termios_1(struct ktermios *k, | ||
| 101 | struct termios __user *u) | ||
| 102 | { | ||
| 103 | return copy_from_user(k, u, sizeof(struct termios)); | ||
| 104 | } | ||
| 105 | |||
| 106 | static inline int kernel_termios_to_user_termios_1(struct termios __user *u, | ||
| 107 | struct ktermios *k) | ||
| 108 | { | ||
| 109 | return copy_to_user(u, k, sizeof(struct termios)); | ||
| 110 | } | ||
| 111 | |||
| 112 | #endif /* __KERNEL__ */ | ||
| 113 | |||
| 114 | #endif /* _ASM_X86_TERMIOS_H */ | ||
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index fad7d40b75f8..d27d0a2fec4c 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h | |||
| @@ -95,7 +95,7 @@ struct thread_info { | |||
| 95 | #define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */ | 95 | #define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */ |
| 96 | #define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */ | 96 | #define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */ |
| 97 | #define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */ | 97 | #define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */ |
| 98 | #define TIF_SYSCALL_FTRACE 28 /* for ftrace syscall instrumentation */ | 98 | #define TIF_SYSCALL_TRACEPOINT 28 /* syscall tracepoint instrumentation */ |
| 99 | 99 | ||
| 100 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) | 100 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) |
| 101 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) | 101 | #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) |
| @@ -118,17 +118,17 @@ struct thread_info { | |||
| 118 | #define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR) | 118 | #define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR) |
| 119 | #define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR) | 119 | #define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR) |
| 120 | #define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES) | 120 | #define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES) |
| 121 | #define _TIF_SYSCALL_FTRACE (1 << TIF_SYSCALL_FTRACE) | 121 | #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) |
| 122 | 122 | ||
| 123 | /* work to do in syscall_trace_enter() */ | 123 | /* work to do in syscall_trace_enter() */ |
| 124 | #define _TIF_WORK_SYSCALL_ENTRY \ | 124 | #define _TIF_WORK_SYSCALL_ENTRY \ |
| 125 | (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_FTRACE | \ | 125 | (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_AUDIT | \ |
| 126 | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | _TIF_SINGLESTEP) | 126 | _TIF_SECCOMP | _TIF_SINGLESTEP | _TIF_SYSCALL_TRACEPOINT) |
| 127 | 127 | ||
| 128 | /* work to do in syscall_trace_leave() */ | 128 | /* work to do in syscall_trace_leave() */ |
| 129 | #define _TIF_WORK_SYSCALL_EXIT \ | 129 | #define _TIF_WORK_SYSCALL_EXIT \ |
| 130 | (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP | \ | 130 | (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP | \ |
| 131 | _TIF_SYSCALL_FTRACE) | 131 | _TIF_SYSCALL_TRACEPOINT) |
| 132 | 132 | ||
| 133 | /* work to do on interrupt/exception return */ | 133 | /* work to do on interrupt/exception return */ |
| 134 | #define _TIF_WORK_MASK \ | 134 | #define _TIF_WORK_MASK \ |
| @@ -137,7 +137,8 @@ struct thread_info { | |||
| 137 | _TIF_SINGLESTEP|_TIF_SECCOMP|_TIF_SYSCALL_EMU)) | 137 | _TIF_SINGLESTEP|_TIF_SECCOMP|_TIF_SYSCALL_EMU)) |
| 138 | 138 | ||
| 139 | /* work to do on any return to user space */ | 139 | /* work to do on any return to user space */ |
| 140 | #define _TIF_ALLWORK_MASK ((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_FTRACE) | 140 | #define _TIF_ALLWORK_MASK \ |
| 141 | ((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_TRACEPOINT) | ||
| 141 | 142 | ||
| 142 | /* Only used for 64 bit */ | 143 | /* Only used for 64 bit */ |
| 143 | #define _TIF_DO_NOTIFY_MASK \ | 144 | #define _TIF_DO_NOTIFY_MASK \ |
| @@ -213,7 +214,7 @@ DECLARE_PER_CPU(unsigned long, kernel_stack); | |||
| 213 | static inline struct thread_info *current_thread_info(void) | 214 | static inline struct thread_info *current_thread_info(void) |
| 214 | { | 215 | { |
| 215 | struct thread_info *ti; | 216 | struct thread_info *ti; |
| 216 | ti = (void *)(percpu_read(kernel_stack) + | 217 | ti = (void *)(percpu_read_stable(kernel_stack) + |
| 217 | KERNEL_STACK_OFFSET - THREAD_SIZE); | 218 | KERNEL_STACK_OFFSET - THREAD_SIZE); |
| 218 | return ti; | 219 | return ti; |
| 219 | } | 220 | } |
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 066ef590d7e0..26d06e052a18 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h | |||
| @@ -129,25 +129,34 @@ extern unsigned long node_remap_size[]; | |||
| 129 | #endif | 129 | #endif |
| 130 | 130 | ||
| 131 | /* sched_domains SD_NODE_INIT for NUMA machines */ | 131 | /* sched_domains SD_NODE_INIT for NUMA machines */ |
| 132 | #define SD_NODE_INIT (struct sched_domain) { \ | 132 | #define SD_NODE_INIT (struct sched_domain) { \ |
| 133 | .min_interval = 8, \ | 133 | .min_interval = 8, \ |
| 134 | .max_interval = 32, \ | 134 | .max_interval = 32, \ |
| 135 | .busy_factor = 32, \ | 135 | .busy_factor = 32, \ |
| 136 | .imbalance_pct = 125, \ | 136 | .imbalance_pct = 125, \ |
| 137 | .cache_nice_tries = SD_CACHE_NICE_TRIES, \ | 137 | .cache_nice_tries = SD_CACHE_NICE_TRIES, \ |
| 138 | .busy_idx = 3, \ | 138 | .busy_idx = 3, \ |
| 139 | .idle_idx = SD_IDLE_IDX, \ | 139 | .idle_idx = SD_IDLE_IDX, \ |
| 140 | .newidle_idx = SD_NEWIDLE_IDX, \ | 140 | .newidle_idx = SD_NEWIDLE_IDX, \ |
| 141 | .wake_idx = 1, \ | 141 | .wake_idx = 1, \ |
| 142 | .forkexec_idx = SD_FORKEXEC_IDX, \ | 142 | .forkexec_idx = SD_FORKEXEC_IDX, \ |
| 143 | .flags = SD_LOAD_BALANCE \ | 143 | \ |
| 144 | | SD_BALANCE_EXEC \ | 144 | .flags = 1*SD_LOAD_BALANCE \ |
| 145 | | SD_BALANCE_FORK \ | 145 | | 1*SD_BALANCE_NEWIDLE \ |
| 146 | | SD_WAKE_AFFINE \ | 146 | | 1*SD_BALANCE_EXEC \ |
| 147 | | SD_WAKE_BALANCE \ | 147 | | 1*SD_BALANCE_FORK \ |
| 148 | | SD_SERIALIZE, \ | 148 | | 0*SD_WAKE_IDLE \ |
| 149 | .last_balance = jiffies, \ | 149 | | 1*SD_WAKE_AFFINE \ |
| 150 | .balance_interval = 1, \ | 150 | | 1*SD_WAKE_BALANCE \ |
| 151 | | 0*SD_SHARE_CPUPOWER \ | ||
| 152 | | 0*SD_POWERSAVINGS_BALANCE \ | ||
| 153 | | 0*SD_SHARE_PKG_RESOURCES \ | ||
| 154 | | 1*SD_SERIALIZE \ | ||
| 155 | | 1*SD_WAKE_IDLE_FAR \ | ||
| 156 | | 0*SD_PREFER_SIBLING \ | ||
| 157 | , \ | ||
| 158 | .last_balance = jiffies, \ | ||
| 159 | .balance_interval = 1, \ | ||
| 151 | } | 160 | } |
| 152 | 161 | ||
| 153 | #ifdef CONFIG_X86_64_ACPI_NUMA | 162 | #ifdef CONFIG_X86_64_ACPI_NUMA |
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index bfd74c032fca..4da91ad69e0d 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h | |||
| @@ -81,9 +81,7 @@ extern int panic_on_unrecovered_nmi; | |||
| 81 | 81 | ||
| 82 | void math_error(void __user *); | 82 | void math_error(void __user *); |
| 83 | void math_emulate(struct math_emu_info *); | 83 | void math_emulate(struct math_emu_info *); |
| 84 | #ifdef CONFIG_X86_32 | 84 | #ifndef CONFIG_X86_32 |
| 85 | unsigned long patch_espfix_desc(unsigned long, unsigned long); | ||
| 86 | #else | ||
| 87 | asmlinkage void smp_thermal_interrupt(void); | 85 | asmlinkage void smp_thermal_interrupt(void); |
| 88 | asmlinkage void mce_threshold_interrupt(void); | 86 | asmlinkage void mce_threshold_interrupt(void); |
| 89 | #endif | 87 | #endif |
diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h index 09b97745772f..df1da20f4534 100644 --- a/arch/x86/include/asm/types.h +++ b/arch/x86/include/asm/types.h | |||
| @@ -1,19 +1,11 @@ | |||
| 1 | #ifndef _ASM_X86_TYPES_H | 1 | #ifndef _ASM_X86_TYPES_H |
| 2 | #define _ASM_X86_TYPES_H | 2 | #define _ASM_X86_TYPES_H |
| 3 | 3 | ||
| 4 | #include <asm-generic/int-ll64.h> | 4 | #define dma_addr_t dma_addr_t |
| 5 | 5 | ||
| 6 | #ifndef __ASSEMBLY__ | 6 | #include <asm-generic/types.h> |
| 7 | |||
| 8 | typedef unsigned short umode_t; | ||
| 9 | 7 | ||
| 10 | #endif /* __ASSEMBLY__ */ | ||
| 11 | |||
| 12 | /* | ||
| 13 | * These aren't exported outside the kernel to avoid name space clashes | ||
| 14 | */ | ||
| 15 | #ifdef __KERNEL__ | 8 | #ifdef __KERNEL__ |
| 16 | |||
| 17 | #ifndef __ASSEMBLY__ | 9 | #ifndef __ASSEMBLY__ |
| 18 | 10 | ||
| 19 | typedef u64 dma64_addr_t; | 11 | typedef u64 dma64_addr_t; |
diff --git a/arch/x86/include/asm/ucontext.h b/arch/x86/include/asm/ucontext.h index 87324cf439d9..b7c29c8017f2 100644 --- a/arch/x86/include/asm/ucontext.h +++ b/arch/x86/include/asm/ucontext.h | |||
| @@ -7,12 +7,6 @@ | |||
| 7 | * sigcontext struct (uc_mcontext). | 7 | * sigcontext struct (uc_mcontext). |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | struct ucontext { | 10 | #include <asm-generic/ucontext.h> |
| 11 | unsigned long uc_flags; | ||
| 12 | struct ucontext *uc_link; | ||
| 13 | stack_t uc_stack; | ||
| 14 | struct sigcontext uc_mcontext; | ||
| 15 | sigset_t uc_sigmask; /* mask last for extensibility */ | ||
| 16 | }; | ||
| 17 | 11 | ||
| 18 | #endif /* _ASM_X86_UCONTEXT_H */ | 12 | #endif /* _ASM_X86_UCONTEXT_H */ |
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h index 732a30706153..8deaada61bc8 100644 --- a/arch/x86/include/asm/unistd_32.h +++ b/arch/x86/include/asm/unistd_32.h | |||
| @@ -345,6 +345,8 @@ | |||
| 345 | 345 | ||
| 346 | #ifdef __KERNEL__ | 346 | #ifdef __KERNEL__ |
| 347 | 347 | ||
| 348 | #define NR_syscalls 337 | ||
| 349 | |||
| 348 | #define __ARCH_WANT_IPC_PARSE_VERSION | 350 | #define __ARCH_WANT_IPC_PARSE_VERSION |
| 349 | #define __ARCH_WANT_OLD_READDIR | 351 | #define __ARCH_WANT_OLD_READDIR |
| 350 | #define __ARCH_WANT_OLD_STAT | 352 | #define __ARCH_WANT_OLD_STAT |
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h index 900e1617e672..b9f3c60de5f7 100644 --- a/arch/x86/include/asm/unistd_64.h +++ b/arch/x86/include/asm/unistd_64.h | |||
| @@ -688,6 +688,12 @@ __SYSCALL(__NR_perf_counter_open, sys_perf_counter_open) | |||
| 688 | #endif /* __NO_STUBS */ | 688 | #endif /* __NO_STUBS */ |
| 689 | 689 | ||
| 690 | #ifdef __KERNEL__ | 690 | #ifdef __KERNEL__ |
| 691 | |||
| 692 | #ifndef COMPILE_OFFSETS | ||
| 693 | #include <asm/asm-offsets.h> | ||
| 694 | #define NR_syscalls (__NR_syscall_max + 1) | ||
| 695 | #endif | ||
| 696 | |||
| 691 | /* | 697 | /* |
| 692 | * "Conditional" syscalls | 698 | * "Conditional" syscalls |
| 693 | * | 699 | * |
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 11be5ad2e0e9..272514c2d456 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h | |||
| @@ -55,6 +55,7 @@ | |||
| 55 | #define SECONDARY_EXEC_ENABLE_EPT 0x00000002 | 55 | #define SECONDARY_EXEC_ENABLE_EPT 0x00000002 |
| 56 | #define SECONDARY_EXEC_ENABLE_VPID 0x00000020 | 56 | #define SECONDARY_EXEC_ENABLE_VPID 0x00000020 |
| 57 | #define SECONDARY_EXEC_WBINVD_EXITING 0x00000040 | 57 | #define SECONDARY_EXEC_WBINVD_EXITING 0x00000040 |
| 58 | #define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080 | ||
| 58 | 59 | ||
| 59 | 60 | ||
| 60 | #define PIN_BASED_EXT_INTR_MASK 0x00000001 | 61 | #define PIN_BASED_EXT_INTR_MASK 0x00000001 |
| @@ -351,9 +352,16 @@ enum vmcs_field { | |||
| 351 | #define VMX_EPT_EXTENT_INDIVIDUAL_ADDR 0 | 352 | #define VMX_EPT_EXTENT_INDIVIDUAL_ADDR 0 |
| 352 | #define VMX_EPT_EXTENT_CONTEXT 1 | 353 | #define VMX_EPT_EXTENT_CONTEXT 1 |
| 353 | #define VMX_EPT_EXTENT_GLOBAL 2 | 354 | #define VMX_EPT_EXTENT_GLOBAL 2 |
| 355 | |||
| 356 | #define VMX_EPT_EXECUTE_ONLY_BIT (1ull) | ||
| 357 | #define VMX_EPT_PAGE_WALK_4_BIT (1ull << 6) | ||
| 358 | #define VMX_EPTP_UC_BIT (1ull << 8) | ||
| 359 | #define VMX_EPTP_WB_BIT (1ull << 14) | ||
| 360 | #define VMX_EPT_2MB_PAGE_BIT (1ull << 16) | ||
| 354 | #define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ull << 24) | 361 | #define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ull << 24) |
| 355 | #define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25) | 362 | #define VMX_EPT_EXTENT_CONTEXT_BIT (1ull << 25) |
| 356 | #define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26) | 363 | #define VMX_EPT_EXTENT_GLOBAL_BIT (1ull << 26) |
| 364 | |||
| 357 | #define VMX_EPT_DEFAULT_GAW 3 | 365 | #define VMX_EPT_DEFAULT_GAW 3 |
| 358 | #define VMX_EPT_MAX_GAW 0x4 | 366 | #define VMX_EPT_MAX_GAW 0x4 |
| 359 | #define VMX_EPT_MT_EPTE_SHIFT 3 | 367 | #define VMX_EPT_MT_EPTE_SHIFT 3 |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 6b8ca3a0285d..67e929b89875 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
| @@ -833,106 +833,6 @@ static int __init acpi_parse_madt_lapic_entries(void) | |||
| 833 | extern int es7000_plat; | 833 | extern int es7000_plat; |
| 834 | #endif | 834 | #endif |
| 835 | 835 | ||
| 836 | static struct { | ||
| 837 | int gsi_base; | ||
| 838 | int gsi_end; | ||
| 839 | } mp_ioapic_routing[MAX_IO_APICS]; | ||
| 840 | |||
| 841 | int mp_find_ioapic(int gsi) | ||
| 842 | { | ||
| 843 | int i = 0; | ||
| 844 | |||
| 845 | /* Find the IOAPIC that manages this GSI. */ | ||
| 846 | for (i = 0; i < nr_ioapics; i++) { | ||
| 847 | if ((gsi >= mp_ioapic_routing[i].gsi_base) | ||
| 848 | && (gsi <= mp_ioapic_routing[i].gsi_end)) | ||
| 849 | return i; | ||
| 850 | } | ||
| 851 | |||
| 852 | printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); | ||
| 853 | return -1; | ||
| 854 | } | ||
| 855 | |||
| 856 | int mp_find_ioapic_pin(int ioapic, int gsi) | ||
| 857 | { | ||
| 858 | if (WARN_ON(ioapic == -1)) | ||
| 859 | return -1; | ||
| 860 | if (WARN_ON(gsi > mp_ioapic_routing[ioapic].gsi_end)) | ||
| 861 | return -1; | ||
| 862 | |||
| 863 | return gsi - mp_ioapic_routing[ioapic].gsi_base; | ||
| 864 | } | ||
| 865 | |||
| 866 | static u8 __init uniq_ioapic_id(u8 id) | ||
| 867 | { | ||
| 868 | #ifdef CONFIG_X86_32 | ||
| 869 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && | ||
| 870 | !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) | ||
| 871 | return io_apic_get_unique_id(nr_ioapics, id); | ||
| 872 | else | ||
| 873 | return id; | ||
| 874 | #else | ||
| 875 | int i; | ||
| 876 | DECLARE_BITMAP(used, 256); | ||
| 877 | bitmap_zero(used, 256); | ||
| 878 | for (i = 0; i < nr_ioapics; i++) { | ||
| 879 | struct mpc_ioapic *ia = &mp_ioapics[i]; | ||
| 880 | __set_bit(ia->apicid, used); | ||
| 881 | } | ||
| 882 | if (!test_bit(id, used)) | ||
| 883 | return id; | ||
| 884 | return find_first_zero_bit(used, 256); | ||
| 885 | #endif | ||
| 886 | } | ||
| 887 | |||
| 888 | static int bad_ioapic(unsigned long address) | ||
| 889 | { | ||
| 890 | if (nr_ioapics >= MAX_IO_APICS) { | ||
| 891 | printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " | ||
| 892 | "(found %d)\n", MAX_IO_APICS, nr_ioapics); | ||
| 893 | panic("Recompile kernel with bigger MAX_IO_APICS!\n"); | ||
| 894 | } | ||
| 895 | if (!address) { | ||
| 896 | printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" | ||
| 897 | " found in table, skipping!\n"); | ||
| 898 | return 1; | ||
| 899 | } | ||
| 900 | return 0; | ||
| 901 | } | ||
| 902 | |||
| 903 | void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) | ||
| 904 | { | ||
| 905 | int idx = 0; | ||
| 906 | |||
| 907 | if (bad_ioapic(address)) | ||
| 908 | return; | ||
| 909 | |||
| 910 | idx = nr_ioapics; | ||
| 911 | |||
| 912 | mp_ioapics[idx].type = MP_IOAPIC; | ||
| 913 | mp_ioapics[idx].flags = MPC_APIC_USABLE; | ||
| 914 | mp_ioapics[idx].apicaddr = address; | ||
| 915 | |||
| 916 | set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); | ||
| 917 | mp_ioapics[idx].apicid = uniq_ioapic_id(id); | ||
| 918 | mp_ioapics[idx].apicver = io_apic_get_version(idx); | ||
| 919 | |||
| 920 | /* | ||
| 921 | * Build basic GSI lookup table to facilitate gsi->io_apic lookups | ||
| 922 | * and to prevent reprogramming of IOAPIC pins (PCI GSIs). | ||
| 923 | */ | ||
| 924 | mp_ioapic_routing[idx].gsi_base = gsi_base; | ||
| 925 | mp_ioapic_routing[idx].gsi_end = gsi_base + | ||
| 926 | io_apic_get_redir_entries(idx); | ||
| 927 | |||
| 928 | printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " | ||
| 929 | "GSI %d-%d\n", idx, mp_ioapics[idx].apicid, | ||
| 930 | mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr, | ||
| 931 | mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end); | ||
| 932 | |||
| 933 | nr_ioapics++; | ||
| 934 | } | ||
| 935 | |||
| 936 | int __init acpi_probe_gsi(void) | 836 | int __init acpi_probe_gsi(void) |
| 937 | { | 837 | { |
| 938 | int idx; | 838 | int idx; |
| @@ -947,7 +847,7 @@ int __init acpi_probe_gsi(void) | |||
| 947 | 847 | ||
| 948 | max_gsi = 0; | 848 | max_gsi = 0; |
| 949 | for (idx = 0; idx < nr_ioapics; idx++) { | 849 | for (idx = 0; idx < nr_ioapics; idx++) { |
| 950 | gsi = mp_ioapic_routing[idx].gsi_end; | 850 | gsi = mp_gsi_routing[idx].gsi_end; |
| 951 | 851 | ||
| 952 | if (gsi > max_gsi) | 852 | if (gsi > max_gsi) |
| 953 | max_gsi = gsi; | 853 | max_gsi = gsi; |
| @@ -1179,9 +1079,8 @@ static int __init acpi_parse_madt_ioapic_entries(void) | |||
| 1179 | * If MPS is present, it will handle them, | 1079 | * If MPS is present, it will handle them, |
| 1180 | * otherwise the system will stay in PIC mode | 1080 | * otherwise the system will stay in PIC mode |
| 1181 | */ | 1081 | */ |
| 1182 | if (acpi_disabled || acpi_noirq) { | 1082 | if (acpi_disabled || acpi_noirq) |
| 1183 | return -ENODEV; | 1083 | return -ENODEV; |
| 1184 | } | ||
| 1185 | 1084 | ||
| 1186 | if (!cpu_has_apic) | 1085 | if (!cpu_has_apic) |
| 1187 | return -ENODEV; | 1086 | return -ENODEV; |
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index f57658702571..de7353c0ce9c 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #include <linux/sched.h> | 2 | #include <linux/sched.h> |
| 3 | #include <linux/mutex.h> | 3 | #include <linux/mutex.h> |
| 4 | #include <linux/list.h> | 4 | #include <linux/list.h> |
| 5 | #include <linux/stringify.h> | ||
| 5 | #include <linux/kprobes.h> | 6 | #include <linux/kprobes.h> |
| 6 | #include <linux/mm.h> | 7 | #include <linux/mm.h> |
| 7 | #include <linux/vmalloc.h> | 8 | #include <linux/vmalloc.h> |
| @@ -32,7 +33,7 @@ __setup("smp-alt-boot", bootonly); | |||
| 32 | #define smp_alt_once 1 | 33 | #define smp_alt_once 1 |
| 33 | #endif | 34 | #endif |
| 34 | 35 | ||
| 35 | static int debug_alternative; | 36 | static int __initdata_or_module debug_alternative; |
| 36 | 37 | ||
| 37 | static int __init debug_alt(char *str) | 38 | static int __init debug_alt(char *str) |
| 38 | { | 39 | { |
| @@ -51,7 +52,7 @@ static int __init setup_noreplace_smp(char *str) | |||
| 51 | __setup("noreplace-smp", setup_noreplace_smp); | 52 | __setup("noreplace-smp", setup_noreplace_smp); |
| 52 | 53 | ||
| 53 | #ifdef CONFIG_PARAVIRT | 54 | #ifdef CONFIG_PARAVIRT |
| 54 | static int noreplace_paravirt = 0; | 55 | static int __initdata_or_module noreplace_paravirt = 0; |
| 55 | 56 | ||
| 56 | static int __init setup_noreplace_paravirt(char *str) | 57 | static int __init setup_noreplace_paravirt(char *str) |
| 57 | { | 58 | { |
| @@ -64,16 +65,17 @@ __setup("noreplace-paravirt", setup_noreplace_paravirt); | |||
| 64 | #define DPRINTK(fmt, args...) if (debug_alternative) \ | 65 | #define DPRINTK(fmt, args...) if (debug_alternative) \ |
| 65 | printk(KERN_DEBUG fmt, args) | 66 | printk(KERN_DEBUG fmt, args) |
| 66 | 67 | ||
| 67 | #ifdef GENERIC_NOP1 | 68 | #if defined(GENERIC_NOP1) && !defined(CONFIG_X86_64) |
| 68 | /* Use inline assembly to define this because the nops are defined | 69 | /* Use inline assembly to define this because the nops are defined |
| 69 | as inline assembly strings in the include files and we cannot | 70 | as inline assembly strings in the include files and we cannot |
| 70 | get them easily into strings. */ | 71 | get them easily into strings. */ |
| 71 | asm("\t.section .rodata, \"a\"\nintelnops: " | 72 | asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nintelnops: " |
| 72 | GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 | 73 | GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 |
| 73 | GENERIC_NOP7 GENERIC_NOP8 | 74 | GENERIC_NOP7 GENERIC_NOP8 |
| 74 | "\t.previous"); | 75 | "\t.previous"); |
| 75 | extern const unsigned char intelnops[]; | 76 | extern const unsigned char intelnops[]; |
| 76 | static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = { | 77 | static const unsigned char *const __initconst_or_module |
| 78 | intel_nops[ASM_NOP_MAX+1] = { | ||
| 77 | NULL, | 79 | NULL, |
| 78 | intelnops, | 80 | intelnops, |
| 79 | intelnops + 1, | 81 | intelnops + 1, |
| @@ -87,12 +89,13 @@ static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = { | |||
| 87 | #endif | 89 | #endif |
| 88 | 90 | ||
| 89 | #ifdef K8_NOP1 | 91 | #ifdef K8_NOP1 |
| 90 | asm("\t.section .rodata, \"a\"\nk8nops: " | 92 | asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk8nops: " |
| 91 | K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 | 93 | K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 |
| 92 | K8_NOP7 K8_NOP8 | 94 | K8_NOP7 K8_NOP8 |
| 93 | "\t.previous"); | 95 | "\t.previous"); |
| 94 | extern const unsigned char k8nops[]; | 96 | extern const unsigned char k8nops[]; |
| 95 | static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = { | 97 | static const unsigned char *const __initconst_or_module |
| 98 | k8_nops[ASM_NOP_MAX+1] = { | ||
| 96 | NULL, | 99 | NULL, |
| 97 | k8nops, | 100 | k8nops, |
| 98 | k8nops + 1, | 101 | k8nops + 1, |
| @@ -105,13 +108,14 @@ static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = { | |||
| 105 | }; | 108 | }; |
| 106 | #endif | 109 | #endif |
| 107 | 110 | ||
| 108 | #ifdef K7_NOP1 | 111 | #if defined(K7_NOP1) && !defined(CONFIG_X86_64) |
| 109 | asm("\t.section .rodata, \"a\"\nk7nops: " | 112 | asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk7nops: " |
| 110 | K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 | 113 | K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 |
| 111 | K7_NOP7 K7_NOP8 | 114 | K7_NOP7 K7_NOP8 |
| 112 | "\t.previous"); | 115 | "\t.previous"); |
| 113 | extern const unsigned char k7nops[]; | 116 | extern const unsigned char k7nops[]; |
| 114 | static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = { | 117 | static const unsigned char *const __initconst_or_module |
| 118 | k7_nops[ASM_NOP_MAX+1] = { | ||
| 115 | NULL, | 119 | NULL, |
| 116 | k7nops, | 120 | k7nops, |
| 117 | k7nops + 1, | 121 | k7nops + 1, |
| @@ -125,12 +129,13 @@ static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = { | |||
| 125 | #endif | 129 | #endif |
| 126 | 130 | ||
| 127 | #ifdef P6_NOP1 | 131 | #ifdef P6_NOP1 |
| 128 | asm("\t.section .rodata, \"a\"\np6nops: " | 132 | asm("\t" __stringify(__INITRODATA_OR_MODULE) "\np6nops: " |
| 129 | P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6 | 133 | P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6 |
| 130 | P6_NOP7 P6_NOP8 | 134 | P6_NOP7 P6_NOP8 |
| 131 | "\t.previous"); | 135 | "\t.previous"); |
| 132 | extern const unsigned char p6nops[]; | 136 | extern const unsigned char p6nops[]; |
| 133 | static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = { | 137 | static const unsigned char *const __initconst_or_module |
| 138 | p6_nops[ASM_NOP_MAX+1] = { | ||
| 134 | NULL, | 139 | NULL, |
| 135 | p6nops, | 140 | p6nops, |
| 136 | p6nops + 1, | 141 | p6nops + 1, |
| @@ -146,7 +151,7 @@ static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = { | |||
| 146 | #ifdef CONFIG_X86_64 | 151 | #ifdef CONFIG_X86_64 |
| 147 | 152 | ||
| 148 | extern char __vsyscall_0; | 153 | extern char __vsyscall_0; |
| 149 | const unsigned char *const *find_nop_table(void) | 154 | static const unsigned char *const *__init_or_module find_nop_table(void) |
| 150 | { | 155 | { |
| 151 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | 156 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && |
| 152 | boot_cpu_has(X86_FEATURE_NOPL)) | 157 | boot_cpu_has(X86_FEATURE_NOPL)) |
| @@ -157,7 +162,7 @@ const unsigned char *const *find_nop_table(void) | |||
| 157 | 162 | ||
| 158 | #else /* CONFIG_X86_64 */ | 163 | #else /* CONFIG_X86_64 */ |
| 159 | 164 | ||
| 160 | const unsigned char *const *find_nop_table(void) | 165 | static const unsigned char *const *__init_or_module find_nop_table(void) |
| 161 | { | 166 | { |
| 162 | if (boot_cpu_has(X86_FEATURE_K8)) | 167 | if (boot_cpu_has(X86_FEATURE_K8)) |
| 163 | return k8_nops; | 168 | return k8_nops; |
| @@ -172,7 +177,7 @@ const unsigned char *const *find_nop_table(void) | |||
| 172 | #endif /* CONFIG_X86_64 */ | 177 | #endif /* CONFIG_X86_64 */ |
| 173 | 178 | ||
| 174 | /* Use this to add nops to a buffer, then text_poke the whole buffer. */ | 179 | /* Use this to add nops to a buffer, then text_poke the whole buffer. */ |
| 175 | void add_nops(void *insns, unsigned int len) | 180 | static void __init_or_module add_nops(void *insns, unsigned int len) |
| 176 | { | 181 | { |
| 177 | const unsigned char *const *noptable = find_nop_table(); | 182 | const unsigned char *const *noptable = find_nop_table(); |
| 178 | 183 | ||
| @@ -185,10 +190,10 @@ void add_nops(void *insns, unsigned int len) | |||
| 185 | len -= noplen; | 190 | len -= noplen; |
| 186 | } | 191 | } |
| 187 | } | 192 | } |
| 188 | EXPORT_SYMBOL_GPL(add_nops); | ||
| 189 | 193 | ||
| 190 | extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; | 194 | extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; |
| 191 | extern u8 *__smp_locks[], *__smp_locks_end[]; | 195 | extern u8 *__smp_locks[], *__smp_locks_end[]; |
| 196 | static void *text_poke_early(void *addr, const void *opcode, size_t len); | ||
| 192 | 197 | ||
| 193 | /* Replace instructions with better alternatives for this CPU type. | 198 | /* Replace instructions with better alternatives for this CPU type. |
| 194 | This runs before SMP is initialized to avoid SMP problems with | 199 | This runs before SMP is initialized to avoid SMP problems with |
| @@ -196,7 +201,8 @@ extern u8 *__smp_locks[], *__smp_locks_end[]; | |||
| 196 | APs have less capabilities than the boot processor are not handled. | 201 | APs have less capabilities than the boot processor are not handled. |
| 197 | Tough. Make sure you disable such features by hand. */ | 202 | Tough. Make sure you disable such features by hand. */ |
| 198 | 203 | ||
| 199 | void apply_alternatives(struct alt_instr *start, struct alt_instr *end) | 204 | void __init_or_module apply_alternatives(struct alt_instr *start, |
| 205 | struct alt_instr *end) | ||
| 200 | { | 206 | { |
| 201 | struct alt_instr *a; | 207 | struct alt_instr *a; |
| 202 | char insnbuf[MAX_PATCH_LEN]; | 208 | char insnbuf[MAX_PATCH_LEN]; |
| @@ -279,9 +285,10 @@ static LIST_HEAD(smp_alt_modules); | |||
| 279 | static DEFINE_MUTEX(smp_alt); | 285 | static DEFINE_MUTEX(smp_alt); |
| 280 | static int smp_mode = 1; /* protected by smp_alt */ | 286 | static int smp_mode = 1; /* protected by smp_alt */ |
| 281 | 287 | ||
| 282 | void alternatives_smp_module_add(struct module *mod, char *name, | 288 | void __init_or_module alternatives_smp_module_add(struct module *mod, |
| 283 | void *locks, void *locks_end, | 289 | char *name, |
| 284 | void *text, void *text_end) | 290 | void *locks, void *locks_end, |
| 291 | void *text, void *text_end) | ||
| 285 | { | 292 | { |
| 286 | struct smp_alt_module *smp; | 293 | struct smp_alt_module *smp; |
| 287 | 294 | ||
| @@ -317,7 +324,7 @@ void alternatives_smp_module_add(struct module *mod, char *name, | |||
| 317 | mutex_unlock(&smp_alt); | 324 | mutex_unlock(&smp_alt); |
| 318 | } | 325 | } |
| 319 | 326 | ||
| 320 | void alternatives_smp_module_del(struct module *mod) | 327 | void __init_or_module alternatives_smp_module_del(struct module *mod) |
| 321 | { | 328 | { |
| 322 | struct smp_alt_module *item; | 329 | struct smp_alt_module *item; |
| 323 | 330 | ||
| @@ -386,8 +393,8 @@ void alternatives_smp_switch(int smp) | |||
| 386 | #endif | 393 | #endif |
| 387 | 394 | ||
| 388 | #ifdef CONFIG_PARAVIRT | 395 | #ifdef CONFIG_PARAVIRT |
| 389 | void apply_paravirt(struct paravirt_patch_site *start, | 396 | void __init_or_module apply_paravirt(struct paravirt_patch_site *start, |
| 390 | struct paravirt_patch_site *end) | 397 | struct paravirt_patch_site *end) |
| 391 | { | 398 | { |
| 392 | struct paravirt_patch_site *p; | 399 | struct paravirt_patch_site *p; |
| 393 | char insnbuf[MAX_PATCH_LEN]; | 400 | char insnbuf[MAX_PATCH_LEN]; |
| @@ -485,13 +492,14 @@ void __init alternative_instructions(void) | |||
| 485 | * instructions. And on the local CPU you need to be protected again NMI or MCE | 492 | * instructions. And on the local CPU you need to be protected again NMI or MCE |
| 486 | * handlers seeing an inconsistent instruction while you patch. | 493 | * handlers seeing an inconsistent instruction while you patch. |
| 487 | */ | 494 | */ |
| 488 | void *text_poke_early(void *addr, const void *opcode, size_t len) | 495 | static void *__init_or_module text_poke_early(void *addr, const void *opcode, |
| 496 | size_t len) | ||
| 489 | { | 497 | { |
| 490 | unsigned long flags; | 498 | unsigned long flags; |
| 491 | local_irq_save(flags); | 499 | local_irq_save(flags); |
| 492 | memcpy(addr, opcode, len); | 500 | memcpy(addr, opcode, len); |
| 493 | local_irq_restore(flags); | ||
| 494 | sync_core(); | 501 | sync_core(); |
| 502 | local_irq_restore(flags); | ||
| 495 | /* Could also do a CLFLUSH here to speed up CPU recovery; but | 503 | /* Could also do a CLFLUSH here to speed up CPU recovery; but |
| 496 | that causes hangs on some VIA CPUs. */ | 504 | that causes hangs on some VIA CPUs. */ |
| 497 | return addr; | 505 | return addr; |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 6c99f5037801..98f230f6a28d 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
| @@ -41,9 +41,13 @@ static DEFINE_RWLOCK(amd_iommu_devtable_lock); | |||
| 41 | static LIST_HEAD(iommu_pd_list); | 41 | static LIST_HEAD(iommu_pd_list); |
| 42 | static DEFINE_SPINLOCK(iommu_pd_list_lock); | 42 | static DEFINE_SPINLOCK(iommu_pd_list_lock); |
| 43 | 43 | ||
| 44 | #ifdef CONFIG_IOMMU_API | 44 | /* |
| 45 | * Domain for untranslated devices - only allocated | ||
| 46 | * if iommu=pt passed on kernel cmd line. | ||
| 47 | */ | ||
| 48 | static struct protection_domain *pt_domain; | ||
| 49 | |||
| 45 | static struct iommu_ops amd_iommu_ops; | 50 | static struct iommu_ops amd_iommu_ops; |
| 46 | #endif | ||
| 47 | 51 | ||
| 48 | /* | 52 | /* |
| 49 | * general struct to manage commands send to an IOMMU | 53 | * general struct to manage commands send to an IOMMU |
| @@ -55,16 +59,16 @@ struct iommu_cmd { | |||
| 55 | static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, | 59 | static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, |
| 56 | struct unity_map_entry *e); | 60 | struct unity_map_entry *e); |
| 57 | static struct dma_ops_domain *find_protection_domain(u16 devid); | 61 | static struct dma_ops_domain *find_protection_domain(u16 devid); |
| 58 | static u64* alloc_pte(struct protection_domain *dom, | 62 | static u64 *alloc_pte(struct protection_domain *domain, |
| 59 | unsigned long address, u64 | 63 | unsigned long address, int end_lvl, |
| 60 | **pte_page, gfp_t gfp); | 64 | u64 **pte_page, gfp_t gfp); |
| 61 | static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, | 65 | static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, |
| 62 | unsigned long start_page, | 66 | unsigned long start_page, |
| 63 | unsigned int pages); | 67 | unsigned int pages); |
| 64 | 68 | static void reset_iommu_command_buffer(struct amd_iommu *iommu); | |
| 65 | #ifndef BUS_NOTIFY_UNBOUND_DRIVER | 69 | static u64 *fetch_pte(struct protection_domain *domain, |
| 66 | #define BUS_NOTIFY_UNBOUND_DRIVER 0x0005 | 70 | unsigned long address, int map_size); |
| 67 | #endif | 71 | static void update_domain(struct protection_domain *domain); |
| 68 | 72 | ||
| 69 | #ifdef CONFIG_AMD_IOMMU_STATS | 73 | #ifdef CONFIG_AMD_IOMMU_STATS |
| 70 | 74 | ||
| @@ -138,7 +142,25 @@ static int iommu_has_npcache(struct amd_iommu *iommu) | |||
| 138 | * | 142 | * |
| 139 | ****************************************************************************/ | 143 | ****************************************************************************/ |
| 140 | 144 | ||
| 141 | static void iommu_print_event(void *__evt) | 145 | static void dump_dte_entry(u16 devid) |
| 146 | { | ||
| 147 | int i; | ||
| 148 | |||
| 149 | for (i = 0; i < 8; ++i) | ||
| 150 | pr_err("AMD-Vi: DTE[%d]: %08x\n", i, | ||
| 151 | amd_iommu_dev_table[devid].data[i]); | ||
| 152 | } | ||
| 153 | |||
| 154 | static void dump_command(unsigned long phys_addr) | ||
| 155 | { | ||
| 156 | struct iommu_cmd *cmd = phys_to_virt(phys_addr); | ||
| 157 | int i; | ||
| 158 | |||
| 159 | for (i = 0; i < 4; ++i) | ||
| 160 | pr_err("AMD-Vi: CMD[%d]: %08x\n", i, cmd->data[i]); | ||
| 161 | } | ||
| 162 | |||
| 163 | static void iommu_print_event(struct amd_iommu *iommu, void *__evt) | ||
| 142 | { | 164 | { |
| 143 | u32 *event = __evt; | 165 | u32 *event = __evt; |
| 144 | int type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; | 166 | int type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; |
| @@ -147,7 +169,7 @@ static void iommu_print_event(void *__evt) | |||
| 147 | int flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK; | 169 | int flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK; |
| 148 | u64 address = (u64)(((u64)event[3]) << 32) | event[2]; | 170 | u64 address = (u64)(((u64)event[3]) << 32) | event[2]; |
| 149 | 171 | ||
| 150 | printk(KERN_ERR "AMD IOMMU: Event logged ["); | 172 | printk(KERN_ERR "AMD-Vi: Event logged ["); |
| 151 | 173 | ||
| 152 | switch (type) { | 174 | switch (type) { |
| 153 | case EVENT_TYPE_ILL_DEV: | 175 | case EVENT_TYPE_ILL_DEV: |
| @@ -155,6 +177,7 @@ static void iommu_print_event(void *__evt) | |||
| 155 | "address=0x%016llx flags=0x%04x]\n", | 177 | "address=0x%016llx flags=0x%04x]\n", |
| 156 | PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), | 178 | PCI_BUS(devid), PCI_SLOT(devid), PCI_FUNC(devid), |
| 157 | address, flags); | 179 | address, flags); |
| 180 | dump_dte_entry(devid); | ||
| 158 | break; | 181 | break; |
| 159 | case EVENT_TYPE_IO_FAULT: | 182 | case EVENT_TYPE_IO_FAULT: |
| 160 | printk("IO_PAGE_FAULT device=%02x:%02x.%x " | 183 | printk("IO_PAGE_FAULT device=%02x:%02x.%x " |
| @@ -176,6 +199,8 @@ static void iommu_print_event(void *__evt) | |||
| 176 | break; | 199 | break; |
| 177 | case EVENT_TYPE_ILL_CMD: | 200 | case EVENT_TYPE_ILL_CMD: |
| 178 | printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address); | 201 | printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address); |
| 202 | reset_iommu_command_buffer(iommu); | ||
| 203 | dump_command(address); | ||
| 179 | break; | 204 | break; |
| 180 | case EVENT_TYPE_CMD_HARD_ERR: | 205 | case EVENT_TYPE_CMD_HARD_ERR: |
| 181 | printk("COMMAND_HARDWARE_ERROR address=0x%016llx " | 206 | printk("COMMAND_HARDWARE_ERROR address=0x%016llx " |
| @@ -209,7 +234,7 @@ static void iommu_poll_events(struct amd_iommu *iommu) | |||
| 209 | tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET); | 234 | tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET); |
| 210 | 235 | ||
| 211 | while (head != tail) { | 236 | while (head != tail) { |
| 212 | iommu_print_event(iommu->evt_buf + head); | 237 | iommu_print_event(iommu, iommu->evt_buf + head); |
| 213 | head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size; | 238 | head = (head + EVENT_ENTRY_SIZE) % iommu->evt_buf_size; |
| 214 | } | 239 | } |
| 215 | 240 | ||
| @@ -296,8 +321,11 @@ static void __iommu_wait_for_completion(struct amd_iommu *iommu) | |||
| 296 | status &= ~MMIO_STATUS_COM_WAIT_INT_MASK; | 321 | status &= ~MMIO_STATUS_COM_WAIT_INT_MASK; |
| 297 | writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET); | 322 | writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET); |
| 298 | 323 | ||
| 299 | if (unlikely(i == EXIT_LOOP_COUNT)) | 324 | if (unlikely(i == EXIT_LOOP_COUNT)) { |
| 300 | panic("AMD IOMMU: Completion wait loop failed\n"); | 325 | spin_unlock(&iommu->lock); |
| 326 | reset_iommu_command_buffer(iommu); | ||
| 327 | spin_lock(&iommu->lock); | ||
| 328 | } | ||
| 301 | } | 329 | } |
| 302 | 330 | ||
| 303 | /* | 331 | /* |
| @@ -445,47 +473,78 @@ static void iommu_flush_tlb_pde(struct amd_iommu *iommu, u16 domid) | |||
| 445 | } | 473 | } |
| 446 | 474 | ||
| 447 | /* | 475 | /* |
| 476 | * This function flushes one domain on one IOMMU | ||
| 477 | */ | ||
| 478 | static void flush_domain_on_iommu(struct amd_iommu *iommu, u16 domid) | ||
| 479 | { | ||
| 480 | struct iommu_cmd cmd; | ||
| 481 | unsigned long flags; | ||
| 482 | |||
| 483 | __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, | ||
| 484 | domid, 1, 1); | ||
| 485 | |||
| 486 | spin_lock_irqsave(&iommu->lock, flags); | ||
| 487 | __iommu_queue_command(iommu, &cmd); | ||
| 488 | __iommu_completion_wait(iommu); | ||
| 489 | __iommu_wait_for_completion(iommu); | ||
| 490 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
| 491 | } | ||
| 492 | |||
| 493 | static void flush_all_domains_on_iommu(struct amd_iommu *iommu) | ||
| 494 | { | ||
| 495 | int i; | ||
| 496 | |||
| 497 | for (i = 1; i < MAX_DOMAIN_ID; ++i) { | ||
| 498 | if (!test_bit(i, amd_iommu_pd_alloc_bitmap)) | ||
| 499 | continue; | ||
| 500 | flush_domain_on_iommu(iommu, i); | ||
| 501 | } | ||
| 502 | |||
| 503 | } | ||
| 504 | |||
| 505 | /* | ||
| 448 | * This function is used to flush the IO/TLB for a given protection domain | 506 | * This function is used to flush the IO/TLB for a given protection domain |
| 449 | * on every IOMMU in the system | 507 | * on every IOMMU in the system |
| 450 | */ | 508 | */ |
| 451 | static void iommu_flush_domain(u16 domid) | 509 | static void iommu_flush_domain(u16 domid) |
| 452 | { | 510 | { |
| 453 | unsigned long flags; | ||
| 454 | struct amd_iommu *iommu; | 511 | struct amd_iommu *iommu; |
| 455 | struct iommu_cmd cmd; | ||
| 456 | 512 | ||
| 457 | INC_STATS_COUNTER(domain_flush_all); | 513 | INC_STATS_COUNTER(domain_flush_all); |
| 458 | 514 | ||
| 459 | __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, | 515 | for_each_iommu(iommu) |
| 460 | domid, 1, 1); | 516 | flush_domain_on_iommu(iommu, domid); |
| 461 | |||
| 462 | for_each_iommu(iommu) { | ||
| 463 | spin_lock_irqsave(&iommu->lock, flags); | ||
| 464 | __iommu_queue_command(iommu, &cmd); | ||
| 465 | __iommu_completion_wait(iommu); | ||
| 466 | __iommu_wait_for_completion(iommu); | ||
| 467 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
| 468 | } | ||
| 469 | } | 517 | } |
| 470 | 518 | ||
| 471 | void amd_iommu_flush_all_domains(void) | 519 | void amd_iommu_flush_all_domains(void) |
| 472 | { | 520 | { |
| 521 | struct amd_iommu *iommu; | ||
| 522 | |||
| 523 | for_each_iommu(iommu) | ||
| 524 | flush_all_domains_on_iommu(iommu); | ||
| 525 | } | ||
| 526 | |||
| 527 | static void flush_all_devices_for_iommu(struct amd_iommu *iommu) | ||
| 528 | { | ||
| 473 | int i; | 529 | int i; |
| 474 | 530 | ||
| 475 | for (i = 1; i < MAX_DOMAIN_ID; ++i) { | 531 | for (i = 0; i <= amd_iommu_last_bdf; ++i) { |
| 476 | if (!test_bit(i, amd_iommu_pd_alloc_bitmap)) | 532 | if (iommu != amd_iommu_rlookup_table[i]) |
| 477 | continue; | 533 | continue; |
| 478 | iommu_flush_domain(i); | 534 | |
| 535 | iommu_queue_inv_dev_entry(iommu, i); | ||
| 536 | iommu_completion_wait(iommu); | ||
| 479 | } | 537 | } |
| 480 | } | 538 | } |
| 481 | 539 | ||
| 482 | void amd_iommu_flush_all_devices(void) | 540 | static void flush_devices_by_domain(struct protection_domain *domain) |
| 483 | { | 541 | { |
| 484 | struct amd_iommu *iommu; | 542 | struct amd_iommu *iommu; |
| 485 | int i; | 543 | int i; |
| 486 | 544 | ||
| 487 | for (i = 0; i <= amd_iommu_last_bdf; ++i) { | 545 | for (i = 0; i <= amd_iommu_last_bdf; ++i) { |
| 488 | if (amd_iommu_pd_table[i] == NULL) | 546 | if ((domain == NULL && amd_iommu_pd_table[i] == NULL) || |
| 547 | (amd_iommu_pd_table[i] != domain)) | ||
| 489 | continue; | 548 | continue; |
| 490 | 549 | ||
| 491 | iommu = amd_iommu_rlookup_table[i]; | 550 | iommu = amd_iommu_rlookup_table[i]; |
| @@ -497,6 +556,27 @@ void amd_iommu_flush_all_devices(void) | |||
| 497 | } | 556 | } |
| 498 | } | 557 | } |
| 499 | 558 | ||
| 559 | static void reset_iommu_command_buffer(struct amd_iommu *iommu) | ||
| 560 | { | ||
| 561 | pr_err("AMD-Vi: Resetting IOMMU command buffer\n"); | ||
| 562 | |||
| 563 | if (iommu->reset_in_progress) | ||
| 564 | panic("AMD-Vi: ILLEGAL_COMMAND_ERROR while resetting command buffer\n"); | ||
| 565 | |||
| 566 | iommu->reset_in_progress = true; | ||
| 567 | |||
| 568 | amd_iommu_reset_cmd_buffer(iommu); | ||
| 569 | flush_all_devices_for_iommu(iommu); | ||
| 570 | flush_all_domains_on_iommu(iommu); | ||
| 571 | |||
| 572 | iommu->reset_in_progress = false; | ||
| 573 | } | ||
| 574 | |||
| 575 | void amd_iommu_flush_all_devices(void) | ||
| 576 | { | ||
| 577 | flush_devices_by_domain(NULL); | ||
| 578 | } | ||
| 579 | |||
| 500 | /**************************************************************************** | 580 | /**************************************************************************** |
| 501 | * | 581 | * |
| 502 | * The functions below are used the create the page table mappings for | 582 | * The functions below are used the create the page table mappings for |
| @@ -514,18 +594,21 @@ void amd_iommu_flush_all_devices(void) | |||
| 514 | static int iommu_map_page(struct protection_domain *dom, | 594 | static int iommu_map_page(struct protection_domain *dom, |
| 515 | unsigned long bus_addr, | 595 | unsigned long bus_addr, |
| 516 | unsigned long phys_addr, | 596 | unsigned long phys_addr, |
| 517 | int prot) | 597 | int prot, |
| 598 | int map_size) | ||
| 518 | { | 599 | { |
| 519 | u64 __pte, *pte; | 600 | u64 __pte, *pte; |
| 520 | 601 | ||
| 521 | bus_addr = PAGE_ALIGN(bus_addr); | 602 | bus_addr = PAGE_ALIGN(bus_addr); |
| 522 | phys_addr = PAGE_ALIGN(phys_addr); | 603 | phys_addr = PAGE_ALIGN(phys_addr); |
| 523 | 604 | ||
| 524 | /* only support 512GB address spaces for now */ | 605 | BUG_ON(!PM_ALIGNED(map_size, bus_addr)); |
| 525 | if (bus_addr > IOMMU_MAP_SIZE_L3 || !(prot & IOMMU_PROT_MASK)) | 606 | BUG_ON(!PM_ALIGNED(map_size, phys_addr)); |
| 607 | |||
| 608 | if (!(prot & IOMMU_PROT_MASK)) | ||
| 526 | return -EINVAL; | 609 | return -EINVAL; |
| 527 | 610 | ||
| 528 | pte = alloc_pte(dom, bus_addr, NULL, GFP_KERNEL); | 611 | pte = alloc_pte(dom, bus_addr, map_size, NULL, GFP_KERNEL); |
| 529 | 612 | ||
| 530 | if (IOMMU_PTE_PRESENT(*pte)) | 613 | if (IOMMU_PTE_PRESENT(*pte)) |
| 531 | return -EBUSY; | 614 | return -EBUSY; |
| @@ -538,29 +621,18 @@ static int iommu_map_page(struct protection_domain *dom, | |||
| 538 | 621 | ||
| 539 | *pte = __pte; | 622 | *pte = __pte; |
| 540 | 623 | ||
| 624 | update_domain(dom); | ||
| 625 | |||
| 541 | return 0; | 626 | return 0; |
| 542 | } | 627 | } |
| 543 | 628 | ||
| 544 | static void iommu_unmap_page(struct protection_domain *dom, | 629 | static void iommu_unmap_page(struct protection_domain *dom, |
| 545 | unsigned long bus_addr) | 630 | unsigned long bus_addr, int map_size) |
| 546 | { | 631 | { |
| 547 | u64 *pte; | 632 | u64 *pte = fetch_pte(dom, bus_addr, map_size); |
| 548 | |||
| 549 | pte = &dom->pt_root[IOMMU_PTE_L2_INDEX(bus_addr)]; | ||
| 550 | |||
| 551 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
| 552 | return; | ||
| 553 | |||
| 554 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 555 | pte = &pte[IOMMU_PTE_L1_INDEX(bus_addr)]; | ||
| 556 | 633 | ||
| 557 | if (!IOMMU_PTE_PRESENT(*pte)) | 634 | if (pte) |
| 558 | return; | 635 | *pte = 0; |
| 559 | |||
| 560 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 561 | pte = &pte[IOMMU_PTE_L1_INDEX(bus_addr)]; | ||
| 562 | |||
| 563 | *pte = 0; | ||
| 564 | } | 636 | } |
| 565 | 637 | ||
| 566 | /* | 638 | /* |
| @@ -615,7 +687,8 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, | |||
| 615 | 687 | ||
| 616 | for (addr = e->address_start; addr < e->address_end; | 688 | for (addr = e->address_start; addr < e->address_end; |
| 617 | addr += PAGE_SIZE) { | 689 | addr += PAGE_SIZE) { |
| 618 | ret = iommu_map_page(&dma_dom->domain, addr, addr, e->prot); | 690 | ret = iommu_map_page(&dma_dom->domain, addr, addr, e->prot, |
| 691 | PM_MAP_4k); | ||
| 619 | if (ret) | 692 | if (ret) |
| 620 | return ret; | 693 | return ret; |
| 621 | /* | 694 | /* |
| @@ -670,24 +743,29 @@ static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom, | |||
| 670 | * This function checks if there is a PTE for a given dma address. If | 743 | * This function checks if there is a PTE for a given dma address. If |
| 671 | * there is one, it returns the pointer to it. | 744 | * there is one, it returns the pointer to it. |
| 672 | */ | 745 | */ |
| 673 | static u64* fetch_pte(struct protection_domain *domain, | 746 | static u64 *fetch_pte(struct protection_domain *domain, |
| 674 | unsigned long address) | 747 | unsigned long address, int map_size) |
| 675 | { | 748 | { |
| 749 | int level; | ||
| 676 | u64 *pte; | 750 | u64 *pte; |
| 677 | 751 | ||
| 678 | pte = &domain->pt_root[IOMMU_PTE_L2_INDEX(address)]; | 752 | level = domain->mode - 1; |
| 753 | pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; | ||
| 679 | 754 | ||
| 680 | if (!IOMMU_PTE_PRESENT(*pte)) | 755 | while (level > map_size) { |
| 681 | return NULL; | 756 | if (!IOMMU_PTE_PRESENT(*pte)) |
| 757 | return NULL; | ||
| 682 | 758 | ||
| 683 | pte = IOMMU_PTE_PAGE(*pte); | 759 | level -= 1; |
| 684 | pte = &pte[IOMMU_PTE_L1_INDEX(address)]; | ||
| 685 | 760 | ||
| 686 | if (!IOMMU_PTE_PRESENT(*pte)) | 761 | pte = IOMMU_PTE_PAGE(*pte); |
| 687 | return NULL; | 762 | pte = &pte[PM_LEVEL_INDEX(level, address)]; |
| 688 | 763 | ||
| 689 | pte = IOMMU_PTE_PAGE(*pte); | 764 | if ((PM_PTE_LEVEL(*pte) == 0) && level != map_size) { |
| 690 | pte = &pte[IOMMU_PTE_L0_INDEX(address)]; | 765 | pte = NULL; |
| 766 | break; | ||
| 767 | } | ||
| 768 | } | ||
| 691 | 769 | ||
| 692 | return pte; | 770 | return pte; |
| 693 | } | 771 | } |
| @@ -727,7 +805,7 @@ static int alloc_new_range(struct amd_iommu *iommu, | |||
| 727 | u64 *pte, *pte_page; | 805 | u64 *pte, *pte_page; |
| 728 | 806 | ||
| 729 | for (i = 0; i < num_ptes; ++i) { | 807 | for (i = 0; i < num_ptes; ++i) { |
| 730 | pte = alloc_pte(&dma_dom->domain, address, | 808 | pte = alloc_pte(&dma_dom->domain, address, PM_MAP_4k, |
| 731 | &pte_page, gfp); | 809 | &pte_page, gfp); |
| 732 | if (!pte) | 810 | if (!pte) |
| 733 | goto out_free; | 811 | goto out_free; |
| @@ -760,16 +838,20 @@ static int alloc_new_range(struct amd_iommu *iommu, | |||
| 760 | for (i = dma_dom->aperture[index]->offset; | 838 | for (i = dma_dom->aperture[index]->offset; |
| 761 | i < dma_dom->aperture_size; | 839 | i < dma_dom->aperture_size; |
| 762 | i += PAGE_SIZE) { | 840 | i += PAGE_SIZE) { |
| 763 | u64 *pte = fetch_pte(&dma_dom->domain, i); | 841 | u64 *pte = fetch_pte(&dma_dom->domain, i, PM_MAP_4k); |
| 764 | if (!pte || !IOMMU_PTE_PRESENT(*pte)) | 842 | if (!pte || !IOMMU_PTE_PRESENT(*pte)) |
| 765 | continue; | 843 | continue; |
| 766 | 844 | ||
| 767 | dma_ops_reserve_addresses(dma_dom, i << PAGE_SHIFT, 1); | 845 | dma_ops_reserve_addresses(dma_dom, i << PAGE_SHIFT, 1); |
| 768 | } | 846 | } |
| 769 | 847 | ||
| 848 | update_domain(&dma_dom->domain); | ||
| 849 | |||
| 770 | return 0; | 850 | return 0; |
| 771 | 851 | ||
| 772 | out_free: | 852 | out_free: |
| 853 | update_domain(&dma_dom->domain); | ||
| 854 | |||
| 773 | free_page((unsigned long)dma_dom->aperture[index]->bitmap); | 855 | free_page((unsigned long)dma_dom->aperture[index]->bitmap); |
| 774 | 856 | ||
| 775 | kfree(dma_dom->aperture[index]); | 857 | kfree(dma_dom->aperture[index]); |
| @@ -1009,7 +1091,7 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu) | |||
| 1009 | dma_dom->domain.id = domain_id_alloc(); | 1091 | dma_dom->domain.id = domain_id_alloc(); |
| 1010 | if (dma_dom->domain.id == 0) | 1092 | if (dma_dom->domain.id == 0) |
| 1011 | goto free_dma_dom; | 1093 | goto free_dma_dom; |
| 1012 | dma_dom->domain.mode = PAGE_MODE_3_LEVEL; | 1094 | dma_dom->domain.mode = PAGE_MODE_2_LEVEL; |
| 1013 | dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL); | 1095 | dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL); |
| 1014 | dma_dom->domain.flags = PD_DMA_OPS_MASK; | 1096 | dma_dom->domain.flags = PD_DMA_OPS_MASK; |
| 1015 | dma_dom->domain.priv = dma_dom; | 1097 | dma_dom->domain.priv = dma_dom; |
| @@ -1063,6 +1145,41 @@ static struct protection_domain *domain_for_device(u16 devid) | |||
| 1063 | return dom; | 1145 | return dom; |
| 1064 | } | 1146 | } |
| 1065 | 1147 | ||
| 1148 | static void set_dte_entry(u16 devid, struct protection_domain *domain) | ||
| 1149 | { | ||
| 1150 | u64 pte_root = virt_to_phys(domain->pt_root); | ||
| 1151 | |||
| 1152 | pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) | ||
| 1153 | << DEV_ENTRY_MODE_SHIFT; | ||
| 1154 | pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV; | ||
| 1155 | |||
| 1156 | amd_iommu_dev_table[devid].data[2] = domain->id; | ||
| 1157 | amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root); | ||
| 1158 | amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root); | ||
| 1159 | |||
| 1160 | amd_iommu_pd_table[devid] = domain; | ||
| 1161 | } | ||
| 1162 | |||
| 1163 | /* | ||
| 1164 | * If a device is not yet associated with a domain, this function does | ||
| 1165 | * assigns it visible for the hardware | ||
| 1166 | */ | ||
| 1167 | static void __attach_device(struct amd_iommu *iommu, | ||
| 1168 | struct protection_domain *domain, | ||
| 1169 | u16 devid) | ||
| 1170 | { | ||
| 1171 | /* lock domain */ | ||
| 1172 | spin_lock(&domain->lock); | ||
| 1173 | |||
| 1174 | /* update DTE entry */ | ||
| 1175 | set_dte_entry(devid, domain); | ||
| 1176 | |||
| 1177 | domain->dev_cnt += 1; | ||
| 1178 | |||
| 1179 | /* ready */ | ||
| 1180 | spin_unlock(&domain->lock); | ||
| 1181 | } | ||
| 1182 | |||
| 1066 | /* | 1183 | /* |
| 1067 | * If a device is not yet associated with a domain, this function does | 1184 | * If a device is not yet associated with a domain, this function does |
| 1068 | * assigns it visible for the hardware | 1185 | * assigns it visible for the hardware |
| @@ -1072,27 +1189,16 @@ static void attach_device(struct amd_iommu *iommu, | |||
| 1072 | u16 devid) | 1189 | u16 devid) |
| 1073 | { | 1190 | { |
| 1074 | unsigned long flags; | 1191 | unsigned long flags; |
| 1075 | u64 pte_root = virt_to_phys(domain->pt_root); | ||
| 1076 | |||
| 1077 | domain->dev_cnt += 1; | ||
| 1078 | |||
| 1079 | pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK) | ||
| 1080 | << DEV_ENTRY_MODE_SHIFT; | ||
| 1081 | pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV; | ||
| 1082 | 1192 | ||
| 1083 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | 1193 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); |
| 1084 | amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root); | 1194 | __attach_device(iommu, domain, devid); |
| 1085 | amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root); | ||
| 1086 | amd_iommu_dev_table[devid].data[2] = domain->id; | ||
| 1087 | |||
| 1088 | amd_iommu_pd_table[devid] = domain; | ||
| 1089 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | 1195 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); |
| 1090 | 1196 | ||
| 1091 | /* | 1197 | /* |
| 1092 | * We might boot into a crash-kernel here. The crashed kernel | 1198 | * We might boot into a crash-kernel here. The crashed kernel |
| 1093 | * left the caches in the IOMMU dirty. So we have to flush | 1199 | * left the caches in the IOMMU dirty. So we have to flush |
| 1094 | * here to evict all dirty stuff. | 1200 | * here to evict all dirty stuff. |
| 1095 | */ | 1201 | */ |
| 1096 | iommu_queue_inv_dev_entry(iommu, devid); | 1202 | iommu_queue_inv_dev_entry(iommu, devid); |
| 1097 | iommu_flush_tlb_pde(iommu, domain->id); | 1203 | iommu_flush_tlb_pde(iommu, domain->id); |
| 1098 | } | 1204 | } |
| @@ -1119,6 +1225,15 @@ static void __detach_device(struct protection_domain *domain, u16 devid) | |||
| 1119 | 1225 | ||
| 1120 | /* ready */ | 1226 | /* ready */ |
| 1121 | spin_unlock(&domain->lock); | 1227 | spin_unlock(&domain->lock); |
| 1228 | |||
| 1229 | /* | ||
| 1230 | * If we run in passthrough mode the device must be assigned to the | ||
| 1231 | * passthrough domain if it is detached from any other domain | ||
| 1232 | */ | ||
| 1233 | if (iommu_pass_through) { | ||
| 1234 | struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; | ||
| 1235 | __attach_device(iommu, pt_domain, devid); | ||
| 1236 | } | ||
| 1122 | } | 1237 | } |
| 1123 | 1238 | ||
| 1124 | /* | 1239 | /* |
| @@ -1164,6 +1279,8 @@ static int device_change_notifier(struct notifier_block *nb, | |||
| 1164 | case BUS_NOTIFY_UNBOUND_DRIVER: | 1279 | case BUS_NOTIFY_UNBOUND_DRIVER: |
| 1165 | if (!domain) | 1280 | if (!domain) |
| 1166 | goto out; | 1281 | goto out; |
| 1282 | if (iommu_pass_through) | ||
| 1283 | break; | ||
| 1167 | detach_device(domain, devid); | 1284 | detach_device(domain, devid); |
| 1168 | break; | 1285 | break; |
| 1169 | case BUS_NOTIFY_ADD_DEVICE: | 1286 | case BUS_NOTIFY_ADD_DEVICE: |
| @@ -1292,39 +1409,91 @@ static int get_device_resources(struct device *dev, | |||
| 1292 | return 1; | 1409 | return 1; |
| 1293 | } | 1410 | } |
| 1294 | 1411 | ||
| 1412 | static void update_device_table(struct protection_domain *domain) | ||
| 1413 | { | ||
| 1414 | unsigned long flags; | ||
| 1415 | int i; | ||
| 1416 | |||
| 1417 | for (i = 0; i <= amd_iommu_last_bdf; ++i) { | ||
| 1418 | if (amd_iommu_pd_table[i] != domain) | ||
| 1419 | continue; | ||
| 1420 | write_lock_irqsave(&amd_iommu_devtable_lock, flags); | ||
| 1421 | set_dte_entry(i, domain); | ||
| 1422 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | ||
| 1423 | } | ||
| 1424 | } | ||
| 1425 | |||
| 1426 | static void update_domain(struct protection_domain *domain) | ||
| 1427 | { | ||
| 1428 | if (!domain->updated) | ||
| 1429 | return; | ||
| 1430 | |||
| 1431 | update_device_table(domain); | ||
| 1432 | flush_devices_by_domain(domain); | ||
| 1433 | iommu_flush_domain(domain->id); | ||
| 1434 | |||
| 1435 | domain->updated = false; | ||
| 1436 | } | ||
| 1437 | |||
| 1295 | /* | 1438 | /* |
| 1296 | * If the pte_page is not yet allocated this function is called | 1439 | * This function is used to add another level to an IO page table. Adding |
| 1440 | * another level increases the size of the address space by 9 bits to a size up | ||
| 1441 | * to 64 bits. | ||
| 1297 | */ | 1442 | */ |
| 1298 | static u64* alloc_pte(struct protection_domain *dom, | 1443 | static bool increase_address_space(struct protection_domain *domain, |
| 1299 | unsigned long address, u64 **pte_page, gfp_t gfp) | 1444 | gfp_t gfp) |
| 1445 | { | ||
| 1446 | u64 *pte; | ||
| 1447 | |||
| 1448 | if (domain->mode == PAGE_MODE_6_LEVEL) | ||
| 1449 | /* address space already 64 bit large */ | ||
| 1450 | return false; | ||
| 1451 | |||
| 1452 | pte = (void *)get_zeroed_page(gfp); | ||
| 1453 | if (!pte) | ||
| 1454 | return false; | ||
| 1455 | |||
| 1456 | *pte = PM_LEVEL_PDE(domain->mode, | ||
| 1457 | virt_to_phys(domain->pt_root)); | ||
| 1458 | domain->pt_root = pte; | ||
| 1459 | domain->mode += 1; | ||
| 1460 | domain->updated = true; | ||
| 1461 | |||
| 1462 | return true; | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | static u64 *alloc_pte(struct protection_domain *domain, | ||
| 1466 | unsigned long address, | ||
| 1467 | int end_lvl, | ||
| 1468 | u64 **pte_page, | ||
| 1469 | gfp_t gfp) | ||
| 1300 | { | 1470 | { |
| 1301 | u64 *pte, *page; | 1471 | u64 *pte, *page; |
| 1472 | int level; | ||
| 1302 | 1473 | ||
| 1303 | pte = &dom->pt_root[IOMMU_PTE_L2_INDEX(address)]; | 1474 | while (address > PM_LEVEL_SIZE(domain->mode)) |
| 1475 | increase_address_space(domain, gfp); | ||
| 1304 | 1476 | ||
| 1305 | if (!IOMMU_PTE_PRESENT(*pte)) { | 1477 | level = domain->mode - 1; |
| 1306 | page = (u64 *)get_zeroed_page(gfp); | 1478 | pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; |
| 1307 | if (!page) | ||
| 1308 | return NULL; | ||
| 1309 | *pte = IOMMU_L2_PDE(virt_to_phys(page)); | ||
| 1310 | } | ||
| 1311 | 1479 | ||
| 1312 | pte = IOMMU_PTE_PAGE(*pte); | 1480 | while (level > end_lvl) { |
| 1313 | pte = &pte[IOMMU_PTE_L1_INDEX(address)]; | 1481 | if (!IOMMU_PTE_PRESENT(*pte)) { |
| 1482 | page = (u64 *)get_zeroed_page(gfp); | ||
| 1483 | if (!page) | ||
| 1484 | return NULL; | ||
| 1485 | *pte = PM_LEVEL_PDE(level, virt_to_phys(page)); | ||
| 1486 | } | ||
| 1314 | 1487 | ||
| 1315 | if (!IOMMU_PTE_PRESENT(*pte)) { | 1488 | level -= 1; |
| 1316 | page = (u64 *)get_zeroed_page(gfp); | ||
| 1317 | if (!page) | ||
| 1318 | return NULL; | ||
| 1319 | *pte = IOMMU_L1_PDE(virt_to_phys(page)); | ||
| 1320 | } | ||
| 1321 | 1489 | ||
| 1322 | pte = IOMMU_PTE_PAGE(*pte); | 1490 | pte = IOMMU_PTE_PAGE(*pte); |
| 1323 | 1491 | ||
| 1324 | if (pte_page) | 1492 | if (pte_page && level == end_lvl) |
| 1325 | *pte_page = pte; | 1493 | *pte_page = pte; |
| 1326 | 1494 | ||
| 1327 | pte = &pte[IOMMU_PTE_L0_INDEX(address)]; | 1495 | pte = &pte[PM_LEVEL_INDEX(level, address)]; |
| 1496 | } | ||
| 1328 | 1497 | ||
| 1329 | return pte; | 1498 | return pte; |
| 1330 | } | 1499 | } |
| @@ -1344,10 +1513,13 @@ static u64* dma_ops_get_pte(struct dma_ops_domain *dom, | |||
| 1344 | 1513 | ||
| 1345 | pte = aperture->pte_pages[APERTURE_PAGE_INDEX(address)]; | 1514 | pte = aperture->pte_pages[APERTURE_PAGE_INDEX(address)]; |
| 1346 | if (!pte) { | 1515 | if (!pte) { |
| 1347 | pte = alloc_pte(&dom->domain, address, &pte_page, GFP_ATOMIC); | 1516 | pte = alloc_pte(&dom->domain, address, PM_MAP_4k, &pte_page, |
| 1517 | GFP_ATOMIC); | ||
| 1348 | aperture->pte_pages[APERTURE_PAGE_INDEX(address)] = pte_page; | 1518 | aperture->pte_pages[APERTURE_PAGE_INDEX(address)] = pte_page; |
| 1349 | } else | 1519 | } else |
| 1350 | pte += IOMMU_PTE_L0_INDEX(address); | 1520 | pte += PM_LEVEL_INDEX(0, address); |
| 1521 | |||
| 1522 | update_domain(&dom->domain); | ||
| 1351 | 1523 | ||
| 1352 | return pte; | 1524 | return pte; |
| 1353 | } | 1525 | } |
| @@ -1409,7 +1581,7 @@ static void dma_ops_domain_unmap(struct amd_iommu *iommu, | |||
| 1409 | if (!pte) | 1581 | if (!pte) |
| 1410 | return; | 1582 | return; |
| 1411 | 1583 | ||
| 1412 | pte += IOMMU_PTE_L0_INDEX(address); | 1584 | pte += PM_LEVEL_INDEX(0, address); |
| 1413 | 1585 | ||
| 1414 | WARN_ON(!*pte); | 1586 | WARN_ON(!*pte); |
| 1415 | 1587 | ||
| @@ -1988,19 +2160,47 @@ static void cleanup_domain(struct protection_domain *domain) | |||
| 1988 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); | 2160 | write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); |
| 1989 | } | 2161 | } |
| 1990 | 2162 | ||
| 1991 | static int amd_iommu_domain_init(struct iommu_domain *dom) | 2163 | static void protection_domain_free(struct protection_domain *domain) |
| 2164 | { | ||
| 2165 | if (!domain) | ||
| 2166 | return; | ||
| 2167 | |||
| 2168 | if (domain->id) | ||
| 2169 | domain_id_free(domain->id); | ||
| 2170 | |||
| 2171 | kfree(domain); | ||
| 2172 | } | ||
| 2173 | |||
| 2174 | static struct protection_domain *protection_domain_alloc(void) | ||
| 1992 | { | 2175 | { |
| 1993 | struct protection_domain *domain; | 2176 | struct protection_domain *domain; |
| 1994 | 2177 | ||
| 1995 | domain = kzalloc(sizeof(*domain), GFP_KERNEL); | 2178 | domain = kzalloc(sizeof(*domain), GFP_KERNEL); |
| 1996 | if (!domain) | 2179 | if (!domain) |
| 1997 | return -ENOMEM; | 2180 | return NULL; |
| 1998 | 2181 | ||
| 1999 | spin_lock_init(&domain->lock); | 2182 | spin_lock_init(&domain->lock); |
| 2000 | domain->mode = PAGE_MODE_3_LEVEL; | ||
| 2001 | domain->id = domain_id_alloc(); | 2183 | domain->id = domain_id_alloc(); |
| 2002 | if (!domain->id) | 2184 | if (!domain->id) |
| 2185 | goto out_err; | ||
| 2186 | |||
| 2187 | return domain; | ||
| 2188 | |||
| 2189 | out_err: | ||
| 2190 | kfree(domain); | ||
| 2191 | |||
| 2192 | return NULL; | ||
| 2193 | } | ||
| 2194 | |||
| 2195 | static int amd_iommu_domain_init(struct iommu_domain *dom) | ||
| 2196 | { | ||
| 2197 | struct protection_domain *domain; | ||
| 2198 | |||
| 2199 | domain = protection_domain_alloc(); | ||
| 2200 | if (!domain) | ||
| 2003 | goto out_free; | 2201 | goto out_free; |
| 2202 | |||
| 2203 | domain->mode = PAGE_MODE_3_LEVEL; | ||
| 2004 | domain->pt_root = (void *)get_zeroed_page(GFP_KERNEL); | 2204 | domain->pt_root = (void *)get_zeroed_page(GFP_KERNEL); |
| 2005 | if (!domain->pt_root) | 2205 | if (!domain->pt_root) |
| 2006 | goto out_free; | 2206 | goto out_free; |
| @@ -2010,7 +2210,7 @@ static int amd_iommu_domain_init(struct iommu_domain *dom) | |||
| 2010 | return 0; | 2210 | return 0; |
| 2011 | 2211 | ||
| 2012 | out_free: | 2212 | out_free: |
| 2013 | kfree(domain); | 2213 | protection_domain_free(domain); |
| 2014 | 2214 | ||
| 2015 | return -ENOMEM; | 2215 | return -ENOMEM; |
| 2016 | } | 2216 | } |
| @@ -2115,7 +2315,7 @@ static int amd_iommu_map_range(struct iommu_domain *dom, | |||
| 2115 | paddr &= PAGE_MASK; | 2315 | paddr &= PAGE_MASK; |
| 2116 | 2316 | ||
| 2117 | for (i = 0; i < npages; ++i) { | 2317 | for (i = 0; i < npages; ++i) { |
| 2118 | ret = iommu_map_page(domain, iova, paddr, prot); | 2318 | ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k); |
| 2119 | if (ret) | 2319 | if (ret) |
| 2120 | return ret; | 2320 | return ret; |
| 2121 | 2321 | ||
| @@ -2136,7 +2336,7 @@ static void amd_iommu_unmap_range(struct iommu_domain *dom, | |||
| 2136 | iova &= PAGE_MASK; | 2336 | iova &= PAGE_MASK; |
| 2137 | 2337 | ||
| 2138 | for (i = 0; i < npages; ++i) { | 2338 | for (i = 0; i < npages; ++i) { |
| 2139 | iommu_unmap_page(domain, iova); | 2339 | iommu_unmap_page(domain, iova, PM_MAP_4k); |
| 2140 | iova += PAGE_SIZE; | 2340 | iova += PAGE_SIZE; |
| 2141 | } | 2341 | } |
| 2142 | 2342 | ||
| @@ -2151,21 +2351,9 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, | |||
| 2151 | phys_addr_t paddr; | 2351 | phys_addr_t paddr; |
| 2152 | u64 *pte; | 2352 | u64 *pte; |
| 2153 | 2353 | ||
| 2154 | pte = &domain->pt_root[IOMMU_PTE_L2_INDEX(iova)]; | 2354 | pte = fetch_pte(domain, iova, PM_MAP_4k); |
| 2155 | |||
| 2156 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
| 2157 | return 0; | ||
| 2158 | |||
| 2159 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 2160 | pte = &pte[IOMMU_PTE_L1_INDEX(iova)]; | ||
| 2161 | |||
| 2162 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
| 2163 | return 0; | ||
| 2164 | |||
| 2165 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 2166 | pte = &pte[IOMMU_PTE_L0_INDEX(iova)]; | ||
| 2167 | 2355 | ||
| 2168 | if (!IOMMU_PTE_PRESENT(*pte)) | 2356 | if (!pte || !IOMMU_PTE_PRESENT(*pte)) |
| 2169 | return 0; | 2357 | return 0; |
| 2170 | 2358 | ||
| 2171 | paddr = *pte & IOMMU_PAGE_MASK; | 2359 | paddr = *pte & IOMMU_PAGE_MASK; |
| @@ -2191,3 +2379,46 @@ static struct iommu_ops amd_iommu_ops = { | |||
| 2191 | .domain_has_cap = amd_iommu_domain_has_cap, | 2379 | .domain_has_cap = amd_iommu_domain_has_cap, |
| 2192 | }; | 2380 | }; |
| 2193 | 2381 | ||
| 2382 | /***************************************************************************** | ||
| 2383 | * | ||
| 2384 | * The next functions do a basic initialization of IOMMU for pass through | ||
| 2385 | * mode | ||
| 2386 | * | ||
| 2387 | * In passthrough mode the IOMMU is initialized and enabled but not used for | ||
| 2388 | * DMA-API translation. | ||
| 2389 | * | ||
| 2390 | *****************************************************************************/ | ||
| 2391 | |||
| 2392 | int __init amd_iommu_init_passthrough(void) | ||
| 2393 | { | ||
| 2394 | struct pci_dev *dev = NULL; | ||
| 2395 | u16 devid, devid2; | ||
| 2396 | |||
| 2397 | /* allocate passthroug domain */ | ||
| 2398 | pt_domain = protection_domain_alloc(); | ||
| 2399 | if (!pt_domain) | ||
| 2400 | return -ENOMEM; | ||
| 2401 | |||
| 2402 | pt_domain->mode |= PAGE_MODE_NONE; | ||
| 2403 | |||
| 2404 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | ||
| 2405 | struct amd_iommu *iommu; | ||
| 2406 | |||
| 2407 | devid = calc_devid(dev->bus->number, dev->devfn); | ||
| 2408 | if (devid > amd_iommu_last_bdf) | ||
| 2409 | continue; | ||
| 2410 | |||
| 2411 | devid2 = amd_iommu_alias_table[devid]; | ||
| 2412 | |||
| 2413 | iommu = amd_iommu_rlookup_table[devid2]; | ||
| 2414 | if (!iommu) | ||
| 2415 | continue; | ||
| 2416 | |||
| 2417 | __attach_device(iommu, pt_domain, devid); | ||
| 2418 | __attach_device(iommu, pt_domain, devid2); | ||
| 2419 | } | ||
| 2420 | |||
| 2421 | pr_info("AMD-Vi: Initialized for Passthrough Mode\n"); | ||
| 2422 | |||
| 2423 | return 0; | ||
| 2424 | } | ||
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index c1b17e97252e..b4b61d462dcc 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
| @@ -252,7 +252,7 @@ static void __init iommu_feature_disable(struct amd_iommu *iommu, u8 bit) | |||
| 252 | /* Function to enable the hardware */ | 252 | /* Function to enable the hardware */ |
| 253 | static void iommu_enable(struct amd_iommu *iommu) | 253 | static void iommu_enable(struct amd_iommu *iommu) |
| 254 | { | 254 | { |
| 255 | printk(KERN_INFO "AMD IOMMU: Enabling IOMMU at %s cap 0x%hx\n", | 255 | printk(KERN_INFO "AMD-Vi: Enabling IOMMU at %s cap 0x%hx\n", |
| 256 | dev_name(&iommu->dev->dev), iommu->cap_ptr); | 256 | dev_name(&iommu->dev->dev), iommu->cap_ptr); |
| 257 | 257 | ||
| 258 | iommu_feature_enable(iommu, CONTROL_IOMMU_EN); | 258 | iommu_feature_enable(iommu, CONTROL_IOMMU_EN); |
| @@ -435,6 +435,20 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu) | |||
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | /* | 437 | /* |
| 438 | * This function resets the command buffer if the IOMMU stopped fetching | ||
| 439 | * commands from it. | ||
| 440 | */ | ||
| 441 | void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu) | ||
| 442 | { | ||
| 443 | iommu_feature_disable(iommu, CONTROL_CMDBUF_EN); | ||
| 444 | |||
| 445 | writel(0x00, iommu->mmio_base + MMIO_CMD_HEAD_OFFSET); | ||
| 446 | writel(0x00, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); | ||
| 447 | |||
| 448 | iommu_feature_enable(iommu, CONTROL_CMDBUF_EN); | ||
| 449 | } | ||
| 450 | |||
| 451 | /* | ||
| 438 | * This function writes the command buffer address to the hardware and | 452 | * This function writes the command buffer address to the hardware and |
| 439 | * enables it. | 453 | * enables it. |
| 440 | */ | 454 | */ |
| @@ -450,11 +464,7 @@ static void iommu_enable_command_buffer(struct amd_iommu *iommu) | |||
| 450 | memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET, | 464 | memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET, |
| 451 | &entry, sizeof(entry)); | 465 | &entry, sizeof(entry)); |
| 452 | 466 | ||
| 453 | /* set head and tail to zero manually */ | 467 | amd_iommu_reset_cmd_buffer(iommu); |
| 454 | writel(0x00, iommu->mmio_base + MMIO_CMD_HEAD_OFFSET); | ||
| 455 | writel(0x00, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); | ||
| 456 | |||
| 457 | iommu_feature_enable(iommu, CONTROL_CMDBUF_EN); | ||
| 458 | } | 468 | } |
| 459 | 469 | ||
| 460 | static void __init free_command_buffer(struct amd_iommu *iommu) | 470 | static void __init free_command_buffer(struct amd_iommu *iommu) |
| @@ -858,7 +868,7 @@ static int __init init_iommu_all(struct acpi_table_header *table) | |||
| 858 | switch (*p) { | 868 | switch (*p) { |
| 859 | case ACPI_IVHD_TYPE: | 869 | case ACPI_IVHD_TYPE: |
| 860 | 870 | ||
| 861 | DUMP_printk("IOMMU: device: %02x:%02x.%01x cap: %04x " | 871 | DUMP_printk("device: %02x:%02x.%01x cap: %04x " |
| 862 | "seg: %d flags: %01x info %04x\n", | 872 | "seg: %d flags: %01x info %04x\n", |
| 863 | PCI_BUS(h->devid), PCI_SLOT(h->devid), | 873 | PCI_BUS(h->devid), PCI_SLOT(h->devid), |
| 864 | PCI_FUNC(h->devid), h->cap_ptr, | 874 | PCI_FUNC(h->devid), h->cap_ptr, |
| @@ -902,7 +912,7 @@ static int __init iommu_setup_msi(struct amd_iommu *iommu) | |||
| 902 | 912 | ||
| 903 | r = request_irq(iommu->dev->irq, amd_iommu_int_handler, | 913 | r = request_irq(iommu->dev->irq, amd_iommu_int_handler, |
| 904 | IRQF_SAMPLE_RANDOM, | 914 | IRQF_SAMPLE_RANDOM, |
| 905 | "AMD IOMMU", | 915 | "AMD-Vi", |
| 906 | NULL); | 916 | NULL); |
| 907 | 917 | ||
| 908 | if (r) { | 918 | if (r) { |
| @@ -1150,7 +1160,7 @@ int __init amd_iommu_init(void) | |||
| 1150 | 1160 | ||
| 1151 | 1161 | ||
| 1152 | if (no_iommu) { | 1162 | if (no_iommu) { |
| 1153 | printk(KERN_INFO "AMD IOMMU disabled by kernel command line\n"); | 1163 | printk(KERN_INFO "AMD-Vi disabled by kernel command line\n"); |
| 1154 | return 0; | 1164 | return 0; |
| 1155 | } | 1165 | } |
| 1156 | 1166 | ||
| @@ -1242,22 +1252,28 @@ int __init amd_iommu_init(void) | |||
| 1242 | if (ret) | 1252 | if (ret) |
| 1243 | goto free; | 1253 | goto free; |
| 1244 | 1254 | ||
| 1245 | ret = amd_iommu_init_dma_ops(); | 1255 | if (iommu_pass_through) |
| 1256 | ret = amd_iommu_init_passthrough(); | ||
| 1257 | else | ||
| 1258 | ret = amd_iommu_init_dma_ops(); | ||
| 1246 | if (ret) | 1259 | if (ret) |
| 1247 | goto free; | 1260 | goto free; |
| 1248 | 1261 | ||
| 1249 | enable_iommus(); | 1262 | enable_iommus(); |
| 1250 | 1263 | ||
| 1251 | printk(KERN_INFO "AMD IOMMU: device isolation "); | 1264 | if (iommu_pass_through) |
| 1265 | goto out; | ||
| 1266 | |||
| 1267 | printk(KERN_INFO "AMD-Vi: device isolation "); | ||
| 1252 | if (amd_iommu_isolate) | 1268 | if (amd_iommu_isolate) |
| 1253 | printk("enabled\n"); | 1269 | printk("enabled\n"); |
| 1254 | else | 1270 | else |
| 1255 | printk("disabled\n"); | 1271 | printk("disabled\n"); |
| 1256 | 1272 | ||
| 1257 | if (amd_iommu_unmap_flush) | 1273 | if (amd_iommu_unmap_flush) |
| 1258 | printk(KERN_INFO "AMD IOMMU: IO/TLB flush on unmap enabled\n"); | 1274 | printk(KERN_INFO "AMD-Vi: IO/TLB flush on unmap enabled\n"); |
| 1259 | else | 1275 | else |
| 1260 | printk(KERN_INFO "AMD IOMMU: Lazy IO/TLB flushing enabled\n"); | 1276 | printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n"); |
| 1261 | 1277 | ||
| 1262 | out: | 1278 | out: |
| 1263 | return ret; | 1279 | return ret; |
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index 676debfc1702..128111d8ffe0 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
| 21 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
| 22 | #include <linux/suspend.h> | 22 | #include <linux/suspend.h> |
| 23 | #include <linux/kmemleak.h> | ||
| 23 | #include <asm/e820.h> | 24 | #include <asm/e820.h> |
| 24 | #include <asm/io.h> | 25 | #include <asm/io.h> |
| 25 | #include <asm/iommu.h> | 26 | #include <asm/iommu.h> |
| @@ -94,6 +95,11 @@ static u32 __init allocate_aperture(void) | |||
| 94 | * code for safe | 95 | * code for safe |
| 95 | */ | 96 | */ |
| 96 | p = __alloc_bootmem_nopanic(aper_size, aper_size, 512ULL<<20); | 97 | p = __alloc_bootmem_nopanic(aper_size, aper_size, 512ULL<<20); |
| 98 | /* | ||
| 99 | * Kmemleak should not scan this block as it may not be mapped via the | ||
| 100 | * kernel direct mapping. | ||
| 101 | */ | ||
| 102 | kmemleak_ignore(p); | ||
| 97 | if (!p || __pa(p)+aper_size > 0xffffffff) { | 103 | if (!p || __pa(p)+aper_size > 0xffffffff) { |
| 98 | printk(KERN_ERR | 104 | printk(KERN_ERR |
| 99 | "Cannot allocate aperture memory hole (%p,%uK)\n", | 105 | "Cannot allocate aperture memory hole (%p,%uK)\n", |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 0a1c2830ec66..159740decc41 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | #include <asm/mtrr.h> | 49 | #include <asm/mtrr.h> |
| 50 | #include <asm/smp.h> | 50 | #include <asm/smp.h> |
| 51 | #include <asm/mce.h> | 51 | #include <asm/mce.h> |
| 52 | #include <asm/kvm_para.h> | ||
| 52 | 53 | ||
| 53 | unsigned int num_processors; | 54 | unsigned int num_processors; |
| 54 | 55 | ||
| @@ -1361,52 +1362,80 @@ void enable_x2apic(void) | |||
| 1361 | } | 1362 | } |
| 1362 | #endif /* CONFIG_X86_X2APIC */ | 1363 | #endif /* CONFIG_X86_X2APIC */ |
| 1363 | 1364 | ||
| 1364 | void __init enable_IR_x2apic(void) | 1365 | int __init enable_IR(void) |
| 1365 | { | 1366 | { |
| 1366 | #ifdef CONFIG_INTR_REMAP | 1367 | #ifdef CONFIG_INTR_REMAP |
| 1367 | int ret; | ||
| 1368 | unsigned long flags; | ||
| 1369 | struct IO_APIC_route_entry **ioapic_entries = NULL; | ||
| 1370 | |||
| 1371 | ret = dmar_table_init(); | ||
| 1372 | if (ret) { | ||
| 1373 | pr_debug("dmar_table_init() failed with %d:\n", ret); | ||
| 1374 | goto ir_failed; | ||
| 1375 | } | ||
| 1376 | |||
| 1377 | if (!intr_remapping_supported()) { | 1368 | if (!intr_remapping_supported()) { |
| 1378 | pr_debug("intr-remapping not supported\n"); | 1369 | pr_debug("intr-remapping not supported\n"); |
| 1379 | goto ir_failed; | 1370 | return 0; |
| 1380 | } | 1371 | } |
| 1381 | 1372 | ||
| 1382 | |||
| 1383 | if (!x2apic_preenabled && skip_ioapic_setup) { | 1373 | if (!x2apic_preenabled && skip_ioapic_setup) { |
| 1384 | pr_info("Skipped enabling intr-remap because of skipping " | 1374 | pr_info("Skipped enabling intr-remap because of skipping " |
| 1385 | "io-apic setup\n"); | 1375 | "io-apic setup\n"); |
| 1386 | return; | 1376 | return 0; |
| 1387 | } | 1377 | } |
| 1388 | 1378 | ||
| 1379 | if (enable_intr_remapping(x2apic_supported())) | ||
| 1380 | return 0; | ||
| 1381 | |||
| 1382 | pr_info("Enabled Interrupt-remapping\n"); | ||
| 1383 | |||
| 1384 | return 1; | ||
| 1385 | |||
| 1386 | #endif | ||
| 1387 | return 0; | ||
| 1388 | } | ||
| 1389 | |||
| 1390 | void __init enable_IR_x2apic(void) | ||
| 1391 | { | ||
| 1392 | unsigned long flags; | ||
| 1393 | struct IO_APIC_route_entry **ioapic_entries = NULL; | ||
| 1394 | int ret, x2apic_enabled = 0; | ||
| 1395 | int dmar_table_init_ret = 0; | ||
| 1396 | |||
| 1397 | #ifdef CONFIG_INTR_REMAP | ||
| 1398 | dmar_table_init_ret = dmar_table_init(); | ||
| 1399 | if (dmar_table_init_ret) | ||
| 1400 | pr_debug("dmar_table_init() failed with %d:\n", | ||
| 1401 | dmar_table_init_ret); | ||
| 1402 | #endif | ||
| 1403 | |||
| 1389 | ioapic_entries = alloc_ioapic_entries(); | 1404 | ioapic_entries = alloc_ioapic_entries(); |
| 1390 | if (!ioapic_entries) { | 1405 | if (!ioapic_entries) { |
| 1391 | pr_info("Allocate ioapic_entries failed: %d\n", ret); | 1406 | pr_err("Allocate ioapic_entries failed\n"); |
| 1392 | goto end; | 1407 | goto out; |
| 1393 | } | 1408 | } |
| 1394 | 1409 | ||
| 1395 | ret = save_IO_APIC_setup(ioapic_entries); | 1410 | ret = save_IO_APIC_setup(ioapic_entries); |
| 1396 | if (ret) { | 1411 | if (ret) { |
| 1397 | pr_info("Saving IO-APIC state failed: %d\n", ret); | 1412 | pr_info("Saving IO-APIC state failed: %d\n", ret); |
| 1398 | goto end; | 1413 | goto out; |
| 1399 | } | 1414 | } |
| 1400 | 1415 | ||
| 1401 | local_irq_save(flags); | 1416 | local_irq_save(flags); |
| 1402 | mask_IO_APIC_setup(ioapic_entries); | ||
| 1403 | mask_8259A(); | 1417 | mask_8259A(); |
| 1418 | mask_IO_APIC_setup(ioapic_entries); | ||
| 1404 | 1419 | ||
| 1405 | ret = enable_intr_remapping(x2apic_supported()); | 1420 | if (dmar_table_init_ret) |
| 1406 | if (ret) | 1421 | ret = 0; |
| 1407 | goto end_restore; | 1422 | else |
| 1423 | ret = enable_IR(); | ||
| 1408 | 1424 | ||
| 1409 | pr_info("Enabled Interrupt-remapping\n"); | 1425 | if (!ret) { |
| 1426 | /* IR is required if there is APIC ID > 255 even when running | ||
| 1427 | * under KVM | ||
| 1428 | */ | ||
| 1429 | if (max_physical_apicid > 255 || !kvm_para_available()) | ||
| 1430 | goto nox2apic; | ||
| 1431 | /* | ||
| 1432 | * without IR all CPUs can be addressed by IOAPIC/MSI | ||
| 1433 | * only in physical mode | ||
| 1434 | */ | ||
| 1435 | x2apic_force_phys(); | ||
| 1436 | } | ||
| 1437 | |||
| 1438 | x2apic_enabled = 1; | ||
| 1410 | 1439 | ||
| 1411 | if (x2apic_supported() && !x2apic_mode) { | 1440 | if (x2apic_supported() && !x2apic_mode) { |
| 1412 | x2apic_mode = 1; | 1441 | x2apic_mode = 1; |
| @@ -1414,41 +1443,25 @@ void __init enable_IR_x2apic(void) | |||
| 1414 | pr_info("Enabled x2apic\n"); | 1443 | pr_info("Enabled x2apic\n"); |
| 1415 | } | 1444 | } |
| 1416 | 1445 | ||
| 1417 | end_restore: | 1446 | nox2apic: |
| 1418 | if (ret) | 1447 | if (!ret) /* IR enabling failed */ |
| 1419 | /* | ||
| 1420 | * IR enabling failed | ||
| 1421 | */ | ||
| 1422 | restore_IO_APIC_setup(ioapic_entries); | 1448 | restore_IO_APIC_setup(ioapic_entries); |
| 1423 | |||
| 1424 | unmask_8259A(); | 1449 | unmask_8259A(); |
| 1425 | local_irq_restore(flags); | 1450 | local_irq_restore(flags); |
| 1426 | 1451 | ||
| 1427 | end: | 1452 | out: |
| 1428 | if (ioapic_entries) | 1453 | if (ioapic_entries) |
| 1429 | free_ioapic_entries(ioapic_entries); | 1454 | free_ioapic_entries(ioapic_entries); |
| 1430 | 1455 | ||
| 1431 | if (!ret) | 1456 | if (x2apic_enabled) |
| 1432 | return; | 1457 | return; |
| 1433 | 1458 | ||
| 1434 | ir_failed: | ||
| 1435 | if (x2apic_preenabled) | 1459 | if (x2apic_preenabled) |
| 1436 | panic("x2apic enabled by bios. But IR enabling failed"); | 1460 | panic("x2apic: enabled by BIOS but kernel init failed."); |
| 1437 | else if (cpu_has_x2apic) | 1461 | else if (cpu_has_x2apic) |
| 1438 | pr_info("Not enabling x2apic,Intr-remapping\n"); | 1462 | pr_info("Not enabling x2apic, Intr-remapping init failed.\n"); |
| 1439 | #else | ||
| 1440 | if (!cpu_has_x2apic) | ||
| 1441 | return; | ||
| 1442 | |||
| 1443 | if (x2apic_preenabled) | ||
| 1444 | panic("x2apic enabled prior OS handover," | ||
| 1445 | " enable CONFIG_X86_X2APIC, CONFIG_INTR_REMAP"); | ||
| 1446 | #endif | ||
| 1447 | |||
| 1448 | return; | ||
| 1449 | } | 1463 | } |
| 1450 | 1464 | ||
| 1451 | |||
| 1452 | #ifdef CONFIG_X86_64 | 1465 | #ifdef CONFIG_X86_64 |
| 1453 | /* | 1466 | /* |
| 1454 | * Detect and enable local APICs on non-SMP boards. | 1467 | * Detect and enable local APICs on non-SMP boards. |
| @@ -1549,8 +1562,6 @@ no_apic: | |||
| 1549 | #ifdef CONFIG_X86_64 | 1562 | #ifdef CONFIG_X86_64 |
| 1550 | void __init early_init_lapic_mapping(void) | 1563 | void __init early_init_lapic_mapping(void) |
| 1551 | { | 1564 | { |
| 1552 | unsigned long phys_addr; | ||
| 1553 | |||
| 1554 | /* | 1565 | /* |
| 1555 | * If no local APIC can be found then go out | 1566 | * If no local APIC can be found then go out |
| 1556 | * : it means there is no mpatable and MADT | 1567 | * : it means there is no mpatable and MADT |
| @@ -1558,11 +1569,9 @@ void __init early_init_lapic_mapping(void) | |||
| 1558 | if (!smp_found_config) | 1569 | if (!smp_found_config) |
| 1559 | return; | 1570 | return; |
| 1560 | 1571 | ||
| 1561 | phys_addr = mp_lapic_addr; | 1572 | set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr); |
| 1562 | |||
| 1563 | set_fixmap_nocache(FIX_APIC_BASE, phys_addr); | ||
| 1564 | apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", | 1573 | apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n", |
| 1565 | APIC_BASE, phys_addr); | 1574 | APIC_BASE, mp_lapic_addr); |
| 1566 | 1575 | ||
| 1567 | /* | 1576 | /* |
| 1568 | * Fetch the APIC ID of the BSP in case we have a | 1577 | * Fetch the APIC ID of the BSP in case we have a |
| @@ -1651,7 +1660,6 @@ int __init APIC_init_uniprocessor(void) | |||
| 1651 | APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { | 1660 | APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { |
| 1652 | pr_err("BIOS bug, local APIC 0x%x not detected!...\n", | 1661 | pr_err("BIOS bug, local APIC 0x%x not detected!...\n", |
| 1653 | boot_cpu_physical_apicid); | 1662 | boot_cpu_physical_apicid); |
| 1654 | clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); | ||
| 1655 | return -1; | 1663 | return -1; |
| 1656 | } | 1664 | } |
| 1657 | #endif | 1665 | #endif |
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 8952a5890281..89174f847b49 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
| @@ -167,7 +167,7 @@ static int es7000_apic_is_cluster(void) | |||
| 167 | { | 167 | { |
| 168 | /* MPENTIUMIII */ | 168 | /* MPENTIUMIII */ |
| 169 | if (boot_cpu_data.x86 == 6 && | 169 | if (boot_cpu_data.x86 == 6 && |
| 170 | (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) | 170 | (boot_cpu_data.x86_model >= 7 && boot_cpu_data.x86_model <= 11)) |
| 171 | return 1; | 171 | return 1; |
| 172 | 172 | ||
| 173 | return 0; | 173 | return 0; |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index d2ed6c5ddc80..3c8f9e75d038 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -66,6 +66,8 @@ | |||
| 66 | #include <asm/apic.h> | 66 | #include <asm/apic.h> |
| 67 | 67 | ||
| 68 | #define __apicdebuginit(type) static type __init | 68 | #define __apicdebuginit(type) static type __init |
| 69 | #define for_each_irq_pin(entry, head) \ | ||
| 70 | for (entry = head; entry; entry = entry->next) | ||
| 69 | 71 | ||
| 70 | /* | 72 | /* |
| 71 | * Is the SiS APIC rmw bug present ? | 73 | * Is the SiS APIC rmw bug present ? |
| @@ -85,6 +87,9 @@ int nr_ioapic_registers[MAX_IO_APICS]; | |||
| 85 | struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; | 87 | struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; |
| 86 | int nr_ioapics; | 88 | int nr_ioapics; |
| 87 | 89 | ||
| 90 | /* IO APIC gsi routing info */ | ||
| 91 | struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS]; | ||
| 92 | |||
| 88 | /* MP IRQ source entries */ | 93 | /* MP IRQ source entries */ |
| 89 | struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; | 94 | struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; |
| 90 | 95 | ||
| @@ -116,15 +121,6 @@ static int __init parse_noapic(char *str) | |||
| 116 | } | 121 | } |
| 117 | early_param("noapic", parse_noapic); | 122 | early_param("noapic", parse_noapic); |
| 118 | 123 | ||
| 119 | struct irq_pin_list; | ||
| 120 | |||
| 121 | /* | ||
| 122 | * This is performance-critical, we want to do it O(1) | ||
| 123 | * | ||
| 124 | * the indexing order of this array favors 1:1 mappings | ||
| 125 | * between pins and IRQs. | ||
| 126 | */ | ||
| 127 | |||
| 128 | struct irq_pin_list { | 124 | struct irq_pin_list { |
| 129 | int apic, pin; | 125 | int apic, pin; |
| 130 | struct irq_pin_list *next; | 126 | struct irq_pin_list *next; |
| @@ -139,6 +135,11 @@ static struct irq_pin_list *get_one_free_irq_2_pin(int node) | |||
| 139 | return pin; | 135 | return pin; |
| 140 | } | 136 | } |
| 141 | 137 | ||
| 138 | /* | ||
| 139 | * This is performance-critical, we want to do it O(1) | ||
| 140 | * | ||
| 141 | * Most irqs are mapped 1:1 with pins. | ||
| 142 | */ | ||
| 142 | struct irq_cfg { | 143 | struct irq_cfg { |
| 143 | struct irq_pin_list *irq_2_pin; | 144 | struct irq_pin_list *irq_2_pin; |
| 144 | cpumask_var_t domain; | 145 | cpumask_var_t domain; |
| @@ -414,13 +415,10 @@ static bool io_apic_level_ack_pending(struct irq_cfg *cfg) | |||
| 414 | unsigned long flags; | 415 | unsigned long flags; |
| 415 | 416 | ||
| 416 | spin_lock_irqsave(&ioapic_lock, flags); | 417 | spin_lock_irqsave(&ioapic_lock, flags); |
| 417 | entry = cfg->irq_2_pin; | 418 | for_each_irq_pin(entry, cfg->irq_2_pin) { |
| 418 | for (;;) { | ||
| 419 | unsigned int reg; | 419 | unsigned int reg; |
| 420 | int pin; | 420 | int pin; |
| 421 | 421 | ||
| 422 | if (!entry) | ||
| 423 | break; | ||
| 424 | pin = entry->pin; | 422 | pin = entry->pin; |
| 425 | reg = io_apic_read(entry->apic, 0x10 + pin*2); | 423 | reg = io_apic_read(entry->apic, 0x10 + pin*2); |
| 426 | /* Is the remote IRR bit set? */ | 424 | /* Is the remote IRR bit set? */ |
| @@ -428,9 +426,6 @@ static bool io_apic_level_ack_pending(struct irq_cfg *cfg) | |||
| 428 | spin_unlock_irqrestore(&ioapic_lock, flags); | 426 | spin_unlock_irqrestore(&ioapic_lock, flags); |
| 429 | return true; | 427 | return true; |
| 430 | } | 428 | } |
| 431 | if (!entry->next) | ||
| 432 | break; | ||
| 433 | entry = entry->next; | ||
| 434 | } | 429 | } |
| 435 | spin_unlock_irqrestore(&ioapic_lock, flags); | 430 | spin_unlock_irqrestore(&ioapic_lock, flags); |
| 436 | 431 | ||
| @@ -498,72 +493,68 @@ static void ioapic_mask_entry(int apic, int pin) | |||
| 498 | * shared ISA-space IRQs, so we have to support them. We are super | 493 | * shared ISA-space IRQs, so we have to support them. We are super |
| 499 | * fast in the common case, and fast for shared ISA-space IRQs. | 494 | * fast in the common case, and fast for shared ISA-space IRQs. |
| 500 | */ | 495 | */ |
| 501 | static void add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin) | 496 | static int |
| 497 | add_pin_to_irq_node_nopanic(struct irq_cfg *cfg, int node, int apic, int pin) | ||
| 502 | { | 498 | { |
| 503 | struct irq_pin_list *entry; | 499 | struct irq_pin_list **last, *entry; |
| 504 | 500 | ||
| 505 | entry = cfg->irq_2_pin; | 501 | /* don't allow duplicates */ |
| 506 | if (!entry) { | 502 | last = &cfg->irq_2_pin; |
| 507 | entry = get_one_free_irq_2_pin(node); | 503 | for_each_irq_pin(entry, cfg->irq_2_pin) { |
| 508 | if (!entry) { | ||
| 509 | printk(KERN_ERR "can not alloc irq_2_pin to add %d - %d\n", | ||
| 510 | apic, pin); | ||
| 511 | return; | ||
| 512 | } | ||
| 513 | cfg->irq_2_pin = entry; | ||
| 514 | entry->apic = apic; | ||
| 515 | entry->pin = pin; | ||
| 516 | return; | ||
| 517 | } | ||
| 518 | |||
| 519 | while (entry->next) { | ||
| 520 | /* not again, please */ | ||
| 521 | if (entry->apic == apic && entry->pin == pin) | 504 | if (entry->apic == apic && entry->pin == pin) |
| 522 | return; | 505 | return 0; |
| 523 | 506 | last = &entry->next; | |
| 524 | entry = entry->next; | ||
| 525 | } | 507 | } |
| 526 | 508 | ||
| 527 | entry->next = get_one_free_irq_2_pin(node); | 509 | entry = get_one_free_irq_2_pin(node); |
| 528 | entry = entry->next; | 510 | if (!entry) { |
| 511 | printk(KERN_ERR "can not alloc irq_pin_list (%d,%d,%d)\n", | ||
| 512 | node, apic, pin); | ||
| 513 | return -ENOMEM; | ||
| 514 | } | ||
| 529 | entry->apic = apic; | 515 | entry->apic = apic; |
| 530 | entry->pin = pin; | 516 | entry->pin = pin; |
| 517 | |||
| 518 | *last = entry; | ||
| 519 | return 0; | ||
| 520 | } | ||
| 521 | |||
| 522 | static void add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin) | ||
| 523 | { | ||
| 524 | if (add_pin_to_irq_node_nopanic(cfg, node, apic, pin)) | ||
| 525 | panic("IO-APIC: failed to add irq-pin. Can not proceed\n"); | ||
| 531 | } | 526 | } |
| 532 | 527 | ||
| 533 | /* | 528 | /* |
| 534 | * Reroute an IRQ to a different pin. | 529 | * Reroute an IRQ to a different pin. |
| 535 | */ | 530 | */ |
| 536 | static void __init replace_pin_at_irq_node(struct irq_cfg *cfg, int node, | 531 | static void __init replace_pin_at_irq_node(struct irq_cfg *cfg, int node, |
| 537 | int oldapic, int oldpin, | 532 | int oldapic, int oldpin, |
| 538 | int newapic, int newpin) | 533 | int newapic, int newpin) |
| 539 | { | 534 | { |
| 540 | struct irq_pin_list *entry = cfg->irq_2_pin; | 535 | struct irq_pin_list *entry; |
| 541 | int replaced = 0; | ||
| 542 | 536 | ||
| 543 | while (entry) { | 537 | for_each_irq_pin(entry, cfg->irq_2_pin) { |
| 544 | if (entry->apic == oldapic && entry->pin == oldpin) { | 538 | if (entry->apic == oldapic && entry->pin == oldpin) { |
| 545 | entry->apic = newapic; | 539 | entry->apic = newapic; |
| 546 | entry->pin = newpin; | 540 | entry->pin = newpin; |
| 547 | replaced = 1; | ||
| 548 | /* every one is different, right? */ | 541 | /* every one is different, right? */ |
| 549 | break; | 542 | return; |
| 550 | } | 543 | } |
| 551 | entry = entry->next; | ||
| 552 | } | 544 | } |
| 553 | 545 | ||
| 554 | /* why? call replace before add? */ | 546 | /* old apic/pin didn't exist, so just add new ones */ |
| 555 | if (!replaced) | 547 | add_pin_to_irq_node(cfg, node, newapic, newpin); |
| 556 | add_pin_to_irq_node(cfg, node, newapic, newpin); | ||
| 557 | } | 548 | } |
| 558 | 549 | ||
| 559 | static inline void io_apic_modify_irq(struct irq_cfg *cfg, | 550 | static void io_apic_modify_irq(struct irq_cfg *cfg, |
| 560 | int mask_and, int mask_or, | 551 | int mask_and, int mask_or, |
| 561 | void (*final)(struct irq_pin_list *entry)) | 552 | void (*final)(struct irq_pin_list *entry)) |
| 562 | { | 553 | { |
| 563 | int pin; | 554 | int pin; |
| 564 | struct irq_pin_list *entry; | 555 | struct irq_pin_list *entry; |
| 565 | 556 | ||
| 566 | for (entry = cfg->irq_2_pin; entry != NULL; entry = entry->next) { | 557 | for_each_irq_pin(entry, cfg->irq_2_pin) { |
| 567 | unsigned int reg; | 558 | unsigned int reg; |
| 568 | pin = entry->pin; | 559 | pin = entry->pin; |
| 569 | reg = io_apic_read(entry->apic, 0x10 + pin * 2); | 560 | reg = io_apic_read(entry->apic, 0x10 + pin * 2); |
| @@ -580,7 +571,6 @@ static void __unmask_IO_APIC_irq(struct irq_cfg *cfg) | |||
| 580 | io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL); | 571 | io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL); |
| 581 | } | 572 | } |
| 582 | 573 | ||
| 583 | #ifdef CONFIG_X86_64 | ||
| 584 | static void io_apic_sync(struct irq_pin_list *entry) | 574 | static void io_apic_sync(struct irq_pin_list *entry) |
| 585 | { | 575 | { |
| 586 | /* | 576 | /* |
| @@ -596,11 +586,6 @@ static void __mask_IO_APIC_irq(struct irq_cfg *cfg) | |||
| 596 | { | 586 | { |
| 597 | io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync); | 587 | io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync); |
| 598 | } | 588 | } |
| 599 | #else /* CONFIG_X86_32 */ | ||
| 600 | static void __mask_IO_APIC_irq(struct irq_cfg *cfg) | ||
| 601 | { | ||
| 602 | io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, NULL); | ||
| 603 | } | ||
| 604 | 589 | ||
| 605 | static void __mask_and_edge_IO_APIC_irq(struct irq_cfg *cfg) | 590 | static void __mask_and_edge_IO_APIC_irq(struct irq_cfg *cfg) |
| 606 | { | 591 | { |
| @@ -613,7 +598,6 @@ static void __unmask_and_level_IO_APIC_irq(struct irq_cfg *cfg) | |||
| 613 | io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, | 598 | io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, |
| 614 | IO_APIC_REDIR_LEVEL_TRIGGER, NULL); | 599 | IO_APIC_REDIR_LEVEL_TRIGGER, NULL); |
| 615 | } | 600 | } |
| 616 | #endif /* CONFIG_X86_32 */ | ||
| 617 | 601 | ||
| 618 | static void mask_IO_APIC_irq_desc(struct irq_desc *desc) | 602 | static void mask_IO_APIC_irq_desc(struct irq_desc *desc) |
| 619 | { | 603 | { |
| @@ -1702,12 +1686,8 @@ __apicdebuginit(void) print_IO_APIC(void) | |||
| 1702 | if (!entry) | 1686 | if (!entry) |
| 1703 | continue; | 1687 | continue; |
| 1704 | printk(KERN_DEBUG "IRQ%d ", irq); | 1688 | printk(KERN_DEBUG "IRQ%d ", irq); |
| 1705 | for (;;) { | 1689 | for_each_irq_pin(entry, cfg->irq_2_pin) |
| 1706 | printk("-> %d:%d", entry->apic, entry->pin); | 1690 | printk("-> %d:%d", entry->apic, entry->pin); |
| 1707 | if (!entry->next) | ||
| 1708 | break; | ||
| 1709 | entry = entry->next; | ||
| 1710 | } | ||
| 1711 | printk("\n"); | 1691 | printk("\n"); |
| 1712 | } | 1692 | } |
| 1713 | 1693 | ||
| @@ -2211,7 +2191,6 @@ static unsigned int startup_ioapic_irq(unsigned int irq) | |||
| 2211 | return was_pending; | 2191 | return was_pending; |
| 2212 | } | 2192 | } |
| 2213 | 2193 | ||
| 2214 | #ifdef CONFIG_X86_64 | ||
| 2215 | static int ioapic_retrigger_irq(unsigned int irq) | 2194 | static int ioapic_retrigger_irq(unsigned int irq) |
| 2216 | { | 2195 | { |
| 2217 | 2196 | ||
| @@ -2224,14 +2203,6 @@ static int ioapic_retrigger_irq(unsigned int irq) | |||
| 2224 | 2203 | ||
| 2225 | return 1; | 2204 | return 1; |
| 2226 | } | 2205 | } |
| 2227 | #else | ||
| 2228 | static int ioapic_retrigger_irq(unsigned int irq) | ||
| 2229 | { | ||
| 2230 | apic->send_IPI_self(irq_cfg(irq)->vector); | ||
| 2231 | |||
| 2232 | return 1; | ||
| 2233 | } | ||
| 2234 | #endif | ||
| 2235 | 2206 | ||
| 2236 | /* | 2207 | /* |
| 2237 | * Level and edge triggered IO-APIC interrupts need different handling, | 2208 | * Level and edge triggered IO-APIC interrupts need different handling, |
| @@ -2269,13 +2240,9 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq | |||
| 2269 | struct irq_pin_list *entry; | 2240 | struct irq_pin_list *entry; |
| 2270 | u8 vector = cfg->vector; | 2241 | u8 vector = cfg->vector; |
| 2271 | 2242 | ||
| 2272 | entry = cfg->irq_2_pin; | 2243 | for_each_irq_pin(entry, cfg->irq_2_pin) { |
| 2273 | for (;;) { | ||
| 2274 | unsigned int reg; | 2244 | unsigned int reg; |
| 2275 | 2245 | ||
| 2276 | if (!entry) | ||
| 2277 | break; | ||
| 2278 | |||
| 2279 | apic = entry->apic; | 2246 | apic = entry->apic; |
| 2280 | pin = entry->pin; | 2247 | pin = entry->pin; |
| 2281 | /* | 2248 | /* |
| @@ -2288,9 +2255,6 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq | |||
| 2288 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; | 2255 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; |
| 2289 | reg |= vector; | 2256 | reg |= vector; |
| 2290 | io_apic_modify(apic, 0x10 + pin*2, reg); | 2257 | io_apic_modify(apic, 0x10 + pin*2, reg); |
| 2291 | if (!entry->next) | ||
| 2292 | break; | ||
| 2293 | entry = entry->next; | ||
| 2294 | } | 2258 | } |
| 2295 | } | 2259 | } |
| 2296 | 2260 | ||
| @@ -2515,11 +2479,8 @@ atomic_t irq_mis_count; | |||
| 2515 | static void ack_apic_level(unsigned int irq) | 2479 | static void ack_apic_level(unsigned int irq) |
| 2516 | { | 2480 | { |
| 2517 | struct irq_desc *desc = irq_to_desc(irq); | 2481 | struct irq_desc *desc = irq_to_desc(irq); |
| 2518 | |||
| 2519 | #ifdef CONFIG_X86_32 | ||
| 2520 | unsigned long v; | 2482 | unsigned long v; |
| 2521 | int i; | 2483 | int i; |
| 2522 | #endif | ||
| 2523 | struct irq_cfg *cfg; | 2484 | struct irq_cfg *cfg; |
| 2524 | int do_unmask_irq = 0; | 2485 | int do_unmask_irq = 0; |
| 2525 | 2486 | ||
| @@ -2532,31 +2493,28 @@ static void ack_apic_level(unsigned int irq) | |||
| 2532 | } | 2493 | } |
| 2533 | #endif | 2494 | #endif |
| 2534 | 2495 | ||
| 2535 | #ifdef CONFIG_X86_32 | ||
| 2536 | /* | 2496 | /* |
| 2537 | * It appears there is an erratum which affects at least version 0x11 | 2497 | * It appears there is an erratum which affects at least version 0x11 |
| 2538 | * of I/O APIC (that's the 82093AA and cores integrated into various | 2498 | * of I/O APIC (that's the 82093AA and cores integrated into various |
| 2539 | * chipsets). Under certain conditions a level-triggered interrupt is | 2499 | * chipsets). Under certain conditions a level-triggered interrupt is |
| 2540 | * erroneously delivered as edge-triggered one but the respective IRR | 2500 | * erroneously delivered as edge-triggered one but the respective IRR |
| 2541 | * bit gets set nevertheless. As a result the I/O unit expects an EOI | 2501 | * bit gets set nevertheless. As a result the I/O unit expects an EOI |
| 2542 | * message but it will never arrive and further interrupts are blocked | 2502 | * message but it will never arrive and further interrupts are blocked |
| 2543 | * from the source. The exact reason is so far unknown, but the | 2503 | * from the source. The exact reason is so far unknown, but the |
| 2544 | * phenomenon was observed when two consecutive interrupt requests | 2504 | * phenomenon was observed when two consecutive interrupt requests |
| 2545 | * from a given source get delivered to the same CPU and the source is | 2505 | * from a given source get delivered to the same CPU and the source is |
| 2546 | * temporarily disabled in between. | 2506 | * temporarily disabled in between. |
| 2547 | * | 2507 | * |
| 2548 | * A workaround is to simulate an EOI message manually. We achieve it | 2508 | * A workaround is to simulate an EOI message manually. We achieve it |
| 2549 | * by setting the trigger mode to edge and then to level when the edge | 2509 | * by setting the trigger mode to edge and then to level when the edge |
| 2550 | * trigger mode gets detected in the TMR of a local APIC for a | 2510 | * trigger mode gets detected in the TMR of a local APIC for a |
| 2551 | * level-triggered interrupt. We mask the source for the time of the | 2511 | * level-triggered interrupt. We mask the source for the time of the |
| 2552 | * operation to prevent an edge-triggered interrupt escaping meanwhile. | 2512 | * operation to prevent an edge-triggered interrupt escaping meanwhile. |
| 2553 | * The idea is from Manfred Spraul. --macro | 2513 | * The idea is from Manfred Spraul. --macro |
| 2554 | */ | 2514 | */ |
| 2555 | cfg = desc->chip_data; | 2515 | cfg = desc->chip_data; |
| 2556 | i = cfg->vector; | 2516 | i = cfg->vector; |
| 2557 | |||
| 2558 | v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); | 2517 | v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); |
| 2559 | #endif | ||
| 2560 | 2518 | ||
| 2561 | /* | 2519 | /* |
| 2562 | * We must acknowledge the irq before we move it or the acknowledge will | 2520 | * We must acknowledge the irq before we move it or the acknowledge will |
| @@ -2598,7 +2556,7 @@ static void ack_apic_level(unsigned int irq) | |||
| 2598 | unmask_IO_APIC_irq_desc(desc); | 2556 | unmask_IO_APIC_irq_desc(desc); |
| 2599 | } | 2557 | } |
| 2600 | 2558 | ||
| 2601 | #ifdef CONFIG_X86_32 | 2559 | /* Tail end of version 0x11 I/O APIC bug workaround */ |
| 2602 | if (!(v & (1 << (i & 0x1f)))) { | 2560 | if (!(v & (1 << (i & 0x1f)))) { |
| 2603 | atomic_inc(&irq_mis_count); | 2561 | atomic_inc(&irq_mis_count); |
| 2604 | spin_lock(&ioapic_lock); | 2562 | spin_lock(&ioapic_lock); |
| @@ -2606,26 +2564,15 @@ static void ack_apic_level(unsigned int irq) | |||
| 2606 | __unmask_and_level_IO_APIC_irq(cfg); | 2564 | __unmask_and_level_IO_APIC_irq(cfg); |
| 2607 | spin_unlock(&ioapic_lock); | 2565 | spin_unlock(&ioapic_lock); |
| 2608 | } | 2566 | } |
| 2609 | #endif | ||
| 2610 | } | 2567 | } |
| 2611 | 2568 | ||
| 2612 | #ifdef CONFIG_INTR_REMAP | 2569 | #ifdef CONFIG_INTR_REMAP |
| 2613 | static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) | 2570 | static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) |
| 2614 | { | 2571 | { |
| 2615 | int apic, pin; | ||
| 2616 | struct irq_pin_list *entry; | 2572 | struct irq_pin_list *entry; |
| 2617 | 2573 | ||
| 2618 | entry = cfg->irq_2_pin; | 2574 | for_each_irq_pin(entry, cfg->irq_2_pin) |
| 2619 | for (;;) { | 2575 | io_apic_eoi(entry->apic, entry->pin); |
| 2620 | |||
| 2621 | if (!entry) | ||
| 2622 | break; | ||
| 2623 | |||
| 2624 | apic = entry->apic; | ||
| 2625 | pin = entry->pin; | ||
| 2626 | io_apic_eoi(apic, pin); | ||
| 2627 | entry = entry->next; | ||
| 2628 | } | ||
| 2629 | } | 2576 | } |
| 2630 | 2577 | ||
| 2631 | static void | 2578 | static void |
| @@ -3241,8 +3188,7 @@ void destroy_irq(unsigned int irq) | |||
| 3241 | cfg = desc->chip_data; | 3188 | cfg = desc->chip_data; |
| 3242 | dynamic_irq_cleanup(irq); | 3189 | dynamic_irq_cleanup(irq); |
| 3243 | /* connect back irq_cfg */ | 3190 | /* connect back irq_cfg */ |
| 3244 | if (desc) | 3191 | desc->chip_data = cfg; |
| 3245 | desc->chip_data = cfg; | ||
| 3246 | 3192 | ||
| 3247 | free_irte(irq); | 3193 | free_irte(irq); |
| 3248 | spin_lock_irqsave(&vector_lock, flags); | 3194 | spin_lock_irqsave(&vector_lock, flags); |
| @@ -3912,7 +3858,11 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq, | |||
| 3912 | */ | 3858 | */ |
| 3913 | if (irq >= NR_IRQS_LEGACY) { | 3859 | if (irq >= NR_IRQS_LEGACY) { |
| 3914 | cfg = desc->chip_data; | 3860 | cfg = desc->chip_data; |
| 3915 | add_pin_to_irq_node(cfg, node, ioapic, pin); | 3861 | if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) { |
| 3862 | printk(KERN_INFO "can not add pin %d for irq %d\n", | ||
| 3863 | pin, irq); | ||
| 3864 | return 0; | ||
| 3865 | } | ||
| 3916 | } | 3866 | } |
| 3917 | 3867 | ||
| 3918 | setup_IO_APIC_irq(ioapic, pin, irq, desc, trigger, polarity); | 3868 | setup_IO_APIC_irq(ioapic, pin, irq, desc, trigger, polarity); |
| @@ -3941,11 +3891,28 @@ int io_apic_set_pci_routing(struct device *dev, int irq, | |||
| 3941 | return __io_apic_set_pci_routing(dev, irq, irq_attr); | 3891 | return __io_apic_set_pci_routing(dev, irq, irq_attr); |
| 3942 | } | 3892 | } |
| 3943 | 3893 | ||
| 3944 | /* -------------------------------------------------------------------------- | 3894 | u8 __init io_apic_unique_id(u8 id) |
| 3945 | ACPI-based IOAPIC Configuration | 3895 | { |
| 3946 | -------------------------------------------------------------------------- */ | 3896 | #ifdef CONFIG_X86_32 |
| 3897 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && | ||
| 3898 | !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) | ||
| 3899 | return io_apic_get_unique_id(nr_ioapics, id); | ||
| 3900 | else | ||
| 3901 | return id; | ||
| 3902 | #else | ||
| 3903 | int i; | ||
| 3904 | DECLARE_BITMAP(used, 256); | ||
| 3947 | 3905 | ||
| 3948 | #ifdef CONFIG_ACPI | 3906 | bitmap_zero(used, 256); |
| 3907 | for (i = 0; i < nr_ioapics; i++) { | ||
| 3908 | struct mpc_ioapic *ia = &mp_ioapics[i]; | ||
| 3909 | __set_bit(ia->apicid, used); | ||
| 3910 | } | ||
| 3911 | if (!test_bit(id, used)) | ||
| 3912 | return id; | ||
| 3913 | return find_first_zero_bit(used, 256); | ||
| 3914 | #endif | ||
| 3915 | } | ||
| 3949 | 3916 | ||
| 3950 | #ifdef CONFIG_X86_32 | 3917 | #ifdef CONFIG_X86_32 |
| 3951 | int __init io_apic_get_unique_id(int ioapic, int apic_id) | 3918 | int __init io_apic_get_unique_id(int ioapic, int apic_id) |
| @@ -4054,8 +4021,6 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity) | |||
| 4054 | return 0; | 4021 | return 0; |
| 4055 | } | 4022 | } |
| 4056 | 4023 | ||
| 4057 | #endif /* CONFIG_ACPI */ | ||
| 4058 | |||
| 4059 | /* | 4024 | /* |
| 4060 | * This function currently is only a helper for the i386 smp boot process where | 4025 | * This function currently is only a helper for the i386 smp boot process where |
| 4061 | * we need to reprogram the ioredtbls to cater for the cpus which have come online | 4026 | * we need to reprogram the ioredtbls to cater for the cpus which have come online |
| @@ -4109,7 +4074,7 @@ void __init setup_ioapic_dest(void) | |||
| 4109 | 4074 | ||
| 4110 | static struct resource *ioapic_resources; | 4075 | static struct resource *ioapic_resources; |
| 4111 | 4076 | ||
| 4112 | static struct resource * __init ioapic_setup_resources(void) | 4077 | static struct resource * __init ioapic_setup_resources(int nr_ioapics) |
| 4113 | { | 4078 | { |
| 4114 | unsigned long n; | 4079 | unsigned long n; |
| 4115 | struct resource *res; | 4080 | struct resource *res; |
| @@ -4125,15 +4090,13 @@ static struct resource * __init ioapic_setup_resources(void) | |||
| 4125 | mem = alloc_bootmem(n); | 4090 | mem = alloc_bootmem(n); |
| 4126 | res = (void *)mem; | 4091 | res = (void *)mem; |
| 4127 | 4092 | ||
| 4128 | if (mem != NULL) { | 4093 | mem += sizeof(struct resource) * nr_ioapics; |
| 4129 | mem += sizeof(struct resource) * nr_ioapics; | ||
| 4130 | 4094 | ||
| 4131 | for (i = 0; i < nr_ioapics; i++) { | 4095 | for (i = 0; i < nr_ioapics; i++) { |
| 4132 | res[i].name = mem; | 4096 | res[i].name = mem; |
| 4133 | res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY; | 4097 | res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY; |
| 4134 | sprintf(mem, "IOAPIC %u", i); | 4098 | sprintf(mem, "IOAPIC %u", i); |
| 4135 | mem += IOAPIC_RESOURCE_NAME_SIZE; | 4099 | mem += IOAPIC_RESOURCE_NAME_SIZE; |
| 4136 | } | ||
| 4137 | } | 4100 | } |
| 4138 | 4101 | ||
| 4139 | ioapic_resources = res; | 4102 | ioapic_resources = res; |
| @@ -4147,7 +4110,7 @@ void __init ioapic_init_mappings(void) | |||
| 4147 | struct resource *ioapic_res; | 4110 | struct resource *ioapic_res; |
| 4148 | int i; | 4111 | int i; |
| 4149 | 4112 | ||
| 4150 | ioapic_res = ioapic_setup_resources(); | 4113 | ioapic_res = ioapic_setup_resources(nr_ioapics); |
| 4151 | for (i = 0; i < nr_ioapics; i++) { | 4114 | for (i = 0; i < nr_ioapics; i++) { |
| 4152 | if (smp_found_config) { | 4115 | if (smp_found_config) { |
| 4153 | ioapic_phys = mp_ioapics[i].apicaddr; | 4116 | ioapic_phys = mp_ioapics[i].apicaddr; |
| @@ -4176,11 +4139,9 @@ fake_ioapic_page: | |||
| 4176 | __fix_to_virt(idx), ioapic_phys); | 4139 | __fix_to_virt(idx), ioapic_phys); |
| 4177 | idx++; | 4140 | idx++; |
| 4178 | 4141 | ||
| 4179 | if (ioapic_res != NULL) { | 4142 | ioapic_res->start = ioapic_phys; |
| 4180 | ioapic_res->start = ioapic_phys; | 4143 | ioapic_res->end = ioapic_phys + (4 * 1024) - 1; |
| 4181 | ioapic_res->end = ioapic_phys + (4 * 1024) - 1; | 4144 | ioapic_res++; |
| 4182 | ioapic_res++; | ||
| 4183 | } | ||
| 4184 | } | 4145 | } |
| 4185 | } | 4146 | } |
| 4186 | 4147 | ||
| @@ -4201,3 +4162,76 @@ void __init ioapic_insert_resources(void) | |||
| 4201 | r++; | 4162 | r++; |
| 4202 | } | 4163 | } |
| 4203 | } | 4164 | } |
| 4165 | |||
| 4166 | int mp_find_ioapic(int gsi) | ||
| 4167 | { | ||
| 4168 | int i = 0; | ||
| 4169 | |||
| 4170 | /* Find the IOAPIC that manages this GSI. */ | ||
| 4171 | for (i = 0; i < nr_ioapics; i++) { | ||
| 4172 | if ((gsi >= mp_gsi_routing[i].gsi_base) | ||
| 4173 | && (gsi <= mp_gsi_routing[i].gsi_end)) | ||
| 4174 | return i; | ||
| 4175 | } | ||
| 4176 | |||
| 4177 | printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); | ||
| 4178 | return -1; | ||
| 4179 | } | ||
| 4180 | |||
| 4181 | int mp_find_ioapic_pin(int ioapic, int gsi) | ||
| 4182 | { | ||
| 4183 | if (WARN_ON(ioapic == -1)) | ||
| 4184 | return -1; | ||
| 4185 | if (WARN_ON(gsi > mp_gsi_routing[ioapic].gsi_end)) | ||
| 4186 | return -1; | ||
| 4187 | |||
| 4188 | return gsi - mp_gsi_routing[ioapic].gsi_base; | ||
| 4189 | } | ||
| 4190 | |||
| 4191 | static int bad_ioapic(unsigned long address) | ||
| 4192 | { | ||
| 4193 | if (nr_ioapics >= MAX_IO_APICS) { | ||
| 4194 | printk(KERN_WARNING "WARING: Max # of I/O APICs (%d) exceeded " | ||
| 4195 | "(found %d), skipping\n", MAX_IO_APICS, nr_ioapics); | ||
| 4196 | return 1; | ||
| 4197 | } | ||
| 4198 | if (!address) { | ||
| 4199 | printk(KERN_WARNING "WARNING: Bogus (zero) I/O APIC address" | ||
| 4200 | " found in table, skipping!\n"); | ||
| 4201 | return 1; | ||
| 4202 | } | ||
| 4203 | return 0; | ||
| 4204 | } | ||
| 4205 | |||
| 4206 | void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) | ||
| 4207 | { | ||
| 4208 | int idx = 0; | ||
| 4209 | |||
| 4210 | if (bad_ioapic(address)) | ||
| 4211 | return; | ||
| 4212 | |||
| 4213 | idx = nr_ioapics; | ||
| 4214 | |||
| 4215 | mp_ioapics[idx].type = MP_IOAPIC; | ||
| 4216 | mp_ioapics[idx].flags = MPC_APIC_USABLE; | ||
| 4217 | mp_ioapics[idx].apicaddr = address; | ||
| 4218 | |||
| 4219 | set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); | ||
| 4220 | mp_ioapics[idx].apicid = io_apic_unique_id(id); | ||
| 4221 | mp_ioapics[idx].apicver = io_apic_get_version(idx); | ||
| 4222 | |||
| 4223 | /* | ||
| 4224 | * Build basic GSI lookup table to facilitate gsi->io_apic lookups | ||
| 4225 | * and to prevent reprogramming of IOAPIC pins (PCI GSIs). | ||
| 4226 | */ | ||
| 4227 | mp_gsi_routing[idx].gsi_base = gsi_base; | ||
| 4228 | mp_gsi_routing[idx].gsi_end = gsi_base + | ||
| 4229 | io_apic_get_redir_entries(idx); | ||
| 4230 | |||
| 4231 | printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " | ||
| 4232 | "GSI %d-%d\n", idx, mp_ioapics[idx].apicid, | ||
| 4233 | mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr, | ||
| 4234 | mp_gsi_routing[idx].gsi_base, mp_gsi_routing[idx].gsi_end); | ||
| 4235 | |||
| 4236 | nr_ioapics++; | ||
| 4237 | } | ||
diff --git a/arch/x86/kernel/apic/ipi.c b/arch/x86/kernel/apic/ipi.c index 6ef00ba4c886..08385e090a6f 100644 --- a/arch/x86/kernel/apic/ipi.c +++ b/arch/x86/kernel/apic/ipi.c | |||
| @@ -153,7 +153,7 @@ int safe_smp_processor_id(void) | |||
| 153 | { | 153 | { |
| 154 | int apicid, cpuid; | 154 | int apicid, cpuid; |
| 155 | 155 | ||
| 156 | if (!boot_cpu_has(X86_FEATURE_APIC)) | 156 | if (!cpu_has_apic) |
| 157 | return 0; | 157 | return 0; |
| 158 | 158 | ||
| 159 | apicid = hard_smp_processor_id(); | 159 | apicid = hard_smp_processor_id(); |
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c index b3025b43b63a..db7220220d09 100644 --- a/arch/x86/kernel/apic/nmi.c +++ b/arch/x86/kernel/apic/nmi.c | |||
| @@ -39,7 +39,7 @@ | |||
| 39 | int unknown_nmi_panic; | 39 | int unknown_nmi_panic; |
| 40 | int nmi_watchdog_enabled; | 40 | int nmi_watchdog_enabled; |
| 41 | 41 | ||
| 42 | static cpumask_var_t backtrace_mask; | 42 | static cpumask_t backtrace_mask __read_mostly; |
| 43 | 43 | ||
| 44 | /* nmi_active: | 44 | /* nmi_active: |
| 45 | * >0: the lapic NMI watchdog is active, but can be disabled | 45 | * >0: the lapic NMI watchdog is active, but can be disabled |
| @@ -138,7 +138,6 @@ int __init check_nmi_watchdog(void) | |||
| 138 | if (!prev_nmi_count) | 138 | if (!prev_nmi_count) |
| 139 | goto error; | 139 | goto error; |
| 140 | 140 | ||
| 141 | alloc_cpumask_var(&backtrace_mask, GFP_KERNEL|__GFP_ZERO); | ||
| 142 | printk(KERN_INFO "Testing NMI watchdog ... "); | 141 | printk(KERN_INFO "Testing NMI watchdog ... "); |
| 143 | 142 | ||
| 144 | #ifdef CONFIG_SMP | 143 | #ifdef CONFIG_SMP |
| @@ -415,14 +414,17 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason) | |||
| 415 | } | 414 | } |
| 416 | 415 | ||
| 417 | /* We can be called before check_nmi_watchdog, hence NULL check. */ | 416 | /* We can be called before check_nmi_watchdog, hence NULL check. */ |
| 418 | if (backtrace_mask != NULL && cpumask_test_cpu(cpu, backtrace_mask)) { | 417 | if (cpumask_test_cpu(cpu, &backtrace_mask)) { |
| 419 | static DEFINE_SPINLOCK(lock); /* Serialise the printks */ | 418 | static DEFINE_SPINLOCK(lock); /* Serialise the printks */ |
| 420 | 419 | ||
| 421 | spin_lock(&lock); | 420 | spin_lock(&lock); |
| 422 | printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); | 421 | printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); |
| 422 | show_regs(regs); | ||
| 423 | dump_stack(); | 423 | dump_stack(); |
| 424 | spin_unlock(&lock); | 424 | spin_unlock(&lock); |
| 425 | cpumask_clear_cpu(cpu, backtrace_mask); | 425 | cpumask_clear_cpu(cpu, &backtrace_mask); |
| 426 | |||
| 427 | rc = 1; | ||
| 426 | } | 428 | } |
| 427 | 429 | ||
| 428 | /* Could check oops_in_progress here too, but it's safer not to */ | 430 | /* Could check oops_in_progress here too, but it's safer not to */ |
| @@ -552,14 +554,18 @@ int do_nmi_callback(struct pt_regs *regs, int cpu) | |||
| 552 | return 0; | 554 | return 0; |
| 553 | } | 555 | } |
| 554 | 556 | ||
| 555 | void __trigger_all_cpu_backtrace(void) | 557 | void arch_trigger_all_cpu_backtrace(void) |
| 556 | { | 558 | { |
| 557 | int i; | 559 | int i; |
| 558 | 560 | ||
| 559 | cpumask_copy(backtrace_mask, cpu_online_mask); | 561 | cpumask_copy(&backtrace_mask, cpu_online_mask); |
| 562 | |||
| 563 | printk(KERN_INFO "sending NMI to all CPUs:\n"); | ||
| 564 | apic->send_IPI_all(NMI_VECTOR); | ||
| 565 | |||
| 560 | /* Wait for up to 10 seconds for all CPUs to do the backtrace */ | 566 | /* Wait for up to 10 seconds for all CPUs to do the backtrace */ |
| 561 | for (i = 0; i < 10 * 1000; i++) { | 567 | for (i = 0; i < 10 * 1000; i++) { |
| 562 | if (cpumask_empty(backtrace_mask)) | 568 | if (cpumask_empty(&backtrace_mask)) |
| 563 | break; | 569 | break; |
| 564 | mdelay(1); | 570 | mdelay(1); |
| 565 | } | 571 | } |
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index bc3e880f9b82..65edc180fc82 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c | |||
| @@ -44,17 +44,22 @@ static struct apic *apic_probe[] __initdata = { | |||
| 44 | NULL, | 44 | NULL, |
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | static int apicid_phys_pkg_id(int initial_apic_id, int index_msb) | ||
| 48 | { | ||
| 49 | return hard_smp_processor_id() >> index_msb; | ||
| 50 | } | ||
| 51 | |||
| 47 | /* | 52 | /* |
| 48 | * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. | 53 | * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. |
| 49 | */ | 54 | */ |
| 50 | void __init default_setup_apic_routing(void) | 55 | void __init default_setup_apic_routing(void) |
| 51 | { | 56 | { |
| 52 | #ifdef CONFIG_X86_X2APIC | 57 | #ifdef CONFIG_X86_X2APIC |
| 53 | if (x2apic_mode && (apic != &apic_x2apic_phys && | 58 | if (x2apic_mode |
| 54 | #ifdef CONFIG_X86_UV | 59 | #ifdef CONFIG_X86_UV |
| 55 | apic != &apic_x2apic_uv_x && | 60 | && apic != &apic_x2apic_uv_x |
| 56 | #endif | 61 | #endif |
| 57 | apic != &apic_x2apic_cluster)) { | 62 | ) { |
| 58 | if (x2apic_phys) | 63 | if (x2apic_phys) |
| 59 | apic = &apic_x2apic_phys; | 64 | apic = &apic_x2apic_phys; |
| 60 | else | 65 | else |
| @@ -69,6 +74,11 @@ void __init default_setup_apic_routing(void) | |||
| 69 | printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); | 74 | printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); |
| 70 | } | 75 | } |
| 71 | 76 | ||
| 77 | if (is_vsmp_box()) { | ||
| 78 | /* need to update phys_pkg_id */ | ||
| 79 | apic->phys_pkg_id = apicid_phys_pkg_id; | ||
| 80 | } | ||
| 81 | |||
| 72 | /* | 82 | /* |
| 73 | * Now that apic routing model is selected, configure the | 83 | * Now that apic routing model is selected, configure the |
| 74 | * fault handling for intr remapping. | 84 | * fault handling for intr remapping. |
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 442b5508893f..151ace69a5aa 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c | |||
| @@ -403,7 +403,15 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); | |||
| 403 | static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); | 403 | static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); |
| 404 | static struct apm_user *user_list; | 404 | static struct apm_user *user_list; |
| 405 | static DEFINE_SPINLOCK(user_list_lock); | 405 | static DEFINE_SPINLOCK(user_list_lock); |
| 406 | static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } }; | 406 | |
| 407 | /* | ||
| 408 | * Set up a segment that references the real mode segment 0x40 | ||
| 409 | * that extends up to the end of page zero (that we have reserved). | ||
| 410 | * This is for buggy BIOS's that refer to (real mode) segment 0x40 | ||
| 411 | * even though they are called in protected mode. | ||
| 412 | */ | ||
| 413 | static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092, | ||
| 414 | (unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1); | ||
| 407 | 415 | ||
| 408 | static const char driver_version[] = "1.16ac"; /* no spaces */ | 416 | static const char driver_version[] = "1.16ac"; /* no spaces */ |
| 409 | 417 | ||
| @@ -2332,15 +2340,6 @@ static int __init apm_init(void) | |||
| 2332 | pm_flags |= PM_APM; | 2340 | pm_flags |= PM_APM; |
| 2333 | 2341 | ||
| 2334 | /* | 2342 | /* |
| 2335 | * Set up a segment that references the real mode segment 0x40 | ||
| 2336 | * that extends up to the end of page zero (that we have reserved). | ||
| 2337 | * This is for buggy BIOS's that refer to (real mode) segment 0x40 | ||
| 2338 | * even though they are called in protected mode. | ||
| 2339 | */ | ||
| 2340 | set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); | ||
| 2341 | _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); | ||
| 2342 | |||
| 2343 | /* | ||
| 2344 | * Set up the long jump entry point to the APM BIOS, which is called | 2343 | * Set up the long jump entry point to the APM BIOS, which is called |
| 2345 | * from inline assembly. | 2344 | * from inline assembly. |
| 2346 | */ | 2345 | */ |
| @@ -2358,12 +2357,12 @@ static int __init apm_init(void) | |||
| 2358 | * code to that CPU. | 2357 | * code to that CPU. |
| 2359 | */ | 2358 | */ |
| 2360 | gdt = get_cpu_gdt_table(0); | 2359 | gdt = get_cpu_gdt_table(0); |
| 2361 | set_base(gdt[APM_CS >> 3], | 2360 | set_desc_base(&gdt[APM_CS >> 3], |
| 2362 | __va((unsigned long)apm_info.bios.cseg << 4)); | 2361 | (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4)); |
| 2363 | set_base(gdt[APM_CS_16 >> 3], | 2362 | set_desc_base(&gdt[APM_CS_16 >> 3], |
| 2364 | __va((unsigned long)apm_info.bios.cseg_16 << 4)); | 2363 | (unsigned long)__va((unsigned long)apm_info.bios.cseg_16 << 4)); |
| 2365 | set_base(gdt[APM_DS >> 3], | 2364 | set_desc_base(&gdt[APM_DS >> 3], |
| 2366 | __va((unsigned long)apm_info.bios.dseg << 4)); | 2365 | (unsigned long)__va((unsigned long)apm_info.bios.dseg << 4)); |
| 2367 | 2366 | ||
| 2368 | proc_create("apm", 0, NULL, &apm_file_ops); | 2367 | proc_create("apm", 0, NULL, &apm_file_ops); |
| 2369 | 2368 | ||
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 898ecc47e129..4a6aeedcd965 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | * This code generates raw asm output which is post-processed to extract | 3 | * This code generates raw asm output which is post-processed to extract |
| 4 | * and format the required data. | 4 | * and format the required data. |
| 5 | */ | 5 | */ |
| 6 | #define COMPILE_OFFSETS | ||
| 6 | 7 | ||
| 7 | #include <linux/crypto.h> | 8 | #include <linux/crypto.h> |
| 8 | #include <linux/sched.h> | 9 | #include <linux/sched.h> |
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 3efcb2b96a15..c1f253dac155 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile | |||
| @@ -7,6 +7,10 @@ ifdef CONFIG_FUNCTION_TRACER | |||
| 7 | CFLAGS_REMOVE_common.o = -pg | 7 | CFLAGS_REMOVE_common.o = -pg |
| 8 | endif | 8 | endif |
| 9 | 9 | ||
| 10 | # Make sure load_percpu_segment has no stackprotector | ||
| 11 | nostackp := $(call cc-option, -fno-stack-protector) | ||
| 12 | CFLAGS_common.o := $(nostackp) | ||
| 13 | |||
| 10 | obj-y := intel_cacheinfo.o addon_cpuid_features.o | 14 | obj-y := intel_cacheinfo.o addon_cpuid_features.o |
| 11 | obj-y += proc.o capflags.o powerflags.o common.o | 15 | obj-y += proc.o capflags.o powerflags.o common.o |
| 12 | obj-y += vmware.o hypervisor.o | 16 | obj-y += vmware.o hypervisor.o |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 63fddcd082cd..22a47c82f3c0 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | #include <linux/bitops.h> | 2 | #include <linux/bitops.h> |
| 3 | #include <linux/mm.h> | 3 | #include <linux/mm.h> |
| 4 | 4 | ||
| 5 | #include <asm/io.h> | 5 | #include <linux/io.h> |
| 6 | #include <asm/processor.h> | 6 | #include <asm/processor.h> |
| 7 | #include <asm/apic.h> | 7 | #include <asm/apic.h> |
| 8 | #include <asm/cpu.h> | 8 | #include <asm/cpu.h> |
| @@ -45,8 +45,8 @@ static void __cpuinit init_amd_k5(struct cpuinfo_x86 *c) | |||
| 45 | #define CBAR_ENB (0x80000000) | 45 | #define CBAR_ENB (0x80000000) |
| 46 | #define CBAR_KEY (0X000000CB) | 46 | #define CBAR_KEY (0X000000CB) |
| 47 | if (c->x86_model == 9 || c->x86_model == 10) { | 47 | if (c->x86_model == 9 || c->x86_model == 10) { |
| 48 | if (inl (CBAR) & CBAR_ENB) | 48 | if (inl(CBAR) & CBAR_ENB) |
| 49 | outl (0 | CBAR_KEY, CBAR); | 49 | outl(0 | CBAR_KEY, CBAR); |
| 50 | } | 50 | } |
| 51 | } | 51 | } |
| 52 | 52 | ||
| @@ -87,9 +87,10 @@ static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c) | |||
| 87 | d = d2-d; | 87 | d = d2-d; |
| 88 | 88 | ||
| 89 | if (d > 20*K6_BUG_LOOP) | 89 | if (d > 20*K6_BUG_LOOP) |
| 90 | printk("system stability may be impaired when more than 32 MB are used.\n"); | 90 | printk(KERN_CONT |
| 91 | "system stability may be impaired when more than 32 MB are used.\n"); | ||
| 91 | else | 92 | else |
| 92 | printk("probably OK (after B9730xxxx).\n"); | 93 | printk(KERN_CONT "probably OK (after B9730xxxx).\n"); |
| 93 | printk(KERN_INFO "Please see http://membres.lycos.fr/poulot/k6bug.html\n"); | 94 | printk(KERN_INFO "Please see http://membres.lycos.fr/poulot/k6bug.html\n"); |
| 94 | } | 95 | } |
| 95 | 96 | ||
| @@ -219,8 +220,9 @@ static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c) | |||
| 219 | if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) { | 220 | if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) { |
| 220 | rdmsr(MSR_K7_CLK_CTL, l, h); | 221 | rdmsr(MSR_K7_CLK_CTL, l, h); |
| 221 | if ((l & 0xfff00000) != 0x20000000) { | 222 | if ((l & 0xfff00000) != 0x20000000) { |
| 222 | printk ("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n", l, | 223 | printk(KERN_INFO |
| 223 | ((l & 0x000fffff)|0x20000000)); | 224 | "CPU: CLK_CTL MSR was %x. Reprogramming to %x\n", |
| 225 | l, ((l & 0x000fffff)|0x20000000)); | ||
| 224 | wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h); | 226 | wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h); |
| 225 | } | 227 | } |
| 226 | } | 228 | } |
| @@ -251,6 +253,64 @@ static int __cpuinit nearby_node(int apicid) | |||
| 251 | #endif | 253 | #endif |
| 252 | 254 | ||
| 253 | /* | 255 | /* |
| 256 | * Fixup core topology information for AMD multi-node processors. | ||
| 257 | * Assumption 1: Number of cores in each internal node is the same. | ||
| 258 | * Assumption 2: Mixed systems with both single-node and dual-node | ||
| 259 | * processors are not supported. | ||
| 260 | */ | ||
| 261 | #ifdef CONFIG_X86_HT | ||
| 262 | static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c) | ||
| 263 | { | ||
| 264 | #ifdef CONFIG_PCI | ||
| 265 | u32 t, cpn; | ||
| 266 | u8 n, n_id; | ||
| 267 | int cpu = smp_processor_id(); | ||
| 268 | |||
| 269 | /* fixup topology information only once for a core */ | ||
| 270 | if (cpu_has(c, X86_FEATURE_AMD_DCM)) | ||
| 271 | return; | ||
| 272 | |||
| 273 | /* check for multi-node processor on boot cpu */ | ||
| 274 | t = read_pci_config(0, 24, 3, 0xe8); | ||
| 275 | if (!(t & (1 << 29))) | ||
| 276 | return; | ||
| 277 | |||
| 278 | set_cpu_cap(c, X86_FEATURE_AMD_DCM); | ||
| 279 | |||
| 280 | /* cores per node: each internal node has half the number of cores */ | ||
| 281 | cpn = c->x86_max_cores >> 1; | ||
| 282 | |||
| 283 | /* even-numbered NB_id of this dual-node processor */ | ||
| 284 | n = c->phys_proc_id << 1; | ||
| 285 | |||
| 286 | /* | ||
| 287 | * determine internal node id and assign cores fifty-fifty to | ||
| 288 | * each node of the dual-node processor | ||
| 289 | */ | ||
| 290 | t = read_pci_config(0, 24 + n, 3, 0xe8); | ||
| 291 | n = (t>>30) & 0x3; | ||
| 292 | if (n == 0) { | ||
| 293 | if (c->cpu_core_id < cpn) | ||
| 294 | n_id = 0; | ||
| 295 | else | ||
| 296 | n_id = 1; | ||
| 297 | } else { | ||
| 298 | if (c->cpu_core_id < cpn) | ||
| 299 | n_id = 1; | ||
| 300 | else | ||
| 301 | n_id = 0; | ||
| 302 | } | ||
| 303 | |||
| 304 | /* compute entire NodeID, use llc_shared_map to store sibling info */ | ||
| 305 | per_cpu(cpu_llc_id, cpu) = (c->phys_proc_id << 1) + n_id; | ||
| 306 | |||
| 307 | /* fixup core id to be in range from 0 to cpn */ | ||
| 308 | c->cpu_core_id = c->cpu_core_id % cpn; | ||
| 309 | #endif | ||
| 310 | } | ||
| 311 | #endif | ||
| 312 | |||
| 313 | /* | ||
| 254 | * On a AMD dual core setup the lower bits of the APIC id distingush the cores. | 314 | * On a AMD dual core setup the lower bits of the APIC id distingush the cores. |
| 255 | * Assumes number of cores is a power of two. | 315 | * Assumes number of cores is a power of two. |
| 256 | */ | 316 | */ |
| @@ -267,6 +327,9 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c) | |||
| 267 | c->phys_proc_id = c->initial_apicid >> bits; | 327 | c->phys_proc_id = c->initial_apicid >> bits; |
| 268 | /* use socket ID also for last level cache */ | 328 | /* use socket ID also for last level cache */ |
| 269 | per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; | 329 | per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; |
| 330 | /* fixup topology information on multi-node processors */ | ||
| 331 | if ((c->x86 == 0x10) && (c->x86_model == 9)) | ||
| 332 | amd_fixup_dcm(c); | ||
| 270 | #endif | 333 | #endif |
| 271 | } | 334 | } |
| 272 | 335 | ||
| @@ -275,9 +338,10 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c) | |||
| 275 | #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) | 338 | #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) |
| 276 | int cpu = smp_processor_id(); | 339 | int cpu = smp_processor_id(); |
| 277 | int node; | 340 | int node; |
| 278 | unsigned apicid = cpu_has_apic ? hard_smp_processor_id() : c->apicid; | 341 | unsigned apicid = c->apicid; |
| 342 | |||
| 343 | node = per_cpu(cpu_llc_id, cpu); | ||
| 279 | 344 | ||
| 280 | node = c->phys_proc_id; | ||
| 281 | if (apicid_to_node[apicid] != NUMA_NO_NODE) | 345 | if (apicid_to_node[apicid] != NUMA_NO_NODE) |
| 282 | node = apicid_to_node[apicid]; | 346 | node = apicid_to_node[apicid]; |
| 283 | if (!node_online(node)) { | 347 | if (!node_online(node)) { |
| @@ -398,18 +462,30 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
| 398 | u32 level; | 462 | u32 level; |
| 399 | 463 | ||
| 400 | level = cpuid_eax(1); | 464 | level = cpuid_eax(1); |
| 401 | if((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58) | 465 | if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58) |
| 402 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | 466 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); |
| 403 | 467 | ||
| 404 | /* | 468 | /* |
| 405 | * Some BIOSes incorrectly force this feature, but only K8 | 469 | * Some BIOSes incorrectly force this feature, but only K8 |
| 406 | * revision D (model = 0x14) and later actually support it. | 470 | * revision D (model = 0x14) and later actually support it. |
| 471 | * (AMD Erratum #110, docId: 25759). | ||
| 407 | */ | 472 | */ |
| 408 | if (c->x86_model < 0x14) | 473 | if (c->x86_model < 0x14 && cpu_has(c, X86_FEATURE_LAHF_LM)) { |
| 474 | u64 val; | ||
| 475 | |||
| 409 | clear_cpu_cap(c, X86_FEATURE_LAHF_LM); | 476 | clear_cpu_cap(c, X86_FEATURE_LAHF_LM); |
| 477 | if (!rdmsrl_amd_safe(0xc001100d, &val)) { | ||
| 478 | val &= ~(1ULL << 32); | ||
| 479 | wrmsrl_amd_safe(0xc001100d, val); | ||
| 480 | } | ||
| 481 | } | ||
| 482 | |||
| 410 | } | 483 | } |
| 411 | if (c->x86 == 0x10 || c->x86 == 0x11) | 484 | if (c->x86 == 0x10 || c->x86 == 0x11) |
| 412 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | 485 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); |
| 486 | |||
| 487 | /* get apicid instead of initial apic id from cpuid */ | ||
| 488 | c->apicid = hard_smp_processor_id(); | ||
| 413 | #else | 489 | #else |
| 414 | 490 | ||
| 415 | /* | 491 | /* |
| @@ -494,27 +570,30 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
| 494 | * benefit in doing so. | 570 | * benefit in doing so. |
| 495 | */ | 571 | */ |
| 496 | if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) { | 572 | if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) { |
| 497 | printk(KERN_DEBUG "tseg: %010llx\n", tseg); | 573 | printk(KERN_DEBUG "tseg: %010llx\n", tseg); |
| 498 | if ((tseg>>PMD_SHIFT) < | 574 | if ((tseg>>PMD_SHIFT) < |
| 499 | (max_low_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) || | 575 | (max_low_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) || |
| 500 | ((tseg>>PMD_SHIFT) < | 576 | ((tseg>>PMD_SHIFT) < |
| 501 | (max_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) && | 577 | (max_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) && |
| 502 | (tseg>>PMD_SHIFT) >= (1ULL<<(32 - PMD_SHIFT)))) | 578 | (tseg>>PMD_SHIFT) >= (1ULL<<(32 - PMD_SHIFT)))) |
| 503 | set_memory_4k((unsigned long)__va(tseg), 1); | 579 | set_memory_4k((unsigned long)__va(tseg), 1); |
| 504 | } | 580 | } |
| 505 | } | 581 | } |
| 506 | #endif | 582 | #endif |
| 507 | } | 583 | } |
| 508 | 584 | ||
| 509 | #ifdef CONFIG_X86_32 | 585 | #ifdef CONFIG_X86_32 |
| 510 | static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c, unsigned int size) | 586 | static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c, |
| 587 | unsigned int size) | ||
| 511 | { | 588 | { |
| 512 | /* AMD errata T13 (order #21922) */ | 589 | /* AMD errata T13 (order #21922) */ |
| 513 | if ((c->x86 == 6)) { | 590 | if ((c->x86 == 6)) { |
| 514 | if (c->x86_model == 3 && c->x86_mask == 0) /* Duron Rev A0 */ | 591 | /* Duron Rev A0 */ |
| 592 | if (c->x86_model == 3 && c->x86_mask == 0) | ||
| 515 | size = 64; | 593 | size = 64; |
| 594 | /* Tbird rev A1/A2 */ | ||
| 516 | if (c->x86_model == 4 && | 595 | if (c->x86_model == 4 && |
| 517 | (c->x86_mask == 0 || c->x86_mask == 1)) /* Tbird rev A1/A2 */ | 596 | (c->x86_mask == 0 || c->x86_mask == 1)) |
| 518 | size = 256; | 597 | size = 256; |
| 519 | } | 598 | } |
| 520 | return size; | 599 | return size; |
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index c8e315f1aa83..01a265212395 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
| @@ -81,7 +81,7 @@ static void __init check_fpu(void) | |||
| 81 | 81 | ||
| 82 | boot_cpu_data.fdiv_bug = fdiv_bug; | 82 | boot_cpu_data.fdiv_bug = fdiv_bug; |
| 83 | if (boot_cpu_data.fdiv_bug) | 83 | if (boot_cpu_data.fdiv_bug) |
| 84 | printk("Hmm, FPU with FDIV bug.\n"); | 84 | printk(KERN_WARNING "Hmm, FPU with FDIV bug.\n"); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | static void __init check_hlt(void) | 87 | static void __init check_hlt(void) |
| @@ -98,7 +98,7 @@ static void __init check_hlt(void) | |||
| 98 | halt(); | 98 | halt(); |
| 99 | halt(); | 99 | halt(); |
| 100 | halt(); | 100 | halt(); |
| 101 | printk("OK.\n"); | 101 | printk(KERN_CONT "OK.\n"); |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | /* | 104 | /* |
| @@ -122,9 +122,9 @@ static void __init check_popad(void) | |||
| 122 | * CPU hard. Too bad. | 122 | * CPU hard. Too bad. |
| 123 | */ | 123 | */ |
| 124 | if (res != 12345678) | 124 | if (res != 12345678) |
| 125 | printk("Buggy.\n"); | 125 | printk(KERN_CONT "Buggy.\n"); |
| 126 | else | 126 | else |
| 127 | printk("OK.\n"); | 127 | printk(KERN_CONT "OK.\n"); |
| 128 | #endif | 128 | #endif |
| 129 | } | 129 | } |
| 130 | 130 | ||
| @@ -156,7 +156,7 @@ void __init check_bugs(void) | |||
| 156 | { | 156 | { |
| 157 | identify_boot_cpu(); | 157 | identify_boot_cpu(); |
| 158 | #ifndef CONFIG_SMP | 158 | #ifndef CONFIG_SMP |
| 159 | printk("CPU: "); | 159 | printk(KERN_INFO "CPU: "); |
| 160 | print_cpu_info(&boot_cpu_data); | 160 | print_cpu_info(&boot_cpu_data); |
| 161 | #endif | 161 | #endif |
| 162 | check_config(); | 162 | check_config(); |
diff --git a/arch/x86/kernel/cpu/bugs_64.c b/arch/x86/kernel/cpu/bugs_64.c index 9a3ed0649d4e..04f0fe5af83e 100644 --- a/arch/x86/kernel/cpu/bugs_64.c +++ b/arch/x86/kernel/cpu/bugs_64.c | |||
| @@ -15,7 +15,7 @@ void __init check_bugs(void) | |||
| 15 | { | 15 | { |
| 16 | identify_boot_cpu(); | 16 | identify_boot_cpu(); |
| 17 | #if !defined(CONFIG_SMP) | 17 | #if !defined(CONFIG_SMP) |
| 18 | printk("CPU: "); | 18 | printk(KERN_INFO "CPU: "); |
| 19 | print_cpu_info(&boot_cpu_data); | 19 | print_cpu_info(&boot_cpu_data); |
| 20 | #endif | 20 | #endif |
| 21 | alternative_instructions(); | 21 | alternative_instructions(); |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 5ce60a88027b..2055fc2b2e6b 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
| @@ -18,8 +18,8 @@ | |||
| 18 | #include <asm/hypervisor.h> | 18 | #include <asm/hypervisor.h> |
| 19 | #include <asm/processor.h> | 19 | #include <asm/processor.h> |
| 20 | #include <asm/sections.h> | 20 | #include <asm/sections.h> |
| 21 | #include <asm/topology.h> | 21 | #include <linux/topology.h> |
| 22 | #include <asm/cpumask.h> | 22 | #include <linux/cpumask.h> |
| 23 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
| 24 | #include <asm/atomic.h> | 24 | #include <asm/atomic.h> |
| 25 | #include <asm/proto.h> | 25 | #include <asm/proto.h> |
| @@ -28,13 +28,13 @@ | |||
| 28 | #include <asm/desc.h> | 28 | #include <asm/desc.h> |
| 29 | #include <asm/i387.h> | 29 | #include <asm/i387.h> |
| 30 | #include <asm/mtrr.h> | 30 | #include <asm/mtrr.h> |
| 31 | #include <asm/numa.h> | 31 | #include <linux/numa.h> |
| 32 | #include <asm/asm.h> | 32 | #include <asm/asm.h> |
| 33 | #include <asm/cpu.h> | 33 | #include <asm/cpu.h> |
| 34 | #include <asm/mce.h> | 34 | #include <asm/mce.h> |
| 35 | #include <asm/msr.h> | 35 | #include <asm/msr.h> |
| 36 | #include <asm/pat.h> | 36 | #include <asm/pat.h> |
| 37 | #include <asm/smp.h> | 37 | #include <linux/smp.h> |
| 38 | 38 | ||
| 39 | #ifdef CONFIG_X86_LOCAL_APIC | 39 | #ifdef CONFIG_X86_LOCAL_APIC |
| 40 | #include <asm/uv/uv.h> | 40 | #include <asm/uv/uv.h> |
| @@ -94,45 +94,45 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = { | |||
| 94 | * TLS descriptors are currently at a different place compared to i386. | 94 | * TLS descriptors are currently at a different place compared to i386. |
| 95 | * Hopefully nobody expects them at a fixed place (Wine?) | 95 | * Hopefully nobody expects them at a fixed place (Wine?) |
| 96 | */ | 96 | */ |
| 97 | [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } }, | 97 | [GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff), |
| 98 | [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } }, | 98 | [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff), |
| 99 | [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } }, | 99 | [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff), |
| 100 | [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } }, | 100 | [GDT_ENTRY_DEFAULT_USER32_CS] = GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff), |
| 101 | [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } }, | 101 | [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff), |
| 102 | [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } }, | 102 | [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff), |
| 103 | #else | 103 | #else |
| 104 | [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } }, | 104 | [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xc09a, 0, 0xfffff), |
| 105 | [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } }, | 105 | [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), |
| 106 | [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } }, | 106 | [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xc0fa, 0, 0xfffff), |
| 107 | [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } }, | 107 | [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f2, 0, 0xfffff), |
| 108 | /* | 108 | /* |
| 109 | * Segments used for calling PnP BIOS have byte granularity. | 109 | * Segments used for calling PnP BIOS have byte granularity. |
| 110 | * They code segments and data segments have fixed 64k limits, | 110 | * They code segments and data segments have fixed 64k limits, |
| 111 | * the transfer segment sizes are set at run time. | 111 | * the transfer segment sizes are set at run time. |
| 112 | */ | 112 | */ |
| 113 | /* 32-bit code */ | 113 | /* 32-bit code */ |
| 114 | [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } }, | 114 | [GDT_ENTRY_PNPBIOS_CS32] = GDT_ENTRY_INIT(0x409a, 0, 0xffff), |
| 115 | /* 16-bit code */ | 115 | /* 16-bit code */ |
| 116 | [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } }, | 116 | [GDT_ENTRY_PNPBIOS_CS16] = GDT_ENTRY_INIT(0x009a, 0, 0xffff), |
| 117 | /* 16-bit data */ | 117 | /* 16-bit data */ |
| 118 | [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } }, | 118 | [GDT_ENTRY_PNPBIOS_DS] = GDT_ENTRY_INIT(0x0092, 0, 0xffff), |
| 119 | /* 16-bit data */ | 119 | /* 16-bit data */ |
| 120 | [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } }, | 120 | [GDT_ENTRY_PNPBIOS_TS1] = GDT_ENTRY_INIT(0x0092, 0, 0), |
| 121 | /* 16-bit data */ | 121 | /* 16-bit data */ |
| 122 | [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } }, | 122 | [GDT_ENTRY_PNPBIOS_TS2] = GDT_ENTRY_INIT(0x0092, 0, 0), |
| 123 | /* | 123 | /* |
| 124 | * The APM segments have byte granularity and their bases | 124 | * The APM segments have byte granularity and their bases |
| 125 | * are set at run time. All have 64k limits. | 125 | * are set at run time. All have 64k limits. |
| 126 | */ | 126 | */ |
| 127 | /* 32-bit code */ | 127 | /* 32-bit code */ |
| 128 | [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } }, | 128 | [GDT_ENTRY_APMBIOS_BASE] = GDT_ENTRY_INIT(0x409a, 0, 0xffff), |
| 129 | /* 16-bit code */ | 129 | /* 16-bit code */ |
| 130 | [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } }, | 130 | [GDT_ENTRY_APMBIOS_BASE+1] = GDT_ENTRY_INIT(0x009a, 0, 0xffff), |
| 131 | /* data */ | 131 | /* data */ |
| 132 | [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } }, | 132 | [GDT_ENTRY_APMBIOS_BASE+2] = GDT_ENTRY_INIT(0x4092, 0, 0xffff), |
| 133 | 133 | ||
| 134 | [GDT_ENTRY_ESPFIX_SS] = { { { 0x0000ffff, 0x00cf9200 } } }, | 134 | [GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), |
| 135 | [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } }, | 135 | [GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), |
| 136 | GDT_STACK_CANARY_INIT | 136 | GDT_STACK_CANARY_INIT |
| 137 | #endif | 137 | #endif |
| 138 | } }; | 138 | } }; |
| @@ -982,18 +982,26 @@ static __init int setup_disablecpuid(char *arg) | |||
| 982 | __setup("clearcpuid=", setup_disablecpuid); | 982 | __setup("clearcpuid=", setup_disablecpuid); |
| 983 | 983 | ||
| 984 | #ifdef CONFIG_X86_64 | 984 | #ifdef CONFIG_X86_64 |
| 985 | struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; | 985 | struct desc_ptr idt_descr = { NR_VECTORS * 16 - 1, (unsigned long) idt_table }; |
| 986 | 986 | ||
| 987 | DEFINE_PER_CPU_FIRST(union irq_stack_union, | 987 | DEFINE_PER_CPU_FIRST(union irq_stack_union, |
| 988 | irq_stack_union) __aligned(PAGE_SIZE); | 988 | irq_stack_union) __aligned(PAGE_SIZE); |
| 989 | 989 | ||
| 990 | DEFINE_PER_CPU(char *, irq_stack_ptr) = | 990 | /* |
| 991 | init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64; | 991 | * The following four percpu variables are hot. Align current_task to |
| 992 | * cacheline size such that all four fall in the same cacheline. | ||
| 993 | */ | ||
| 994 | DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned = | ||
| 995 | &init_task; | ||
| 996 | EXPORT_PER_CPU_SYMBOL(current_task); | ||
| 992 | 997 | ||
| 993 | DEFINE_PER_CPU(unsigned long, kernel_stack) = | 998 | DEFINE_PER_CPU(unsigned long, kernel_stack) = |
| 994 | (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE; | 999 | (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE; |
| 995 | EXPORT_PER_CPU_SYMBOL(kernel_stack); | 1000 | EXPORT_PER_CPU_SYMBOL(kernel_stack); |
| 996 | 1001 | ||
| 1002 | DEFINE_PER_CPU(char *, irq_stack_ptr) = | ||
| 1003 | init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64; | ||
| 1004 | |||
| 997 | DEFINE_PER_CPU(unsigned int, irq_count) = -1; | 1005 | DEFINE_PER_CPU(unsigned int, irq_count) = -1; |
| 998 | 1006 | ||
| 999 | /* | 1007 | /* |
| @@ -1008,8 +1016,7 @@ static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = { | |||
| 1008 | }; | 1016 | }; |
| 1009 | 1017 | ||
| 1010 | static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks | 1018 | static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks |
| 1011 | [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]) | 1019 | [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]); |
| 1012 | __aligned(PAGE_SIZE); | ||
| 1013 | 1020 | ||
| 1014 | /* May not be marked __init: used by software suspend */ | 1021 | /* May not be marked __init: used by software suspend */ |
| 1015 | void syscall_init(void) | 1022 | void syscall_init(void) |
| @@ -1042,8 +1049,11 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist); | |||
| 1042 | 1049 | ||
| 1043 | #else /* CONFIG_X86_64 */ | 1050 | #else /* CONFIG_X86_64 */ |
| 1044 | 1051 | ||
| 1052 | DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; | ||
| 1053 | EXPORT_PER_CPU_SYMBOL(current_task); | ||
| 1054 | |||
| 1045 | #ifdef CONFIG_CC_STACKPROTECTOR | 1055 | #ifdef CONFIG_CC_STACKPROTECTOR |
| 1046 | DEFINE_PER_CPU(unsigned long, stack_canary); | 1056 | DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary); |
| 1047 | #endif | 1057 | #endif |
| 1048 | 1058 | ||
| 1049 | /* Make sure %fs and %gs are initialized properly in idle threads */ | 1059 | /* Make sure %fs and %gs are initialized properly in idle threads */ |
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c index 593171e967ef..19807b89f058 100644 --- a/arch/x86/kernel/cpu/cyrix.c +++ b/arch/x86/kernel/cpu/cyrix.c | |||
| @@ -3,10 +3,10 @@ | |||
| 3 | #include <linux/delay.h> | 3 | #include <linux/delay.h> |
| 4 | #include <linux/pci.h> | 4 | #include <linux/pci.h> |
| 5 | #include <asm/dma.h> | 5 | #include <asm/dma.h> |
| 6 | #include <asm/io.h> | 6 | #include <linux/io.h> |
| 7 | #include <asm/processor-cyrix.h> | 7 | #include <asm/processor-cyrix.h> |
| 8 | #include <asm/processor-flags.h> | 8 | #include <asm/processor-flags.h> |
| 9 | #include <asm/timer.h> | 9 | #include <linux/timer.h> |
| 10 | #include <asm/pci-direct.h> | 10 | #include <asm/pci-direct.h> |
| 11 | #include <asm/tsc.h> | 11 | #include <asm/tsc.h> |
| 12 | 12 | ||
| @@ -282,7 +282,8 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c) | |||
| 282 | * The 5510/5520 companion chips have a funky PIT. | 282 | * The 5510/5520 companion chips have a funky PIT. |
| 283 | */ | 283 | */ |
| 284 | if (vendor == PCI_VENDOR_ID_CYRIX && | 284 | if (vendor == PCI_VENDOR_ID_CYRIX && |
| 285 | (device == PCI_DEVICE_ID_CYRIX_5510 || device == PCI_DEVICE_ID_CYRIX_5520)) | 285 | (device == PCI_DEVICE_ID_CYRIX_5510 || |
| 286 | device == PCI_DEVICE_ID_CYRIX_5520)) | ||
| 286 | mark_tsc_unstable("cyrix 5510/5520 detected"); | 287 | mark_tsc_unstable("cyrix 5510/5520 detected"); |
| 287 | } | 288 | } |
| 288 | #endif | 289 | #endif |
| @@ -299,7 +300,8 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c) | |||
| 299 | * ? : 0x7x | 300 | * ? : 0x7x |
| 300 | * GX1 : 0x8x GX1 datasheet 56 | 301 | * GX1 : 0x8x GX1 datasheet 56 |
| 301 | */ | 302 | */ |
| 302 | if ((0x30 <= dir1 && dir1 <= 0x6f) || (0x80 <= dir1 && dir1 <= 0x8f)) | 303 | if ((0x30 <= dir1 && dir1 <= 0x6f) || |
| 304 | (0x80 <= dir1 && dir1 <= 0x8f)) | ||
| 303 | geode_configure(); | 305 | geode_configure(); |
| 304 | return; | 306 | return; |
| 305 | } else { /* MediaGX */ | 307 | } else { /* MediaGX */ |
| @@ -427,9 +429,12 @@ static void __cpuinit cyrix_identify(struct cpuinfo_x86 *c) | |||
| 427 | printk(KERN_INFO "Enabling CPUID on Cyrix processor.\n"); | 429 | printk(KERN_INFO "Enabling CPUID on Cyrix processor.\n"); |
| 428 | local_irq_save(flags); | 430 | local_irq_save(flags); |
| 429 | ccr3 = getCx86(CX86_CCR3); | 431 | ccr3 = getCx86(CX86_CCR3); |
| 430 | setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ | 432 | /* enable MAPEN */ |
| 431 | setCx86_old(CX86_CCR4, getCx86_old(CX86_CCR4) | 0x80); /* enable cpuid */ | 433 | setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); |
| 432 | setCx86(CX86_CCR3, ccr3); /* disable MAPEN */ | 434 | /* enable cpuid */ |
| 435 | setCx86_old(CX86_CCR4, getCx86_old(CX86_CCR4) | 0x80); | ||
| 436 | /* disable MAPEN */ | ||
| 437 | setCx86(CX86_CCR3, ccr3); | ||
| 433 | local_irq_restore(flags); | 438 | local_irq_restore(flags); |
| 434 | } | 439 | } |
| 435 | } | 440 | } |
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c index fb5b86af0b01..93ba8eeb100a 100644 --- a/arch/x86/kernel/cpu/hypervisor.c +++ b/arch/x86/kernel/cpu/hypervisor.c | |||
| @@ -28,11 +28,10 @@ | |||
| 28 | static inline void __cpuinit | 28 | static inline void __cpuinit |
| 29 | detect_hypervisor_vendor(struct cpuinfo_x86 *c) | 29 | detect_hypervisor_vendor(struct cpuinfo_x86 *c) |
| 30 | { | 30 | { |
| 31 | if (vmware_platform()) { | 31 | if (vmware_platform()) |
| 32 | c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE; | 32 | c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE; |
| 33 | } else { | 33 | else |
| 34 | c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE; | 34 | c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE; |
| 35 | } | ||
| 36 | } | 35 | } |
| 37 | 36 | ||
| 38 | unsigned long get_hypervisor_tsc_freq(void) | 37 | unsigned long get_hypervisor_tsc_freq(void) |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 3260ab044996..80a722a071b5 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
| @@ -7,17 +7,17 @@ | |||
| 7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
| 8 | #include <linux/thread_info.h> | 8 | #include <linux/thread_info.h> |
| 9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 10 | #include <linux/uaccess.h> | ||
| 10 | 11 | ||
| 11 | #include <asm/processor.h> | 12 | #include <asm/processor.h> |
| 12 | #include <asm/pgtable.h> | 13 | #include <asm/pgtable.h> |
| 13 | #include <asm/msr.h> | 14 | #include <asm/msr.h> |
| 14 | #include <asm/uaccess.h> | ||
| 15 | #include <asm/ds.h> | 15 | #include <asm/ds.h> |
| 16 | #include <asm/bugs.h> | 16 | #include <asm/bugs.h> |
| 17 | #include <asm/cpu.h> | 17 | #include <asm/cpu.h> |
| 18 | 18 | ||
| 19 | #ifdef CONFIG_X86_64 | 19 | #ifdef CONFIG_X86_64 |
| 20 | #include <asm/topology.h> | 20 | #include <linux/topology.h> |
| 21 | #include <asm/numa_64.h> | 21 | #include <asm/numa_64.h> |
| 22 | #endif | 22 | #endif |
| 23 | 23 | ||
| @@ -174,7 +174,8 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c) | |||
| 174 | #ifdef CONFIG_X86_F00F_BUG | 174 | #ifdef CONFIG_X86_F00F_BUG |
| 175 | /* | 175 | /* |
| 176 | * All current models of Pentium and Pentium with MMX technology CPUs | 176 | * All current models of Pentium and Pentium with MMX technology CPUs |
| 177 | * have the F0 0F bug, which lets nonprivileged users lock up the system. | 177 | * have the F0 0F bug, which lets nonprivileged users lock up the |
| 178 | * system. | ||
| 178 | * Note that the workaround only should be initialized once... | 179 | * Note that the workaround only should be initialized once... |
| 179 | */ | 180 | */ |
| 180 | c->f00f_bug = 0; | 181 | c->f00f_bug = 0; |
| @@ -207,7 +208,7 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c) | |||
| 207 | printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n"); | 208 | printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n"); |
| 208 | printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n"); | 209 | printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n"); |
| 209 | lo |= MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE; | 210 | lo |= MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE; |
| 210 | wrmsr (MSR_IA32_MISC_ENABLE, lo, hi); | 211 | wrmsr(MSR_IA32_MISC_ENABLE, lo, hi); |
| 211 | } | 212 | } |
| 212 | } | 213 | } |
| 213 | 214 | ||
| @@ -283,7 +284,7 @@ static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c) | |||
| 283 | /* Intel has a non-standard dependency on %ecx for this CPUID level. */ | 284 | /* Intel has a non-standard dependency on %ecx for this CPUID level. */ |
| 284 | cpuid_count(4, 0, &eax, &ebx, &ecx, &edx); | 285 | cpuid_count(4, 0, &eax, &ebx, &ecx, &edx); |
| 285 | if (eax & 0x1f) | 286 | if (eax & 0x1f) |
| 286 | return ((eax >> 26) + 1); | 287 | return (eax >> 26) + 1; |
| 287 | else | 288 | else |
| 288 | return 1; | 289 | return 1; |
| 289 | } | 290 | } |
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 789efe217e1a..804c40e2bc3e 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Changes: | 4 | * Changes: |
| 5 | * Venkatesh Pallipadi : Adding cache identification through cpuid(4) | 5 | * Venkatesh Pallipadi : Adding cache identification through cpuid(4) |
| 6 | * Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure. | 6 | * Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure. |
| 7 | * Andi Kleen / Andreas Herrmann : CPUID4 emulation on AMD. | 7 | * Andi Kleen / Andreas Herrmann : CPUID4 emulation on AMD. |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
| 17 | 17 | ||
| 18 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
| 19 | #include <asm/smp.h> | 19 | #include <linux/smp.h> |
| 20 | #include <asm/k8.h> | 20 | #include <asm/k8.h> |
| 21 | 21 | ||
| 22 | #define LVL_1_INST 1 | 22 | #define LVL_1_INST 1 |
| @@ -25,14 +25,15 @@ | |||
| 25 | #define LVL_3 4 | 25 | #define LVL_3 4 |
| 26 | #define LVL_TRACE 5 | 26 | #define LVL_TRACE 5 |
| 27 | 27 | ||
| 28 | struct _cache_table | 28 | struct _cache_table { |
| 29 | { | ||
| 30 | unsigned char descriptor; | 29 | unsigned char descriptor; |
| 31 | char cache_type; | 30 | char cache_type; |
| 32 | short size; | 31 | short size; |
| 33 | }; | 32 | }; |
| 34 | 33 | ||
| 35 | /* all the cache descriptor types we care about (no TLB or trace cache entries) */ | 34 | /* All the cache descriptor types we care about (no TLB or |
| 35 | trace cache entries) */ | ||
| 36 | |||
| 36 | static const struct _cache_table __cpuinitconst cache_table[] = | 37 | static const struct _cache_table __cpuinitconst cache_table[] = |
| 37 | { | 38 | { |
| 38 | { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ | 39 | { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ |
| @@ -105,8 +106,7 @@ static const struct _cache_table __cpuinitconst cache_table[] = | |||
| 105 | }; | 106 | }; |
| 106 | 107 | ||
| 107 | 108 | ||
| 108 | enum _cache_type | 109 | enum _cache_type { |
| 109 | { | ||
| 110 | CACHE_TYPE_NULL = 0, | 110 | CACHE_TYPE_NULL = 0, |
| 111 | CACHE_TYPE_DATA = 1, | 111 | CACHE_TYPE_DATA = 1, |
| 112 | CACHE_TYPE_INST = 2, | 112 | CACHE_TYPE_INST = 2, |
| @@ -170,31 +170,31 @@ unsigned short num_cache_leaves; | |||
| 170 | Maybe later */ | 170 | Maybe later */ |
| 171 | union l1_cache { | 171 | union l1_cache { |
| 172 | struct { | 172 | struct { |
| 173 | unsigned line_size : 8; | 173 | unsigned line_size:8; |
| 174 | unsigned lines_per_tag : 8; | 174 | unsigned lines_per_tag:8; |
| 175 | unsigned assoc : 8; | 175 | unsigned assoc:8; |
| 176 | unsigned size_in_kb : 8; | 176 | unsigned size_in_kb:8; |
| 177 | }; | 177 | }; |
| 178 | unsigned val; | 178 | unsigned val; |
| 179 | }; | 179 | }; |
| 180 | 180 | ||
| 181 | union l2_cache { | 181 | union l2_cache { |
| 182 | struct { | 182 | struct { |
| 183 | unsigned line_size : 8; | 183 | unsigned line_size:8; |
| 184 | unsigned lines_per_tag : 4; | 184 | unsigned lines_per_tag:4; |
| 185 | unsigned assoc : 4; | 185 | unsigned assoc:4; |
| 186 | unsigned size_in_kb : 16; | 186 | unsigned size_in_kb:16; |
| 187 | }; | 187 | }; |
| 188 | unsigned val; | 188 | unsigned val; |
| 189 | }; | 189 | }; |
| 190 | 190 | ||
| 191 | union l3_cache { | 191 | union l3_cache { |
| 192 | struct { | 192 | struct { |
| 193 | unsigned line_size : 8; | 193 | unsigned line_size:8; |
| 194 | unsigned lines_per_tag : 4; | 194 | unsigned lines_per_tag:4; |
| 195 | unsigned assoc : 4; | 195 | unsigned assoc:4; |
| 196 | unsigned res : 2; | 196 | unsigned res:2; |
| 197 | unsigned size_encoded : 14; | 197 | unsigned size_encoded:14; |
| 198 | }; | 198 | }; |
| 199 | unsigned val; | 199 | unsigned val; |
| 200 | }; | 200 | }; |
| @@ -241,7 +241,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, | |||
| 241 | case 0: | 241 | case 0: |
| 242 | if (!l1->val) | 242 | if (!l1->val) |
| 243 | return; | 243 | return; |
| 244 | assoc = l1->assoc; | 244 | assoc = assocs[l1->assoc]; |
| 245 | line_size = l1->line_size; | 245 | line_size = l1->line_size; |
| 246 | lines_per_tag = l1->lines_per_tag; | 246 | lines_per_tag = l1->lines_per_tag; |
| 247 | size_in_kb = l1->size_in_kb; | 247 | size_in_kb = l1->size_in_kb; |
| @@ -249,7 +249,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, | |||
| 249 | case 2: | 249 | case 2: |
| 250 | if (!l2.val) | 250 | if (!l2.val) |
| 251 | return; | 251 | return; |
| 252 | assoc = l2.assoc; | 252 | assoc = assocs[l2.assoc]; |
| 253 | line_size = l2.line_size; | 253 | line_size = l2.line_size; |
| 254 | lines_per_tag = l2.lines_per_tag; | 254 | lines_per_tag = l2.lines_per_tag; |
| 255 | /* cpu_data has errata corrections for K7 applied */ | 255 | /* cpu_data has errata corrections for K7 applied */ |
| @@ -258,10 +258,14 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, | |||
| 258 | case 3: | 258 | case 3: |
| 259 | if (!l3.val) | 259 | if (!l3.val) |
| 260 | return; | 260 | return; |
| 261 | assoc = l3.assoc; | 261 | assoc = assocs[l3.assoc]; |
| 262 | line_size = l3.line_size; | 262 | line_size = l3.line_size; |
| 263 | lines_per_tag = l3.lines_per_tag; | 263 | lines_per_tag = l3.lines_per_tag; |
| 264 | size_in_kb = l3.size_encoded * 512; | 264 | size_in_kb = l3.size_encoded * 512; |
| 265 | if (boot_cpu_has(X86_FEATURE_AMD_DCM)) { | ||
| 266 | size_in_kb = size_in_kb >> 1; | ||
| 267 | assoc = assoc >> 1; | ||
| 268 | } | ||
| 265 | break; | 269 | break; |
| 266 | default: | 270 | default: |
| 267 | return; | 271 | return; |
| @@ -270,18 +274,14 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, | |||
| 270 | eax->split.is_self_initializing = 1; | 274 | eax->split.is_self_initializing = 1; |
| 271 | eax->split.type = types[leaf]; | 275 | eax->split.type = types[leaf]; |
| 272 | eax->split.level = levels[leaf]; | 276 | eax->split.level = levels[leaf]; |
| 273 | if (leaf == 3) | 277 | eax->split.num_threads_sharing = 0; |
| 274 | eax->split.num_threads_sharing = | ||
| 275 | current_cpu_data.x86_max_cores - 1; | ||
| 276 | else | ||
| 277 | eax->split.num_threads_sharing = 0; | ||
| 278 | eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1; | 278 | eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1; |
| 279 | 279 | ||
| 280 | 280 | ||
| 281 | if (assoc == 0xf) | 281 | if (assoc == 0xffff) |
| 282 | eax->split.is_fully_associative = 1; | 282 | eax->split.is_fully_associative = 1; |
| 283 | ebx->split.coherency_line_size = line_size - 1; | 283 | ebx->split.coherency_line_size = line_size - 1; |
| 284 | ebx->split.ways_of_associativity = assocs[assoc] - 1; | 284 | ebx->split.ways_of_associativity = assoc - 1; |
| 285 | ebx->split.physical_line_partition = lines_per_tag - 1; | 285 | ebx->split.physical_line_partition = lines_per_tag - 1; |
| 286 | ecx->split.number_of_sets = (size_in_kb * 1024) / line_size / | 286 | ecx->split.number_of_sets = (size_in_kb * 1024) / line_size / |
| 287 | (ebx->split.ways_of_associativity + 1) - 1; | 287 | (ebx->split.ways_of_associativity + 1) - 1; |
| @@ -350,7 +350,8 @@ static int __cpuinit find_num_cache_leaves(void) | |||
| 350 | 350 | ||
| 351 | unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | 351 | unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) |
| 352 | { | 352 | { |
| 353 | unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ | 353 | /* Cache sizes */ |
| 354 | unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; | ||
| 354 | unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ | 355 | unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ |
| 355 | unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ | 356 | unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ |
| 356 | unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; | 357 | unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; |
| @@ -377,8 +378,8 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | |||
| 377 | 378 | ||
| 378 | retval = cpuid4_cache_lookup_regs(i, &this_leaf); | 379 | retval = cpuid4_cache_lookup_regs(i, &this_leaf); |
| 379 | if (retval >= 0) { | 380 | if (retval >= 0) { |
| 380 | switch(this_leaf.eax.split.level) { | 381 | switch (this_leaf.eax.split.level) { |
| 381 | case 1: | 382 | case 1: |
| 382 | if (this_leaf.eax.split.type == | 383 | if (this_leaf.eax.split.type == |
| 383 | CACHE_TYPE_DATA) | 384 | CACHE_TYPE_DATA) |
| 384 | new_l1d = this_leaf.size/1024; | 385 | new_l1d = this_leaf.size/1024; |
| @@ -386,19 +387,20 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | |||
| 386 | CACHE_TYPE_INST) | 387 | CACHE_TYPE_INST) |
| 387 | new_l1i = this_leaf.size/1024; | 388 | new_l1i = this_leaf.size/1024; |
| 388 | break; | 389 | break; |
| 389 | case 2: | 390 | case 2: |
| 390 | new_l2 = this_leaf.size/1024; | 391 | new_l2 = this_leaf.size/1024; |
| 391 | num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; | 392 | num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; |
| 392 | index_msb = get_count_order(num_threads_sharing); | 393 | index_msb = get_count_order(num_threads_sharing); |
| 393 | l2_id = c->apicid >> index_msb; | 394 | l2_id = c->apicid >> index_msb; |
| 394 | break; | 395 | break; |
| 395 | case 3: | 396 | case 3: |
| 396 | new_l3 = this_leaf.size/1024; | 397 | new_l3 = this_leaf.size/1024; |
| 397 | num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; | 398 | num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; |
| 398 | index_msb = get_count_order(num_threads_sharing); | 399 | index_msb = get_count_order( |
| 400 | num_threads_sharing); | ||
| 399 | l3_id = c->apicid >> index_msb; | 401 | l3_id = c->apicid >> index_msb; |
| 400 | break; | 402 | break; |
| 401 | default: | 403 | default: |
| 402 | break; | 404 | break; |
| 403 | } | 405 | } |
| 404 | } | 406 | } |
| @@ -421,22 +423,21 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | |||
| 421 | /* Number of times to iterate */ | 423 | /* Number of times to iterate */ |
| 422 | n = cpuid_eax(2) & 0xFF; | 424 | n = cpuid_eax(2) & 0xFF; |
| 423 | 425 | ||
| 424 | for ( i = 0 ; i < n ; i++ ) { | 426 | for (i = 0 ; i < n ; i++) { |
| 425 | cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]); | 427 | cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]); |
| 426 | 428 | ||
| 427 | /* If bit 31 is set, this is an unknown format */ | 429 | /* If bit 31 is set, this is an unknown format */ |
| 428 | for ( j = 0 ; j < 3 ; j++ ) { | 430 | for (j = 0 ; j < 3 ; j++) |
| 429 | if (regs[j] & (1 << 31)) regs[j] = 0; | 431 | if (regs[j] & (1 << 31)) |
| 430 | } | 432 | regs[j] = 0; |
| 431 | 433 | ||
| 432 | /* Byte 0 is level count, not a descriptor */ | 434 | /* Byte 0 is level count, not a descriptor */ |
| 433 | for ( j = 1 ; j < 16 ; j++ ) { | 435 | for (j = 1 ; j < 16 ; j++) { |
| 434 | unsigned char des = dp[j]; | 436 | unsigned char des = dp[j]; |
| 435 | unsigned char k = 0; | 437 | unsigned char k = 0; |
| 436 | 438 | ||
| 437 | /* look up this descriptor in the table */ | 439 | /* look up this descriptor in the table */ |
| 438 | while (cache_table[k].descriptor != 0) | 440 | while (cache_table[k].descriptor != 0) { |
| 439 | { | ||
| 440 | if (cache_table[k].descriptor == des) { | 441 | if (cache_table[k].descriptor == des) { |
| 441 | if (only_trace && cache_table[k].cache_type != LVL_TRACE) | 442 | if (only_trace && cache_table[k].cache_type != LVL_TRACE) |
| 442 | break; | 443 | break; |
| @@ -488,14 +489,14 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | |||
| 488 | } | 489 | } |
| 489 | 490 | ||
| 490 | if (trace) | 491 | if (trace) |
| 491 | printk (KERN_INFO "CPU: Trace cache: %dK uops", trace); | 492 | printk(KERN_INFO "CPU: Trace cache: %dK uops", trace); |
| 492 | else if ( l1i ) | 493 | else if (l1i) |
| 493 | printk (KERN_INFO "CPU: L1 I cache: %dK", l1i); | 494 | printk(KERN_INFO "CPU: L1 I cache: %dK", l1i); |
| 494 | 495 | ||
| 495 | if (l1d) | 496 | if (l1d) |
| 496 | printk(", L1 D cache: %dK\n", l1d); | 497 | printk(KERN_CONT ", L1 D cache: %dK\n", l1d); |
| 497 | else | 498 | else |
| 498 | printk("\n"); | 499 | printk(KERN_CONT "\n"); |
| 499 | 500 | ||
| 500 | if (l2) | 501 | if (l2) |
| 501 | printk(KERN_INFO "CPU: L2 cache: %dK\n", l2); | 502 | printk(KERN_INFO "CPU: L2 cache: %dK\n", l2); |
| @@ -522,6 +523,18 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) | |||
| 522 | int index_msb, i; | 523 | int index_msb, i; |
| 523 | struct cpuinfo_x86 *c = &cpu_data(cpu); | 524 | struct cpuinfo_x86 *c = &cpu_data(cpu); |
| 524 | 525 | ||
| 526 | if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) { | ||
| 527 | struct cpuinfo_x86 *d; | ||
| 528 | for_each_online_cpu(i) { | ||
| 529 | if (!per_cpu(cpuid4_info, i)) | ||
| 530 | continue; | ||
| 531 | d = &cpu_data(i); | ||
| 532 | this_leaf = CPUID4_INFO_IDX(i, index); | ||
| 533 | cpumask_copy(to_cpumask(this_leaf->shared_cpu_map), | ||
| 534 | d->llc_shared_map); | ||
| 535 | } | ||
| 536 | return; | ||
| 537 | } | ||
| 525 | this_leaf = CPUID4_INFO_IDX(cpu, index); | 538 | this_leaf = CPUID4_INFO_IDX(cpu, index); |
| 526 | num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; | 539 | num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; |
| 527 | 540 | ||
| @@ -558,8 +571,13 @@ static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) | |||
| 558 | } | 571 | } |
| 559 | } | 572 | } |
| 560 | #else | 573 | #else |
| 561 | static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) {} | 574 | static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) |
| 562 | static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) {} | 575 | { |
| 576 | } | ||
| 577 | |||
| 578 | static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) | ||
| 579 | { | ||
| 580 | } | ||
| 563 | #endif | 581 | #endif |
| 564 | 582 | ||
| 565 | static void __cpuinit free_cache_attributes(unsigned int cpu) | 583 | static void __cpuinit free_cache_attributes(unsigned int cpu) |
| @@ -645,7 +663,7 @@ static DEFINE_PER_CPU(struct _index_kobject *, index_kobject); | |||
| 645 | static ssize_t show_##file_name \ | 663 | static ssize_t show_##file_name \ |
| 646 | (struct _cpuid4_info *this_leaf, char *buf) \ | 664 | (struct _cpuid4_info *this_leaf, char *buf) \ |
| 647 | { \ | 665 | { \ |
| 648 | return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \ | 666 | return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \ |
| 649 | } | 667 | } |
| 650 | 668 | ||
| 651 | show_one_plus(level, eax.split.level, 0); | 669 | show_one_plus(level, eax.split.level, 0); |
| @@ -656,7 +674,7 @@ show_one_plus(number_of_sets, ecx.split.number_of_sets, 1); | |||
| 656 | 674 | ||
| 657 | static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf) | 675 | static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf) |
| 658 | { | 676 | { |
| 659 | return sprintf (buf, "%luK\n", this_leaf->size / 1024); | 677 | return sprintf(buf, "%luK\n", this_leaf->size / 1024); |
| 660 | } | 678 | } |
| 661 | 679 | ||
| 662 | static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf, | 680 | static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf, |
| @@ -669,7 +687,7 @@ static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf, | |||
| 669 | const struct cpumask *mask; | 687 | const struct cpumask *mask; |
| 670 | 688 | ||
| 671 | mask = to_cpumask(this_leaf->shared_cpu_map); | 689 | mask = to_cpumask(this_leaf->shared_cpu_map); |
| 672 | n = type? | 690 | n = type ? |
| 673 | cpulist_scnprintf(buf, len-2, mask) : | 691 | cpulist_scnprintf(buf, len-2, mask) : |
| 674 | cpumask_scnprintf(buf, len-2, mask); | 692 | cpumask_scnprintf(buf, len-2, mask); |
| 675 | buf[n++] = '\n'; | 693 | buf[n++] = '\n'; |
| @@ -800,7 +818,7 @@ static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644, | |||
| 800 | static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644, | 818 | static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644, |
| 801 | show_cache_disable_1, store_cache_disable_1); | 819 | show_cache_disable_1, store_cache_disable_1); |
| 802 | 820 | ||
| 803 | static struct attribute * default_attrs[] = { | 821 | static struct attribute *default_attrs[] = { |
| 804 | &type.attr, | 822 | &type.attr, |
| 805 | &level.attr, | 823 | &level.attr, |
| 806 | &coherency_line_size.attr, | 824 | &coherency_line_size.attr, |
| @@ -815,7 +833,7 @@ static struct attribute * default_attrs[] = { | |||
| 815 | NULL | 833 | NULL |
| 816 | }; | 834 | }; |
| 817 | 835 | ||
| 818 | static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf) | 836 | static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) |
| 819 | { | 837 | { |
| 820 | struct _cache_attr *fattr = to_attr(attr); | 838 | struct _cache_attr *fattr = to_attr(attr); |
| 821 | struct _index_kobject *this_leaf = to_object(kobj); | 839 | struct _index_kobject *this_leaf = to_object(kobj); |
| @@ -828,8 +846,8 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf) | |||
| 828 | return ret; | 846 | return ret; |
| 829 | } | 847 | } |
| 830 | 848 | ||
| 831 | static ssize_t store(struct kobject * kobj, struct attribute * attr, | 849 | static ssize_t store(struct kobject *kobj, struct attribute *attr, |
| 832 | const char * buf, size_t count) | 850 | const char *buf, size_t count) |
| 833 | { | 851 | { |
| 834 | struct _cache_attr *fattr = to_attr(attr); | 852 | struct _cache_attr *fattr = to_attr(attr); |
| 835 | struct _index_kobject *this_leaf = to_object(kobj); | 853 | struct _index_kobject *this_leaf = to_object(kobj); |
| @@ -883,7 +901,7 @@ static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu) | |||
| 883 | goto err_out; | 901 | goto err_out; |
| 884 | 902 | ||
| 885 | per_cpu(index_kobject, cpu) = kzalloc( | 903 | per_cpu(index_kobject, cpu) = kzalloc( |
| 886 | sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL); | 904 | sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL); |
| 887 | if (unlikely(per_cpu(index_kobject, cpu) == NULL)) | 905 | if (unlikely(per_cpu(index_kobject, cpu) == NULL)) |
| 888 | goto err_out; | 906 | goto err_out; |
| 889 | 907 | ||
| @@ -917,7 +935,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) | |||
| 917 | } | 935 | } |
| 918 | 936 | ||
| 919 | for (i = 0; i < num_cache_leaves; i++) { | 937 | for (i = 0; i < num_cache_leaves; i++) { |
| 920 | this_object = INDEX_KOBJECT_PTR(cpu,i); | 938 | this_object = INDEX_KOBJECT_PTR(cpu, i); |
| 921 | this_object->cpu = cpu; | 939 | this_object->cpu = cpu; |
| 922 | this_object->index = i; | 940 | this_object->index = i; |
| 923 | retval = kobject_init_and_add(&(this_object->kobj), | 941 | retval = kobject_init_and_add(&(this_object->kobj), |
| @@ -925,9 +943,8 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) | |||
| 925 | per_cpu(cache_kobject, cpu), | 943 | per_cpu(cache_kobject, cpu), |
| 926 | "index%1lu", i); | 944 | "index%1lu", i); |
| 927 | if (unlikely(retval)) { | 945 | if (unlikely(retval)) { |
| 928 | for (j = 0; j < i; j++) { | 946 | for (j = 0; j < i; j++) |
| 929 | kobject_put(&(INDEX_KOBJECT_PTR(cpu,j)->kobj)); | 947 | kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj)); |
| 930 | } | ||
| 931 | kobject_put(per_cpu(cache_kobject, cpu)); | 948 | kobject_put(per_cpu(cache_kobject, cpu)); |
| 932 | cpuid4_cache_sysfs_exit(cpu); | 949 | cpuid4_cache_sysfs_exit(cpu); |
| 933 | return retval; | 950 | return retval; |
| @@ -952,7 +969,7 @@ static void __cpuinit cache_remove_dev(struct sys_device * sys_dev) | |||
| 952 | cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map)); | 969 | cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map)); |
| 953 | 970 | ||
| 954 | for (i = 0; i < num_cache_leaves; i++) | 971 | for (i = 0; i < num_cache_leaves; i++) |
| 955 | kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); | 972 | kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj)); |
| 956 | kobject_put(per_cpu(cache_kobject, cpu)); | 973 | kobject_put(per_cpu(cache_kobject, cpu)); |
| 957 | cpuid4_cache_sysfs_exit(cpu); | 974 | cpuid4_cache_sysfs_exit(cpu); |
| 958 | } | 975 | } |
| @@ -977,8 +994,7 @@ static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, | |||
| 977 | return NOTIFY_OK; | 994 | return NOTIFY_OK; |
| 978 | } | 995 | } |
| 979 | 996 | ||
| 980 | static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = | 997 | static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = { |
| 981 | { | ||
| 982 | .notifier_call = cacheinfo_cpu_callback, | 998 | .notifier_call = cacheinfo_cpu_callback, |
| 983 | }; | 999 | }; |
| 984 | 1000 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 01213048f62f..9bfe9d2ea615 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
| @@ -183,6 +183,11 @@ void mce_log(struct mce *mce) | |||
| 183 | set_bit(0, &mce_need_notify); | 183 | set_bit(0, &mce_need_notify); |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | void __weak decode_mce(struct mce *m) | ||
| 187 | { | ||
| 188 | return; | ||
| 189 | } | ||
| 190 | |||
| 186 | static void print_mce(struct mce *m) | 191 | static void print_mce(struct mce *m) |
| 187 | { | 192 | { |
| 188 | printk(KERN_EMERG | 193 | printk(KERN_EMERG |
| @@ -205,6 +210,8 @@ static void print_mce(struct mce *m) | |||
| 205 | printk(KERN_EMERG "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n", | 210 | printk(KERN_EMERG "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n", |
| 206 | m->cpuvendor, m->cpuid, m->time, m->socketid, | 211 | m->cpuvendor, m->cpuid, m->time, m->socketid, |
| 207 | m->apicid); | 212 | m->apicid); |
| 213 | |||
| 214 | decode_mce(m); | ||
| 208 | } | 215 | } |
| 209 | 216 | ||
| 210 | static void print_mce_head(void) | 217 | static void print_mce_head(void) |
| @@ -215,7 +222,10 @@ static void print_mce_head(void) | |||
| 215 | static void print_mce_tail(void) | 222 | static void print_mce_tail(void) |
| 216 | { | 223 | { |
| 217 | printk(KERN_EMERG "This is not a software problem!\n" | 224 | printk(KERN_EMERG "This is not a software problem!\n" |
| 218 | "Run through mcelog --ascii to decode and contact your hardware vendor\n"); | 225 | #if (!defined(CONFIG_EDAC) || !defined(CONFIG_CPU_SUP_AMD)) |
| 226 | "Run through mcelog --ascii to decode and contact your hardware vendor\n" | ||
| 227 | #endif | ||
| 228 | ); | ||
| 219 | } | 229 | } |
| 220 | 230 | ||
| 221 | #define PANIC_TIMEOUT 5 /* 5 seconds */ | 231 | #define PANIC_TIMEOUT 5 /* 5 seconds */ |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index ddae21620bda..1fecba404fd8 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c | |||
| @@ -489,12 +489,14 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
| 489 | int i, err = 0; | 489 | int i, err = 0; |
| 490 | struct threshold_bank *b = NULL; | 490 | struct threshold_bank *b = NULL; |
| 491 | char name[32]; | 491 | char name[32]; |
| 492 | struct cpuinfo_x86 *c = &cpu_data(cpu); | ||
| 493 | |||
| 492 | 494 | ||
| 493 | sprintf(name, "threshold_bank%i", bank); | 495 | sprintf(name, "threshold_bank%i", bank); |
| 494 | 496 | ||
| 495 | #ifdef CONFIG_SMP | 497 | #ifdef CONFIG_SMP |
| 496 | if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) { /* symlink */ | 498 | if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) { /* symlink */ |
| 497 | i = cpumask_first(cpu_core_mask(cpu)); | 499 | i = cpumask_first(c->llc_shared_map); |
| 498 | 500 | ||
| 499 | /* first core not up yet */ | 501 | /* first core not up yet */ |
| 500 | if (cpu_data(i).cpu_core_id) | 502 | if (cpu_data(i).cpu_core_id) |
| @@ -514,7 +516,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
| 514 | if (err) | 516 | if (err) |
| 515 | goto out; | 517 | goto out; |
| 516 | 518 | ||
| 517 | cpumask_copy(b->cpus, cpu_core_mask(cpu)); | 519 | cpumask_copy(b->cpus, c->llc_shared_map); |
| 518 | per_cpu(threshold_banks, cpu)[bank] = b; | 520 | per_cpu(threshold_banks, cpu)[bank] = b; |
| 519 | 521 | ||
| 520 | goto out; | 522 | goto out; |
| @@ -539,7 +541,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank) | |||
| 539 | #ifndef CONFIG_SMP | 541 | #ifndef CONFIG_SMP |
| 540 | cpumask_setall(b->cpus); | 542 | cpumask_setall(b->cpus); |
| 541 | #else | 543 | #else |
| 542 | cpumask_copy(b->cpus, cpu_core_mask(cpu)); | 544 | cpumask_copy(b->cpus, c->llc_shared_map); |
| 543 | #endif | 545 | #endif |
| 544 | 546 | ||
| 545 | per_cpu(threshold_banks, cpu)[bank] = b; | 547 | per_cpu(threshold_banks, cpu)[bank] = b; |
diff --git a/arch/x86/kernel/cpu/mtrr/amd.c b/arch/x86/kernel/cpu/mtrr/amd.c index ee2331b0e58f..33af14110dfd 100644 --- a/arch/x86/kernel/cpu/mtrr/amd.c +++ b/arch/x86/kernel/cpu/mtrr/amd.c | |||
| @@ -7,15 +7,15 @@ | |||
| 7 | 7 | ||
| 8 | static void | 8 | static void |
| 9 | amd_get_mtrr(unsigned int reg, unsigned long *base, | 9 | amd_get_mtrr(unsigned int reg, unsigned long *base, |
| 10 | unsigned long *size, mtrr_type * type) | 10 | unsigned long *size, mtrr_type *type) |
| 11 | { | 11 | { |
| 12 | unsigned long low, high; | 12 | unsigned long low, high; |
| 13 | 13 | ||
| 14 | rdmsr(MSR_K6_UWCCR, low, high); | 14 | rdmsr(MSR_K6_UWCCR, low, high); |
| 15 | /* Upper dword is region 1, lower is region 0 */ | 15 | /* Upper dword is region 1, lower is region 0 */ |
| 16 | if (reg == 1) | 16 | if (reg == 1) |
| 17 | low = high; | 17 | low = high; |
| 18 | /* The base masks off on the right alignment */ | 18 | /* The base masks off on the right alignment */ |
| 19 | *base = (low & 0xFFFE0000) >> PAGE_SHIFT; | 19 | *base = (low & 0xFFFE0000) >> PAGE_SHIFT; |
| 20 | *type = 0; | 20 | *type = 0; |
| 21 | if (low & 1) | 21 | if (low & 1) |
| @@ -27,74 +27,81 @@ amd_get_mtrr(unsigned int reg, unsigned long *base, | |||
| 27 | return; | 27 | return; |
| 28 | } | 28 | } |
| 29 | /* | 29 | /* |
| 30 | * This needs a little explaining. The size is stored as an | 30 | * This needs a little explaining. The size is stored as an |
| 31 | * inverted mask of bits of 128K granularity 15 bits long offset | 31 | * inverted mask of bits of 128K granularity 15 bits long offset |
| 32 | * 2 bits | 32 | * 2 bits. |
| 33 | * | 33 | * |
| 34 | * So to get a size we do invert the mask and add 1 to the lowest | 34 | * So to get a size we do invert the mask and add 1 to the lowest |
| 35 | * mask bit (4 as its 2 bits in). This gives us a size we then shift | 35 | * mask bit (4 as its 2 bits in). This gives us a size we then shift |
| 36 | * to turn into 128K blocks | 36 | * to turn into 128K blocks. |
| 37 | * | 37 | * |
| 38 | * eg 111 1111 1111 1100 is 512K | 38 | * eg 111 1111 1111 1100 is 512K |
| 39 | * | 39 | * |
| 40 | * invert 000 0000 0000 0011 | 40 | * invert 000 0000 0000 0011 |
| 41 | * +1 000 0000 0000 0100 | 41 | * +1 000 0000 0000 0100 |
| 42 | * *128K ... | 42 | * *128K ... |
| 43 | */ | 43 | */ |
| 44 | low = (~low) & 0x1FFFC; | 44 | low = (~low) & 0x1FFFC; |
| 45 | *size = (low + 4) << (15 - PAGE_SHIFT); | 45 | *size = (low + 4) << (15 - PAGE_SHIFT); |
| 46 | return; | ||
| 47 | } | 46 | } |
| 48 | 47 | ||
| 49 | static void amd_set_mtrr(unsigned int reg, unsigned long base, | 48 | /** |
| 50 | unsigned long size, mtrr_type type) | 49 | * amd_set_mtrr - Set variable MTRR register on the local CPU. |
| 51 | /* [SUMMARY] Set variable MTRR register on the local CPU. | 50 | * |
| 52 | <reg> The register to set. | 51 | * @reg The register to set. |
| 53 | <base> The base address of the region. | 52 | * @base The base address of the region. |
| 54 | <size> The size of the region. If this is 0 the region is disabled. | 53 | * @size The size of the region. If this is 0 the region is disabled. |
| 55 | <type> The type of the region. | 54 | * @type The type of the region. |
| 56 | [RETURNS] Nothing. | 55 | * |
| 57 | */ | 56 | * Returns nothing. |
| 57 | */ | ||
| 58 | static void | ||
| 59 | amd_set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type) | ||
| 58 | { | 60 | { |
| 59 | u32 regs[2]; | 61 | u32 regs[2]; |
| 60 | 62 | ||
| 61 | /* | 63 | /* |
| 62 | * Low is MTRR0 , High MTRR 1 | 64 | * Low is MTRR0, High MTRR 1 |
| 63 | */ | 65 | */ |
| 64 | rdmsr(MSR_K6_UWCCR, regs[0], regs[1]); | 66 | rdmsr(MSR_K6_UWCCR, regs[0], regs[1]); |
| 65 | /* | 67 | /* |
| 66 | * Blank to disable | 68 | * Blank to disable |
| 67 | */ | 69 | */ |
| 68 | if (size == 0) | 70 | if (size == 0) { |
| 69 | regs[reg] = 0; | 71 | regs[reg] = 0; |
| 70 | else | 72 | } else { |
| 71 | /* Set the register to the base, the type (off by one) and an | 73 | /* |
| 72 | inverted bitmask of the size The size is the only odd | 74 | * Set the register to the base, the type (off by one) and an |
| 73 | bit. We are fed say 512K We invert this and we get 111 1111 | 75 | * inverted bitmask of the size The size is the only odd |
| 74 | 1111 1011 but if you subtract one and invert you get the | 76 | * bit. We are fed say 512K We invert this and we get 111 1111 |
| 75 | desired 111 1111 1111 1100 mask | 77 | * 1111 1011 but if you subtract one and invert you get the |
| 76 | 78 | * desired 111 1111 1111 1100 mask | |
| 77 | But ~(x - 1) == ~x + 1 == -x. Two's complement rocks! */ | 79 | * |
| 80 | * But ~(x - 1) == ~x + 1 == -x. Two's complement rocks! | ||
| 81 | */ | ||
| 78 | regs[reg] = (-size >> (15 - PAGE_SHIFT) & 0x0001FFFC) | 82 | regs[reg] = (-size >> (15 - PAGE_SHIFT) & 0x0001FFFC) |
| 79 | | (base << PAGE_SHIFT) | (type + 1); | 83 | | (base << PAGE_SHIFT) | (type + 1); |
| 84 | } | ||
| 80 | 85 | ||
| 81 | /* | 86 | /* |
| 82 | * The writeback rule is quite specific. See the manual. Its | 87 | * The writeback rule is quite specific. See the manual. Its |
| 83 | * disable local interrupts, write back the cache, set the mtrr | 88 | * disable local interrupts, write back the cache, set the mtrr |
| 84 | */ | 89 | */ |
| 85 | wbinvd(); | 90 | wbinvd(); |
| 86 | wrmsr(MSR_K6_UWCCR, regs[0], regs[1]); | 91 | wrmsr(MSR_K6_UWCCR, regs[0], regs[1]); |
| 87 | } | 92 | } |
| 88 | 93 | ||
| 89 | static int amd_validate_add_page(unsigned long base, unsigned long size, unsigned int type) | 94 | static int |
| 95 | amd_validate_add_page(unsigned long base, unsigned long size, unsigned int type) | ||
| 90 | { | 96 | { |
| 91 | /* Apply the K6 block alignment and size rules | 97 | /* |
| 92 | In order | 98 | * Apply the K6 block alignment and size rules |
| 93 | o Uncached or gathering only | 99 | * In order |
| 94 | o 128K or bigger block | 100 | * o Uncached or gathering only |
| 95 | o Power of 2 block | 101 | * o 128K or bigger block |
| 96 | o base suitably aligned to the power | 102 | * o Power of 2 block |
| 97 | */ | 103 | * o base suitably aligned to the power |
| 104 | */ | ||
| 98 | if (type > MTRR_TYPE_WRCOMB || size < (1 << (17 - PAGE_SHIFT)) | 105 | if (type > MTRR_TYPE_WRCOMB || size < (1 << (17 - PAGE_SHIFT)) |
| 99 | || (size & ~(size - 1)) - size || (base & (size - 1))) | 106 | || (size & ~(size - 1)) - size || (base & (size - 1))) |
| 100 | return -EINVAL; | 107 | return -EINVAL; |
| @@ -115,5 +122,3 @@ int __init amd_init_mtrr(void) | |||
| 115 | set_mtrr_ops(&amd_mtrr_ops); | 122 | set_mtrr_ops(&amd_mtrr_ops); |
| 116 | return 0; | 123 | return 0; |
| 117 | } | 124 | } |
| 118 | |||
| 119 | //arch_initcall(amd_mtrr_init); | ||
diff --git a/arch/x86/kernel/cpu/mtrr/centaur.c b/arch/x86/kernel/cpu/mtrr/centaur.c index cb9aa3a7a7ab..de89f14eff3a 100644 --- a/arch/x86/kernel/cpu/mtrr/centaur.c +++ b/arch/x86/kernel/cpu/mtrr/centaur.c | |||
| @@ -1,7 +1,9 @@ | |||
| 1 | #include <linux/init.h> | 1 | #include <linux/init.h> |
| 2 | #include <linux/mm.h> | 2 | #include <linux/mm.h> |
| 3 | |||
| 3 | #include <asm/mtrr.h> | 4 | #include <asm/mtrr.h> |
| 4 | #include <asm/msr.h> | 5 | #include <asm/msr.h> |
| 6 | |||
| 5 | #include "mtrr.h" | 7 | #include "mtrr.h" |
| 6 | 8 | ||
| 7 | static struct { | 9 | static struct { |
| @@ -12,25 +14,25 @@ static struct { | |||
| 12 | static u8 centaur_mcr_reserved; | 14 | static u8 centaur_mcr_reserved; |
| 13 | static u8 centaur_mcr_type; /* 0 for winchip, 1 for winchip2 */ | 15 | static u8 centaur_mcr_type; /* 0 for winchip, 1 for winchip2 */ |
| 14 | 16 | ||
| 15 | /* | 17 | /** |
| 16 | * Report boot time MCR setups | 18 | * centaur_get_free_region - Get a free MTRR. |
| 19 | * | ||
| 20 | * @base: The starting (base) address of the region. | ||
| 21 | * @size: The size (in bytes) of the region. | ||
| 22 | * | ||
| 23 | * Returns: the index of the region on success, else -1 on error. | ||
| 17 | */ | 24 | */ |
| 18 | |||
| 19 | static int | 25 | static int |
| 20 | centaur_get_free_region(unsigned long base, unsigned long size, int replace_reg) | 26 | centaur_get_free_region(unsigned long base, unsigned long size, int replace_reg) |
| 21 | /* [SUMMARY] Get a free MTRR. | ||
| 22 | <base> The starting (base) address of the region. | ||
| 23 | <size> The size (in bytes) of the region. | ||
| 24 | [RETURNS] The index of the region on success, else -1 on error. | ||
| 25 | */ | ||
| 26 | { | 27 | { |
| 27 | int i, max; | ||
| 28 | mtrr_type ltype; | ||
| 29 | unsigned long lbase, lsize; | 28 | unsigned long lbase, lsize; |
| 29 | mtrr_type ltype; | ||
| 30 | int i, max; | ||
| 30 | 31 | ||
| 31 | max = num_var_ranges; | 32 | max = num_var_ranges; |
| 32 | if (replace_reg >= 0 && replace_reg < max) | 33 | if (replace_reg >= 0 && replace_reg < max) |
| 33 | return replace_reg; | 34 | return replace_reg; |
| 35 | |||
| 34 | for (i = 0; i < max; ++i) { | 36 | for (i = 0; i < max; ++i) { |
| 35 | if (centaur_mcr_reserved & (1 << i)) | 37 | if (centaur_mcr_reserved & (1 << i)) |
| 36 | continue; | 38 | continue; |
| @@ -38,11 +40,14 @@ centaur_get_free_region(unsigned long base, unsigned long size, int replace_reg) | |||
| 38 | if (lsize == 0) | 40 | if (lsize == 0) |
| 39 | return i; | 41 | return i; |
| 40 | } | 42 | } |
| 43 | |||
| 41 | return -ENOSPC; | 44 | return -ENOSPC; |
| 42 | } | 45 | } |
| 43 | 46 | ||
| 44 | void | 47 | /* |
| 45 | mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) | 48 | * Report boot time MCR setups |
| 49 | */ | ||
| 50 | void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) | ||
| 46 | { | 51 | { |
| 47 | centaur_mcr[mcr].low = lo; | 52 | centaur_mcr[mcr].low = lo; |
| 48 | centaur_mcr[mcr].high = hi; | 53 | centaur_mcr[mcr].high = hi; |
| @@ -54,33 +59,35 @@ centaur_get_mcr(unsigned int reg, unsigned long *base, | |||
| 54 | { | 59 | { |
| 55 | *base = centaur_mcr[reg].high >> PAGE_SHIFT; | 60 | *base = centaur_mcr[reg].high >> PAGE_SHIFT; |
| 56 | *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT; | 61 | *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT; |
| 57 | *type = MTRR_TYPE_WRCOMB; /* If it is there, it is write-combining */ | 62 | *type = MTRR_TYPE_WRCOMB; /* write-combining */ |
| 63 | |||
| 58 | if (centaur_mcr_type == 1 && ((centaur_mcr[reg].low & 31) & 2)) | 64 | if (centaur_mcr_type == 1 && ((centaur_mcr[reg].low & 31) & 2)) |
| 59 | *type = MTRR_TYPE_UNCACHABLE; | 65 | *type = MTRR_TYPE_UNCACHABLE; |
| 60 | if (centaur_mcr_type == 1 && (centaur_mcr[reg].low & 31) == 25) | 66 | if (centaur_mcr_type == 1 && (centaur_mcr[reg].low & 31) == 25) |
| 61 | *type = MTRR_TYPE_WRBACK; | 67 | *type = MTRR_TYPE_WRBACK; |
| 62 | if (centaur_mcr_type == 0 && (centaur_mcr[reg].low & 31) == 31) | 68 | if (centaur_mcr_type == 0 && (centaur_mcr[reg].low & 31) == 31) |
| 63 | *type = MTRR_TYPE_WRBACK; | 69 | *type = MTRR_TYPE_WRBACK; |
| 64 | |||
| 65 | } | 70 | } |
| 66 | 71 | ||
| 67 | static void centaur_set_mcr(unsigned int reg, unsigned long base, | 72 | static void |
| 68 | unsigned long size, mtrr_type type) | 73 | centaur_set_mcr(unsigned int reg, unsigned long base, |
| 74 | unsigned long size, mtrr_type type) | ||
| 69 | { | 75 | { |
| 70 | unsigned long low, high; | 76 | unsigned long low, high; |
| 71 | 77 | ||
| 72 | if (size == 0) { | 78 | if (size == 0) { |
| 73 | /* Disable */ | 79 | /* Disable */ |
| 74 | high = low = 0; | 80 | high = low = 0; |
| 75 | } else { | 81 | } else { |
| 76 | high = base << PAGE_SHIFT; | 82 | high = base << PAGE_SHIFT; |
| 77 | if (centaur_mcr_type == 0) | 83 | if (centaur_mcr_type == 0) { |
| 78 | low = -size << PAGE_SHIFT | 0x1f; /* only support write-combining... */ | 84 | /* Only support write-combining... */ |
| 79 | else { | 85 | low = -size << PAGE_SHIFT | 0x1f; |
| 86 | } else { | ||
| 80 | if (type == MTRR_TYPE_UNCACHABLE) | 87 | if (type == MTRR_TYPE_UNCACHABLE) |
| 81 | low = -size << PAGE_SHIFT | 0x02; /* NC */ | 88 | low = -size << PAGE_SHIFT | 0x02; /* NC */ |
| 82 | else | 89 | else |
| 83 | low = -size << PAGE_SHIFT | 0x09; /* WWO,WC */ | 90 | low = -size << PAGE_SHIFT | 0x09; /* WWO, WC */ |
| 84 | } | 91 | } |
| 85 | } | 92 | } |
| 86 | centaur_mcr[reg].high = high; | 93 | centaur_mcr[reg].high = high; |
| @@ -88,118 +95,16 @@ static void centaur_set_mcr(unsigned int reg, unsigned long base, | |||
| 88 | wrmsr(MSR_IDT_MCR0 + reg, low, high); | 95 | wrmsr(MSR_IDT_MCR0 + reg, low, high); |
| 89 | } | 96 | } |
| 90 | 97 | ||
| 91 | #if 0 | 98 | static int |
| 92 | /* | 99 | centaur_validate_add_page(unsigned long base, unsigned long size, unsigned int type) |
| 93 | * Initialise the later (saner) Winchip MCR variant. In this version | ||
| 94 | * the BIOS can pass us the registers it has used (but not their values) | ||
| 95 | * and the control register is read/write | ||
| 96 | */ | ||
| 97 | |||
| 98 | static void __init | ||
| 99 | centaur_mcr1_init(void) | ||
| 100 | { | ||
| 101 | unsigned i; | ||
| 102 | u32 lo, hi; | ||
| 103 | |||
| 104 | /* Unfortunately, MCR's are read-only, so there is no way to | ||
| 105 | * find out what the bios might have done. | ||
| 106 | */ | ||
| 107 | |||
| 108 | rdmsr(MSR_IDT_MCR_CTRL, lo, hi); | ||
| 109 | if (((lo >> 17) & 7) == 1) { /* Type 1 Winchip2 MCR */ | ||
| 110 | lo &= ~0x1C0; /* clear key */ | ||
| 111 | lo |= 0x040; /* set key to 1 */ | ||
| 112 | wrmsr(MSR_IDT_MCR_CTRL, lo, hi); /* unlock MCR */ | ||
| 113 | } | ||
| 114 | |||
| 115 | centaur_mcr_type = 1; | ||
| 116 | |||
| 117 | /* | ||
| 118 | * Clear any unconfigured MCR's. | ||
| 119 | */ | ||
| 120 | |||
| 121 | for (i = 0; i < 8; ++i) { | ||
| 122 | if (centaur_mcr[i].high == 0 && centaur_mcr[i].low == 0) { | ||
| 123 | if (!(lo & (1 << (9 + i)))) | ||
| 124 | wrmsr(MSR_IDT_MCR0 + i, 0, 0); | ||
| 125 | else | ||
| 126 | /* | ||
| 127 | * If the BIOS set up an MCR we cannot see it | ||
| 128 | * but we don't wish to obliterate it | ||
| 129 | */ | ||
| 130 | centaur_mcr_reserved |= (1 << i); | ||
| 131 | } | ||
| 132 | } | ||
| 133 | /* | ||
| 134 | * Throw the main write-combining switch... | ||
| 135 | * However if OOSTORE is enabled then people have already done far | ||
| 136 | * cleverer things and we should behave. | ||
| 137 | */ | ||
| 138 | |||
| 139 | lo |= 15; /* Write combine enables */ | ||
| 140 | wrmsr(MSR_IDT_MCR_CTRL, lo, hi); | ||
| 141 | } | ||
| 142 | |||
| 143 | /* | ||
| 144 | * Initialise the original winchip with read only MCR registers | ||
| 145 | * no used bitmask for the BIOS to pass on and write only control | ||
| 146 | */ | ||
| 147 | |||
| 148 | static void __init | ||
| 149 | centaur_mcr0_init(void) | ||
| 150 | { | ||
| 151 | unsigned i; | ||
| 152 | |||
| 153 | /* Unfortunately, MCR's are read-only, so there is no way to | ||
| 154 | * find out what the bios might have done. | ||
| 155 | */ | ||
| 156 | |||
| 157 | /* Clear any unconfigured MCR's. | ||
| 158 | * This way we are sure that the centaur_mcr array contains the actual | ||
| 159 | * values. The disadvantage is that any BIOS tweaks are thus undone. | ||
| 160 | * | ||
| 161 | */ | ||
| 162 | for (i = 0; i < 8; ++i) { | ||
| 163 | if (centaur_mcr[i].high == 0 && centaur_mcr[i].low == 0) | ||
| 164 | wrmsr(MSR_IDT_MCR0 + i, 0, 0); | ||
| 165 | } | ||
| 166 | |||
| 167 | wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0); /* Write only */ | ||
| 168 | } | ||
| 169 | |||
| 170 | /* | ||
| 171 | * Initialise Winchip series MCR registers | ||
| 172 | */ | ||
| 173 | |||
| 174 | static void __init | ||
| 175 | centaur_mcr_init(void) | ||
| 176 | { | ||
| 177 | struct set_mtrr_context ctxt; | ||
| 178 | |||
| 179 | set_mtrr_prepare_save(&ctxt); | ||
| 180 | set_mtrr_cache_disable(&ctxt); | ||
| 181 | |||
| 182 | if (boot_cpu_data.x86_model == 4) | ||
| 183 | centaur_mcr0_init(); | ||
| 184 | else if (boot_cpu_data.x86_model == 8 || boot_cpu_data.x86_model == 9) | ||
| 185 | centaur_mcr1_init(); | ||
| 186 | |||
| 187 | set_mtrr_done(&ctxt); | ||
| 188 | } | ||
| 189 | #endif | ||
| 190 | |||
| 191 | static int centaur_validate_add_page(unsigned long base, | ||
| 192 | unsigned long size, unsigned int type) | ||
| 193 | { | 100 | { |
| 194 | /* | 101 | /* |
| 195 | * FIXME: Winchip2 supports uncached | 102 | * FIXME: Winchip2 supports uncached |
| 196 | */ | 103 | */ |
| 197 | if (type != MTRR_TYPE_WRCOMB && | 104 | if (type != MTRR_TYPE_WRCOMB && |
| 198 | (centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE)) { | 105 | (centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE)) { |
| 199 | printk(KERN_WARNING | 106 | pr_warning("mtrr: only write-combining%s supported\n", |
| 200 | "mtrr: only write-combining%s supported\n", | 107 | centaur_mcr_type ? " and uncacheable are" : " is"); |
| 201 | centaur_mcr_type ? " and uncacheable are" | ||
| 202 | : " is"); | ||
| 203 | return -EINVAL; | 108 | return -EINVAL; |
| 204 | } | 109 | } |
| 205 | return 0; | 110 | return 0; |
| @@ -207,7 +112,6 @@ static int centaur_validate_add_page(unsigned long base, | |||
| 207 | 112 | ||
| 208 | static struct mtrr_ops centaur_mtrr_ops = { | 113 | static struct mtrr_ops centaur_mtrr_ops = { |
| 209 | .vendor = X86_VENDOR_CENTAUR, | 114 | .vendor = X86_VENDOR_CENTAUR, |
| 210 | // .init = centaur_mcr_init, | ||
| 211 | .set = centaur_set_mcr, | 115 | .set = centaur_set_mcr, |
| 212 | .get = centaur_get_mcr, | 116 | .get = centaur_get_mcr, |
| 213 | .get_free_region = centaur_get_free_region, | 117 | .get_free_region = centaur_get_free_region, |
| @@ -220,5 +124,3 @@ int __init centaur_init_mtrr(void) | |||
| 220 | set_mtrr_ops(¢aur_mtrr_ops); | 124 | set_mtrr_ops(¢aur_mtrr_ops); |
| 221 | return 0; | 125 | return 0; |
| 222 | } | 126 | } |
| 223 | |||
| 224 | //arch_initcall(centaur_init_mtrr); | ||
diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c index 1d584a18a50d..315738c74aad 100644 --- a/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/arch/x86/kernel/cpu/mtrr/cleanup.c | |||
| @@ -1,51 +1,75 @@ | |||
| 1 | /* MTRR (Memory Type Range Register) cleanup | 1 | /* |
| 2 | 2 | * MTRR (Memory Type Range Register) cleanup | |
| 3 | Copyright (C) 2009 Yinghai Lu | 3 | * |
| 4 | 4 | * Copyright (C) 2009 Yinghai Lu | |
| 5 | This library is free software; you can redistribute it and/or | 5 | * |
| 6 | modify it under the terms of the GNU Library General Public | 6 | * This library is free software; you can redistribute it and/or |
| 7 | License as published by the Free Software Foundation; either | 7 | * modify it under the terms of the GNU Library General Public |
| 8 | version 2 of the License, or (at your option) any later version. | 8 | * License as published by the Free Software Foundation; either |
| 9 | 9 | * version 2 of the License, or (at your option) any later version. | |
| 10 | This library is distributed in the hope that it will be useful, | 10 | * |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * This library is distributed in the hope that it will be useful, |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | Library General Public License for more details. | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | 14 | * Library General Public License for more details. | |
| 15 | You should have received a copy of the GNU Library General Public | 15 | * |
| 16 | License along with this library; if not, write to the Free | 16 | * You should have received a copy of the GNU Library General Public |
| 17 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 17 | * License along with this library; if not, write to the Free |
| 18 | */ | 18 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 19 | 19 | */ | |
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
| 23 | #include <linux/smp.h> | 23 | #include <linux/smp.h> |
| 24 | #include <linux/cpu.h> | 24 | #include <linux/cpu.h> |
| 25 | #include <linux/mutex.h> | ||
| 26 | #include <linux/sort.h> | 25 | #include <linux/sort.h> |
| 26 | #include <linux/mutex.h> | ||
| 27 | #include <linux/uaccess.h> | ||
| 28 | #include <linux/kvm_para.h> | ||
| 27 | 29 | ||
| 30 | #include <asm/processor.h> | ||
| 28 | #include <asm/e820.h> | 31 | #include <asm/e820.h> |
| 29 | #include <asm/mtrr.h> | 32 | #include <asm/mtrr.h> |
| 30 | #include <asm/uaccess.h> | ||
| 31 | #include <asm/processor.h> | ||
| 32 | #include <asm/msr.h> | 33 | #include <asm/msr.h> |
| 33 | #include <asm/kvm_para.h> | ||
| 34 | #include "mtrr.h" | ||
| 35 | 34 | ||
| 36 | /* should be related to MTRR_VAR_RANGES nums */ | 35 | #include "mtrr.h" |
| 37 | #define RANGE_NUM 256 | ||
| 38 | 36 | ||
| 39 | struct res_range { | 37 | struct res_range { |
| 40 | unsigned long start; | 38 | unsigned long start; |
| 41 | unsigned long end; | 39 | unsigned long end; |
| 40 | }; | ||
| 41 | |||
| 42 | struct var_mtrr_range_state { | ||
| 43 | unsigned long base_pfn; | ||
| 44 | unsigned long size_pfn; | ||
| 45 | mtrr_type type; | ||
| 46 | }; | ||
| 47 | |||
| 48 | struct var_mtrr_state { | ||
| 49 | unsigned long range_startk; | ||
| 50 | unsigned long range_sizek; | ||
| 51 | unsigned long chunk_sizek; | ||
| 52 | unsigned long gran_sizek; | ||
| 53 | unsigned int reg; | ||
| 42 | }; | 54 | }; |
| 43 | 55 | ||
| 56 | /* Should be related to MTRR_VAR_RANGES nums */ | ||
| 57 | #define RANGE_NUM 256 | ||
| 58 | |||
| 59 | static struct res_range __initdata range[RANGE_NUM]; | ||
| 60 | static int __initdata nr_range; | ||
| 61 | |||
| 62 | static struct var_mtrr_range_state __initdata range_state[RANGE_NUM]; | ||
| 63 | |||
| 64 | static int __initdata debug_print; | ||
| 65 | #define Dprintk(x...) do { if (debug_print) printk(KERN_DEBUG x); } while (0) | ||
| 66 | |||
| 67 | |||
| 44 | static int __init | 68 | static int __init |
| 45 | add_range(struct res_range *range, int nr_range, unsigned long start, | 69 | add_range(struct res_range *range, int nr_range, |
| 46 | unsigned long end) | 70 | unsigned long start, unsigned long end) |
| 47 | { | 71 | { |
| 48 | /* out of slots */ | 72 | /* Out of slots: */ |
| 49 | if (nr_range >= RANGE_NUM) | 73 | if (nr_range >= RANGE_NUM) |
| 50 | return nr_range; | 74 | return nr_range; |
| 51 | 75 | ||
| @@ -58,12 +82,12 @@ add_range(struct res_range *range, int nr_range, unsigned long start, | |||
| 58 | } | 82 | } |
| 59 | 83 | ||
| 60 | static int __init | 84 | static int __init |
| 61 | add_range_with_merge(struct res_range *range, int nr_range, unsigned long start, | 85 | add_range_with_merge(struct res_range *range, int nr_range, |
| 62 | unsigned long end) | 86 | unsigned long start, unsigned long end) |
| 63 | { | 87 | { |
| 64 | int i; | 88 | int i; |
| 65 | 89 | ||
| 66 | /* try to merge it with old one */ | 90 | /* Try to merge it with old one: */ |
| 67 | for (i = 0; i < nr_range; i++) { | 91 | for (i = 0; i < nr_range; i++) { |
| 68 | unsigned long final_start, final_end; | 92 | unsigned long final_start, final_end; |
| 69 | unsigned long common_start, common_end; | 93 | unsigned long common_start, common_end; |
| @@ -84,7 +108,7 @@ add_range_with_merge(struct res_range *range, int nr_range, unsigned long start, | |||
| 84 | return nr_range; | 108 | return nr_range; |
| 85 | } | 109 | } |
| 86 | 110 | ||
| 87 | /* need to add that */ | 111 | /* Need to add it: */ |
| 88 | return add_range(range, nr_range, start, end); | 112 | return add_range(range, nr_range, start, end); |
| 89 | } | 113 | } |
| 90 | 114 | ||
| @@ -117,7 +141,7 @@ subtract_range(struct res_range *range, unsigned long start, unsigned long end) | |||
| 117 | } | 141 | } |
| 118 | 142 | ||
| 119 | if (start > range[j].start && end < range[j].end) { | 143 | if (start > range[j].start && end < range[j].end) { |
| 120 | /* find the new spare */ | 144 | /* Find the new spare: */ |
| 121 | for (i = 0; i < RANGE_NUM; i++) { | 145 | for (i = 0; i < RANGE_NUM; i++) { |
| 122 | if (range[i].end == 0) | 146 | if (range[i].end == 0) |
| 123 | break; | 147 | break; |
| @@ -146,14 +170,8 @@ static int __init cmp_range(const void *x1, const void *x2) | |||
| 146 | return start1 - start2; | 170 | return start1 - start2; |
| 147 | } | 171 | } |
| 148 | 172 | ||
| 149 | struct var_mtrr_range_state { | 173 | #define BIOS_BUG_MSG KERN_WARNING \ |
| 150 | unsigned long base_pfn; | 174 | "WARNING: BIOS bug: VAR MTRR %d contains strange UC entry under 1M, check with your system vendor!\n" |
| 151 | unsigned long size_pfn; | ||
| 152 | mtrr_type type; | ||
| 153 | }; | ||
| 154 | |||
| 155 | static struct var_mtrr_range_state __initdata range_state[RANGE_NUM]; | ||
| 156 | static int __initdata debug_print; | ||
| 157 | 175 | ||
| 158 | static int __init | 176 | static int __init |
| 159 | x86_get_mtrr_mem_range(struct res_range *range, int nr_range, | 177 | x86_get_mtrr_mem_range(struct res_range *range, int nr_range, |
| @@ -180,7 +198,7 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range, | |||
| 180 | range[i].start, range[i].end + 1); | 198 | range[i].start, range[i].end + 1); |
| 181 | } | 199 | } |
| 182 | 200 | ||
| 183 | /* take out UC ranges */ | 201 | /* Take out UC ranges: */ |
| 184 | for (i = 0; i < num_var_ranges; i++) { | 202 | for (i = 0; i < num_var_ranges; i++) { |
| 185 | type = range_state[i].type; | 203 | type = range_state[i].type; |
| 186 | if (type != MTRR_TYPE_UNCACHABLE && | 204 | if (type != MTRR_TYPE_UNCACHABLE && |
| @@ -193,9 +211,7 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range, | |||
| 193 | if (base < (1<<(20-PAGE_SHIFT)) && mtrr_state.have_fixed && | 211 | if (base < (1<<(20-PAGE_SHIFT)) && mtrr_state.have_fixed && |
| 194 | (mtrr_state.enabled & 1)) { | 212 | (mtrr_state.enabled & 1)) { |
| 195 | /* Var MTRR contains UC entry below 1M? Skip it: */ | 213 | /* Var MTRR contains UC entry below 1M? Skip it: */ |
| 196 | printk(KERN_WARNING "WARNING: BIOS bug: VAR MTRR %d " | 214 | printk(BIOS_BUG_MSG, i); |
| 197 | "contains strange UC entry under 1M, check " | ||
| 198 | "with your system vendor!\n", i); | ||
| 199 | if (base + size <= (1<<(20-PAGE_SHIFT))) | 215 | if (base + size <= (1<<(20-PAGE_SHIFT))) |
| 200 | continue; | 216 | continue; |
| 201 | size -= (1<<(20-PAGE_SHIFT)) - base; | 217 | size -= (1<<(20-PAGE_SHIFT)) - base; |
| @@ -237,17 +253,13 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range, | |||
| 237 | return nr_range; | 253 | return nr_range; |
| 238 | } | 254 | } |
| 239 | 255 | ||
| 240 | static struct res_range __initdata range[RANGE_NUM]; | ||
| 241 | static int __initdata nr_range; | ||
| 242 | |||
| 243 | #ifdef CONFIG_MTRR_SANITIZER | 256 | #ifdef CONFIG_MTRR_SANITIZER |
| 244 | 257 | ||
| 245 | static unsigned long __init sum_ranges(struct res_range *range, int nr_range) | 258 | static unsigned long __init sum_ranges(struct res_range *range, int nr_range) |
| 246 | { | 259 | { |
| 247 | unsigned long sum; | 260 | unsigned long sum = 0; |
| 248 | int i; | 261 | int i; |
| 249 | 262 | ||
| 250 | sum = 0; | ||
| 251 | for (i = 0; i < nr_range; i++) | 263 | for (i = 0; i < nr_range; i++) |
| 252 | sum += range[i].end + 1 - range[i].start; | 264 | sum += range[i].end + 1 - range[i].start; |
| 253 | 265 | ||
| @@ -278,17 +290,9 @@ static int __init mtrr_cleanup_debug_setup(char *str) | |||
| 278 | } | 290 | } |
| 279 | early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup); | 291 | early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup); |
| 280 | 292 | ||
| 281 | struct var_mtrr_state { | ||
| 282 | unsigned long range_startk; | ||
| 283 | unsigned long range_sizek; | ||
| 284 | unsigned long chunk_sizek; | ||
| 285 | unsigned long gran_sizek; | ||
| 286 | unsigned int reg; | ||
| 287 | }; | ||
| 288 | |||
| 289 | static void __init | 293 | static void __init |
| 290 | set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, | 294 | set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, |
| 291 | unsigned char type, unsigned int address_bits) | 295 | unsigned char type, unsigned int address_bits) |
| 292 | { | 296 | { |
| 293 | u32 base_lo, base_hi, mask_lo, mask_hi; | 297 | u32 base_lo, base_hi, mask_lo, mask_hi; |
| 294 | u64 base, mask; | 298 | u64 base, mask; |
| @@ -301,7 +305,7 @@ set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, | |||
| 301 | mask = (1ULL << address_bits) - 1; | 305 | mask = (1ULL << address_bits) - 1; |
| 302 | mask &= ~((((u64)sizek) << 10) - 1); | 306 | mask &= ~((((u64)sizek) << 10) - 1); |
| 303 | 307 | ||
| 304 | base = ((u64)basek) << 10; | 308 | base = ((u64)basek) << 10; |
| 305 | 309 | ||
| 306 | base |= type; | 310 | base |= type; |
| 307 | mask |= 0x800; | 311 | mask |= 0x800; |
| @@ -317,15 +321,14 @@ set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, | |||
| 317 | 321 | ||
| 318 | static void __init | 322 | static void __init |
| 319 | save_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, | 323 | save_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, |
| 320 | unsigned char type) | 324 | unsigned char type) |
| 321 | { | 325 | { |
| 322 | range_state[reg].base_pfn = basek >> (PAGE_SHIFT - 10); | 326 | range_state[reg].base_pfn = basek >> (PAGE_SHIFT - 10); |
| 323 | range_state[reg].size_pfn = sizek >> (PAGE_SHIFT - 10); | 327 | range_state[reg].size_pfn = sizek >> (PAGE_SHIFT - 10); |
| 324 | range_state[reg].type = type; | 328 | range_state[reg].type = type; |
| 325 | } | 329 | } |
| 326 | 330 | ||
| 327 | static void __init | 331 | static void __init set_var_mtrr_all(unsigned int address_bits) |
| 328 | set_var_mtrr_all(unsigned int address_bits) | ||
| 329 | { | 332 | { |
| 330 | unsigned long basek, sizek; | 333 | unsigned long basek, sizek; |
| 331 | unsigned char type; | 334 | unsigned char type; |
| @@ -342,11 +345,11 @@ set_var_mtrr_all(unsigned int address_bits) | |||
| 342 | 345 | ||
| 343 | static unsigned long to_size_factor(unsigned long sizek, char *factorp) | 346 | static unsigned long to_size_factor(unsigned long sizek, char *factorp) |
| 344 | { | 347 | { |
| 345 | char factor; | ||
| 346 | unsigned long base = sizek; | 348 | unsigned long base = sizek; |
| 349 | char factor; | ||
| 347 | 350 | ||
| 348 | if (base & ((1<<10) - 1)) { | 351 | if (base & ((1<<10) - 1)) { |
| 349 | /* not MB alignment */ | 352 | /* Not MB-aligned: */ |
| 350 | factor = 'K'; | 353 | factor = 'K'; |
| 351 | } else if (base & ((1<<20) - 1)) { | 354 | } else if (base & ((1<<20) - 1)) { |
| 352 | factor = 'M'; | 355 | factor = 'M'; |
| @@ -372,11 +375,12 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk, | |||
| 372 | unsigned long max_align, align; | 375 | unsigned long max_align, align; |
| 373 | unsigned long sizek; | 376 | unsigned long sizek; |
| 374 | 377 | ||
| 375 | /* Compute the maximum size I can make a range */ | 378 | /* Compute the maximum size with which we can make a range: */ |
| 376 | if (range_startk) | 379 | if (range_startk) |
| 377 | max_align = ffs(range_startk) - 1; | 380 | max_align = ffs(range_startk) - 1; |
| 378 | else | 381 | else |
| 379 | max_align = 32; | 382 | max_align = 32; |
| 383 | |||
| 380 | align = fls(range_sizek) - 1; | 384 | align = fls(range_sizek) - 1; |
| 381 | if (align > max_align) | 385 | if (align > max_align) |
| 382 | align = max_align; | 386 | align = max_align; |
| @@ -386,11 +390,10 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk, | |||
| 386 | char start_factor = 'K', size_factor = 'K'; | 390 | char start_factor = 'K', size_factor = 'K'; |
| 387 | unsigned long start_base, size_base; | 391 | unsigned long start_base, size_base; |
| 388 | 392 | ||
| 389 | start_base = to_size_factor(range_startk, | 393 | start_base = to_size_factor(range_startk, &start_factor); |
| 390 | &start_factor), | 394 | size_base = to_size_factor(sizek, &size_factor); |
| 391 | size_base = to_size_factor(sizek, &size_factor), | ||
| 392 | 395 | ||
| 393 | printk(KERN_DEBUG "Setting variable MTRR %d, " | 396 | Dprintk("Setting variable MTRR %d, " |
| 394 | "base: %ld%cB, range: %ld%cB, type %s\n", | 397 | "base: %ld%cB, range: %ld%cB, type %s\n", |
| 395 | reg, start_base, start_factor, | 398 | reg, start_base, start_factor, |
| 396 | size_base, size_factor, | 399 | size_base, size_factor, |
| @@ -425,10 +428,11 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek, | |||
| 425 | chunk_sizek = state->chunk_sizek; | 428 | chunk_sizek = state->chunk_sizek; |
| 426 | gran_sizek = state->gran_sizek; | 429 | gran_sizek = state->gran_sizek; |
| 427 | 430 | ||
| 428 | /* align with gran size, prevent small block used up MTRRs */ | 431 | /* Align with gran size, prevent small block used up MTRRs: */ |
| 429 | range_basek = ALIGN(state->range_startk, gran_sizek); | 432 | range_basek = ALIGN(state->range_startk, gran_sizek); |
| 430 | if ((range_basek > basek) && basek) | 433 | if ((range_basek > basek) && basek) |
| 431 | return second_sizek; | 434 | return second_sizek; |
| 435 | |||
| 432 | state->range_sizek -= (range_basek - state->range_startk); | 436 | state->range_sizek -= (range_basek - state->range_startk); |
| 433 | range_sizek = ALIGN(state->range_sizek, gran_sizek); | 437 | range_sizek = ALIGN(state->range_sizek, gran_sizek); |
| 434 | 438 | ||
| @@ -439,22 +443,21 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek, | |||
| 439 | } | 443 | } |
| 440 | state->range_sizek = range_sizek; | 444 | state->range_sizek = range_sizek; |
| 441 | 445 | ||
| 442 | /* try to append some small hole */ | 446 | /* Try to append some small hole: */ |
| 443 | range0_basek = state->range_startk; | 447 | range0_basek = state->range_startk; |
| 444 | range0_sizek = ALIGN(state->range_sizek, chunk_sizek); | 448 | range0_sizek = ALIGN(state->range_sizek, chunk_sizek); |
| 445 | 449 | ||
| 446 | /* no increase */ | 450 | /* No increase: */ |
| 447 | if (range0_sizek == state->range_sizek) { | 451 | if (range0_sizek == state->range_sizek) { |
| 448 | if (debug_print) | 452 | Dprintk("rangeX: %016lx - %016lx\n", |
| 449 | printk(KERN_DEBUG "rangeX: %016lx - %016lx\n", | 453 | range0_basek<<10, |
| 450 | range0_basek<<10, | 454 | (range0_basek + state->range_sizek)<<10); |
| 451 | (range0_basek + state->range_sizek)<<10); | ||
| 452 | state->reg = range_to_mtrr(state->reg, range0_basek, | 455 | state->reg = range_to_mtrr(state->reg, range0_basek, |
| 453 | state->range_sizek, MTRR_TYPE_WRBACK); | 456 | state->range_sizek, MTRR_TYPE_WRBACK); |
| 454 | return 0; | 457 | return 0; |
| 455 | } | 458 | } |
| 456 | 459 | ||
| 457 | /* only cut back, when it is not the last */ | 460 | /* Only cut back when it is not the last: */ |
| 458 | if (sizek) { | 461 | if (sizek) { |
| 459 | while (range0_basek + range0_sizek > (basek + sizek)) { | 462 | while (range0_basek + range0_sizek > (basek + sizek)) { |
| 460 | if (range0_sizek >= chunk_sizek) | 463 | if (range0_sizek >= chunk_sizek) |
| @@ -470,16 +473,16 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek, | |||
| 470 | second_try: | 473 | second_try: |
| 471 | range_basek = range0_basek + range0_sizek; | 474 | range_basek = range0_basek + range0_sizek; |
| 472 | 475 | ||
| 473 | /* one hole in the middle */ | 476 | /* One hole in the middle: */ |
| 474 | if (range_basek > basek && range_basek <= (basek + sizek)) | 477 | if (range_basek > basek && range_basek <= (basek + sizek)) |
| 475 | second_sizek = range_basek - basek; | 478 | second_sizek = range_basek - basek; |
| 476 | 479 | ||
| 477 | if (range0_sizek > state->range_sizek) { | 480 | if (range0_sizek > state->range_sizek) { |
| 478 | 481 | ||
| 479 | /* one hole in middle or at end */ | 482 | /* One hole in middle or at the end: */ |
| 480 | hole_sizek = range0_sizek - state->range_sizek - second_sizek; | 483 | hole_sizek = range0_sizek - state->range_sizek - second_sizek; |
| 481 | 484 | ||
| 482 | /* hole size should be less than half of range0 size */ | 485 | /* Hole size should be less than half of range0 size: */ |
| 483 | if (hole_sizek >= (range0_sizek >> 1) && | 486 | if (hole_sizek >= (range0_sizek >> 1) && |
| 484 | range0_sizek >= chunk_sizek) { | 487 | range0_sizek >= chunk_sizek) { |
| 485 | range0_sizek -= chunk_sizek; | 488 | range0_sizek -= chunk_sizek; |
| @@ -491,32 +494,30 @@ second_try: | |||
| 491 | } | 494 | } |
| 492 | 495 | ||
| 493 | if (range0_sizek) { | 496 | if (range0_sizek) { |
| 494 | if (debug_print) | 497 | Dprintk("range0: %016lx - %016lx\n", |
| 495 | printk(KERN_DEBUG "range0: %016lx - %016lx\n", | 498 | range0_basek<<10, |
| 496 | range0_basek<<10, | 499 | (range0_basek + range0_sizek)<<10); |
| 497 | (range0_basek + range0_sizek)<<10); | ||
| 498 | state->reg = range_to_mtrr(state->reg, range0_basek, | 500 | state->reg = range_to_mtrr(state->reg, range0_basek, |
| 499 | range0_sizek, MTRR_TYPE_WRBACK); | 501 | range0_sizek, MTRR_TYPE_WRBACK); |
| 500 | } | 502 | } |
| 501 | 503 | ||
| 502 | if (range0_sizek < state->range_sizek) { | 504 | if (range0_sizek < state->range_sizek) { |
| 503 | /* need to handle left over */ | 505 | /* Need to handle left over range: */ |
| 504 | range_sizek = state->range_sizek - range0_sizek; | 506 | range_sizek = state->range_sizek - range0_sizek; |
| 505 | 507 | ||
| 506 | if (debug_print) | 508 | Dprintk("range: %016lx - %016lx\n", |
| 507 | printk(KERN_DEBUG "range: %016lx - %016lx\n", | 509 | range_basek<<10, |
| 508 | range_basek<<10, | 510 | (range_basek + range_sizek)<<10); |
| 509 | (range_basek + range_sizek)<<10); | 511 | |
| 510 | state->reg = range_to_mtrr(state->reg, range_basek, | 512 | state->reg = range_to_mtrr(state->reg, range_basek, |
| 511 | range_sizek, MTRR_TYPE_WRBACK); | 513 | range_sizek, MTRR_TYPE_WRBACK); |
| 512 | } | 514 | } |
| 513 | 515 | ||
| 514 | if (hole_sizek) { | 516 | if (hole_sizek) { |
| 515 | hole_basek = range_basek - hole_sizek - second_sizek; | 517 | hole_basek = range_basek - hole_sizek - second_sizek; |
| 516 | if (debug_print) | 518 | Dprintk("hole: %016lx - %016lx\n", |
| 517 | printk(KERN_DEBUG "hole: %016lx - %016lx\n", | 519 | hole_basek<<10, |
| 518 | hole_basek<<10, | 520 | (hole_basek + hole_sizek)<<10); |
| 519 | (hole_basek + hole_sizek)<<10); | ||
| 520 | state->reg = range_to_mtrr(state->reg, hole_basek, | 521 | state->reg = range_to_mtrr(state->reg, hole_basek, |
| 521 | hole_sizek, MTRR_TYPE_UNCACHABLE); | 522 | hole_sizek, MTRR_TYPE_UNCACHABLE); |
| 522 | } | 523 | } |
| @@ -537,23 +538,23 @@ set_var_mtrr_range(struct var_mtrr_state *state, unsigned long base_pfn, | |||
| 537 | basek = base_pfn << (PAGE_SHIFT - 10); | 538 | basek = base_pfn << (PAGE_SHIFT - 10); |
| 538 | sizek = size_pfn << (PAGE_SHIFT - 10); | 539 | sizek = size_pfn << (PAGE_SHIFT - 10); |
| 539 | 540 | ||
| 540 | /* See if I can merge with the last range */ | 541 | /* See if I can merge with the last range: */ |
| 541 | if ((basek <= 1024) || | 542 | if ((basek <= 1024) || |
| 542 | (state->range_startk + state->range_sizek == basek)) { | 543 | (state->range_startk + state->range_sizek == basek)) { |
| 543 | unsigned long endk = basek + sizek; | 544 | unsigned long endk = basek + sizek; |
| 544 | state->range_sizek = endk - state->range_startk; | 545 | state->range_sizek = endk - state->range_startk; |
| 545 | return; | 546 | return; |
| 546 | } | 547 | } |
| 547 | /* Write the range mtrrs */ | 548 | /* Write the range mtrrs: */ |
| 548 | if (state->range_sizek != 0) | 549 | if (state->range_sizek != 0) |
| 549 | second_sizek = range_to_mtrr_with_hole(state, basek, sizek); | 550 | second_sizek = range_to_mtrr_with_hole(state, basek, sizek); |
| 550 | 551 | ||
| 551 | /* Allocate an msr */ | 552 | /* Allocate an msr: */ |
| 552 | state->range_startk = basek + second_sizek; | 553 | state->range_startk = basek + second_sizek; |
| 553 | state->range_sizek = sizek - second_sizek; | 554 | state->range_sizek = sizek - second_sizek; |
| 554 | } | 555 | } |
| 555 | 556 | ||
| 556 | /* mininum size of mtrr block that can take hole */ | 557 | /* Mininum size of mtrr block that can take hole: */ |
| 557 | static u64 mtrr_chunk_size __initdata = (256ULL<<20); | 558 | static u64 mtrr_chunk_size __initdata = (256ULL<<20); |
| 558 | 559 | ||
| 559 | static int __init parse_mtrr_chunk_size_opt(char *p) | 560 | static int __init parse_mtrr_chunk_size_opt(char *p) |
| @@ -565,7 +566,7 @@ static int __init parse_mtrr_chunk_size_opt(char *p) | |||
| 565 | } | 566 | } |
| 566 | early_param("mtrr_chunk_size", parse_mtrr_chunk_size_opt); | 567 | early_param("mtrr_chunk_size", parse_mtrr_chunk_size_opt); |
| 567 | 568 | ||
| 568 | /* granity of mtrr of block */ | 569 | /* Granularity of mtrr of block: */ |
| 569 | static u64 mtrr_gran_size __initdata; | 570 | static u64 mtrr_gran_size __initdata; |
| 570 | 571 | ||
| 571 | static int __init parse_mtrr_gran_size_opt(char *p) | 572 | static int __init parse_mtrr_gran_size_opt(char *p) |
| @@ -577,7 +578,7 @@ static int __init parse_mtrr_gran_size_opt(char *p) | |||
| 577 | } | 578 | } |
| 578 | early_param("mtrr_gran_size", parse_mtrr_gran_size_opt); | 579 | early_param("mtrr_gran_size", parse_mtrr_gran_size_opt); |
| 579 | 580 | ||
| 580 | static int nr_mtrr_spare_reg __initdata = | 581 | static unsigned long nr_mtrr_spare_reg __initdata = |
| 581 | CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT; | 582 | CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT; |
| 582 | 583 | ||
| 583 | static int __init parse_mtrr_spare_reg(char *arg) | 584 | static int __init parse_mtrr_spare_reg(char *arg) |
| @@ -586,7 +587,6 @@ static int __init parse_mtrr_spare_reg(char *arg) | |||
| 586 | nr_mtrr_spare_reg = simple_strtoul(arg, NULL, 0); | 587 | nr_mtrr_spare_reg = simple_strtoul(arg, NULL, 0); |
| 587 | return 0; | 588 | return 0; |
| 588 | } | 589 | } |
| 589 | |||
| 590 | early_param("mtrr_spare_reg_nr", parse_mtrr_spare_reg); | 590 | early_param("mtrr_spare_reg_nr", parse_mtrr_spare_reg); |
| 591 | 591 | ||
| 592 | static int __init | 592 | static int __init |
| @@ -594,8 +594,8 @@ x86_setup_var_mtrrs(struct res_range *range, int nr_range, | |||
| 594 | u64 chunk_size, u64 gran_size) | 594 | u64 chunk_size, u64 gran_size) |
| 595 | { | 595 | { |
| 596 | struct var_mtrr_state var_state; | 596 | struct var_mtrr_state var_state; |
| 597 | int i; | ||
| 598 | int num_reg; | 597 | int num_reg; |
| 598 | int i; | ||
| 599 | 599 | ||
| 600 | var_state.range_startk = 0; | 600 | var_state.range_startk = 0; |
| 601 | var_state.range_sizek = 0; | 601 | var_state.range_sizek = 0; |
| @@ -605,17 +605,18 @@ x86_setup_var_mtrrs(struct res_range *range, int nr_range, | |||
| 605 | 605 | ||
| 606 | memset(range_state, 0, sizeof(range_state)); | 606 | memset(range_state, 0, sizeof(range_state)); |
| 607 | 607 | ||
| 608 | /* Write the range etc */ | 608 | /* Write the range: */ |
| 609 | for (i = 0; i < nr_range; i++) | 609 | for (i = 0; i < nr_range; i++) { |
| 610 | set_var_mtrr_range(&var_state, range[i].start, | 610 | set_var_mtrr_range(&var_state, range[i].start, |
| 611 | range[i].end - range[i].start + 1); | 611 | range[i].end - range[i].start + 1); |
| 612 | } | ||
| 612 | 613 | ||
| 613 | /* Write the last range */ | 614 | /* Write the last range: */ |
| 614 | if (var_state.range_sizek != 0) | 615 | if (var_state.range_sizek != 0) |
| 615 | range_to_mtrr_with_hole(&var_state, 0, 0); | 616 | range_to_mtrr_with_hole(&var_state, 0, 0); |
| 616 | 617 | ||
| 617 | num_reg = var_state.reg; | 618 | num_reg = var_state.reg; |
| 618 | /* Clear out the extra MTRR's */ | 619 | /* Clear out the extra MTRR's: */ |
| 619 | while (var_state.reg < num_var_ranges) { | 620 | while (var_state.reg < num_var_ranges) { |
| 620 | save_var_mtrr(var_state.reg, 0, 0, 0); | 621 | save_var_mtrr(var_state.reg, 0, 0, 0); |
| 621 | var_state.reg++; | 622 | var_state.reg++; |
| @@ -625,11 +626,11 @@ x86_setup_var_mtrrs(struct res_range *range, int nr_range, | |||
| 625 | } | 626 | } |
| 626 | 627 | ||
| 627 | struct mtrr_cleanup_result { | 628 | struct mtrr_cleanup_result { |
| 628 | unsigned long gran_sizek; | 629 | unsigned long gran_sizek; |
| 629 | unsigned long chunk_sizek; | 630 | unsigned long chunk_sizek; |
| 630 | unsigned long lose_cover_sizek; | 631 | unsigned long lose_cover_sizek; |
| 631 | unsigned int num_reg; | 632 | unsigned int num_reg; |
| 632 | int bad; | 633 | int bad; |
| 633 | }; | 634 | }; |
| 634 | 635 | ||
| 635 | /* | 636 | /* |
| @@ -645,10 +646,10 @@ static unsigned long __initdata min_loss_pfn[RANGE_NUM]; | |||
| 645 | 646 | ||
| 646 | static void __init print_out_mtrr_range_state(void) | 647 | static void __init print_out_mtrr_range_state(void) |
| 647 | { | 648 | { |
| 648 | int i; | ||
| 649 | char start_factor = 'K', size_factor = 'K'; | 649 | char start_factor = 'K', size_factor = 'K'; |
| 650 | unsigned long start_base, size_base; | 650 | unsigned long start_base, size_base; |
| 651 | mtrr_type type; | 651 | mtrr_type type; |
| 652 | int i; | ||
| 652 | 653 | ||
| 653 | for (i = 0; i < num_var_ranges; i++) { | 654 | for (i = 0; i < num_var_ranges; i++) { |
| 654 | 655 | ||
| @@ -676,10 +677,10 @@ static int __init mtrr_need_cleanup(void) | |||
| 676 | int i; | 677 | int i; |
| 677 | mtrr_type type; | 678 | mtrr_type type; |
| 678 | unsigned long size; | 679 | unsigned long size; |
| 679 | /* extra one for all 0 */ | 680 | /* Extra one for all 0: */ |
| 680 | int num[MTRR_NUM_TYPES + 1]; | 681 | int num[MTRR_NUM_TYPES + 1]; |
| 681 | 682 | ||
| 682 | /* check entries number */ | 683 | /* Check entries number: */ |
| 683 | memset(num, 0, sizeof(num)); | 684 | memset(num, 0, sizeof(num)); |
| 684 | for (i = 0; i < num_var_ranges; i++) { | 685 | for (i = 0; i < num_var_ranges; i++) { |
| 685 | type = range_state[i].type; | 686 | type = range_state[i].type; |
| @@ -693,88 +694,86 @@ static int __init mtrr_need_cleanup(void) | |||
| 693 | num[type]++; | 694 | num[type]++; |
| 694 | } | 695 | } |
| 695 | 696 | ||
| 696 | /* check if we got UC entries */ | 697 | /* Check if we got UC entries: */ |
| 697 | if (!num[MTRR_TYPE_UNCACHABLE]) | 698 | if (!num[MTRR_TYPE_UNCACHABLE]) |
| 698 | return 0; | 699 | return 0; |
| 699 | 700 | ||
| 700 | /* check if we only had WB and UC */ | 701 | /* Check if we only had WB and UC */ |
| 701 | if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] != | 702 | if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] != |
| 702 | num_var_ranges - num[MTRR_NUM_TYPES]) | 703 | num_var_ranges - num[MTRR_NUM_TYPES]) |
| 703 | return 0; | 704 | return 0; |
| 704 | 705 | ||
| 705 | return 1; | 706 | return 1; |
| 706 | } | 707 | } |
| 707 | 708 | ||
| 708 | static unsigned long __initdata range_sums; | 709 | static unsigned long __initdata range_sums; |
| 709 | static void __init mtrr_calc_range_state(u64 chunk_size, u64 gran_size, | 710 | |
| 710 | unsigned long extra_remove_base, | 711 | static void __init |
| 711 | unsigned long extra_remove_size, | 712 | mtrr_calc_range_state(u64 chunk_size, u64 gran_size, |
| 712 | int i) | 713 | unsigned long x_remove_base, |
| 714 | unsigned long x_remove_size, int i) | ||
| 713 | { | 715 | { |
| 714 | int num_reg; | ||
| 715 | static struct res_range range_new[RANGE_NUM]; | 716 | static struct res_range range_new[RANGE_NUM]; |
| 716 | static int nr_range_new; | ||
| 717 | unsigned long range_sums_new; | 717 | unsigned long range_sums_new; |
| 718 | static int nr_range_new; | ||
| 719 | int num_reg; | ||
| 718 | 720 | ||
| 719 | /* convert ranges to var ranges state */ | 721 | /* Convert ranges to var ranges state: */ |
| 720 | num_reg = x86_setup_var_mtrrs(range, nr_range, | 722 | num_reg = x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size); |
| 721 | chunk_size, gran_size); | ||
| 722 | 723 | ||
| 723 | /* we got new setting in range_state, check it */ | 724 | /* We got new setting in range_state, check it: */ |
| 724 | memset(range_new, 0, sizeof(range_new)); | 725 | memset(range_new, 0, sizeof(range_new)); |
| 725 | nr_range_new = x86_get_mtrr_mem_range(range_new, 0, | 726 | nr_range_new = x86_get_mtrr_mem_range(range_new, 0, |
| 726 | extra_remove_base, extra_remove_size); | 727 | x_remove_base, x_remove_size); |
| 727 | range_sums_new = sum_ranges(range_new, nr_range_new); | 728 | range_sums_new = sum_ranges(range_new, nr_range_new); |
| 728 | 729 | ||
| 729 | result[i].chunk_sizek = chunk_size >> 10; | 730 | result[i].chunk_sizek = chunk_size >> 10; |
| 730 | result[i].gran_sizek = gran_size >> 10; | 731 | result[i].gran_sizek = gran_size >> 10; |
| 731 | result[i].num_reg = num_reg; | 732 | result[i].num_reg = num_reg; |
| 733 | |||
| 732 | if (range_sums < range_sums_new) { | 734 | if (range_sums < range_sums_new) { |
| 733 | result[i].lose_cover_sizek = | 735 | result[i].lose_cover_sizek = (range_sums_new - range_sums) << PSHIFT; |
| 734 | (range_sums_new - range_sums) << PSHIFT; | ||
| 735 | result[i].bad = 1; | 736 | result[i].bad = 1; |
| 736 | } else | 737 | } else { |
| 737 | result[i].lose_cover_sizek = | 738 | result[i].lose_cover_sizek = (range_sums - range_sums_new) << PSHIFT; |
| 738 | (range_sums - range_sums_new) << PSHIFT; | 739 | } |
| 739 | 740 | ||
| 740 | /* double check it */ | 741 | /* Double check it: */ |
| 741 | if (!result[i].bad && !result[i].lose_cover_sizek) { | 742 | if (!result[i].bad && !result[i].lose_cover_sizek) { |
| 742 | if (nr_range_new != nr_range || | 743 | if (nr_range_new != nr_range || memcmp(range, range_new, sizeof(range))) |
| 743 | memcmp(range, range_new, sizeof(range))) | 744 | result[i].bad = 1; |
| 744 | result[i].bad = 1; | ||
| 745 | } | 745 | } |
| 746 | 746 | ||
| 747 | if (!result[i].bad && (range_sums - range_sums_new < | 747 | if (!result[i].bad && (range_sums - range_sums_new < min_loss_pfn[num_reg])) |
| 748 | min_loss_pfn[num_reg])) { | 748 | min_loss_pfn[num_reg] = range_sums - range_sums_new; |
| 749 | min_loss_pfn[num_reg] = | ||
| 750 | range_sums - range_sums_new; | ||
| 751 | } | ||
| 752 | } | 749 | } |
| 753 | 750 | ||
| 754 | static void __init mtrr_print_out_one_result(int i) | 751 | static void __init mtrr_print_out_one_result(int i) |
| 755 | { | 752 | { |
| 756 | char gran_factor, chunk_factor, lose_factor; | ||
| 757 | unsigned long gran_base, chunk_base, lose_base; | 753 | unsigned long gran_base, chunk_base, lose_base; |
| 754 | char gran_factor, chunk_factor, lose_factor; | ||
| 758 | 755 | ||
| 759 | gran_base = to_size_factor(result[i].gran_sizek, &gran_factor), | 756 | gran_base = to_size_factor(result[i].gran_sizek, &gran_factor), |
| 760 | chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor), | 757 | chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor), |
| 761 | lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor), | 758 | lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor), |
| 762 | printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t", | 759 | |
| 763 | result[i].bad ? "*BAD*" : " ", | 760 | pr_info("%sgran_size: %ld%c \tchunk_size: %ld%c \t", |
| 764 | gran_base, gran_factor, chunk_base, chunk_factor); | 761 | result[i].bad ? "*BAD*" : " ", |
| 765 | printk(KERN_CONT "num_reg: %d \tlose cover RAM: %s%ld%c\n", | 762 | gran_base, gran_factor, chunk_base, chunk_factor); |
| 766 | result[i].num_reg, result[i].bad ? "-" : "", | 763 | pr_cont("num_reg: %d \tlose cover RAM: %s%ld%c\n", |
| 767 | lose_base, lose_factor); | 764 | result[i].num_reg, result[i].bad ? "-" : "", |
| 765 | lose_base, lose_factor); | ||
| 768 | } | 766 | } |
| 769 | 767 | ||
| 770 | static int __init mtrr_search_optimal_index(void) | 768 | static int __init mtrr_search_optimal_index(void) |
| 771 | { | 769 | { |
| 772 | int i; | ||
| 773 | int num_reg_good; | 770 | int num_reg_good; |
| 774 | int index_good; | 771 | int index_good; |
| 772 | int i; | ||
| 775 | 773 | ||
| 776 | if (nr_mtrr_spare_reg >= num_var_ranges) | 774 | if (nr_mtrr_spare_reg >= num_var_ranges) |
| 777 | nr_mtrr_spare_reg = num_var_ranges - 1; | 775 | nr_mtrr_spare_reg = num_var_ranges - 1; |
| 776 | |||
| 778 | num_reg_good = -1; | 777 | num_reg_good = -1; |
| 779 | for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) { | 778 | for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) { |
| 780 | if (!min_loss_pfn[i]) | 779 | if (!min_loss_pfn[i]) |
| @@ -796,24 +795,24 @@ static int __init mtrr_search_optimal_index(void) | |||
| 796 | return index_good; | 795 | return index_good; |
| 797 | } | 796 | } |
| 798 | 797 | ||
| 799 | |||
| 800 | int __init mtrr_cleanup(unsigned address_bits) | 798 | int __init mtrr_cleanup(unsigned address_bits) |
| 801 | { | 799 | { |
| 802 | unsigned long extra_remove_base, extra_remove_size; | 800 | unsigned long x_remove_base, x_remove_size; |
| 803 | unsigned long base, size, def, dummy; | 801 | unsigned long base, size, def, dummy; |
| 804 | mtrr_type type; | ||
| 805 | u64 chunk_size, gran_size; | 802 | u64 chunk_size, gran_size; |
| 803 | mtrr_type type; | ||
| 806 | int index_good; | 804 | int index_good; |
| 807 | int i; | 805 | int i; |
| 808 | 806 | ||
| 809 | if (!is_cpu(INTEL) || enable_mtrr_cleanup < 1) | 807 | if (!is_cpu(INTEL) || enable_mtrr_cleanup < 1) |
| 810 | return 0; | 808 | return 0; |
| 809 | |||
| 811 | rdmsr(MSR_MTRRdefType, def, dummy); | 810 | rdmsr(MSR_MTRRdefType, def, dummy); |
| 812 | def &= 0xff; | 811 | def &= 0xff; |
| 813 | if (def != MTRR_TYPE_UNCACHABLE) | 812 | if (def != MTRR_TYPE_UNCACHABLE) |
| 814 | return 0; | 813 | return 0; |
| 815 | 814 | ||
| 816 | /* get it and store it aside */ | 815 | /* Get it and store it aside: */ |
| 817 | memset(range_state, 0, sizeof(range_state)); | 816 | memset(range_state, 0, sizeof(range_state)); |
| 818 | for (i = 0; i < num_var_ranges; i++) { | 817 | for (i = 0; i < num_var_ranges; i++) { |
| 819 | mtrr_if->get(i, &base, &size, &type); | 818 | mtrr_if->get(i, &base, &size, &type); |
| @@ -822,29 +821,28 @@ int __init mtrr_cleanup(unsigned address_bits) | |||
| 822 | range_state[i].type = type; | 821 | range_state[i].type = type; |
| 823 | } | 822 | } |
| 824 | 823 | ||
| 825 | /* check if we need handle it and can handle it */ | 824 | /* Check if we need handle it and can handle it: */ |
| 826 | if (!mtrr_need_cleanup()) | 825 | if (!mtrr_need_cleanup()) |
| 827 | return 0; | 826 | return 0; |
| 828 | 827 | ||
| 829 | /* print original var MTRRs at first, for debugging: */ | 828 | /* Print original var MTRRs at first, for debugging: */ |
| 830 | printk(KERN_DEBUG "original variable MTRRs\n"); | 829 | printk(KERN_DEBUG "original variable MTRRs\n"); |
| 831 | print_out_mtrr_range_state(); | 830 | print_out_mtrr_range_state(); |
| 832 | 831 | ||
| 833 | memset(range, 0, sizeof(range)); | 832 | memset(range, 0, sizeof(range)); |
| 834 | extra_remove_size = 0; | 833 | x_remove_size = 0; |
| 835 | extra_remove_base = 1 << (32 - PAGE_SHIFT); | 834 | x_remove_base = 1 << (32 - PAGE_SHIFT); |
| 836 | if (mtrr_tom2) | 835 | if (mtrr_tom2) |
| 837 | extra_remove_size = | 836 | x_remove_size = (mtrr_tom2 >> PAGE_SHIFT) - x_remove_base; |
| 838 | (mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base; | 837 | |
| 839 | nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base, | 838 | nr_range = x86_get_mtrr_mem_range(range, 0, x_remove_base, x_remove_size); |
| 840 | extra_remove_size); | ||
| 841 | /* | 839 | /* |
| 842 | * [0, 1M) should always be coverred by var mtrr with WB | 840 | * [0, 1M) should always be covered by var mtrr with WB |
| 843 | * and fixed mtrrs should take effective before var mtrr for it | 841 | * and fixed mtrrs should take effect before var mtrr for it: |
| 844 | */ | 842 | */ |
| 845 | nr_range = add_range_with_merge(range, nr_range, 0, | 843 | nr_range = add_range_with_merge(range, nr_range, 0, |
| 846 | (1ULL<<(20 - PAGE_SHIFT)) - 1); | 844 | (1ULL<<(20 - PAGE_SHIFT)) - 1); |
| 847 | /* sort the ranges */ | 845 | /* Sort the ranges: */ |
| 848 | sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL); | 846 | sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL); |
| 849 | 847 | ||
| 850 | range_sums = sum_ranges(range, nr_range); | 848 | range_sums = sum_ranges(range, nr_range); |
| @@ -854,7 +852,7 @@ int __init mtrr_cleanup(unsigned address_bits) | |||
| 854 | if (mtrr_chunk_size && mtrr_gran_size) { | 852 | if (mtrr_chunk_size && mtrr_gran_size) { |
| 855 | i = 0; | 853 | i = 0; |
| 856 | mtrr_calc_range_state(mtrr_chunk_size, mtrr_gran_size, | 854 | mtrr_calc_range_state(mtrr_chunk_size, mtrr_gran_size, |
| 857 | extra_remove_base, extra_remove_size, i); | 855 | x_remove_base, x_remove_size, i); |
| 858 | 856 | ||
| 859 | mtrr_print_out_one_result(i); | 857 | mtrr_print_out_one_result(i); |
| 860 | 858 | ||
| @@ -880,7 +878,7 @@ int __init mtrr_cleanup(unsigned address_bits) | |||
| 880 | continue; | 878 | continue; |
| 881 | 879 | ||
| 882 | mtrr_calc_range_state(chunk_size, gran_size, | 880 | mtrr_calc_range_state(chunk_size, gran_size, |
| 883 | extra_remove_base, extra_remove_size, i); | 881 | x_remove_base, x_remove_size, i); |
| 884 | if (debug_print) { | 882 | if (debug_print) { |
| 885 | mtrr_print_out_one_result(i); | 883 | mtrr_print_out_one_result(i); |
| 886 | printk(KERN_INFO "\n"); | 884 | printk(KERN_INFO "\n"); |
| @@ -890,7 +888,7 @@ int __init mtrr_cleanup(unsigned address_bits) | |||
| 890 | } | 888 | } |
| 891 | } | 889 | } |
| 892 | 890 | ||
| 893 | /* try to find the optimal index */ | 891 | /* Try to find the optimal index: */ |
| 894 | index_good = mtrr_search_optimal_index(); | 892 | index_good = mtrr_search_optimal_index(); |
| 895 | 893 | ||
| 896 | if (index_good != -1) { | 894 | if (index_good != -1) { |
| @@ -898,7 +896,7 @@ int __init mtrr_cleanup(unsigned address_bits) | |||
| 898 | i = index_good; | 896 | i = index_good; |
| 899 | mtrr_print_out_one_result(i); | 897 | mtrr_print_out_one_result(i); |
| 900 | 898 | ||
| 901 | /* convert ranges to var ranges state */ | 899 | /* Convert ranges to var ranges state: */ |
| 902 | chunk_size = result[i].chunk_sizek; | 900 | chunk_size = result[i].chunk_sizek; |
| 903 | chunk_size <<= 10; | 901 | chunk_size <<= 10; |
| 904 | gran_size = result[i].gran_sizek; | 902 | gran_size = result[i].gran_sizek; |
| @@ -941,8 +939,8 @@ early_param("disable_mtrr_trim", disable_mtrr_trim_setup); | |||
| 941 | * Note this won't check if the MTRRs < 4GB where the magic bit doesn't | 939 | * Note this won't check if the MTRRs < 4GB where the magic bit doesn't |
| 942 | * apply to are wrong, but so far we don't know of any such case in the wild. | 940 | * apply to are wrong, but so far we don't know of any such case in the wild. |
| 943 | */ | 941 | */ |
| 944 | #define Tom2Enabled (1U << 21) | 942 | #define Tom2Enabled (1U << 21) |
| 945 | #define Tom2ForceMemTypeWB (1U << 22) | 943 | #define Tom2ForceMemTypeWB (1U << 22) |
| 946 | 944 | ||
| 947 | int __init amd_special_default_mtrr(void) | 945 | int __init amd_special_default_mtrr(void) |
| 948 | { | 946 | { |
| @@ -952,7 +950,7 @@ int __init amd_special_default_mtrr(void) | |||
| 952 | return 0; | 950 | return 0; |
| 953 | if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11) | 951 | if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11) |
| 954 | return 0; | 952 | return 0; |
| 955 | /* In case some hypervisor doesn't pass SYSCFG through */ | 953 | /* In case some hypervisor doesn't pass SYSCFG through: */ |
| 956 | if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0) | 954 | if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0) |
| 957 | return 0; | 955 | return 0; |
| 958 | /* | 956 | /* |
| @@ -965,19 +963,21 @@ int __init amd_special_default_mtrr(void) | |||
| 965 | return 0; | 963 | return 0; |
| 966 | } | 964 | } |
| 967 | 965 | ||
| 968 | static u64 __init real_trim_memory(unsigned long start_pfn, | 966 | static u64 __init |
| 969 | unsigned long limit_pfn) | 967 | real_trim_memory(unsigned long start_pfn, unsigned long limit_pfn) |
| 970 | { | 968 | { |
| 971 | u64 trim_start, trim_size; | 969 | u64 trim_start, trim_size; |
| 970 | |||
| 972 | trim_start = start_pfn; | 971 | trim_start = start_pfn; |
| 973 | trim_start <<= PAGE_SHIFT; | 972 | trim_start <<= PAGE_SHIFT; |
| 973 | |||
| 974 | trim_size = limit_pfn; | 974 | trim_size = limit_pfn; |
| 975 | trim_size <<= PAGE_SHIFT; | 975 | trim_size <<= PAGE_SHIFT; |
| 976 | trim_size -= trim_start; | 976 | trim_size -= trim_start; |
| 977 | 977 | ||
| 978 | return e820_update_range(trim_start, trim_size, E820_RAM, | 978 | return e820_update_range(trim_start, trim_size, E820_RAM, E820_RESERVED); |
| 979 | E820_RESERVED); | ||
| 980 | } | 979 | } |
| 980 | |||
| 981 | /** | 981 | /** |
| 982 | * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs | 982 | * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs |
| 983 | * @end_pfn: ending page frame number | 983 | * @end_pfn: ending page frame number |
| @@ -985,7 +985,7 @@ static u64 __init real_trim_memory(unsigned long start_pfn, | |||
| 985 | * Some buggy BIOSes don't setup the MTRRs properly for systems with certain | 985 | * Some buggy BIOSes don't setup the MTRRs properly for systems with certain |
| 986 | * memory configurations. This routine checks that the highest MTRR matches | 986 | * memory configurations. This routine checks that the highest MTRR matches |
| 987 | * the end of memory, to make sure the MTRRs having a write back type cover | 987 | * the end of memory, to make sure the MTRRs having a write back type cover |
| 988 | * all of the memory the kernel is intending to use. If not, it'll trim any | 988 | * all of the memory the kernel is intending to use. If not, it'll trim any |
| 989 | * memory off the end by adjusting end_pfn, removing it from the kernel's | 989 | * memory off the end by adjusting end_pfn, removing it from the kernel's |
| 990 | * allocation pools, warning the user with an obnoxious message. | 990 | * allocation pools, warning the user with an obnoxious message. |
| 991 | */ | 991 | */ |
| @@ -994,21 +994,22 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) | |||
| 994 | unsigned long i, base, size, highest_pfn = 0, def, dummy; | 994 | unsigned long i, base, size, highest_pfn = 0, def, dummy; |
| 995 | mtrr_type type; | 995 | mtrr_type type; |
| 996 | u64 total_trim_size; | 996 | u64 total_trim_size; |
| 997 | |||
| 998 | /* extra one for all 0 */ | 997 | /* extra one for all 0 */ |
| 999 | int num[MTRR_NUM_TYPES + 1]; | 998 | int num[MTRR_NUM_TYPES + 1]; |
| 999 | |||
| 1000 | /* | 1000 | /* |
| 1001 | * Make sure we only trim uncachable memory on machines that | 1001 | * Make sure we only trim uncachable memory on machines that |
| 1002 | * support the Intel MTRR architecture: | 1002 | * support the Intel MTRR architecture: |
| 1003 | */ | 1003 | */ |
| 1004 | if (!is_cpu(INTEL) || disable_mtrr_trim) | 1004 | if (!is_cpu(INTEL) || disable_mtrr_trim) |
| 1005 | return 0; | 1005 | return 0; |
| 1006 | |||
| 1006 | rdmsr(MSR_MTRRdefType, def, dummy); | 1007 | rdmsr(MSR_MTRRdefType, def, dummy); |
| 1007 | def &= 0xff; | 1008 | def &= 0xff; |
| 1008 | if (def != MTRR_TYPE_UNCACHABLE) | 1009 | if (def != MTRR_TYPE_UNCACHABLE) |
| 1009 | return 0; | 1010 | return 0; |
| 1010 | 1011 | ||
| 1011 | /* get it and store it aside */ | 1012 | /* Get it and store it aside: */ |
| 1012 | memset(range_state, 0, sizeof(range_state)); | 1013 | memset(range_state, 0, sizeof(range_state)); |
| 1013 | for (i = 0; i < num_var_ranges; i++) { | 1014 | for (i = 0; i < num_var_ranges; i++) { |
| 1014 | mtrr_if->get(i, &base, &size, &type); | 1015 | mtrr_if->get(i, &base, &size, &type); |
| @@ -1017,7 +1018,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) | |||
| 1017 | range_state[i].type = type; | 1018 | range_state[i].type = type; |
| 1018 | } | 1019 | } |
| 1019 | 1020 | ||
| 1020 | /* Find highest cached pfn */ | 1021 | /* Find highest cached pfn: */ |
| 1021 | for (i = 0; i < num_var_ranges; i++) { | 1022 | for (i = 0; i < num_var_ranges; i++) { |
| 1022 | type = range_state[i].type; | 1023 | type = range_state[i].type; |
| 1023 | if (type != MTRR_TYPE_WRBACK) | 1024 | if (type != MTRR_TYPE_WRBACK) |
| @@ -1028,13 +1029,13 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) | |||
| 1028 | highest_pfn = base + size; | 1029 | highest_pfn = base + size; |
| 1029 | } | 1030 | } |
| 1030 | 1031 | ||
| 1031 | /* kvm/qemu doesn't have mtrr set right, don't trim them all */ | 1032 | /* kvm/qemu doesn't have mtrr set right, don't trim them all: */ |
| 1032 | if (!highest_pfn) { | 1033 | if (!highest_pfn) { |
| 1033 | printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n"); | 1034 | printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n"); |
| 1034 | return 0; | 1035 | return 0; |
| 1035 | } | 1036 | } |
| 1036 | 1037 | ||
| 1037 | /* check entries number */ | 1038 | /* Check entries number: */ |
| 1038 | memset(num, 0, sizeof(num)); | 1039 | memset(num, 0, sizeof(num)); |
| 1039 | for (i = 0; i < num_var_ranges; i++) { | 1040 | for (i = 0; i < num_var_ranges; i++) { |
| 1040 | type = range_state[i].type; | 1041 | type = range_state[i].type; |
| @@ -1046,11 +1047,11 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) | |||
| 1046 | num[type]++; | 1047 | num[type]++; |
| 1047 | } | 1048 | } |
| 1048 | 1049 | ||
| 1049 | /* no entry for WB? */ | 1050 | /* No entry for WB? */ |
| 1050 | if (!num[MTRR_TYPE_WRBACK]) | 1051 | if (!num[MTRR_TYPE_WRBACK]) |
| 1051 | return 0; | 1052 | return 0; |
| 1052 | 1053 | ||
| 1053 | /* check if we only had WB and UC */ | 1054 | /* Check if we only had WB and UC: */ |
| 1054 | if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] != | 1055 | if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] != |
| 1055 | num_var_ranges - num[MTRR_NUM_TYPES]) | 1056 | num_var_ranges - num[MTRR_NUM_TYPES]) |
| 1056 | return 0; | 1057 | return 0; |
| @@ -1066,31 +1067,31 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) | |||
| 1066 | } | 1067 | } |
| 1067 | nr_range = x86_get_mtrr_mem_range(range, nr_range, 0, 0); | 1068 | nr_range = x86_get_mtrr_mem_range(range, nr_range, 0, 0); |
| 1068 | 1069 | ||
| 1070 | /* Check the head: */ | ||
| 1069 | total_trim_size = 0; | 1071 | total_trim_size = 0; |
| 1070 | /* check the head */ | ||
| 1071 | if (range[0].start) | 1072 | if (range[0].start) |
| 1072 | total_trim_size += real_trim_memory(0, range[0].start); | 1073 | total_trim_size += real_trim_memory(0, range[0].start); |
| 1073 | /* check the holes */ | 1074 | |
| 1075 | /* Check the holes: */ | ||
| 1074 | for (i = 0; i < nr_range - 1; i++) { | 1076 | for (i = 0; i < nr_range - 1; i++) { |
| 1075 | if (range[i].end + 1 < range[i+1].start) | 1077 | if (range[i].end + 1 < range[i+1].start) |
| 1076 | total_trim_size += real_trim_memory(range[i].end + 1, | 1078 | total_trim_size += real_trim_memory(range[i].end + 1, |
| 1077 | range[i+1].start); | 1079 | range[i+1].start); |
| 1078 | } | 1080 | } |
| 1079 | /* check the top */ | 1081 | |
| 1082 | /* Check the top: */ | ||
| 1080 | i = nr_range - 1; | 1083 | i = nr_range - 1; |
| 1081 | if (range[i].end + 1 < end_pfn) | 1084 | if (range[i].end + 1 < end_pfn) |
| 1082 | total_trim_size += real_trim_memory(range[i].end + 1, | 1085 | total_trim_size += real_trim_memory(range[i].end + 1, |
| 1083 | end_pfn); | 1086 | end_pfn); |
| 1084 | 1087 | ||
| 1085 | if (total_trim_size) { | 1088 | if (total_trim_size) { |
| 1086 | printk(KERN_WARNING "WARNING: BIOS bug: CPU MTRRs don't cover" | 1089 | pr_warning("WARNING: BIOS bug: CPU MTRRs don't cover all of memory, losing %lluMB of RAM.\n", total_trim_size >> 20); |
| 1087 | " all of memory, losing %lluMB of RAM.\n", | ||
| 1088 | total_trim_size >> 20); | ||
| 1089 | 1090 | ||
| 1090 | if (!changed_by_mtrr_cleanup) | 1091 | if (!changed_by_mtrr_cleanup) |
| 1091 | WARN_ON(1); | 1092 | WARN_ON(1); |
| 1092 | 1093 | ||
| 1093 | printk(KERN_INFO "update e820 for mtrr\n"); | 1094 | pr_info("update e820 for mtrr\n"); |
| 1094 | update_e820(); | 1095 | update_e820(); |
| 1095 | 1096 | ||
| 1096 | return 1; | 1097 | return 1; |
| @@ -1098,4 +1099,3 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) | |||
| 1098 | 1099 | ||
| 1099 | return 0; | 1100 | return 0; |
| 1100 | } | 1101 | } |
| 1101 | |||
diff --git a/arch/x86/kernel/cpu/mtrr/cyrix.c b/arch/x86/kernel/cpu/mtrr/cyrix.c index ff14c320040c..228d982ce09c 100644 --- a/arch/x86/kernel/cpu/mtrr/cyrix.c +++ b/arch/x86/kernel/cpu/mtrr/cyrix.c | |||
| @@ -1,38 +1,40 @@ | |||
| 1 | #include <linux/init.h> | 1 | #include <linux/init.h> |
| 2 | #include <linux/io.h> | ||
| 2 | #include <linux/mm.h> | 3 | #include <linux/mm.h> |
| 3 | #include <asm/mtrr.h> | 4 | |
| 4 | #include <asm/msr.h> | ||
| 5 | #include <asm/io.h> | ||
| 6 | #include <asm/processor-cyrix.h> | 5 | #include <asm/processor-cyrix.h> |
| 7 | #include <asm/processor-flags.h> | 6 | #include <asm/processor-flags.h> |
| 7 | #include <asm/mtrr.h> | ||
| 8 | #include <asm/msr.h> | ||
| 9 | |||
| 8 | #include "mtrr.h" | 10 | #include "mtrr.h" |
| 9 | 11 | ||
| 10 | static void | 12 | static void |
| 11 | cyrix_get_arr(unsigned int reg, unsigned long *base, | 13 | cyrix_get_arr(unsigned int reg, unsigned long *base, |
| 12 | unsigned long *size, mtrr_type * type) | 14 | unsigned long *size, mtrr_type * type) |
| 13 | { | 15 | { |
| 14 | unsigned long flags; | ||
| 15 | unsigned char arr, ccr3, rcr, shift; | 16 | unsigned char arr, ccr3, rcr, shift; |
| 17 | unsigned long flags; | ||
| 16 | 18 | ||
| 17 | arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */ | 19 | arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */ |
| 18 | 20 | ||
| 19 | /* Save flags and disable interrupts */ | ||
| 20 | local_irq_save(flags); | 21 | local_irq_save(flags); |
| 21 | 22 | ||
| 22 | ccr3 = getCx86(CX86_CCR3); | 23 | ccr3 = getCx86(CX86_CCR3); |
| 23 | setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ | 24 | setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ |
| 24 | ((unsigned char *) base)[3] = getCx86(arr); | 25 | ((unsigned char *)base)[3] = getCx86(arr); |
| 25 | ((unsigned char *) base)[2] = getCx86(arr + 1); | 26 | ((unsigned char *)base)[2] = getCx86(arr + 1); |
| 26 | ((unsigned char *) base)[1] = getCx86(arr + 2); | 27 | ((unsigned char *)base)[1] = getCx86(arr + 2); |
| 27 | rcr = getCx86(CX86_RCR_BASE + reg); | 28 | rcr = getCx86(CX86_RCR_BASE + reg); |
| 28 | setCx86(CX86_CCR3, ccr3); /* disable MAPEN */ | 29 | setCx86(CX86_CCR3, ccr3); /* disable MAPEN */ |
| 29 | 30 | ||
| 30 | /* Enable interrupts if it was enabled previously */ | ||
| 31 | local_irq_restore(flags); | 31 | local_irq_restore(flags); |
| 32 | |||
| 32 | shift = ((unsigned char *) base)[1] & 0x0f; | 33 | shift = ((unsigned char *) base)[1] & 0x0f; |
| 33 | *base >>= PAGE_SHIFT; | 34 | *base >>= PAGE_SHIFT; |
| 34 | 35 | ||
| 35 | /* Power of two, at least 4K on ARR0-ARR6, 256K on ARR7 | 36 | /* |
| 37 | * Power of two, at least 4K on ARR0-ARR6, 256K on ARR7 | ||
| 36 | * Note: shift==0xf means 4G, this is unsupported. | 38 | * Note: shift==0xf means 4G, this is unsupported. |
| 37 | */ | 39 | */ |
| 38 | if (shift) | 40 | if (shift) |
| @@ -76,17 +78,20 @@ cyrix_get_arr(unsigned int reg, unsigned long *base, | |||
| 76 | } | 78 | } |
| 77 | } | 79 | } |
| 78 | 80 | ||
| 81 | /* | ||
| 82 | * cyrix_get_free_region - get a free ARR. | ||
| 83 | * | ||
| 84 | * @base: the starting (base) address of the region. | ||
| 85 | * @size: the size (in bytes) of the region. | ||
| 86 | * | ||
| 87 | * Returns: the index of the region on success, else -1 on error. | ||
| 88 | */ | ||
| 79 | static int | 89 | static int |
| 80 | cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg) | 90 | cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg) |
| 81 | /* [SUMMARY] Get a free ARR. | ||
| 82 | <base> The starting (base) address of the region. | ||
| 83 | <size> The size (in bytes) of the region. | ||
| 84 | [RETURNS] The index of the region on success, else -1 on error. | ||
| 85 | */ | ||
| 86 | { | 91 | { |
| 87 | int i; | ||
| 88 | mtrr_type ltype; | ||
| 89 | unsigned long lbase, lsize; | 92 | unsigned long lbase, lsize; |
| 93 | mtrr_type ltype; | ||
| 94 | int i; | ||
| 90 | 95 | ||
| 91 | switch (replace_reg) { | 96 | switch (replace_reg) { |
| 92 | case 7: | 97 | case 7: |
| @@ -107,14 +112,17 @@ cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg) | |||
| 107 | cyrix_get_arr(7, &lbase, &lsize, <ype); | 112 | cyrix_get_arr(7, &lbase, &lsize, <ype); |
| 108 | if (lsize == 0) | 113 | if (lsize == 0) |
| 109 | return 7; | 114 | return 7; |
| 110 | /* Else try ARR0-ARR6 first */ | 115 | /* Else try ARR0-ARR6 first */ |
| 111 | } else { | 116 | } else { |
| 112 | for (i = 0; i < 7; i++) { | 117 | for (i = 0; i < 7; i++) { |
| 113 | cyrix_get_arr(i, &lbase, &lsize, <ype); | 118 | cyrix_get_arr(i, &lbase, &lsize, <ype); |
| 114 | if (lsize == 0) | 119 | if (lsize == 0) |
| 115 | return i; | 120 | return i; |
| 116 | } | 121 | } |
| 117 | /* ARR0-ARR6 isn't free, try ARR7 but its size must be at least 256K */ | 122 | /* |
| 123 | * ARR0-ARR6 isn't free | ||
| 124 | * try ARR7 but its size must be at least 256K | ||
| 125 | */ | ||
| 118 | cyrix_get_arr(i, &lbase, &lsize, <ype); | 126 | cyrix_get_arr(i, &lbase, &lsize, <ype); |
| 119 | if ((lsize == 0) && (size >= 0x40)) | 127 | if ((lsize == 0) && (size >= 0x40)) |
| 120 | return i; | 128 | return i; |
| @@ -122,21 +130,22 @@ cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg) | |||
| 122 | return -ENOSPC; | 130 | return -ENOSPC; |
| 123 | } | 131 | } |
| 124 | 132 | ||
| 125 | static u32 cr4 = 0; | 133 | static u32 cr4, ccr3; |
| 126 | static u32 ccr3; | ||
| 127 | 134 | ||
| 128 | static void prepare_set(void) | 135 | static void prepare_set(void) |
| 129 | { | 136 | { |
| 130 | u32 cr0; | 137 | u32 cr0; |
| 131 | 138 | ||
| 132 | /* Save value of CR4 and clear Page Global Enable (bit 7) */ | 139 | /* Save value of CR4 and clear Page Global Enable (bit 7) */ |
| 133 | if ( cpu_has_pge ) { | 140 | if (cpu_has_pge) { |
| 134 | cr4 = read_cr4(); | 141 | cr4 = read_cr4(); |
| 135 | write_cr4(cr4 & ~X86_CR4_PGE); | 142 | write_cr4(cr4 & ~X86_CR4_PGE); |
| 136 | } | 143 | } |
| 137 | 144 | ||
| 138 | /* Disable and flush caches. Note that wbinvd flushes the TLBs as | 145 | /* |
| 139 | a side-effect */ | 146 | * Disable and flush caches. |
| 147 | * Note that wbinvd flushes the TLBs as a side-effect | ||
| 148 | */ | ||
| 140 | cr0 = read_cr0() | X86_CR0_CD; | 149 | cr0 = read_cr0() | X86_CR0_CD; |
| 141 | wbinvd(); | 150 | wbinvd(); |
| 142 | write_cr0(cr0); | 151 | write_cr0(cr0); |
| @@ -147,22 +156,21 @@ static void prepare_set(void) | |||
| 147 | 156 | ||
| 148 | /* Cyrix ARRs - everything else was excluded at the top */ | 157 | /* Cyrix ARRs - everything else was excluded at the top */ |
| 149 | setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); | 158 | setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); |
| 150 | |||
| 151 | } | 159 | } |
| 152 | 160 | ||
| 153 | static void post_set(void) | 161 | static void post_set(void) |
| 154 | { | 162 | { |
| 155 | /* Flush caches and TLBs */ | 163 | /* Flush caches and TLBs */ |
| 156 | wbinvd(); | 164 | wbinvd(); |
| 157 | 165 | ||
| 158 | /* Cyrix ARRs - everything else was excluded at the top */ | 166 | /* Cyrix ARRs - everything else was excluded at the top */ |
| 159 | setCx86(CX86_CCR3, ccr3); | 167 | setCx86(CX86_CCR3, ccr3); |
| 160 | 168 | ||
| 161 | /* Enable caches */ | 169 | /* Enable caches */ |
| 162 | write_cr0(read_cr0() & 0xbfffffff); | 170 | write_cr0(read_cr0() & 0xbfffffff); |
| 163 | 171 | ||
| 164 | /* Restore value of CR4 */ | 172 | /* Restore value of CR4 */ |
| 165 | if ( cpu_has_pge ) | 173 | if (cpu_has_pge) |
| 166 | write_cr4(cr4); | 174 | write_cr4(cr4); |
| 167 | } | 175 | } |
| 168 | 176 | ||
| @@ -178,7 +186,8 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base, | |||
| 178 | size >>= 6; | 186 | size >>= 6; |
| 179 | 187 | ||
| 180 | size &= 0x7fff; /* make sure arr_size <= 14 */ | 188 | size &= 0x7fff; /* make sure arr_size <= 14 */ |
| 181 | for (arr_size = 0; size; arr_size++, size >>= 1) ; | 189 | for (arr_size = 0; size; arr_size++, size >>= 1) |
| 190 | ; | ||
| 182 | 191 | ||
| 183 | if (reg < 7) { | 192 | if (reg < 7) { |
| 184 | switch (type) { | 193 | switch (type) { |
| @@ -215,18 +224,18 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base, | |||
| 215 | prepare_set(); | 224 | prepare_set(); |
| 216 | 225 | ||
| 217 | base <<= PAGE_SHIFT; | 226 | base <<= PAGE_SHIFT; |
| 218 | setCx86(arr, ((unsigned char *) &base)[3]); | 227 | setCx86(arr + 0, ((unsigned char *)&base)[3]); |
| 219 | setCx86(arr + 1, ((unsigned char *) &base)[2]); | 228 | setCx86(arr + 1, ((unsigned char *)&base)[2]); |
| 220 | setCx86(arr + 2, (((unsigned char *) &base)[1]) | arr_size); | 229 | setCx86(arr + 2, (((unsigned char *)&base)[1]) | arr_size); |
| 221 | setCx86(CX86_RCR_BASE + reg, arr_type); | 230 | setCx86(CX86_RCR_BASE + reg, arr_type); |
| 222 | 231 | ||
| 223 | post_set(); | 232 | post_set(); |
| 224 | } | 233 | } |
| 225 | 234 | ||
| 226 | typedef struct { | 235 | typedef struct { |
| 227 | unsigned long base; | 236 | unsigned long base; |
| 228 | unsigned long size; | 237 | unsigned long size; |
| 229 | mtrr_type type; | 238 | mtrr_type type; |
| 230 | } arr_state_t; | 239 | } arr_state_t; |
| 231 | 240 | ||
| 232 | static arr_state_t arr_state[8] = { | 241 | static arr_state_t arr_state[8] = { |
| @@ -247,16 +256,17 @@ static void cyrix_set_all(void) | |||
| 247 | setCx86(CX86_CCR0 + i, ccr_state[i]); | 256 | setCx86(CX86_CCR0 + i, ccr_state[i]); |
| 248 | for (; i < 7; i++) | 257 | for (; i < 7; i++) |
| 249 | setCx86(CX86_CCR4 + i, ccr_state[i]); | 258 | setCx86(CX86_CCR4 + i, ccr_state[i]); |
| 250 | for (i = 0; i < 8; i++) | 259 | |
| 251 | cyrix_set_arr(i, arr_state[i].base, | 260 | for (i = 0; i < 8; i++) { |
| 261 | cyrix_set_arr(i, arr_state[i].base, | ||
| 252 | arr_state[i].size, arr_state[i].type); | 262 | arr_state[i].size, arr_state[i].type); |
| 263 | } | ||
| 253 | 264 | ||
| 254 | post_set(); | 265 | post_set(); |
| 255 | } | 266 | } |
| 256 | 267 | ||
| 257 | static struct mtrr_ops cyrix_mtrr_ops = { | 268 | static struct mtrr_ops cyrix_mtrr_ops = { |
| 258 | .vendor = X86_VENDOR_CYRIX, | 269 | .vendor = X86_VENDOR_CYRIX, |
| 259 | // .init = cyrix_arr_init, | ||
| 260 | .set_all = cyrix_set_all, | 270 | .set_all = cyrix_set_all, |
| 261 | .set = cyrix_set_arr, | 271 | .set = cyrix_set_arr, |
| 262 | .get = cyrix_get_arr, | 272 | .get = cyrix_get_arr, |
| @@ -270,5 +280,3 @@ int __init cyrix_init_mtrr(void) | |||
| 270 | set_mtrr_ops(&cyrix_mtrr_ops); | 280 | set_mtrr_ops(&cyrix_mtrr_ops); |
| 271 | return 0; | 281 | return 0; |
| 272 | } | 282 | } |
| 273 | |||
| 274 | //arch_initcall(cyrix_init_mtrr); | ||
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 0543f69f0b27..55da0c5f68dd 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c | |||
| @@ -1,28 +1,34 @@ | |||
| 1 | /* This only handles 32bit MTRR on 32bit hosts. This is strictly wrong | 1 | /* |
| 2 | because MTRRs can span upto 40 bits (36bits on most modern x86) */ | 2 | * This only handles 32bit MTRR on 32bit hosts. This is strictly wrong |
| 3 | * because MTRRs can span upto 40 bits (36bits on most modern x86) | ||
| 4 | */ | ||
| 5 | #define DEBUG | ||
| 6 | |||
| 7 | #include <linux/module.h> | ||
| 3 | #include <linux/init.h> | 8 | #include <linux/init.h> |
| 4 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
| 10 | #include <linux/io.h> | ||
| 5 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
| 6 | #include <linux/module.h> | 12 | |
| 7 | #include <asm/io.h> | ||
| 8 | #include <asm/mtrr.h> | ||
| 9 | #include <asm/msr.h> | ||
| 10 | #include <asm/system.h> | ||
| 11 | #include <asm/cpufeature.h> | ||
| 12 | #include <asm/processor-flags.h> | 13 | #include <asm/processor-flags.h> |
| 14 | #include <asm/cpufeature.h> | ||
| 13 | #include <asm/tlbflush.h> | 15 | #include <asm/tlbflush.h> |
| 16 | #include <asm/system.h> | ||
| 17 | #include <asm/mtrr.h> | ||
| 18 | #include <asm/msr.h> | ||
| 14 | #include <asm/pat.h> | 19 | #include <asm/pat.h> |
| 20 | |||
| 15 | #include "mtrr.h" | 21 | #include "mtrr.h" |
| 16 | 22 | ||
| 17 | struct fixed_range_block { | 23 | struct fixed_range_block { |
| 18 | int base_msr; /* start address of an MTRR block */ | 24 | int base_msr; /* start address of an MTRR block */ |
| 19 | int ranges; /* number of MTRRs in this block */ | 25 | int ranges; /* number of MTRRs in this block */ |
| 20 | }; | 26 | }; |
| 21 | 27 | ||
| 22 | static struct fixed_range_block fixed_range_blocks[] = { | 28 | static struct fixed_range_block fixed_range_blocks[] = { |
| 23 | { MSR_MTRRfix64K_00000, 1 }, /* one 64k MTRR */ | 29 | { MSR_MTRRfix64K_00000, 1 }, /* one 64k MTRR */ |
| 24 | { MSR_MTRRfix16K_80000, 2 }, /* two 16k MTRRs */ | 30 | { MSR_MTRRfix16K_80000, 2 }, /* two 16k MTRRs */ |
| 25 | { MSR_MTRRfix4K_C0000, 8 }, /* eight 4k MTRRs */ | 31 | { MSR_MTRRfix4K_C0000, 8 }, /* eight 4k MTRRs */ |
| 26 | {} | 32 | {} |
| 27 | }; | 33 | }; |
| 28 | 34 | ||
| @@ -30,10 +36,10 @@ static unsigned long smp_changes_mask; | |||
| 30 | static int mtrr_state_set; | 36 | static int mtrr_state_set; |
| 31 | u64 mtrr_tom2; | 37 | u64 mtrr_tom2; |
| 32 | 38 | ||
| 33 | struct mtrr_state_type mtrr_state = {}; | 39 | struct mtrr_state_type mtrr_state; |
| 34 | EXPORT_SYMBOL_GPL(mtrr_state); | 40 | EXPORT_SYMBOL_GPL(mtrr_state); |
| 35 | 41 | ||
| 36 | /** | 42 | /* |
| 37 | * BIOS is expected to clear MtrrFixDramModEn bit, see for example | 43 | * BIOS is expected to clear MtrrFixDramModEn bit, see for example |
| 38 | * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD | 44 | * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD |
| 39 | * Opteron Processors" (26094 Rev. 3.30 February 2006), section | 45 | * Opteron Processors" (26094 Rev. 3.30 February 2006), section |
| @@ -104,9 +110,8 @@ u8 mtrr_type_lookup(u64 start, u64 end) | |||
| 104 | * Look of multiple ranges matching this address and pick type | 110 | * Look of multiple ranges matching this address and pick type |
| 105 | * as per MTRR precedence | 111 | * as per MTRR precedence |
| 106 | */ | 112 | */ |
| 107 | if (!(mtrr_state.enabled & 2)) { | 113 | if (!(mtrr_state.enabled & 2)) |
| 108 | return mtrr_state.def_type; | 114 | return mtrr_state.def_type; |
| 109 | } | ||
| 110 | 115 | ||
| 111 | prev_match = 0xFF; | 116 | prev_match = 0xFF; |
| 112 | for (i = 0; i < num_var_ranges; ++i) { | 117 | for (i = 0; i < num_var_ranges; ++i) { |
| @@ -125,9 +130,8 @@ u8 mtrr_type_lookup(u64 start, u64 end) | |||
| 125 | if (start_state != end_state) | 130 | if (start_state != end_state) |
| 126 | return 0xFE; | 131 | return 0xFE; |
| 127 | 132 | ||
| 128 | if ((start & mask) != (base & mask)) { | 133 | if ((start & mask) != (base & mask)) |
| 129 | continue; | 134 | continue; |
| 130 | } | ||
| 131 | 135 | ||
| 132 | curr_match = mtrr_state.var_ranges[i].base_lo & 0xff; | 136 | curr_match = mtrr_state.var_ranges[i].base_lo & 0xff; |
| 133 | if (prev_match == 0xFF) { | 137 | if (prev_match == 0xFF) { |
| @@ -148,9 +152,8 @@ u8 mtrr_type_lookup(u64 start, u64 end) | |||
| 148 | curr_match = MTRR_TYPE_WRTHROUGH; | 152 | curr_match = MTRR_TYPE_WRTHROUGH; |
| 149 | } | 153 | } |
| 150 | 154 | ||
| 151 | if (prev_match != curr_match) { | 155 | if (prev_match != curr_match) |
| 152 | return MTRR_TYPE_UNCACHABLE; | 156 | return MTRR_TYPE_UNCACHABLE; |
| 153 | } | ||
| 154 | } | 157 | } |
| 155 | 158 | ||
| 156 | if (mtrr_tom2) { | 159 | if (mtrr_tom2) { |
| @@ -164,7 +167,7 @@ u8 mtrr_type_lookup(u64 start, u64 end) | |||
| 164 | return mtrr_state.def_type; | 167 | return mtrr_state.def_type; |
| 165 | } | 168 | } |
| 166 | 169 | ||
| 167 | /* Get the MSR pair relating to a var range */ | 170 | /* Get the MSR pair relating to a var range */ |
| 168 | static void | 171 | static void |
| 169 | get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr) | 172 | get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr) |
| 170 | { | 173 | { |
| @@ -172,7 +175,7 @@ get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr) | |||
| 172 | rdmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi); | 175 | rdmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi); |
| 173 | } | 176 | } |
| 174 | 177 | ||
| 175 | /* fill the MSR pair relating to a var range */ | 178 | /* Fill the MSR pair relating to a var range */ |
| 176 | void fill_mtrr_var_range(unsigned int index, | 179 | void fill_mtrr_var_range(unsigned int index, |
| 177 | u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi) | 180 | u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi) |
| 178 | { | 181 | { |
| @@ -186,10 +189,9 @@ void fill_mtrr_var_range(unsigned int index, | |||
| 186 | vr[index].mask_hi = mask_hi; | 189 | vr[index].mask_hi = mask_hi; |
| 187 | } | 190 | } |
| 188 | 191 | ||
| 189 | static void | 192 | static void get_fixed_ranges(mtrr_type *frs) |
| 190 | get_fixed_ranges(mtrr_type * frs) | ||
| 191 | { | 193 | { |
| 192 | unsigned int *p = (unsigned int *) frs; | 194 | unsigned int *p = (unsigned int *)frs; |
| 193 | int i; | 195 | int i; |
| 194 | 196 | ||
| 195 | k8_check_syscfg_dram_mod_en(); | 197 | k8_check_syscfg_dram_mod_en(); |
| @@ -217,22 +219,22 @@ static void __init print_fixed_last(void) | |||
| 217 | if (!last_fixed_end) | 219 | if (!last_fixed_end) |
| 218 | return; | 220 | return; |
| 219 | 221 | ||
| 220 | printk(KERN_DEBUG " %05X-%05X %s\n", last_fixed_start, | 222 | pr_debug(" %05X-%05X %s\n", last_fixed_start, |
| 221 | last_fixed_end - 1, mtrr_attrib_to_str(last_fixed_type)); | 223 | last_fixed_end - 1, mtrr_attrib_to_str(last_fixed_type)); |
| 222 | 224 | ||
| 223 | last_fixed_end = 0; | 225 | last_fixed_end = 0; |
| 224 | } | 226 | } |
| 225 | 227 | ||
| 226 | static void __init update_fixed_last(unsigned base, unsigned end, | 228 | static void __init update_fixed_last(unsigned base, unsigned end, |
| 227 | mtrr_type type) | 229 | mtrr_type type) |
| 228 | { | 230 | { |
| 229 | last_fixed_start = base; | 231 | last_fixed_start = base; |
| 230 | last_fixed_end = end; | 232 | last_fixed_end = end; |
| 231 | last_fixed_type = type; | 233 | last_fixed_type = type; |
| 232 | } | 234 | } |
| 233 | 235 | ||
| 234 | static void __init print_fixed(unsigned base, unsigned step, | 236 | static void __init |
| 235 | const mtrr_type *types) | 237 | print_fixed(unsigned base, unsigned step, const mtrr_type *types) |
| 236 | { | 238 | { |
| 237 | unsigned i; | 239 | unsigned i; |
| 238 | 240 | ||
| @@ -259,54 +261,55 @@ static void __init print_mtrr_state(void) | |||
| 259 | unsigned int i; | 261 | unsigned int i; |
| 260 | int high_width; | 262 | int high_width; |
| 261 | 263 | ||
| 262 | printk(KERN_DEBUG "MTRR default type: %s\n", | 264 | pr_debug("MTRR default type: %s\n", |
| 263 | mtrr_attrib_to_str(mtrr_state.def_type)); | 265 | mtrr_attrib_to_str(mtrr_state.def_type)); |
| 264 | if (mtrr_state.have_fixed) { | 266 | if (mtrr_state.have_fixed) { |
| 265 | printk(KERN_DEBUG "MTRR fixed ranges %sabled:\n", | 267 | pr_debug("MTRR fixed ranges %sabled:\n", |
| 266 | mtrr_state.enabled & 1 ? "en" : "dis"); | 268 | mtrr_state.enabled & 1 ? "en" : "dis"); |
| 267 | print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0); | 269 | print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0); |
| 268 | for (i = 0; i < 2; ++i) | 270 | for (i = 0; i < 2; ++i) |
| 269 | print_fixed(0x80000 + i * 0x20000, 0x04000, mtrr_state.fixed_ranges + (i + 1) * 8); | 271 | print_fixed(0x80000 + i * 0x20000, 0x04000, |
| 272 | mtrr_state.fixed_ranges + (i + 1) * 8); | ||
| 270 | for (i = 0; i < 8; ++i) | 273 | for (i = 0; i < 8; ++i) |
| 271 | print_fixed(0xC0000 + i * 0x08000, 0x01000, mtrr_state.fixed_ranges + (i + 3) * 8); | 274 | print_fixed(0xC0000 + i * 0x08000, 0x01000, |
| 275 | mtrr_state.fixed_ranges + (i + 3) * 8); | ||
| 272 | 276 | ||
| 273 | /* tail */ | 277 | /* tail */ |
| 274 | print_fixed_last(); | 278 | print_fixed_last(); |
| 275 | } | 279 | } |
| 276 | printk(KERN_DEBUG "MTRR variable ranges %sabled:\n", | 280 | pr_debug("MTRR variable ranges %sabled:\n", |
| 277 | mtrr_state.enabled & 2 ? "en" : "dis"); | 281 | mtrr_state.enabled & 2 ? "en" : "dis"); |
| 278 | if (size_or_mask & 0xffffffffUL) | 282 | if (size_or_mask & 0xffffffffUL) |
| 279 | high_width = ffs(size_or_mask & 0xffffffffUL) - 1; | 283 | high_width = ffs(size_or_mask & 0xffffffffUL) - 1; |
| 280 | else | 284 | else |
| 281 | high_width = ffs(size_or_mask>>32) + 32 - 1; | 285 | high_width = ffs(size_or_mask>>32) + 32 - 1; |
| 282 | high_width = (high_width - (32 - PAGE_SHIFT) + 3) / 4; | 286 | high_width = (high_width - (32 - PAGE_SHIFT) + 3) / 4; |
| 287 | |||
| 283 | for (i = 0; i < num_var_ranges; ++i) { | 288 | for (i = 0; i < num_var_ranges; ++i) { |
| 284 | if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) | 289 | if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) |
| 285 | printk(KERN_DEBUG " %u base %0*X%05X000 mask %0*X%05X000 %s\n", | 290 | pr_debug(" %u base %0*X%05X000 mask %0*X%05X000 %s\n", |
| 286 | i, | 291 | i, |
| 287 | high_width, | 292 | high_width, |
| 288 | mtrr_state.var_ranges[i].base_hi, | 293 | mtrr_state.var_ranges[i].base_hi, |
| 289 | mtrr_state.var_ranges[i].base_lo >> 12, | 294 | mtrr_state.var_ranges[i].base_lo >> 12, |
| 290 | high_width, | 295 | high_width, |
| 291 | mtrr_state.var_ranges[i].mask_hi, | 296 | mtrr_state.var_ranges[i].mask_hi, |
| 292 | mtrr_state.var_ranges[i].mask_lo >> 12, | 297 | mtrr_state.var_ranges[i].mask_lo >> 12, |
| 293 | mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff)); | 298 | mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff)); |
| 294 | else | 299 | else |
| 295 | printk(KERN_DEBUG " %u disabled\n", i); | 300 | pr_debug(" %u disabled\n", i); |
| 296 | } | ||
| 297 | if (mtrr_tom2) { | ||
| 298 | printk(KERN_DEBUG "TOM2: %016llx aka %lldM\n", | ||
| 299 | mtrr_tom2, mtrr_tom2>>20); | ||
| 300 | } | 301 | } |
| 302 | if (mtrr_tom2) | ||
| 303 | pr_debug("TOM2: %016llx aka %lldM\n", mtrr_tom2, mtrr_tom2>>20); | ||
| 301 | } | 304 | } |
| 302 | 305 | ||
| 303 | /* Grab all of the MTRR state for this CPU into *state */ | 306 | /* Grab all of the MTRR state for this CPU into *state */ |
| 304 | void __init get_mtrr_state(void) | 307 | void __init get_mtrr_state(void) |
| 305 | { | 308 | { |
| 306 | unsigned int i; | ||
| 307 | struct mtrr_var_range *vrs; | 309 | struct mtrr_var_range *vrs; |
| 308 | unsigned lo, dummy; | ||
| 309 | unsigned long flags; | 310 | unsigned long flags; |
| 311 | unsigned lo, dummy; | ||
| 312 | unsigned int i; | ||
| 310 | 313 | ||
| 311 | vrs = mtrr_state.var_ranges; | 314 | vrs = mtrr_state.var_ranges; |
| 312 | 315 | ||
| @@ -324,6 +327,7 @@ void __init get_mtrr_state(void) | |||
| 324 | 327 | ||
| 325 | if (amd_special_default_mtrr()) { | 328 | if (amd_special_default_mtrr()) { |
| 326 | unsigned low, high; | 329 | unsigned low, high; |
| 330 | |||
| 327 | /* TOP_MEM2 */ | 331 | /* TOP_MEM2 */ |
| 328 | rdmsr(MSR_K8_TOP_MEM2, low, high); | 332 | rdmsr(MSR_K8_TOP_MEM2, low, high); |
| 329 | mtrr_tom2 = high; | 333 | mtrr_tom2 = high; |
| @@ -344,10 +348,9 @@ void __init get_mtrr_state(void) | |||
| 344 | 348 | ||
| 345 | post_set(); | 349 | post_set(); |
| 346 | local_irq_restore(flags); | 350 | local_irq_restore(flags); |
| 347 | |||
| 348 | } | 351 | } |
| 349 | 352 | ||
| 350 | /* Some BIOS's are fucked and don't set all MTRRs the same! */ | 353 | /* Some BIOS's are messed up and don't set all MTRRs the same! */ |
| 351 | void __init mtrr_state_warn(void) | 354 | void __init mtrr_state_warn(void) |
| 352 | { | 355 | { |
| 353 | unsigned long mask = smp_changes_mask; | 356 | unsigned long mask = smp_changes_mask; |
| @@ -355,28 +358,33 @@ void __init mtrr_state_warn(void) | |||
| 355 | if (!mask) | 358 | if (!mask) |
| 356 | return; | 359 | return; |
| 357 | if (mask & MTRR_CHANGE_MASK_FIXED) | 360 | if (mask & MTRR_CHANGE_MASK_FIXED) |
| 358 | printk(KERN_WARNING "mtrr: your CPUs had inconsistent fixed MTRR settings\n"); | 361 | pr_warning("mtrr: your CPUs had inconsistent fixed MTRR settings\n"); |
| 359 | if (mask & MTRR_CHANGE_MASK_VARIABLE) | 362 | if (mask & MTRR_CHANGE_MASK_VARIABLE) |
| 360 | printk(KERN_WARNING "mtrr: your CPUs had inconsistent variable MTRR settings\n"); | 363 | pr_warning("mtrr: your CPUs had inconsistent variable MTRR settings\n"); |
| 361 | if (mask & MTRR_CHANGE_MASK_DEFTYPE) | 364 | if (mask & MTRR_CHANGE_MASK_DEFTYPE) |
| 362 | printk(KERN_WARNING "mtrr: your CPUs had inconsistent MTRRdefType settings\n"); | 365 | pr_warning("mtrr: your CPUs had inconsistent MTRRdefType settings\n"); |
| 366 | |||
| 363 | printk(KERN_INFO "mtrr: probably your BIOS does not setup all CPUs.\n"); | 367 | printk(KERN_INFO "mtrr: probably your BIOS does not setup all CPUs.\n"); |
| 364 | printk(KERN_INFO "mtrr: corrected configuration.\n"); | 368 | printk(KERN_INFO "mtrr: corrected configuration.\n"); |
| 365 | } | 369 | } |
| 366 | 370 | ||
| 367 | /* Doesn't attempt to pass an error out to MTRR users | 371 | /* |
| 368 | because it's quite complicated in some cases and probably not | 372 | * Doesn't attempt to pass an error out to MTRR users |
| 369 | worth it because the best error handling is to ignore it. */ | 373 | * because it's quite complicated in some cases and probably not |
| 374 | * worth it because the best error handling is to ignore it. | ||
| 375 | */ | ||
| 370 | void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b) | 376 | void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b) |
| 371 | { | 377 | { |
| 372 | if (wrmsr_safe(msr, a, b) < 0) | 378 | if (wrmsr_safe(msr, a, b) < 0) { |
| 373 | printk(KERN_ERR | 379 | printk(KERN_ERR |
| 374 | "MTRR: CPU %u: Writing MSR %x to %x:%x failed\n", | 380 | "MTRR: CPU %u: Writing MSR %x to %x:%x failed\n", |
| 375 | smp_processor_id(), msr, a, b); | 381 | smp_processor_id(), msr, a, b); |
| 382 | } | ||
| 376 | } | 383 | } |
| 377 | 384 | ||
| 378 | /** | 385 | /** |
| 379 | * set_fixed_range - checks & updates a fixed-range MTRR if it differs from the value it should have | 386 | * set_fixed_range - checks & updates a fixed-range MTRR if it |
| 387 | * differs from the value it should have | ||
| 380 | * @msr: MSR address of the MTTR which should be checked and updated | 388 | * @msr: MSR address of the MTTR which should be checked and updated |
| 381 | * @changed: pointer which indicates whether the MTRR needed to be changed | 389 | * @changed: pointer which indicates whether the MTRR needed to be changed |
| 382 | * @msrwords: pointer to the MSR values which the MSR should have | 390 | * @msrwords: pointer to the MSR values which the MSR should have |
| @@ -401,20 +409,23 @@ static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords) | |||
| 401 | * | 409 | * |
| 402 | * Returns: The index of the region on success, else negative on error. | 410 | * Returns: The index of the region on success, else negative on error. |
| 403 | */ | 411 | */ |
| 404 | int generic_get_free_region(unsigned long base, unsigned long size, int replace_reg) | 412 | int |
| 413 | generic_get_free_region(unsigned long base, unsigned long size, int replace_reg) | ||
| 405 | { | 414 | { |
| 406 | int i, max; | ||
| 407 | mtrr_type ltype; | ||
| 408 | unsigned long lbase, lsize; | 415 | unsigned long lbase, lsize; |
| 416 | mtrr_type ltype; | ||
| 417 | int i, max; | ||
| 409 | 418 | ||
| 410 | max = num_var_ranges; | 419 | max = num_var_ranges; |
| 411 | if (replace_reg >= 0 && replace_reg < max) | 420 | if (replace_reg >= 0 && replace_reg < max) |
| 412 | return replace_reg; | 421 | return replace_reg; |
| 422 | |||
| 413 | for (i = 0; i < max; ++i) { | 423 | for (i = 0; i < max; ++i) { |
| 414 | mtrr_if->get(i, &lbase, &lsize, <ype); | 424 | mtrr_if->get(i, &lbase, &lsize, <ype); |
| 415 | if (lsize == 0) | 425 | if (lsize == 0) |
| 416 | return i; | 426 | return i; |
| 417 | } | 427 | } |
| 428 | |||
| 418 | return -ENOSPC; | 429 | return -ENOSPC; |
| 419 | } | 430 | } |
| 420 | 431 | ||
| @@ -434,7 +445,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, | |||
| 434 | rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi); | 445 | rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi); |
| 435 | 446 | ||
| 436 | if ((mask_lo & 0x800) == 0) { | 447 | if ((mask_lo & 0x800) == 0) { |
| 437 | /* Invalid (i.e. free) range */ | 448 | /* Invalid (i.e. free) range */ |
| 438 | *base = 0; | 449 | *base = 0; |
| 439 | *size = 0; | 450 | *size = 0; |
| 440 | *type = 0; | 451 | *type = 0; |
| @@ -471,27 +482,31 @@ out_put_cpu: | |||
| 471 | } | 482 | } |
| 472 | 483 | ||
| 473 | /** | 484 | /** |
| 474 | * set_fixed_ranges - checks & updates the fixed-range MTRRs if they differ from the saved set | 485 | * set_fixed_ranges - checks & updates the fixed-range MTRRs if they |
| 486 | * differ from the saved set | ||
| 475 | * @frs: pointer to fixed-range MTRR values, saved by get_fixed_ranges() | 487 | * @frs: pointer to fixed-range MTRR values, saved by get_fixed_ranges() |
| 476 | */ | 488 | */ |
| 477 | static int set_fixed_ranges(mtrr_type * frs) | 489 | static int set_fixed_ranges(mtrr_type *frs) |
| 478 | { | 490 | { |
| 479 | unsigned long long *saved = (unsigned long long *) frs; | 491 | unsigned long long *saved = (unsigned long long *)frs; |
| 480 | bool changed = false; | 492 | bool changed = false; |
| 481 | int block=-1, range; | 493 | int block = -1, range; |
| 482 | 494 | ||
| 483 | k8_check_syscfg_dram_mod_en(); | 495 | k8_check_syscfg_dram_mod_en(); |
| 484 | 496 | ||
| 485 | while (fixed_range_blocks[++block].ranges) | 497 | while (fixed_range_blocks[++block].ranges) { |
| 486 | for (range=0; range < fixed_range_blocks[block].ranges; range++) | 498 | for (range = 0; range < fixed_range_blocks[block].ranges; range++) |
| 487 | set_fixed_range(fixed_range_blocks[block].base_msr + range, | 499 | set_fixed_range(fixed_range_blocks[block].base_msr + range, |
| 488 | &changed, (unsigned int *) saved++); | 500 | &changed, (unsigned int *)saved++); |
| 501 | } | ||
| 489 | 502 | ||
| 490 | return changed; | 503 | return changed; |
| 491 | } | 504 | } |
| 492 | 505 | ||
| 493 | /* Set the MSR pair relating to a var range. Returns TRUE if | 506 | /* |
| 494 | changes are made */ | 507 | * Set the MSR pair relating to a var range. |
| 508 | * Returns true if changes are made. | ||
| 509 | */ | ||
| 495 | static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr) | 510 | static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr) |
| 496 | { | 511 | { |
| 497 | unsigned int lo, hi; | 512 | unsigned int lo, hi; |
| @@ -501,6 +516,7 @@ static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr) | |||
| 501 | if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL) | 516 | if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL) |
| 502 | || (vr->base_hi & (size_and_mask >> (32 - PAGE_SHIFT))) != | 517 | || (vr->base_hi & (size_and_mask >> (32 - PAGE_SHIFT))) != |
| 503 | (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) { | 518 | (hi & (size_and_mask >> (32 - PAGE_SHIFT)))) { |
| 519 | |||
| 504 | mtrr_wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi); | 520 | mtrr_wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi); |
| 505 | changed = true; | 521 | changed = true; |
| 506 | } | 522 | } |
| @@ -526,21 +542,26 @@ static u32 deftype_lo, deftype_hi; | |||
| 526 | */ | 542 | */ |
| 527 | static unsigned long set_mtrr_state(void) | 543 | static unsigned long set_mtrr_state(void) |
| 528 | { | 544 | { |
| 529 | unsigned int i; | ||
| 530 | unsigned long change_mask = 0; | 545 | unsigned long change_mask = 0; |
| 546 | unsigned int i; | ||
| 531 | 547 | ||
| 532 | for (i = 0; i < num_var_ranges; i++) | 548 | for (i = 0; i < num_var_ranges; i++) { |
| 533 | if (set_mtrr_var_ranges(i, &mtrr_state.var_ranges[i])) | 549 | if (set_mtrr_var_ranges(i, &mtrr_state.var_ranges[i])) |
| 534 | change_mask |= MTRR_CHANGE_MASK_VARIABLE; | 550 | change_mask |= MTRR_CHANGE_MASK_VARIABLE; |
| 551 | } | ||
| 535 | 552 | ||
| 536 | if (mtrr_state.have_fixed && set_fixed_ranges(mtrr_state.fixed_ranges)) | 553 | if (mtrr_state.have_fixed && set_fixed_ranges(mtrr_state.fixed_ranges)) |
| 537 | change_mask |= MTRR_CHANGE_MASK_FIXED; | 554 | change_mask |= MTRR_CHANGE_MASK_FIXED; |
| 538 | 555 | ||
| 539 | /* Set_mtrr_restore restores the old value of MTRRdefType, | 556 | /* |
| 540 | so to set it we fiddle with the saved value */ | 557 | * Set_mtrr_restore restores the old value of MTRRdefType, |
| 558 | * so to set it we fiddle with the saved value: | ||
| 559 | */ | ||
| 541 | if ((deftype_lo & 0xff) != mtrr_state.def_type | 560 | if ((deftype_lo & 0xff) != mtrr_state.def_type |
| 542 | || ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) { | 561 | || ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) { |
| 543 | deftype_lo = (deftype_lo & ~0xcff) | mtrr_state.def_type | (mtrr_state.enabled << 10); | 562 | |
| 563 | deftype_lo = (deftype_lo & ~0xcff) | mtrr_state.def_type | | ||
| 564 | (mtrr_state.enabled << 10); | ||
| 544 | change_mask |= MTRR_CHANGE_MASK_DEFTYPE; | 565 | change_mask |= MTRR_CHANGE_MASK_DEFTYPE; |
| 545 | } | 566 | } |
| 546 | 567 | ||
| @@ -548,33 +569,36 @@ static unsigned long set_mtrr_state(void) | |||
| 548 | } | 569 | } |
| 549 | 570 | ||
| 550 | 571 | ||
| 551 | static unsigned long cr4 = 0; | 572 | static unsigned long cr4; |
| 552 | static DEFINE_SPINLOCK(set_atomicity_lock); | 573 | static DEFINE_SPINLOCK(set_atomicity_lock); |
| 553 | 574 | ||
| 554 | /* | 575 | /* |
| 555 | * Since we are disabling the cache don't allow any interrupts - they | 576 | * Since we are disabling the cache don't allow any interrupts, |
| 556 | * would run extremely slow and would only increase the pain. The caller must | 577 | * they would run extremely slow and would only increase the pain. |
| 557 | * ensure that local interrupts are disabled and are reenabled after post_set() | 578 | * |
| 558 | * has been called. | 579 | * The caller must ensure that local interrupts are disabled and |
| 580 | * are reenabled after post_set() has been called. | ||
| 559 | */ | 581 | */ |
| 560 | |||
| 561 | static void prepare_set(void) __acquires(set_atomicity_lock) | 582 | static void prepare_set(void) __acquires(set_atomicity_lock) |
| 562 | { | 583 | { |
| 563 | unsigned long cr0; | 584 | unsigned long cr0; |
| 564 | 585 | ||
| 565 | /* Note that this is not ideal, since the cache is only flushed/disabled | 586 | /* |
| 566 | for this CPU while the MTRRs are changed, but changing this requires | 587 | * Note that this is not ideal |
| 567 | more invasive changes to the way the kernel boots */ | 588 | * since the cache is only flushed/disabled for this CPU while the |
| 589 | * MTRRs are changed, but changing this requires more invasive | ||
| 590 | * changes to the way the kernel boots | ||
| 591 | */ | ||
| 568 | 592 | ||
| 569 | spin_lock(&set_atomicity_lock); | 593 | spin_lock(&set_atomicity_lock); |
| 570 | 594 | ||
| 571 | /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */ | 595 | /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */ |
| 572 | cr0 = read_cr0() | X86_CR0_CD; | 596 | cr0 = read_cr0() | X86_CR0_CD; |
| 573 | write_cr0(cr0); | 597 | write_cr0(cr0); |
| 574 | wbinvd(); | 598 | wbinvd(); |
| 575 | 599 | ||
| 576 | /* Save value of CR4 and clear Page Global Enable (bit 7) */ | 600 | /* Save value of CR4 and clear Page Global Enable (bit 7) */ |
| 577 | if ( cpu_has_pge ) { | 601 | if (cpu_has_pge) { |
| 578 | cr4 = read_cr4(); | 602 | cr4 = read_cr4(); |
| 579 | write_cr4(cr4 & ~X86_CR4_PGE); | 603 | write_cr4(cr4 & ~X86_CR4_PGE); |
| 580 | } | 604 | } |
| @@ -582,26 +606,26 @@ static void prepare_set(void) __acquires(set_atomicity_lock) | |||
| 582 | /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ | 606 | /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ |
| 583 | __flush_tlb(); | 607 | __flush_tlb(); |
| 584 | 608 | ||
| 585 | /* Save MTRR state */ | 609 | /* Save MTRR state */ |
| 586 | rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); | 610 | rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); |
| 587 | 611 | ||
| 588 | /* Disable MTRRs, and set the default type to uncached */ | 612 | /* Disable MTRRs, and set the default type to uncached */ |
| 589 | mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi); | 613 | mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi); |
| 590 | } | 614 | } |
| 591 | 615 | ||
| 592 | static void post_set(void) __releases(set_atomicity_lock) | 616 | static void post_set(void) __releases(set_atomicity_lock) |
| 593 | { | 617 | { |
| 594 | /* Flush TLBs (no need to flush caches - they are disabled) */ | 618 | /* Flush TLBs (no need to flush caches - they are disabled) */ |
| 595 | __flush_tlb(); | 619 | __flush_tlb(); |
| 596 | 620 | ||
| 597 | /* Intel (P6) standard MTRRs */ | 621 | /* Intel (P6) standard MTRRs */ |
| 598 | mtrr_wrmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); | 622 | mtrr_wrmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); |
| 599 | 623 | ||
| 600 | /* Enable caches */ | 624 | /* Enable caches */ |
| 601 | write_cr0(read_cr0() & 0xbfffffff); | 625 | write_cr0(read_cr0() & 0xbfffffff); |
| 602 | 626 | ||
| 603 | /* Restore value of CR4 */ | 627 | /* Restore value of CR4 */ |
| 604 | if ( cpu_has_pge ) | 628 | if (cpu_has_pge) |
| 605 | write_cr4(cr4); | 629 | write_cr4(cr4); |
| 606 | spin_unlock(&set_atomicity_lock); | 630 | spin_unlock(&set_atomicity_lock); |
| 607 | } | 631 | } |
| @@ -623,24 +647,27 @@ static void generic_set_all(void) | |||
| 623 | post_set(); | 647 | post_set(); |
| 624 | local_irq_restore(flags); | 648 | local_irq_restore(flags); |
| 625 | 649 | ||
| 626 | /* Use the atomic bitops to update the global mask */ | 650 | /* Use the atomic bitops to update the global mask */ |
| 627 | for (count = 0; count < sizeof mask * 8; ++count) { | 651 | for (count = 0; count < sizeof mask * 8; ++count) { |
| 628 | if (mask & 0x01) | 652 | if (mask & 0x01) |
| 629 | set_bit(count, &smp_changes_mask); | 653 | set_bit(count, &smp_changes_mask); |
| 630 | mask >>= 1; | 654 | mask >>= 1; |
| 631 | } | 655 | } |
| 632 | 656 | ||
| 633 | } | 657 | } |
| 634 | 658 | ||
| 659 | /** | ||
| 660 | * generic_set_mtrr - set variable MTRR register on the local CPU. | ||
| 661 | * | ||
| 662 | * @reg: The register to set. | ||
| 663 | * @base: The base address of the region. | ||
| 664 | * @size: The size of the region. If this is 0 the region is disabled. | ||
| 665 | * @type: The type of the region. | ||
| 666 | * | ||
| 667 | * Returns nothing. | ||
| 668 | */ | ||
| 635 | static void generic_set_mtrr(unsigned int reg, unsigned long base, | 669 | static void generic_set_mtrr(unsigned int reg, unsigned long base, |
| 636 | unsigned long size, mtrr_type type) | 670 | unsigned long size, mtrr_type type) |
| 637 | /* [SUMMARY] Set variable MTRR register on the local CPU. | ||
| 638 | <reg> The register to set. | ||
| 639 | <base> The base address of the region. | ||
| 640 | <size> The size of the region. If this is 0 the region is disabled. | ||
| 641 | <type> The type of the region. | ||
| 642 | [RETURNS] Nothing. | ||
| 643 | */ | ||
| 644 | { | 671 | { |
| 645 | unsigned long flags; | 672 | unsigned long flags; |
| 646 | struct mtrr_var_range *vr; | 673 | struct mtrr_var_range *vr; |
| @@ -651,8 +678,10 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base, | |||
| 651 | prepare_set(); | 678 | prepare_set(); |
| 652 | 679 | ||
| 653 | if (size == 0) { | 680 | if (size == 0) { |
| 654 | /* The invalid bit is kept in the mask, so we simply clear the | 681 | /* |
| 655 | relevant mask register to disable a range. */ | 682 | * The invalid bit is kept in the mask, so we simply |
| 683 | * clear the relevant mask register to disable a range. | ||
| 684 | */ | ||
| 656 | mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0); | 685 | mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0); |
| 657 | memset(vr, 0, sizeof(struct mtrr_var_range)); | 686 | memset(vr, 0, sizeof(struct mtrr_var_range)); |
| 658 | } else { | 687 | } else { |
| @@ -669,46 +698,50 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base, | |||
| 669 | local_irq_restore(flags); | 698 | local_irq_restore(flags); |
| 670 | } | 699 | } |
| 671 | 700 | ||
| 672 | int generic_validate_add_page(unsigned long base, unsigned long size, unsigned int type) | 701 | int generic_validate_add_page(unsigned long base, unsigned long size, |
| 702 | unsigned int type) | ||
| 673 | { | 703 | { |
| 674 | unsigned long lbase, last; | 704 | unsigned long lbase, last; |
| 675 | 705 | ||
| 676 | /* For Intel PPro stepping <= 7, must be 4 MiB aligned | 706 | /* |
| 677 | and not touch 0x70000000->0x7003FFFF */ | 707 | * For Intel PPro stepping <= 7 |
| 708 | * must be 4 MiB aligned and not touch 0x70000000 -> 0x7003FFFF | ||
| 709 | */ | ||
| 678 | if (is_cpu(INTEL) && boot_cpu_data.x86 == 6 && | 710 | if (is_cpu(INTEL) && boot_cpu_data.x86 == 6 && |
| 679 | boot_cpu_data.x86_model == 1 && | 711 | boot_cpu_data.x86_model == 1 && |
| 680 | boot_cpu_data.x86_mask <= 7) { | 712 | boot_cpu_data.x86_mask <= 7) { |
| 681 | if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) { | 713 | if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) { |
| 682 | printk(KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base); | 714 | pr_warning("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base); |
| 683 | return -EINVAL; | 715 | return -EINVAL; |
| 684 | } | 716 | } |
| 685 | if (!(base + size < 0x70000 || base > 0x7003F) && | 717 | if (!(base + size < 0x70000 || base > 0x7003F) && |
| 686 | (type == MTRR_TYPE_WRCOMB | 718 | (type == MTRR_TYPE_WRCOMB |
| 687 | || type == MTRR_TYPE_WRBACK)) { | 719 | || type == MTRR_TYPE_WRBACK)) { |
| 688 | printk(KERN_WARNING "mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n"); | 720 | pr_warning("mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n"); |
| 689 | return -EINVAL; | 721 | return -EINVAL; |
| 690 | } | 722 | } |
| 691 | } | 723 | } |
| 692 | 724 | ||
| 693 | /* Check upper bits of base and last are equal and lower bits are 0 | 725 | /* |
| 694 | for base and 1 for last */ | 726 | * Check upper bits of base and last are equal and lower bits are 0 |
| 727 | * for base and 1 for last | ||
| 728 | */ | ||
| 695 | last = base + size - 1; | 729 | last = base + size - 1; |
| 696 | for (lbase = base; !(lbase & 1) && (last & 1); | 730 | for (lbase = base; !(lbase & 1) && (last & 1); |
| 697 | lbase = lbase >> 1, last = last >> 1) ; | 731 | lbase = lbase >> 1, last = last >> 1) |
| 732 | ; | ||
| 698 | if (lbase != last) { | 733 | if (lbase != last) { |
| 699 | printk(KERN_WARNING "mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n", | 734 | pr_warning("mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n", base, size); |
| 700 | base, size); | ||
| 701 | return -EINVAL; | 735 | return -EINVAL; |
| 702 | } | 736 | } |
| 703 | return 0; | 737 | return 0; |
| 704 | } | 738 | } |
| 705 | 739 | ||
| 706 | |||
| 707 | static int generic_have_wrcomb(void) | 740 | static int generic_have_wrcomb(void) |
| 708 | { | 741 | { |
| 709 | unsigned long config, dummy; | 742 | unsigned long config, dummy; |
| 710 | rdmsr(MSR_MTRRcap, config, dummy); | 743 | rdmsr(MSR_MTRRcap, config, dummy); |
| 711 | return (config & (1 << 10)); | 744 | return config & (1 << 10); |
| 712 | } | 745 | } |
| 713 | 746 | ||
| 714 | int positive_have_wrcomb(void) | 747 | int positive_have_wrcomb(void) |
| @@ -716,14 +749,15 @@ int positive_have_wrcomb(void) | |||
| 716 | return 1; | 749 | return 1; |
| 717 | } | 750 | } |
| 718 | 751 | ||
| 719 | /* generic structure... | 752 | /* |
| 753 | * Generic structure... | ||
| 720 | */ | 754 | */ |
| 721 | struct mtrr_ops generic_mtrr_ops = { | 755 | struct mtrr_ops generic_mtrr_ops = { |
| 722 | .use_intel_if = 1, | 756 | .use_intel_if = 1, |
| 723 | .set_all = generic_set_all, | 757 | .set_all = generic_set_all, |
| 724 | .get = generic_get_mtrr, | 758 | .get = generic_get_mtrr, |
| 725 | .get_free_region = generic_get_free_region, | 759 | .get_free_region = generic_get_free_region, |
| 726 | .set = generic_set_mtrr, | 760 | .set = generic_set_mtrr, |
| 727 | .validate_add_page = generic_validate_add_page, | 761 | .validate_add_page = generic_validate_add_page, |
| 728 | .have_wrcomb = generic_have_wrcomb, | 762 | .have_wrcomb = generic_have_wrcomb, |
| 729 | }; | 763 | }; |
diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c index fb73a52913a4..08b6ea4c62b4 100644 --- a/arch/x86/kernel/cpu/mtrr/if.c +++ b/arch/x86/kernel/cpu/mtrr/if.c | |||
| @@ -1,27 +1,28 @@ | |||
| 1 | #include <linux/init.h> | ||
| 2 | #include <linux/proc_fs.h> | ||
| 3 | #include <linux/capability.h> | 1 | #include <linux/capability.h> |
| 4 | #include <linux/ctype.h> | ||
| 5 | #include <linux/module.h> | ||
| 6 | #include <linux/seq_file.h> | 2 | #include <linux/seq_file.h> |
| 7 | #include <asm/uaccess.h> | 3 | #include <linux/uaccess.h> |
| 4 | #include <linux/proc_fs.h> | ||
| 5 | #include <linux/module.h> | ||
| 6 | #include <linux/ctype.h> | ||
| 7 | #include <linux/init.h> | ||
| 8 | 8 | ||
| 9 | #define LINE_SIZE 80 | 9 | #define LINE_SIZE 80 |
| 10 | 10 | ||
| 11 | #include <asm/mtrr.h> | 11 | #include <asm/mtrr.h> |
| 12 | |||
| 12 | #include "mtrr.h" | 13 | #include "mtrr.h" |
| 13 | 14 | ||
| 14 | #define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private) | 15 | #define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private) |
| 15 | 16 | ||
| 16 | static const char *const mtrr_strings[MTRR_NUM_TYPES] = | 17 | static const char *const mtrr_strings[MTRR_NUM_TYPES] = |
| 17 | { | 18 | { |
| 18 | "uncachable", /* 0 */ | 19 | "uncachable", /* 0 */ |
| 19 | "write-combining", /* 1 */ | 20 | "write-combining", /* 1 */ |
| 20 | "?", /* 2 */ | 21 | "?", /* 2 */ |
| 21 | "?", /* 3 */ | 22 | "?", /* 3 */ |
| 22 | "write-through", /* 4 */ | 23 | "write-through", /* 4 */ |
| 23 | "write-protect", /* 5 */ | 24 | "write-protect", /* 5 */ |
| 24 | "write-back", /* 6 */ | 25 | "write-back", /* 6 */ |
| 25 | }; | 26 | }; |
| 26 | 27 | ||
| 27 | const char *mtrr_attrib_to_str(int x) | 28 | const char *mtrr_attrib_to_str(int x) |
| @@ -35,8 +36,8 @@ static int | |||
| 35 | mtrr_file_add(unsigned long base, unsigned long size, | 36 | mtrr_file_add(unsigned long base, unsigned long size, |
| 36 | unsigned int type, bool increment, struct file *file, int page) | 37 | unsigned int type, bool increment, struct file *file, int page) |
| 37 | { | 38 | { |
| 39 | unsigned int *fcount = FILE_FCOUNT(file); | ||
| 38 | int reg, max; | 40 | int reg, max; |
| 39 | unsigned int *fcount = FILE_FCOUNT(file); | ||
| 40 | 41 | ||
| 41 | max = num_var_ranges; | 42 | max = num_var_ranges; |
| 42 | if (fcount == NULL) { | 43 | if (fcount == NULL) { |
| @@ -61,8 +62,8 @@ static int | |||
| 61 | mtrr_file_del(unsigned long base, unsigned long size, | 62 | mtrr_file_del(unsigned long base, unsigned long size, |
| 62 | struct file *file, int page) | 63 | struct file *file, int page) |
| 63 | { | 64 | { |
| 64 | int reg; | ||
| 65 | unsigned int *fcount = FILE_FCOUNT(file); | 65 | unsigned int *fcount = FILE_FCOUNT(file); |
| 66 | int reg; | ||
| 66 | 67 | ||
| 67 | if (!page) { | 68 | if (!page) { |
| 68 | if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) | 69 | if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) |
| @@ -81,13 +82,14 @@ mtrr_file_del(unsigned long base, unsigned long size, | |||
| 81 | return reg; | 82 | return reg; |
| 82 | } | 83 | } |
| 83 | 84 | ||
| 84 | /* RED-PEN: seq_file can seek now. this is ignored. */ | 85 | /* |
| 86 | * seq_file can seek but we ignore it. | ||
| 87 | * | ||
| 88 | * Format of control line: | ||
| 89 | * "base=%Lx size=%Lx type=%s" or "disable=%d" | ||
| 90 | */ | ||
| 85 | static ssize_t | 91 | static ssize_t |
| 86 | mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos) | 92 | mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos) |
| 87 | /* Format of control line: | ||
| 88 | "base=%Lx size=%Lx type=%s" OR: | ||
| 89 | "disable=%d" | ||
| 90 | */ | ||
| 91 | { | 93 | { |
| 92 | int i, err; | 94 | int i, err; |
| 93 | unsigned long reg; | 95 | unsigned long reg; |
| @@ -100,15 +102,18 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos) | |||
| 100 | return -EPERM; | 102 | return -EPERM; |
| 101 | if (!len) | 103 | if (!len) |
| 102 | return -EINVAL; | 104 | return -EINVAL; |
| 105 | |||
| 103 | memset(line, 0, LINE_SIZE); | 106 | memset(line, 0, LINE_SIZE); |
| 104 | if (len > LINE_SIZE) | 107 | if (len > LINE_SIZE) |
| 105 | len = LINE_SIZE; | 108 | len = LINE_SIZE; |
| 106 | if (copy_from_user(line, buf, len - 1)) | 109 | if (copy_from_user(line, buf, len - 1)) |
| 107 | return -EFAULT; | 110 | return -EFAULT; |
| 111 | |||
| 108 | linelen = strlen(line); | 112 | linelen = strlen(line); |
| 109 | ptr = line + linelen - 1; | 113 | ptr = line + linelen - 1; |
| 110 | if (linelen && *ptr == '\n') | 114 | if (linelen && *ptr == '\n') |
| 111 | *ptr = '\0'; | 115 | *ptr = '\0'; |
| 116 | |||
| 112 | if (!strncmp(line, "disable=", 8)) { | 117 | if (!strncmp(line, "disable=", 8)) { |
| 113 | reg = simple_strtoul(line + 8, &ptr, 0); | 118 | reg = simple_strtoul(line + 8, &ptr, 0); |
| 114 | err = mtrr_del_page(reg, 0, 0); | 119 | err = mtrr_del_page(reg, 0, 0); |
| @@ -116,28 +121,35 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos) | |||
| 116 | return err; | 121 | return err; |
| 117 | return len; | 122 | return len; |
| 118 | } | 123 | } |
| 124 | |||
| 119 | if (strncmp(line, "base=", 5)) | 125 | if (strncmp(line, "base=", 5)) |
| 120 | return -EINVAL; | 126 | return -EINVAL; |
| 127 | |||
| 121 | base = simple_strtoull(line + 5, &ptr, 0); | 128 | base = simple_strtoull(line + 5, &ptr, 0); |
| 122 | for (; isspace(*ptr); ++ptr) ; | 129 | for (; isspace(*ptr); ++ptr) |
| 130 | ; | ||
| 131 | |||
| 123 | if (strncmp(ptr, "size=", 5)) | 132 | if (strncmp(ptr, "size=", 5)) |
| 124 | return -EINVAL; | 133 | return -EINVAL; |
| 134 | |||
| 125 | size = simple_strtoull(ptr + 5, &ptr, 0); | 135 | size = simple_strtoull(ptr + 5, &ptr, 0); |
| 126 | if ((base & 0xfff) || (size & 0xfff)) | 136 | if ((base & 0xfff) || (size & 0xfff)) |
| 127 | return -EINVAL; | 137 | return -EINVAL; |
| 128 | for (; isspace(*ptr); ++ptr) ; | 138 | for (; isspace(*ptr); ++ptr) |
| 139 | ; | ||
| 140 | |||
| 129 | if (strncmp(ptr, "type=", 5)) | 141 | if (strncmp(ptr, "type=", 5)) |
| 130 | return -EINVAL; | 142 | return -EINVAL; |
| 131 | ptr += 5; | 143 | ptr += 5; |
| 132 | for (; isspace(*ptr); ++ptr) ; | 144 | for (; isspace(*ptr); ++ptr) |
| 145 | ; | ||
| 146 | |||
| 133 | for (i = 0; i < MTRR_NUM_TYPES; ++i) { | 147 | for (i = 0; i < MTRR_NUM_TYPES; ++i) { |
| 134 | if (strcmp(ptr, mtrr_strings[i])) | 148 | if (strcmp(ptr, mtrr_strings[i])) |
| 135 | continue; | 149 | continue; |
| 136 | base >>= PAGE_SHIFT; | 150 | base >>= PAGE_SHIFT; |
| 137 | size >>= PAGE_SHIFT; | 151 | size >>= PAGE_SHIFT; |
| 138 | err = | 152 | err = mtrr_add_page((unsigned long)base, (unsigned long)size, i, true); |
| 139 | mtrr_add_page((unsigned long) base, (unsigned long) size, i, | ||
| 140 | true); | ||
| 141 | if (err < 0) | 153 | if (err < 0) |
| 142 | return err; | 154 | return err; |
| 143 | return len; | 155 | return len; |
| @@ -181,7 +193,9 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) | |||
| 181 | case MTRRIOC32_SET_PAGE_ENTRY: | 193 | case MTRRIOC32_SET_PAGE_ENTRY: |
| 182 | case MTRRIOC32_DEL_PAGE_ENTRY: | 194 | case MTRRIOC32_DEL_PAGE_ENTRY: |
| 183 | case MTRRIOC32_KILL_PAGE_ENTRY: { | 195 | case MTRRIOC32_KILL_PAGE_ENTRY: { |
| 184 | struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)__arg; | 196 | struct mtrr_sentry32 __user *s32; |
| 197 | |||
| 198 | s32 = (struct mtrr_sentry32 __user *)__arg; | ||
| 185 | err = get_user(sentry.base, &s32->base); | 199 | err = get_user(sentry.base, &s32->base); |
| 186 | err |= get_user(sentry.size, &s32->size); | 200 | err |= get_user(sentry.size, &s32->size); |
| 187 | err |= get_user(sentry.type, &s32->type); | 201 | err |= get_user(sentry.type, &s32->type); |
| @@ -191,7 +205,9 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) | |||
| 191 | } | 205 | } |
| 192 | case MTRRIOC32_GET_ENTRY: | 206 | case MTRRIOC32_GET_ENTRY: |
| 193 | case MTRRIOC32_GET_PAGE_ENTRY: { | 207 | case MTRRIOC32_GET_PAGE_ENTRY: { |
| 194 | struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg; | 208 | struct mtrr_gentry32 __user *g32; |
| 209 | |||
| 210 | g32 = (struct mtrr_gentry32 __user *)__arg; | ||
| 195 | err = get_user(gentry.regnum, &g32->regnum); | 211 | err = get_user(gentry.regnum, &g32->regnum); |
| 196 | err |= get_user(gentry.base, &g32->base); | 212 | err |= get_user(gentry.base, &g32->base); |
| 197 | err |= get_user(gentry.size, &g32->size); | 213 | err |= get_user(gentry.size, &g32->size); |
| @@ -314,7 +330,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) | |||
| 314 | if (err) | 330 | if (err) |
| 315 | return err; | 331 | return err; |
| 316 | 332 | ||
| 317 | switch(cmd) { | 333 | switch (cmd) { |
| 318 | case MTRRIOC_GET_ENTRY: | 334 | case MTRRIOC_GET_ENTRY: |
| 319 | case MTRRIOC_GET_PAGE_ENTRY: | 335 | case MTRRIOC_GET_PAGE_ENTRY: |
| 320 | if (copy_to_user(arg, &gentry, sizeof gentry)) | 336 | if (copy_to_user(arg, &gentry, sizeof gentry)) |
| @@ -323,7 +339,9 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) | |||
| 323 | #ifdef CONFIG_COMPAT | 339 | #ifdef CONFIG_COMPAT |
| 324 | case MTRRIOC32_GET_ENTRY: | 340 | case MTRRIOC32_GET_ENTRY: |
| 325 | case MTRRIOC32_GET_PAGE_ENTRY: { | 341 | case MTRRIOC32_GET_PAGE_ENTRY: { |
| 326 | struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg; | 342 | struct mtrr_gentry32 __user *g32; |
| 343 | |||
| 344 | g32 = (struct mtrr_gentry32 __user *)__arg; | ||
| 327 | err = put_user(gentry.base, &g32->base); | 345 | err = put_user(gentry.base, &g32->base); |
| 328 | err |= put_user(gentry.size, &g32->size); | 346 | err |= put_user(gentry.size, &g32->size); |
| 329 | err |= put_user(gentry.regnum, &g32->regnum); | 347 | err |= put_user(gentry.regnum, &g32->regnum); |
| @@ -335,11 +353,10 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) | |||
| 335 | return err; | 353 | return err; |
| 336 | } | 354 | } |
| 337 | 355 | ||
| 338 | static int | 356 | static int mtrr_close(struct inode *ino, struct file *file) |
| 339 | mtrr_close(struct inode *ino, struct file *file) | ||
| 340 | { | 357 | { |
| 341 | int i, max; | ||
| 342 | unsigned int *fcount = FILE_FCOUNT(file); | 358 | unsigned int *fcount = FILE_FCOUNT(file); |
| 359 | int i, max; | ||
| 343 | 360 | ||
| 344 | if (fcount != NULL) { | 361 | if (fcount != NULL) { |
| 345 | max = num_var_ranges; | 362 | max = num_var_ranges; |
| @@ -359,22 +376,22 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset); | |||
| 359 | 376 | ||
| 360 | static int mtrr_open(struct inode *inode, struct file *file) | 377 | static int mtrr_open(struct inode *inode, struct file *file) |
| 361 | { | 378 | { |
| 362 | if (!mtrr_if) | 379 | if (!mtrr_if) |
| 363 | return -EIO; | 380 | return -EIO; |
| 364 | if (!mtrr_if->get) | 381 | if (!mtrr_if->get) |
| 365 | return -ENXIO; | 382 | return -ENXIO; |
| 366 | return single_open(file, mtrr_seq_show, NULL); | 383 | return single_open(file, mtrr_seq_show, NULL); |
| 367 | } | 384 | } |
| 368 | 385 | ||
| 369 | static const struct file_operations mtrr_fops = { | 386 | static const struct file_operations mtrr_fops = { |
| 370 | .owner = THIS_MODULE, | 387 | .owner = THIS_MODULE, |
| 371 | .open = mtrr_open, | 388 | .open = mtrr_open, |
| 372 | .read = seq_read, | 389 | .read = seq_read, |
| 373 | .llseek = seq_lseek, | 390 | .llseek = seq_lseek, |
| 374 | .write = mtrr_write, | 391 | .write = mtrr_write, |
| 375 | .unlocked_ioctl = mtrr_ioctl, | 392 | .unlocked_ioctl = mtrr_ioctl, |
| 376 | .compat_ioctl = mtrr_ioctl, | 393 | .compat_ioctl = mtrr_ioctl, |
| 377 | .release = mtrr_close, | 394 | .release = mtrr_close, |
| 378 | }; | 395 | }; |
| 379 | 396 | ||
| 380 | static int mtrr_seq_show(struct seq_file *seq, void *offset) | 397 | static int mtrr_seq_show(struct seq_file *seq, void *offset) |
| @@ -388,23 +405,24 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset) | |||
| 388 | max = num_var_ranges; | 405 | max = num_var_ranges; |
| 389 | for (i = 0; i < max; i++) { | 406 | for (i = 0; i < max; i++) { |
| 390 | mtrr_if->get(i, &base, &size, &type); | 407 | mtrr_if->get(i, &base, &size, &type); |
| 391 | if (size == 0) | 408 | if (size == 0) { |
| 392 | mtrr_usage_table[i] = 0; | 409 | mtrr_usage_table[i] = 0; |
| 393 | else { | 410 | continue; |
| 394 | if (size < (0x100000 >> PAGE_SHIFT)) { | ||
| 395 | /* less than 1MB */ | ||
| 396 | factor = 'K'; | ||
| 397 | size <<= PAGE_SHIFT - 10; | ||
| 398 | } else { | ||
| 399 | factor = 'M'; | ||
| 400 | size >>= 20 - PAGE_SHIFT; | ||
| 401 | } | ||
| 402 | /* RED-PEN: base can be > 32bit */ | ||
| 403 | len += seq_printf(seq, | ||
| 404 | "reg%02i: base=0x%06lx000 (%5luMB), size=%5lu%cB, count=%d: %s\n", | ||
| 405 | i, base, base >> (20 - PAGE_SHIFT), size, factor, | ||
| 406 | mtrr_usage_table[i], mtrr_attrib_to_str(type)); | ||
| 407 | } | 411 | } |
| 412 | if (size < (0x100000 >> PAGE_SHIFT)) { | ||
| 413 | /* less than 1MB */ | ||
| 414 | factor = 'K'; | ||
| 415 | size <<= PAGE_SHIFT - 10; | ||
| 416 | } else { | ||
| 417 | factor = 'M'; | ||
| 418 | size >>= 20 - PAGE_SHIFT; | ||
| 419 | } | ||
| 420 | /* Base can be > 32bit */ | ||
| 421 | len += seq_printf(seq, "reg%02i: base=0x%06lx000 " | ||
| 422 | "(%5luMB), size=%5lu%cB, count=%d: %s\n", | ||
| 423 | i, base, base >> (20 - PAGE_SHIFT), size, | ||
| 424 | factor, mtrr_usage_table[i], | ||
| 425 | mtrr_attrib_to_str(type)); | ||
| 408 | } | 426 | } |
| 409 | return 0; | 427 | return 0; |
| 410 | } | 428 | } |
| @@ -422,6 +440,5 @@ static int __init mtrr_if_init(void) | |||
| 422 | proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops); | 440 | proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops); |
| 423 | return 0; | 441 | return 0; |
| 424 | } | 442 | } |
| 425 | |||
| 426 | arch_initcall(mtrr_if_init); | 443 | arch_initcall(mtrr_if_init); |
| 427 | #endif /* CONFIG_PROC_FS */ | 444 | #endif /* CONFIG_PROC_FS */ |
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 8fc248b5aeaf..7af0f88a4163 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c | |||
| @@ -25,43 +25,48 @@ | |||
| 25 | Operating System Writer's Guide" (Intel document number 242692), | 25 | Operating System Writer's Guide" (Intel document number 242692), |
| 26 | section 11.11.7 | 26 | section 11.11.7 |
| 27 | 27 | ||
| 28 | This was cleaned and made readable by Patrick Mochel <mochel@osdl.org> | 28 | This was cleaned and made readable by Patrick Mochel <mochel@osdl.org> |
| 29 | on 6-7 March 2002. | 29 | on 6-7 March 2002. |
| 30 | Source: Intel Architecture Software Developers Manual, Volume 3: | 30 | Source: Intel Architecture Software Developers Manual, Volume 3: |
| 31 | System Programming Guide; Section 9.11. (1997 edition - PPro). | 31 | System Programming Guide; Section 9.11. (1997 edition - PPro). |
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | #define DEBUG | ||
| 35 | |||
| 36 | #include <linux/types.h> /* FIXME: kvm_para.h needs this */ | ||
| 37 | |||
| 38 | #include <linux/kvm_para.h> | ||
| 39 | #include <linux/uaccess.h> | ||
| 34 | #include <linux/module.h> | 40 | #include <linux/module.h> |
| 41 | #include <linux/mutex.h> | ||
| 35 | #include <linux/init.h> | 42 | #include <linux/init.h> |
| 43 | #include <linux/sort.h> | ||
| 44 | #include <linux/cpu.h> | ||
| 36 | #include <linux/pci.h> | 45 | #include <linux/pci.h> |
| 37 | #include <linux/smp.h> | 46 | #include <linux/smp.h> |
| 38 | #include <linux/cpu.h> | ||
| 39 | #include <linux/mutex.h> | ||
| 40 | #include <linux/sort.h> | ||
| 41 | 47 | ||
| 48 | #include <asm/processor.h> | ||
| 42 | #include <asm/e820.h> | 49 | #include <asm/e820.h> |
| 43 | #include <asm/mtrr.h> | 50 | #include <asm/mtrr.h> |
| 44 | #include <asm/uaccess.h> | ||
| 45 | #include <asm/processor.h> | ||
| 46 | #include <asm/msr.h> | 51 | #include <asm/msr.h> |
| 47 | #include <asm/kvm_para.h> | 52 | |
| 48 | #include "mtrr.h" | 53 | #include "mtrr.h" |
| 49 | 54 | ||
| 50 | u32 num_var_ranges = 0; | 55 | u32 num_var_ranges; |
| 51 | 56 | ||
| 52 | unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES]; | 57 | unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES]; |
| 53 | static DEFINE_MUTEX(mtrr_mutex); | 58 | static DEFINE_MUTEX(mtrr_mutex); |
| 54 | 59 | ||
| 55 | u64 size_or_mask, size_and_mask; | 60 | u64 size_or_mask, size_and_mask; |
| 56 | 61 | ||
| 57 | static struct mtrr_ops * mtrr_ops[X86_VENDOR_NUM] = {}; | 62 | static struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM]; |
| 58 | 63 | ||
| 59 | struct mtrr_ops * mtrr_if = NULL; | 64 | struct mtrr_ops *mtrr_if; |
| 60 | 65 | ||
| 61 | static void set_mtrr(unsigned int reg, unsigned long base, | 66 | static void set_mtrr(unsigned int reg, unsigned long base, |
| 62 | unsigned long size, mtrr_type type); | 67 | unsigned long size, mtrr_type type); |
| 63 | 68 | ||
| 64 | void set_mtrr_ops(struct mtrr_ops * ops) | 69 | void set_mtrr_ops(struct mtrr_ops *ops) |
| 65 | { | 70 | { |
| 66 | if (ops->vendor && ops->vendor < X86_VENDOR_NUM) | 71 | if (ops->vendor && ops->vendor < X86_VENDOR_NUM) |
| 67 | mtrr_ops[ops->vendor] = ops; | 72 | mtrr_ops[ops->vendor] = ops; |
| @@ -72,30 +77,36 @@ static int have_wrcomb(void) | |||
| 72 | { | 77 | { |
| 73 | struct pci_dev *dev; | 78 | struct pci_dev *dev; |
| 74 | u8 rev; | 79 | u8 rev; |
| 75 | 80 | ||
| 76 | if ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) { | 81 | dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL); |
| 77 | /* ServerWorks LE chipsets < rev 6 have problems with write-combining | 82 | if (dev != NULL) { |
| 78 | Don't allow it and leave room for other chipsets to be tagged */ | 83 | /* |
| 84 | * ServerWorks LE chipsets < rev 6 have problems with | ||
| 85 | * write-combining. Don't allow it and leave room for other | ||
| 86 | * chipsets to be tagged | ||
| 87 | */ | ||
| 79 | if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS && | 88 | if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS && |
| 80 | dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) { | 89 | dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) { |
| 81 | pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); | 90 | pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); |
| 82 | if (rev <= 5) { | 91 | if (rev <= 5) { |
| 83 | printk(KERN_INFO "mtrr: Serverworks LE rev < 6 detected. Write-combining disabled.\n"); | 92 | pr_info("mtrr: Serverworks LE rev < 6 detected. Write-combining disabled.\n"); |
| 84 | pci_dev_put(dev); | 93 | pci_dev_put(dev); |
| 85 | return 0; | 94 | return 0; |
| 86 | } | 95 | } |
| 87 | } | 96 | } |
| 88 | /* Intel 450NX errata # 23. Non ascending cacheline evictions to | 97 | /* |
| 89 | write combining memory may resulting in data corruption */ | 98 | * Intel 450NX errata # 23. Non ascending cacheline evictions to |
| 99 | * write combining memory may resulting in data corruption | ||
| 100 | */ | ||
| 90 | if (dev->vendor == PCI_VENDOR_ID_INTEL && | 101 | if (dev->vendor == PCI_VENDOR_ID_INTEL && |
| 91 | dev->device == PCI_DEVICE_ID_INTEL_82451NX) { | 102 | dev->device == PCI_DEVICE_ID_INTEL_82451NX) { |
| 92 | printk(KERN_INFO "mtrr: Intel 450NX MMC detected. Write-combining disabled.\n"); | 103 | pr_info("mtrr: Intel 450NX MMC detected. Write-combining disabled.\n"); |
| 93 | pci_dev_put(dev); | 104 | pci_dev_put(dev); |
| 94 | return 0; | 105 | return 0; |
| 95 | } | 106 | } |
| 96 | pci_dev_put(dev); | 107 | pci_dev_put(dev); |
| 97 | } | 108 | } |
| 98 | return (mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0); | 109 | return mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0; |
| 99 | } | 110 | } |
| 100 | 111 | ||
| 101 | /* This function returns the number of variable MTRRs */ | 112 | /* This function returns the number of variable MTRRs */ |
| @@ -103,12 +114,13 @@ static void __init set_num_var_ranges(void) | |||
| 103 | { | 114 | { |
| 104 | unsigned long config = 0, dummy; | 115 | unsigned long config = 0, dummy; |
| 105 | 116 | ||
| 106 | if (use_intel()) { | 117 | if (use_intel()) |
| 107 | rdmsr(MSR_MTRRcap, config, dummy); | 118 | rdmsr(MSR_MTRRcap, config, dummy); |
| 108 | } else if (is_cpu(AMD)) | 119 | else if (is_cpu(AMD)) |
| 109 | config = 2; | 120 | config = 2; |
| 110 | else if (is_cpu(CYRIX) || is_cpu(CENTAUR)) | 121 | else if (is_cpu(CYRIX) || is_cpu(CENTAUR)) |
| 111 | config = 8; | 122 | config = 8; |
| 123 | |||
| 112 | num_var_ranges = config & 0xff; | 124 | num_var_ranges = config & 0xff; |
| 113 | } | 125 | } |
| 114 | 126 | ||
| @@ -130,10 +142,12 @@ struct set_mtrr_data { | |||
| 130 | mtrr_type smp_type; | 142 | mtrr_type smp_type; |
| 131 | }; | 143 | }; |
| 132 | 144 | ||
| 145 | /** | ||
| 146 | * ipi_handler - Synchronisation handler. Executed by "other" CPUs. | ||
| 147 | * | ||
| 148 | * Returns nothing. | ||
| 149 | */ | ||
| 133 | static void ipi_handler(void *info) | 150 | static void ipi_handler(void *info) |
| 134 | /* [SUMMARY] Synchronisation handler. Executed by "other" CPUs. | ||
| 135 | [RETURNS] Nothing. | ||
| 136 | */ | ||
| 137 | { | 151 | { |
| 138 | #ifdef CONFIG_SMP | 152 | #ifdef CONFIG_SMP |
| 139 | struct set_mtrr_data *data = info; | 153 | struct set_mtrr_data *data = info; |
| @@ -142,18 +156,19 @@ static void ipi_handler(void *info) | |||
| 142 | local_irq_save(flags); | 156 | local_irq_save(flags); |
| 143 | 157 | ||
| 144 | atomic_dec(&data->count); | 158 | atomic_dec(&data->count); |
| 145 | while(!atomic_read(&data->gate)) | 159 | while (!atomic_read(&data->gate)) |
| 146 | cpu_relax(); | 160 | cpu_relax(); |
| 147 | 161 | ||
| 148 | /* The master has cleared me to execute */ | 162 | /* The master has cleared me to execute */ |
| 149 | if (data->smp_reg != ~0U) | 163 | if (data->smp_reg != ~0U) { |
| 150 | mtrr_if->set(data->smp_reg, data->smp_base, | 164 | mtrr_if->set(data->smp_reg, data->smp_base, |
| 151 | data->smp_size, data->smp_type); | 165 | data->smp_size, data->smp_type); |
| 152 | else | 166 | } else { |
| 153 | mtrr_if->set_all(); | 167 | mtrr_if->set_all(); |
| 168 | } | ||
| 154 | 169 | ||
| 155 | atomic_dec(&data->count); | 170 | atomic_dec(&data->count); |
| 156 | while(atomic_read(&data->gate)) | 171 | while (atomic_read(&data->gate)) |
| 157 | cpu_relax(); | 172 | cpu_relax(); |
| 158 | 173 | ||
| 159 | atomic_dec(&data->count); | 174 | atomic_dec(&data->count); |
| @@ -161,7 +176,8 @@ static void ipi_handler(void *info) | |||
| 161 | #endif | 176 | #endif |
| 162 | } | 177 | } |
| 163 | 178 | ||
| 164 | static inline int types_compatible(mtrr_type type1, mtrr_type type2) { | 179 | static inline int types_compatible(mtrr_type type1, mtrr_type type2) |
| 180 | { | ||
| 165 | return type1 == MTRR_TYPE_UNCACHABLE || | 181 | return type1 == MTRR_TYPE_UNCACHABLE || |
| 166 | type2 == MTRR_TYPE_UNCACHABLE || | 182 | type2 == MTRR_TYPE_UNCACHABLE || |
| 167 | (type1 == MTRR_TYPE_WRTHROUGH && type2 == MTRR_TYPE_WRBACK) || | 183 | (type1 == MTRR_TYPE_WRTHROUGH && type2 == MTRR_TYPE_WRBACK) || |
| @@ -176,10 +192,10 @@ static inline int types_compatible(mtrr_type type1, mtrr_type type2) { | |||
| 176 | * @type: mtrr type | 192 | * @type: mtrr type |
| 177 | * | 193 | * |
| 178 | * This is kinda tricky, but fortunately, Intel spelled it out for us cleanly: | 194 | * This is kinda tricky, but fortunately, Intel spelled it out for us cleanly: |
| 179 | * | 195 | * |
| 180 | * 1. Send IPI to do the following: | 196 | * 1. Send IPI to do the following: |
| 181 | * 2. Disable Interrupts | 197 | * 2. Disable Interrupts |
| 182 | * 3. Wait for all procs to do so | 198 | * 3. Wait for all procs to do so |
| 183 | * 4. Enter no-fill cache mode | 199 | * 4. Enter no-fill cache mode |
| 184 | * 5. Flush caches | 200 | * 5. Flush caches |
| 185 | * 6. Clear PGE bit | 201 | * 6. Clear PGE bit |
| @@ -189,26 +205,27 @@ static inline int types_compatible(mtrr_type type1, mtrr_type type2) { | |||
| 189 | * 10. Enable all range registers | 205 | * 10. Enable all range registers |
| 190 | * 11. Flush all TLBs and caches again | 206 | * 11. Flush all TLBs and caches again |
| 191 | * 12. Enter normal cache mode and reenable caching | 207 | * 12. Enter normal cache mode and reenable caching |
| 192 | * 13. Set PGE | 208 | * 13. Set PGE |
| 193 | * 14. Wait for buddies to catch up | 209 | * 14. Wait for buddies to catch up |
| 194 | * 15. Enable interrupts. | 210 | * 15. Enable interrupts. |
| 195 | * | 211 | * |
| 196 | * What does that mean for us? Well, first we set data.count to the number | 212 | * What does that mean for us? Well, first we set data.count to the number |
| 197 | * of CPUs. As each CPU disables interrupts, it'll decrement it once. We wait | 213 | * of CPUs. As each CPU disables interrupts, it'll decrement it once. We wait |
| 198 | * until it hits 0 and proceed. We set the data.gate flag and reset data.count. | 214 | * until it hits 0 and proceed. We set the data.gate flag and reset data.count. |
| 199 | * Meanwhile, they are waiting for that flag to be set. Once it's set, each | 215 | * Meanwhile, they are waiting for that flag to be set. Once it's set, each |
| 200 | * CPU goes through the transition of updating MTRRs. The CPU vendors may each do it | 216 | * CPU goes through the transition of updating MTRRs. |
| 201 | * differently, so we call mtrr_if->set() callback and let them take care of it. | 217 | * The CPU vendors may each do it differently, |
| 202 | * When they're done, they again decrement data->count and wait for data.gate to | 218 | * so we call mtrr_if->set() callback and let them take care of it. |
| 203 | * be reset. | 219 | * When they're done, they again decrement data->count and wait for data.gate |
| 204 | * When we finish, we wait for data.count to hit 0 and toggle the data.gate flag. | 220 | * to be reset. |
| 221 | * When we finish, we wait for data.count to hit 0 and toggle the data.gate flag | ||
| 205 | * Everyone then enables interrupts and we all continue on. | 222 | * Everyone then enables interrupts and we all continue on. |
| 206 | * | 223 | * |
| 207 | * Note that the mechanism is the same for UP systems, too; all the SMP stuff | 224 | * Note that the mechanism is the same for UP systems, too; all the SMP stuff |
| 208 | * becomes nops. | 225 | * becomes nops. |
| 209 | */ | 226 | */ |
| 210 | static void set_mtrr(unsigned int reg, unsigned long base, | 227 | static void |
| 211 | unsigned long size, mtrr_type type) | 228 | set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type) |
| 212 | { | 229 | { |
| 213 | struct set_mtrr_data data; | 230 | struct set_mtrr_data data; |
| 214 | unsigned long flags; | 231 | unsigned long flags; |
| @@ -218,121 +235,122 @@ static void set_mtrr(unsigned int reg, unsigned long base, | |||
| 218 | data.smp_size = size; | 235 | data.smp_size = size; |
| 219 | data.smp_type = type; | 236 | data.smp_type = type; |
| 220 | atomic_set(&data.count, num_booting_cpus() - 1); | 237 | atomic_set(&data.count, num_booting_cpus() - 1); |
| 221 | /* make sure data.count is visible before unleashing other CPUs */ | 238 | |
| 239 | /* Make sure data.count is visible before unleashing other CPUs */ | ||
| 222 | smp_wmb(); | 240 | smp_wmb(); |
| 223 | atomic_set(&data.gate,0); | 241 | atomic_set(&data.gate, 0); |
| 224 | 242 | ||
| 225 | /* Start the ball rolling on other CPUs */ | 243 | /* Start the ball rolling on other CPUs */ |
| 226 | if (smp_call_function(ipi_handler, &data, 0) != 0) | 244 | if (smp_call_function(ipi_handler, &data, 0) != 0) |
| 227 | panic("mtrr: timed out waiting for other CPUs\n"); | 245 | panic("mtrr: timed out waiting for other CPUs\n"); |
| 228 | 246 | ||
| 229 | local_irq_save(flags); | 247 | local_irq_save(flags); |
| 230 | 248 | ||
| 231 | while(atomic_read(&data.count)) | 249 | while (atomic_read(&data.count)) |
| 232 | cpu_relax(); | 250 | cpu_relax(); |
| 233 | 251 | ||
| 234 | /* ok, reset count and toggle gate */ | 252 | /* Ok, reset count and toggle gate */ |
| 235 | atomic_set(&data.count, num_booting_cpus() - 1); | 253 | atomic_set(&data.count, num_booting_cpus() - 1); |
| 236 | smp_wmb(); | 254 | smp_wmb(); |
| 237 | atomic_set(&data.gate,1); | 255 | atomic_set(&data.gate, 1); |
| 238 | 256 | ||
| 239 | /* do our MTRR business */ | 257 | /* Do our MTRR business */ |
| 240 | 258 | ||
| 241 | /* HACK! | 259 | /* |
| 260 | * HACK! | ||
| 242 | * We use this same function to initialize the mtrrs on boot. | 261 | * We use this same function to initialize the mtrrs on boot. |
| 243 | * The state of the boot cpu's mtrrs has been saved, and we want | 262 | * The state of the boot cpu's mtrrs has been saved, and we want |
| 244 | * to replicate across all the APs. | 263 | * to replicate across all the APs. |
| 245 | * If we're doing that @reg is set to something special... | 264 | * If we're doing that @reg is set to something special... |
| 246 | */ | 265 | */ |
| 247 | if (reg != ~0U) | 266 | if (reg != ~0U) |
| 248 | mtrr_if->set(reg,base,size,type); | 267 | mtrr_if->set(reg, base, size, type); |
| 249 | 268 | ||
| 250 | /* wait for the others */ | 269 | /* Wait for the others */ |
| 251 | while(atomic_read(&data.count)) | 270 | while (atomic_read(&data.count)) |
| 252 | cpu_relax(); | 271 | cpu_relax(); |
| 253 | 272 | ||
| 254 | atomic_set(&data.count, num_booting_cpus() - 1); | 273 | atomic_set(&data.count, num_booting_cpus() - 1); |
| 255 | smp_wmb(); | 274 | smp_wmb(); |
| 256 | atomic_set(&data.gate,0); | 275 | atomic_set(&data.gate, 0); |
| 257 | 276 | ||
| 258 | /* | 277 | /* |
| 259 | * Wait here for everyone to have seen the gate change | 278 | * Wait here for everyone to have seen the gate change |
| 260 | * So we're the last ones to touch 'data' | 279 | * So we're the last ones to touch 'data' |
| 261 | */ | 280 | */ |
| 262 | while(atomic_read(&data.count)) | 281 | while (atomic_read(&data.count)) |
| 263 | cpu_relax(); | 282 | cpu_relax(); |
| 264 | 283 | ||
| 265 | local_irq_restore(flags); | 284 | local_irq_restore(flags); |
| 266 | } | 285 | } |
| 267 | 286 | ||
| 268 | /** | 287 | /** |
| 269 | * mtrr_add_page - Add a memory type region | 288 | * mtrr_add_page - Add a memory type region |
| 270 | * @base: Physical base address of region in pages (in units of 4 kB!) | 289 | * @base: Physical base address of region in pages (in units of 4 kB!) |
| 271 | * @size: Physical size of region in pages (4 kB) | 290 | * @size: Physical size of region in pages (4 kB) |
| 272 | * @type: Type of MTRR desired | 291 | * @type: Type of MTRR desired |
| 273 | * @increment: If this is true do usage counting on the region | 292 | * @increment: If this is true do usage counting on the region |
| 274 | * | 293 | * |
| 275 | * Memory type region registers control the caching on newer Intel and | 294 | * Memory type region registers control the caching on newer Intel and |
| 276 | * non Intel processors. This function allows drivers to request an | 295 | * non Intel processors. This function allows drivers to request an |
| 277 | * MTRR is added. The details and hardware specifics of each processor's | 296 | * MTRR is added. The details and hardware specifics of each processor's |
| 278 | * implementation are hidden from the caller, but nevertheless the | 297 | * implementation are hidden from the caller, but nevertheless the |
| 279 | * caller should expect to need to provide a power of two size on an | 298 | * caller should expect to need to provide a power of two size on an |
| 280 | * equivalent power of two boundary. | 299 | * equivalent power of two boundary. |
| 281 | * | 300 | * |
| 282 | * If the region cannot be added either because all regions are in use | 301 | * If the region cannot be added either because all regions are in use |
| 283 | * or the CPU cannot support it a negative value is returned. On success | 302 | * or the CPU cannot support it a negative value is returned. On success |
| 284 | * the register number for this entry is returned, but should be treated | 303 | * the register number for this entry is returned, but should be treated |
| 285 | * as a cookie only. | 304 | * as a cookie only. |
| 286 | * | 305 | * |
| 287 | * On a multiprocessor machine the changes are made to all processors. | 306 | * On a multiprocessor machine the changes are made to all processors. |
| 288 | * This is required on x86 by the Intel processors. | 307 | * This is required on x86 by the Intel processors. |
| 289 | * | 308 | * |
| 290 | * The available types are | 309 | * The available types are |
| 291 | * | 310 | * |
| 292 | * %MTRR_TYPE_UNCACHABLE - No caching | 311 | * %MTRR_TYPE_UNCACHABLE - No caching |
| 293 | * | 312 | * |
| 294 | * %MTRR_TYPE_WRBACK - Write data back in bursts whenever | 313 | * %MTRR_TYPE_WRBACK - Write data back in bursts whenever |
| 295 | * | 314 | * |
| 296 | * %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts | 315 | * %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts |
| 297 | * | 316 | * |
| 298 | * %MTRR_TYPE_WRTHROUGH - Cache reads but not writes | 317 | * %MTRR_TYPE_WRTHROUGH - Cache reads but not writes |
| 299 | * | 318 | * |
| 300 | * BUGS: Needs a quiet flag for the cases where drivers do not mind | 319 | * BUGS: Needs a quiet flag for the cases where drivers do not mind |
| 301 | * failures and do not wish system log messages to be sent. | 320 | * failures and do not wish system log messages to be sent. |
| 302 | */ | 321 | */ |
| 303 | 322 | int mtrr_add_page(unsigned long base, unsigned long size, | |
| 304 | int mtrr_add_page(unsigned long base, unsigned long size, | ||
| 305 | unsigned int type, bool increment) | 323 | unsigned int type, bool increment) |
| 306 | { | 324 | { |
| 325 | unsigned long lbase, lsize; | ||
| 307 | int i, replace, error; | 326 | int i, replace, error; |
| 308 | mtrr_type ltype; | 327 | mtrr_type ltype; |
| 309 | unsigned long lbase, lsize; | ||
| 310 | 328 | ||
| 311 | if (!mtrr_if) | 329 | if (!mtrr_if) |
| 312 | return -ENXIO; | 330 | return -ENXIO; |
| 313 | 331 | ||
| 314 | if ((error = mtrr_if->validate_add_page(base,size,type))) | 332 | error = mtrr_if->validate_add_page(base, size, type); |
| 333 | if (error) | ||
| 315 | return error; | 334 | return error; |
| 316 | 335 | ||
| 317 | if (type >= MTRR_NUM_TYPES) { | 336 | if (type >= MTRR_NUM_TYPES) { |
| 318 | printk(KERN_WARNING "mtrr: type: %u invalid\n", type); | 337 | pr_warning("mtrr: type: %u invalid\n", type); |
| 319 | return -EINVAL; | 338 | return -EINVAL; |
| 320 | } | 339 | } |
| 321 | 340 | ||
| 322 | /* If the type is WC, check that this processor supports it */ | 341 | /* If the type is WC, check that this processor supports it */ |
| 323 | if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) { | 342 | if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) { |
| 324 | printk(KERN_WARNING | 343 | pr_warning("mtrr: your processor doesn't support write-combining\n"); |
| 325 | "mtrr: your processor doesn't support write-combining\n"); | ||
| 326 | return -ENOSYS; | 344 | return -ENOSYS; |
| 327 | } | 345 | } |
| 328 | 346 | ||
| 329 | if (!size) { | 347 | if (!size) { |
| 330 | printk(KERN_WARNING "mtrr: zero sized request\n"); | 348 | pr_warning("mtrr: zero sized request\n"); |
| 331 | return -EINVAL; | 349 | return -EINVAL; |
| 332 | } | 350 | } |
| 333 | 351 | ||
| 334 | if (base & size_or_mask || size & size_or_mask) { | 352 | if (base & size_or_mask || size & size_or_mask) { |
| 335 | printk(KERN_WARNING "mtrr: base or size exceeds the MTRR width\n"); | 353 | pr_warning("mtrr: base or size exceeds the MTRR width\n"); |
| 336 | return -EINVAL; | 354 | return -EINVAL; |
| 337 | } | 355 | } |
| 338 | 356 | ||
| @@ -341,36 +359,40 @@ int mtrr_add_page(unsigned long base, unsigned long size, | |||
| 341 | 359 | ||
| 342 | /* No CPU hotplug when we change MTRR entries */ | 360 | /* No CPU hotplug when we change MTRR entries */ |
| 343 | get_online_cpus(); | 361 | get_online_cpus(); |
| 344 | /* Search for existing MTRR */ | 362 | |
| 363 | /* Search for existing MTRR */ | ||
| 345 | mutex_lock(&mtrr_mutex); | 364 | mutex_lock(&mtrr_mutex); |
| 346 | for (i = 0; i < num_var_ranges; ++i) { | 365 | for (i = 0; i < num_var_ranges; ++i) { |
| 347 | mtrr_if->get(i, &lbase, &lsize, <ype); | 366 | mtrr_if->get(i, &lbase, &lsize, <ype); |
| 348 | if (!lsize || base > lbase + lsize - 1 || base + size - 1 < lbase) | 367 | if (!lsize || base > lbase + lsize - 1 || |
| 368 | base + size - 1 < lbase) | ||
| 349 | continue; | 369 | continue; |
| 350 | /* At this point we know there is some kind of overlap/enclosure */ | 370 | /* |
| 371 | * At this point we know there is some kind of | ||
| 372 | * overlap/enclosure | ||
| 373 | */ | ||
| 351 | if (base < lbase || base + size - 1 > lbase + lsize - 1) { | 374 | if (base < lbase || base + size - 1 > lbase + lsize - 1) { |
| 352 | if (base <= lbase && base + size - 1 >= lbase + lsize - 1) { | 375 | if (base <= lbase && |
| 376 | base + size - 1 >= lbase + lsize - 1) { | ||
| 353 | /* New region encloses an existing region */ | 377 | /* New region encloses an existing region */ |
| 354 | if (type == ltype) { | 378 | if (type == ltype) { |
| 355 | replace = replace == -1 ? i : -2; | 379 | replace = replace == -1 ? i : -2; |
| 356 | continue; | 380 | continue; |
| 357 | } | 381 | } else if (types_compatible(type, ltype)) |
| 358 | else if (types_compatible(type, ltype)) | ||
| 359 | continue; | 382 | continue; |
| 360 | } | 383 | } |
| 361 | printk(KERN_WARNING | 384 | pr_warning("mtrr: 0x%lx000,0x%lx000 overlaps existing" |
| 362 | "mtrr: 0x%lx000,0x%lx000 overlaps existing" | 385 | " 0x%lx000,0x%lx000\n", base, size, lbase, |
| 363 | " 0x%lx000,0x%lx000\n", base, size, lbase, | 386 | lsize); |
| 364 | lsize); | ||
| 365 | goto out; | 387 | goto out; |
| 366 | } | 388 | } |
| 367 | /* New region is enclosed by an existing region */ | 389 | /* New region is enclosed by an existing region */ |
| 368 | if (ltype != type) { | 390 | if (ltype != type) { |
| 369 | if (types_compatible(type, ltype)) | 391 | if (types_compatible(type, ltype)) |
| 370 | continue; | 392 | continue; |
| 371 | printk (KERN_WARNING "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n", | 393 | pr_warning("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n", |
| 372 | base, size, mtrr_attrib_to_str(ltype), | 394 | base, size, mtrr_attrib_to_str(ltype), |
| 373 | mtrr_attrib_to_str(type)); | 395 | mtrr_attrib_to_str(type)); |
| 374 | goto out; | 396 | goto out; |
| 375 | } | 397 | } |
| 376 | if (increment) | 398 | if (increment) |
| @@ -378,7 +400,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, | |||
| 378 | error = i; | 400 | error = i; |
| 379 | goto out; | 401 | goto out; |
| 380 | } | 402 | } |
| 381 | /* Search for an empty MTRR */ | 403 | /* Search for an empty MTRR */ |
| 382 | i = mtrr_if->get_free_region(base, size, replace); | 404 | i = mtrr_if->get_free_region(base, size, replace); |
| 383 | if (i >= 0) { | 405 | if (i >= 0) { |
| 384 | set_mtrr(i, base, size, type); | 406 | set_mtrr(i, base, size, type); |
| @@ -393,8 +415,9 @@ int mtrr_add_page(unsigned long base, unsigned long size, | |||
| 393 | mtrr_usage_table[replace] = 0; | 415 | mtrr_usage_table[replace] = 0; |
| 394 | } | 416 | } |
| 395 | } | 417 | } |
| 396 | } else | 418 | } else { |
| 397 | printk(KERN_INFO "mtrr: no more MTRRs available\n"); | 419 | pr_info("mtrr: no more MTRRs available\n"); |
| 420 | } | ||
| 398 | error = i; | 421 | error = i; |
| 399 | out: | 422 | out: |
| 400 | mutex_unlock(&mtrr_mutex); | 423 | mutex_unlock(&mtrr_mutex); |
| @@ -405,10 +428,8 @@ int mtrr_add_page(unsigned long base, unsigned long size, | |||
| 405 | static int mtrr_check(unsigned long base, unsigned long size) | 428 | static int mtrr_check(unsigned long base, unsigned long size) |
| 406 | { | 429 | { |
| 407 | if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { | 430 | if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) { |
| 408 | printk(KERN_WARNING | 431 | pr_warning("mtrr: size and base must be multiples of 4 kiB\n"); |
| 409 | "mtrr: size and base must be multiples of 4 kiB\n"); | 432 | pr_debug("mtrr: size: 0x%lx base: 0x%lx\n", size, base); |
| 410 | printk(KERN_DEBUG | ||
| 411 | "mtrr: size: 0x%lx base: 0x%lx\n", size, base); | ||
| 412 | dump_stack(); | 433 | dump_stack(); |
| 413 | return -1; | 434 | return -1; |
| 414 | } | 435 | } |
| @@ -416,66 +437,64 @@ static int mtrr_check(unsigned long base, unsigned long size) | |||
| 416 | } | 437 | } |
| 417 | 438 | ||
| 418 | /** | 439 | /** |
| 419 | * mtrr_add - Add a memory type region | 440 | * mtrr_add - Add a memory type region |
| 420 | * @base: Physical base address of region | 441 | * @base: Physical base address of region |
| 421 | * @size: Physical size of region | 442 | * @size: Physical size of region |
| 422 | * @type: Type of MTRR desired | 443 | * @type: Type of MTRR desired |
| 423 | * @increment: If this is true do usage counting on the region | 444 | * @increment: If this is true do usage counting on the region |
| 424 | * | 445 | * |
| 425 | * Memory type region registers control the caching on newer Intel and | 446 | * Memory type region registers control the caching on newer Intel and |
| 426 | * non Intel processors. This function allows drivers to request an | 447 | * non Intel processors. This function allows drivers to request an |
| 427 | * MTRR is added. The details and hardware specifics of each processor's | 448 | * MTRR is added. The details and hardware specifics of each processor's |
| 428 | * implementation are hidden from the caller, but nevertheless the | 449 | * implementation are hidden from the caller, but nevertheless the |
| 429 | * caller should expect to need to provide a power of two size on an | 450 | * caller should expect to need to provide a power of two size on an |
| 430 | * equivalent power of two boundary. | 451 | * equivalent power of two boundary. |
| 431 | * | 452 | * |
| 432 | * If the region cannot be added either because all regions are in use | 453 | * If the region cannot be added either because all regions are in use |
| 433 | * or the CPU cannot support it a negative value is returned. On success | 454 | * or the CPU cannot support it a negative value is returned. On success |
| 434 | * the register number for this entry is returned, but should be treated | 455 | * the register number for this entry is returned, but should be treated |
| 435 | * as a cookie only. | 456 | * as a cookie only. |
| 436 | * | 457 | * |
| 437 | * On a multiprocessor machine the changes are made to all processors. | 458 | * On a multiprocessor machine the changes are made to all processors. |
| 438 | * This is required on x86 by the Intel processors. | 459 | * This is required on x86 by the Intel processors. |
| 439 | * | 460 | * |
| 440 | * The available types are | 461 | * The available types are |
| 441 | * | 462 | * |
| 442 | * %MTRR_TYPE_UNCACHABLE - No caching | 463 | * %MTRR_TYPE_UNCACHABLE - No caching |
| 443 | * | 464 | * |
| 444 | * %MTRR_TYPE_WRBACK - Write data back in bursts whenever | 465 | * %MTRR_TYPE_WRBACK - Write data back in bursts whenever |
| 445 | * | 466 | * |
| 446 | * %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts | 467 | * %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts |
| 447 | * | 468 | * |
| 448 | * %MTRR_TYPE_WRTHROUGH - Cache reads but not writes | 469 | * %MTRR_TYPE_WRTHROUGH - Cache reads but not writes |
| 449 | * | 470 | * |
| 450 | * BUGS: Needs a quiet flag for the cases where drivers do not mind | 471 | * BUGS: Needs a quiet flag for the cases where drivers do not mind |
| 451 | * failures and do not wish system log messages to be sent. | 472 | * failures and do not wish system log messages to be sent. |
| 452 | */ | 473 | */ |
| 453 | 474 | int mtrr_add(unsigned long base, unsigned long size, unsigned int type, | |
| 454 | int | 475 | bool increment) |
| 455 | mtrr_add(unsigned long base, unsigned long size, unsigned int type, | ||
| 456 | bool increment) | ||
| 457 | { | 476 | { |
| 458 | if (mtrr_check(base, size)) | 477 | if (mtrr_check(base, size)) |
| 459 | return -EINVAL; | 478 | return -EINVAL; |
| 460 | return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type, | 479 | return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type, |
| 461 | increment); | 480 | increment); |
| 462 | } | 481 | } |
| 482 | EXPORT_SYMBOL(mtrr_add); | ||
| 463 | 483 | ||
| 464 | /** | 484 | /** |
| 465 | * mtrr_del_page - delete a memory type region | 485 | * mtrr_del_page - delete a memory type region |
| 466 | * @reg: Register returned by mtrr_add | 486 | * @reg: Register returned by mtrr_add |
| 467 | * @base: Physical base address | 487 | * @base: Physical base address |
| 468 | * @size: Size of region | 488 | * @size: Size of region |
| 469 | * | 489 | * |
| 470 | * If register is supplied then base and size are ignored. This is | 490 | * If register is supplied then base and size are ignored. This is |
| 471 | * how drivers should call it. | 491 | * how drivers should call it. |
| 472 | * | 492 | * |
| 473 | * Releases an MTRR region. If the usage count drops to zero the | 493 | * Releases an MTRR region. If the usage count drops to zero the |
| 474 | * register is freed and the region returns to default state. | 494 | * register is freed and the region returns to default state. |
| 475 | * On success the register is returned, on failure a negative error | 495 | * On success the register is returned, on failure a negative error |
| 476 | * code. | 496 | * code. |
| 477 | */ | 497 | */ |
| 478 | |||
| 479 | int mtrr_del_page(int reg, unsigned long base, unsigned long size) | 498 | int mtrr_del_page(int reg, unsigned long base, unsigned long size) |
| 480 | { | 499 | { |
| 481 | int i, max; | 500 | int i, max; |
| @@ -500,22 +519,22 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) | |||
| 500 | } | 519 | } |
| 501 | } | 520 | } |
| 502 | if (reg < 0) { | 521 | if (reg < 0) { |
| 503 | printk(KERN_DEBUG "mtrr: no MTRR for %lx000,%lx000 found\n", base, | 522 | pr_debug("mtrr: no MTRR for %lx000,%lx000 found\n", |
| 504 | size); | 523 | base, size); |
| 505 | goto out; | 524 | goto out; |
| 506 | } | 525 | } |
| 507 | } | 526 | } |
| 508 | if (reg >= max) { | 527 | if (reg >= max) { |
| 509 | printk(KERN_WARNING "mtrr: register: %d too big\n", reg); | 528 | pr_warning("mtrr: register: %d too big\n", reg); |
| 510 | goto out; | 529 | goto out; |
| 511 | } | 530 | } |
| 512 | mtrr_if->get(reg, &lbase, &lsize, <ype); | 531 | mtrr_if->get(reg, &lbase, &lsize, <ype); |
| 513 | if (lsize < 1) { | 532 | if (lsize < 1) { |
| 514 | printk(KERN_WARNING "mtrr: MTRR %d not used\n", reg); | 533 | pr_warning("mtrr: MTRR %d not used\n", reg); |
| 515 | goto out; | 534 | goto out; |
| 516 | } | 535 | } |
| 517 | if (mtrr_usage_table[reg] < 1) { | 536 | if (mtrr_usage_table[reg] < 1) { |
| 518 | printk(KERN_WARNING "mtrr: reg: %d has count=0\n", reg); | 537 | pr_warning("mtrr: reg: %d has count=0\n", reg); |
| 519 | goto out; | 538 | goto out; |
| 520 | } | 539 | } |
| 521 | if (--mtrr_usage_table[reg] < 1) | 540 | if (--mtrr_usage_table[reg] < 1) |
| @@ -526,33 +545,31 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) | |||
| 526 | put_online_cpus(); | 545 | put_online_cpus(); |
| 527 | return error; | 546 | return error; |
| 528 | } | 547 | } |
| 548 | |||
| 529 | /** | 549 | /** |
| 530 | * mtrr_del - delete a memory type region | 550 | * mtrr_del - delete a memory type region |
| 531 | * @reg: Register returned by mtrr_add | 551 | * @reg: Register returned by mtrr_add |
| 532 | * @base: Physical base address | 552 | * @base: Physical base address |
| 533 | * @size: Size of region | 553 | * @size: Size of region |
| 534 | * | 554 | * |
| 535 | * If register is supplied then base and size are ignored. This is | 555 | * If register is supplied then base and size are ignored. This is |
| 536 | * how drivers should call it. | 556 | * how drivers should call it. |
| 537 | * | 557 | * |
| 538 | * Releases an MTRR region. If the usage count drops to zero the | 558 | * Releases an MTRR region. If the usage count drops to zero the |
| 539 | * register is freed and the region returns to default state. | 559 | * register is freed and the region returns to default state. |
| 540 | * On success the register is returned, on failure a negative error | 560 | * On success the register is returned, on failure a negative error |
| 541 | * code. | 561 | * code. |
| 542 | */ | 562 | */ |
| 543 | 563 | int mtrr_del(int reg, unsigned long base, unsigned long size) | |
| 544 | int | ||
| 545 | mtrr_del(int reg, unsigned long base, unsigned long size) | ||
| 546 | { | 564 | { |
| 547 | if (mtrr_check(base, size)) | 565 | if (mtrr_check(base, size)) |
| 548 | return -EINVAL; | 566 | return -EINVAL; |
| 549 | return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT); | 567 | return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT); |
| 550 | } | 568 | } |
| 551 | |||
| 552 | EXPORT_SYMBOL(mtrr_add); | ||
| 553 | EXPORT_SYMBOL(mtrr_del); | 569 | EXPORT_SYMBOL(mtrr_del); |
| 554 | 570 | ||
| 555 | /* HACK ALERT! | 571 | /* |
| 572 | * HACK ALERT! | ||
| 556 | * These should be called implicitly, but we can't yet until all the initcall | 573 | * These should be called implicitly, but we can't yet until all the initcall |
| 557 | * stuff is done... | 574 | * stuff is done... |
| 558 | */ | 575 | */ |
| @@ -576,29 +593,28 @@ struct mtrr_value { | |||
| 576 | 593 | ||
| 577 | static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES]; | 594 | static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES]; |
| 578 | 595 | ||
| 579 | static int mtrr_save(struct sys_device * sysdev, pm_message_t state) | 596 | static int mtrr_save(struct sys_device *sysdev, pm_message_t state) |
| 580 | { | 597 | { |
| 581 | int i; | 598 | int i; |
| 582 | 599 | ||
| 583 | for (i = 0; i < num_var_ranges; i++) { | 600 | for (i = 0; i < num_var_ranges; i++) { |
| 584 | mtrr_if->get(i, | 601 | mtrr_if->get(i, &mtrr_value[i].lbase, |
| 585 | &mtrr_value[i].lbase, | 602 | &mtrr_value[i].lsize, |
| 586 | &mtrr_value[i].lsize, | 603 | &mtrr_value[i].ltype); |
| 587 | &mtrr_value[i].ltype); | ||
| 588 | } | 604 | } |
| 589 | return 0; | 605 | return 0; |
| 590 | } | 606 | } |
| 591 | 607 | ||
| 592 | static int mtrr_restore(struct sys_device * sysdev) | 608 | static int mtrr_restore(struct sys_device *sysdev) |
| 593 | { | 609 | { |
| 594 | int i; | 610 | int i; |
| 595 | 611 | ||
| 596 | for (i = 0; i < num_var_ranges; i++) { | 612 | for (i = 0; i < num_var_ranges; i++) { |
| 597 | if (mtrr_value[i].lsize) | 613 | if (mtrr_value[i].lsize) { |
| 598 | set_mtrr(i, | 614 | set_mtrr(i, mtrr_value[i].lbase, |
| 599 | mtrr_value[i].lbase, | 615 | mtrr_value[i].lsize, |
| 600 | mtrr_value[i].lsize, | 616 | mtrr_value[i].ltype); |
| 601 | mtrr_value[i].ltype); | 617 | } |
| 602 | } | 618 | } |
| 603 | return 0; | 619 | return 0; |
| 604 | } | 620 | } |
| @@ -615,26 +631,29 @@ int __initdata changed_by_mtrr_cleanup; | |||
| 615 | /** | 631 | /** |
| 616 | * mtrr_bp_init - initialize mtrrs on the boot CPU | 632 | * mtrr_bp_init - initialize mtrrs on the boot CPU |
| 617 | * | 633 | * |
| 618 | * This needs to be called early; before any of the other CPUs are | 634 | * This needs to be called early; before any of the other CPUs are |
| 619 | * initialized (i.e. before smp_init()). | 635 | * initialized (i.e. before smp_init()). |
| 620 | * | 636 | * |
| 621 | */ | 637 | */ |
| 622 | void __init mtrr_bp_init(void) | 638 | void __init mtrr_bp_init(void) |
| 623 | { | 639 | { |
| 624 | u32 phys_addr; | 640 | u32 phys_addr; |
| 641 | |||
| 625 | init_ifs(); | 642 | init_ifs(); |
| 626 | 643 | ||
| 627 | phys_addr = 32; | 644 | phys_addr = 32; |
| 628 | 645 | ||
| 629 | if (cpu_has_mtrr) { | 646 | if (cpu_has_mtrr) { |
| 630 | mtrr_if = &generic_mtrr_ops; | 647 | mtrr_if = &generic_mtrr_ops; |
| 631 | size_or_mask = 0xff000000; /* 36 bits */ | 648 | size_or_mask = 0xff000000; /* 36 bits */ |
| 632 | size_and_mask = 0x00f00000; | 649 | size_and_mask = 0x00f00000; |
| 633 | phys_addr = 36; | 650 | phys_addr = 36; |
| 634 | 651 | ||
| 635 | /* This is an AMD specific MSR, but we assume(hope?) that | 652 | /* |
| 636 | Intel will implement it to when they extend the address | 653 | * This is an AMD specific MSR, but we assume(hope?) that |
| 637 | bus of the Xeon. */ | 654 | * Intel will implement it to when they extend the address |
| 655 | * bus of the Xeon. | ||
| 656 | */ | ||
| 638 | if (cpuid_eax(0x80000000) >= 0x80000008) { | 657 | if (cpuid_eax(0x80000000) >= 0x80000008) { |
| 639 | phys_addr = cpuid_eax(0x80000008) & 0xff; | 658 | phys_addr = cpuid_eax(0x80000008) & 0xff; |
| 640 | /* CPUID workaround for Intel 0F33/0F34 CPU */ | 659 | /* CPUID workaround for Intel 0F33/0F34 CPU */ |
| @@ -649,9 +668,11 @@ void __init mtrr_bp_init(void) | |||
| 649 | size_and_mask = ~size_or_mask & 0xfffff00000ULL; | 668 | size_and_mask = ~size_or_mask & 0xfffff00000ULL; |
| 650 | } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR && | 669 | } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR && |
| 651 | boot_cpu_data.x86 == 6) { | 670 | boot_cpu_data.x86 == 6) { |
| 652 | /* VIA C* family have Intel style MTRRs, but | 671 | /* |
| 653 | don't support PAE */ | 672 | * VIA C* family have Intel style MTRRs, |
| 654 | size_or_mask = 0xfff00000; /* 32 bits */ | 673 | * but don't support PAE |
| 674 | */ | ||
| 675 | size_or_mask = 0xfff00000; /* 32 bits */ | ||
| 655 | size_and_mask = 0; | 676 | size_and_mask = 0; |
| 656 | phys_addr = 32; | 677 | phys_addr = 32; |
| 657 | } | 678 | } |
| @@ -694,7 +715,6 @@ void __init mtrr_bp_init(void) | |||
| 694 | changed_by_mtrr_cleanup = 1; | 715 | changed_by_mtrr_cleanup = 1; |
| 695 | mtrr_if->set_all(); | 716 | mtrr_if->set_all(); |
| 696 | } | 717 | } |
| 697 | |||
| 698 | } | 718 | } |
| 699 | } | 719 | } |
| 700 | } | 720 | } |
| @@ -706,12 +726,17 @@ void mtrr_ap_init(void) | |||
| 706 | if (!mtrr_if || !use_intel()) | 726 | if (!mtrr_if || !use_intel()) |
| 707 | return; | 727 | return; |
| 708 | /* | 728 | /* |
| 709 | * Ideally we should hold mtrr_mutex here to avoid mtrr entries changed, | 729 | * Ideally we should hold mtrr_mutex here to avoid mtrr entries |
| 710 | * but this routine will be called in cpu boot time, holding the lock | 730 | * changed, but this routine will be called in cpu boot time, |
| 711 | * breaks it. This routine is called in two cases: 1.very earily time | 731 | * holding the lock breaks it. |
| 712 | * of software resume, when there absolutely isn't mtrr entry changes; | 732 | * |
| 713 | * 2.cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug lock to | 733 | * This routine is called in two cases: |
| 714 | * prevent mtrr entry changes | 734 | * |
| 735 | * 1. very earily time of software resume, when there absolutely | ||
| 736 | * isn't mtrr entry changes; | ||
| 737 | * | ||
| 738 | * 2. cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug | ||
| 739 | * lock to prevent mtrr entry changes | ||
| 715 | */ | 740 | */ |
| 716 | local_irq_save(flags); | 741 | local_irq_save(flags); |
| 717 | 742 | ||
| @@ -732,19 +757,23 @@ static int __init mtrr_init_finialize(void) | |||
| 732 | { | 757 | { |
| 733 | if (!mtrr_if) | 758 | if (!mtrr_if) |
| 734 | return 0; | 759 | return 0; |
| 760 | |||
| 735 | if (use_intel()) { | 761 | if (use_intel()) { |
| 736 | if (!changed_by_mtrr_cleanup) | 762 | if (!changed_by_mtrr_cleanup) |
| 737 | mtrr_state_warn(); | 763 | mtrr_state_warn(); |
| 738 | } else { | 764 | return 0; |
| 739 | /* The CPUs haven't MTRR and seem to not support SMP. They have | ||
| 740 | * specific drivers, we use a tricky method to support | ||
| 741 | * suspend/resume for them. | ||
| 742 | * TBD: is there any system with such CPU which supports | ||
| 743 | * suspend/resume? if no, we should remove the code. | ||
| 744 | */ | ||
| 745 | sysdev_driver_register(&cpu_sysdev_class, | ||
| 746 | &mtrr_sysdev_driver); | ||
| 747 | } | 765 | } |
| 766 | |||
| 767 | /* | ||
| 768 | * The CPU has no MTRR and seems to not support SMP. They have | ||
| 769 | * specific drivers, we use a tricky method to support | ||
| 770 | * suspend/resume for them. | ||
| 771 | * | ||
| 772 | * TBD: is there any system with such CPU which supports | ||
| 773 | * suspend/resume? If no, we should remove the code. | ||
| 774 | */ | ||
| 775 | sysdev_driver_register(&cpu_sysdev_class, &mtrr_sysdev_driver); | ||
| 776 | |||
| 748 | return 0; | 777 | return 0; |
| 749 | } | 778 | } |
| 750 | subsys_initcall(mtrr_init_finialize); | 779 | subsys_initcall(mtrr_init_finialize); |
diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h index 7538b767f206..a501dee9a87a 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.h +++ b/arch/x86/kernel/cpu/mtrr/mtrr.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * local mtrr defines. | 2 | * local MTRR defines. |
| 3 | */ | 3 | */ |
| 4 | 4 | ||
| 5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
| @@ -14,13 +14,12 @@ extern unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES]; | |||
| 14 | struct mtrr_ops { | 14 | struct mtrr_ops { |
| 15 | u32 vendor; | 15 | u32 vendor; |
| 16 | u32 use_intel_if; | 16 | u32 use_intel_if; |
| 17 | // void (*init)(void); | ||
| 18 | void (*set)(unsigned int reg, unsigned long base, | 17 | void (*set)(unsigned int reg, unsigned long base, |
| 19 | unsigned long size, mtrr_type type); | 18 | unsigned long size, mtrr_type type); |
| 20 | void (*set_all)(void); | 19 | void (*set_all)(void); |
| 21 | 20 | ||
| 22 | void (*get)(unsigned int reg, unsigned long *base, | 21 | void (*get)(unsigned int reg, unsigned long *base, |
| 23 | unsigned long *size, mtrr_type * type); | 22 | unsigned long *size, mtrr_type *type); |
| 24 | int (*get_free_region)(unsigned long base, unsigned long size, | 23 | int (*get_free_region)(unsigned long base, unsigned long size, |
| 25 | int replace_reg); | 24 | int replace_reg); |
| 26 | int (*validate_add_page)(unsigned long base, unsigned long size, | 25 | int (*validate_add_page)(unsigned long base, unsigned long size, |
| @@ -39,11 +38,11 @@ extern int positive_have_wrcomb(void); | |||
| 39 | 38 | ||
| 40 | /* library functions for processor-specific routines */ | 39 | /* library functions for processor-specific routines */ |
| 41 | struct set_mtrr_context { | 40 | struct set_mtrr_context { |
| 42 | unsigned long flags; | 41 | unsigned long flags; |
| 43 | unsigned long cr4val; | 42 | unsigned long cr4val; |
| 44 | u32 deftype_lo; | 43 | u32 deftype_lo; |
| 45 | u32 deftype_hi; | 44 | u32 deftype_hi; |
| 46 | u32 ccr3; | 45 | u32 ccr3; |
| 47 | }; | 46 | }; |
| 48 | 47 | ||
| 49 | void set_mtrr_done(struct set_mtrr_context *ctxt); | 48 | void set_mtrr_done(struct set_mtrr_context *ctxt); |
| @@ -54,10 +53,10 @@ void fill_mtrr_var_range(unsigned int index, | |||
| 54 | u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi); | 53 | u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi); |
| 55 | void get_mtrr_state(void); | 54 | void get_mtrr_state(void); |
| 56 | 55 | ||
| 57 | extern void set_mtrr_ops(struct mtrr_ops * ops); | 56 | extern void set_mtrr_ops(struct mtrr_ops *ops); |
| 58 | 57 | ||
| 59 | extern u64 size_or_mask, size_and_mask; | 58 | extern u64 size_or_mask, size_and_mask; |
| 60 | extern struct mtrr_ops * mtrr_if; | 59 | extern struct mtrr_ops *mtrr_if; |
| 61 | 60 | ||
| 62 | #define is_cpu(vnd) (mtrr_if && mtrr_if->vendor == X86_VENDOR_##vnd) | 61 | #define is_cpu(vnd) (mtrr_if && mtrr_if->vendor == X86_VENDOR_##vnd) |
| 63 | #define use_intel() (mtrr_if && mtrr_if->use_intel_if == 1) | 62 | #define use_intel() (mtrr_if && mtrr_if->use_intel_if == 1) |
diff --git a/arch/x86/kernel/cpu/mtrr/state.c b/arch/x86/kernel/cpu/mtrr/state.c index 1f5fb1588d1f..dfc80b4e6b0d 100644 --- a/arch/x86/kernel/cpu/mtrr/state.c +++ b/arch/x86/kernel/cpu/mtrr/state.c | |||
| @@ -1,24 +1,25 @@ | |||
| 1 | #include <linux/mm.h> | ||
| 2 | #include <linux/init.h> | 1 | #include <linux/init.h> |
| 3 | #include <asm/io.h> | 2 | #include <linux/io.h> |
| 4 | #include <asm/mtrr.h> | 3 | #include <linux/mm.h> |
| 5 | #include <asm/msr.h> | 4 | |
| 6 | #include <asm/processor-cyrix.h> | 5 | #include <asm/processor-cyrix.h> |
| 7 | #include <asm/processor-flags.h> | 6 | #include <asm/processor-flags.h> |
| 8 | #include "mtrr.h" | 7 | #include <asm/mtrr.h> |
| 8 | #include <asm/msr.h> | ||
| 9 | 9 | ||
| 10 | #include "mtrr.h" | ||
| 10 | 11 | ||
| 11 | /* Put the processor into a state where MTRRs can be safely set */ | 12 | /* Put the processor into a state where MTRRs can be safely set */ |
| 12 | void set_mtrr_prepare_save(struct set_mtrr_context *ctxt) | 13 | void set_mtrr_prepare_save(struct set_mtrr_context *ctxt) |
| 13 | { | 14 | { |
| 14 | unsigned int cr0; | 15 | unsigned int cr0; |
| 15 | 16 | ||
| 16 | /* Disable interrupts locally */ | 17 | /* Disable interrupts locally */ |
| 17 | local_irq_save(ctxt->flags); | 18 | local_irq_save(ctxt->flags); |
| 18 | 19 | ||
| 19 | if (use_intel() || is_cpu(CYRIX)) { | 20 | if (use_intel() || is_cpu(CYRIX)) { |
| 20 | 21 | ||
| 21 | /* Save value of CR4 and clear Page Global Enable (bit 7) */ | 22 | /* Save value of CR4 and clear Page Global Enable (bit 7) */ |
| 22 | if (cpu_has_pge) { | 23 | if (cpu_has_pge) { |
| 23 | ctxt->cr4val = read_cr4(); | 24 | ctxt->cr4val = read_cr4(); |
| 24 | write_cr4(ctxt->cr4val & ~X86_CR4_PGE); | 25 | write_cr4(ctxt->cr4val & ~X86_CR4_PGE); |
| @@ -33,50 +34,61 @@ void set_mtrr_prepare_save(struct set_mtrr_context *ctxt) | |||
| 33 | write_cr0(cr0); | 34 | write_cr0(cr0); |
| 34 | wbinvd(); | 35 | wbinvd(); |
| 35 | 36 | ||
| 36 | if (use_intel()) | 37 | if (use_intel()) { |
| 37 | /* Save MTRR state */ | 38 | /* Save MTRR state */ |
| 38 | rdmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi); | 39 | rdmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi); |
| 39 | else | 40 | } else { |
| 40 | /* Cyrix ARRs - everything else were excluded at the top */ | 41 | /* |
| 42 | * Cyrix ARRs - | ||
| 43 | * everything else were excluded at the top | ||
| 44 | */ | ||
| 41 | ctxt->ccr3 = getCx86(CX86_CCR3); | 45 | ctxt->ccr3 = getCx86(CX86_CCR3); |
| 46 | } | ||
| 42 | } | 47 | } |
| 43 | } | 48 | } |
| 44 | 49 | ||
| 45 | void set_mtrr_cache_disable(struct set_mtrr_context *ctxt) | 50 | void set_mtrr_cache_disable(struct set_mtrr_context *ctxt) |
| 46 | { | 51 | { |
| 47 | if (use_intel()) | 52 | if (use_intel()) { |
| 48 | /* Disable MTRRs, and set the default type to uncached */ | 53 | /* Disable MTRRs, and set the default type to uncached */ |
| 49 | mtrr_wrmsr(MSR_MTRRdefType, ctxt->deftype_lo & 0xf300UL, | 54 | mtrr_wrmsr(MSR_MTRRdefType, ctxt->deftype_lo & 0xf300UL, |
| 50 | ctxt->deftype_hi); | 55 | ctxt->deftype_hi); |
| 51 | else if (is_cpu(CYRIX)) | 56 | } else { |
| 52 | /* Cyrix ARRs - everything else were excluded at the top */ | 57 | if (is_cpu(CYRIX)) { |
| 53 | setCx86(CX86_CCR3, (ctxt->ccr3 & 0x0f) | 0x10); | 58 | /* Cyrix ARRs - everything else were excluded at the top */ |
| 59 | setCx86(CX86_CCR3, (ctxt->ccr3 & 0x0f) | 0x10); | ||
| 60 | } | ||
| 61 | } | ||
| 54 | } | 62 | } |
| 55 | 63 | ||
| 56 | /* Restore the processor after a set_mtrr_prepare */ | 64 | /* Restore the processor after a set_mtrr_prepare */ |
| 57 | void set_mtrr_done(struct set_mtrr_context *ctxt) | 65 | void set_mtrr_done(struct set_mtrr_context *ctxt) |
| 58 | { | 66 | { |
| 59 | if (use_intel() || is_cpu(CYRIX)) { | 67 | if (use_intel() || is_cpu(CYRIX)) { |
| 60 | 68 | ||
| 61 | /* Flush caches and TLBs */ | 69 | /* Flush caches and TLBs */ |
| 62 | wbinvd(); | 70 | wbinvd(); |
| 63 | 71 | ||
| 64 | /* Restore MTRRdefType */ | 72 | /* Restore MTRRdefType */ |
| 65 | if (use_intel()) | 73 | if (use_intel()) { |
| 66 | /* Intel (P6) standard MTRRs */ | 74 | /* Intel (P6) standard MTRRs */ |
| 67 | mtrr_wrmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi); | 75 | mtrr_wrmsr(MSR_MTRRdefType, ctxt->deftype_lo, |
| 68 | else | 76 | ctxt->deftype_hi); |
| 69 | /* Cyrix ARRs - everything else was excluded at the top */ | 77 | } else { |
| 78 | /* | ||
| 79 | * Cyrix ARRs - | ||
| 80 | * everything else was excluded at the top | ||
| 81 | */ | ||
| 70 | setCx86(CX86_CCR3, ctxt->ccr3); | 82 | setCx86(CX86_CCR3, ctxt->ccr3); |
| 83 | } | ||
| 71 | 84 | ||
| 72 | /* Enable caches */ | 85 | /* Enable caches */ |
| 73 | write_cr0(read_cr0() & 0xbfffffff); | 86 | write_cr0(read_cr0() & 0xbfffffff); |
| 74 | 87 | ||
| 75 | /* Restore value of CR4 */ | 88 | /* Restore value of CR4 */ |
| 76 | if (cpu_has_pge) | 89 | if (cpu_has_pge) |
| 77 | write_cr4(ctxt->cr4val); | 90 | write_cr4(ctxt->cr4val); |
| 78 | } | 91 | } |
| 79 | /* Re-enable interrupts locally (if enabled previously) */ | 92 | /* Re-enable interrupts locally (if enabled previously) */ |
| 80 | local_irq_restore(ctxt->flags); | 93 | local_irq_restore(ctxt->flags); |
| 81 | } | 94 | } |
| 82 | |||
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 900332b800f8..f9cd0849bd42 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | * Copyright (C) 2009 Jaswinder Singh Rajput | 6 | * Copyright (C) 2009 Jaswinder Singh Rajput |
| 7 | * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter | 7 | * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter |
| 8 | * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com> | 8 | * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com> |
| 9 | * Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com> | ||
| 9 | * | 10 | * |
| 10 | * For licencing details see kernel-base/COPYING | 11 | * For licencing details see kernel-base/COPYING |
| 11 | */ | 12 | */ |
| @@ -20,6 +21,7 @@ | |||
| 20 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
| 21 | #include <linux/uaccess.h> | 22 | #include <linux/uaccess.h> |
| 22 | #include <linux/highmem.h> | 23 | #include <linux/highmem.h> |
| 24 | #include <linux/cpu.h> | ||
| 23 | 25 | ||
| 24 | #include <asm/apic.h> | 26 | #include <asm/apic.h> |
| 25 | #include <asm/stacktrace.h> | 27 | #include <asm/stacktrace.h> |
| @@ -27,12 +29,52 @@ | |||
| 27 | 29 | ||
| 28 | static u64 perf_counter_mask __read_mostly; | 30 | static u64 perf_counter_mask __read_mostly; |
| 29 | 31 | ||
| 32 | /* The maximal number of PEBS counters: */ | ||
| 33 | #define MAX_PEBS_COUNTERS 4 | ||
| 34 | |||
| 35 | /* The size of a BTS record in bytes: */ | ||
| 36 | #define BTS_RECORD_SIZE 24 | ||
| 37 | |||
| 38 | /* The size of a per-cpu BTS buffer in bytes: */ | ||
| 39 | #define BTS_BUFFER_SIZE (BTS_RECORD_SIZE * 1024) | ||
| 40 | |||
| 41 | /* The BTS overflow threshold in bytes from the end of the buffer: */ | ||
| 42 | #define BTS_OVFL_TH (BTS_RECORD_SIZE * 64) | ||
| 43 | |||
| 44 | |||
| 45 | /* | ||
| 46 | * Bits in the debugctlmsr controlling branch tracing. | ||
| 47 | */ | ||
| 48 | #define X86_DEBUGCTL_TR (1 << 6) | ||
| 49 | #define X86_DEBUGCTL_BTS (1 << 7) | ||
| 50 | #define X86_DEBUGCTL_BTINT (1 << 8) | ||
| 51 | #define X86_DEBUGCTL_BTS_OFF_OS (1 << 9) | ||
| 52 | #define X86_DEBUGCTL_BTS_OFF_USR (1 << 10) | ||
| 53 | |||
| 54 | /* | ||
| 55 | * A debug store configuration. | ||
| 56 | * | ||
| 57 | * We only support architectures that use 64bit fields. | ||
| 58 | */ | ||
| 59 | struct debug_store { | ||
| 60 | u64 bts_buffer_base; | ||
| 61 | u64 bts_index; | ||
| 62 | u64 bts_absolute_maximum; | ||
| 63 | u64 bts_interrupt_threshold; | ||
| 64 | u64 pebs_buffer_base; | ||
| 65 | u64 pebs_index; | ||
| 66 | u64 pebs_absolute_maximum; | ||
| 67 | u64 pebs_interrupt_threshold; | ||
| 68 | u64 pebs_counter_reset[MAX_PEBS_COUNTERS]; | ||
| 69 | }; | ||
| 70 | |||
| 30 | struct cpu_hw_counters { | 71 | struct cpu_hw_counters { |
| 31 | struct perf_counter *counters[X86_PMC_IDX_MAX]; | 72 | struct perf_counter *counters[X86_PMC_IDX_MAX]; |
| 32 | unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; | 73 | unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; |
| 33 | unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; | 74 | unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; |
| 34 | unsigned long interrupts; | 75 | unsigned long interrupts; |
| 35 | int enabled; | 76 | int enabled; |
| 77 | struct debug_store *ds; | ||
| 36 | }; | 78 | }; |
| 37 | 79 | ||
| 38 | /* | 80 | /* |
| @@ -58,6 +100,8 @@ struct x86_pmu { | |||
| 58 | int apic; | 100 | int apic; |
| 59 | u64 max_period; | 101 | u64 max_period; |
| 60 | u64 intel_ctrl; | 102 | u64 intel_ctrl; |
| 103 | void (*enable_bts)(u64 config); | ||
| 104 | void (*disable_bts)(void); | ||
| 61 | }; | 105 | }; |
| 62 | 106 | ||
| 63 | static struct x86_pmu x86_pmu __read_mostly; | 107 | static struct x86_pmu x86_pmu __read_mostly; |
| @@ -577,6 +621,9 @@ x86_perf_counter_update(struct perf_counter *counter, | |||
| 577 | u64 prev_raw_count, new_raw_count; | 621 | u64 prev_raw_count, new_raw_count; |
| 578 | s64 delta; | 622 | s64 delta; |
| 579 | 623 | ||
| 624 | if (idx == X86_PMC_IDX_FIXED_BTS) | ||
| 625 | return 0; | ||
| 626 | |||
| 580 | /* | 627 | /* |
| 581 | * Careful: an NMI might modify the previous counter value. | 628 | * Careful: an NMI might modify the previous counter value. |
| 582 | * | 629 | * |
| @@ -666,10 +713,110 @@ static void release_pmc_hardware(void) | |||
| 666 | #endif | 713 | #endif |
| 667 | } | 714 | } |
| 668 | 715 | ||
| 716 | static inline bool bts_available(void) | ||
| 717 | { | ||
| 718 | return x86_pmu.enable_bts != NULL; | ||
| 719 | } | ||
| 720 | |||
| 721 | static inline void init_debug_store_on_cpu(int cpu) | ||
| 722 | { | ||
| 723 | struct debug_store *ds = per_cpu(cpu_hw_counters, cpu).ds; | ||
| 724 | |||
| 725 | if (!ds) | ||
| 726 | return; | ||
| 727 | |||
| 728 | wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, | ||
| 729 | (u32)((u64)(unsigned long)ds), | ||
| 730 | (u32)((u64)(unsigned long)ds >> 32)); | ||
| 731 | } | ||
| 732 | |||
| 733 | static inline void fini_debug_store_on_cpu(int cpu) | ||
| 734 | { | ||
| 735 | if (!per_cpu(cpu_hw_counters, cpu).ds) | ||
| 736 | return; | ||
| 737 | |||
| 738 | wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0); | ||
| 739 | } | ||
| 740 | |||
| 741 | static void release_bts_hardware(void) | ||
| 742 | { | ||
| 743 | int cpu; | ||
| 744 | |||
| 745 | if (!bts_available()) | ||
| 746 | return; | ||
| 747 | |||
| 748 | get_online_cpus(); | ||
| 749 | |||
| 750 | for_each_online_cpu(cpu) | ||
| 751 | fini_debug_store_on_cpu(cpu); | ||
| 752 | |||
| 753 | for_each_possible_cpu(cpu) { | ||
| 754 | struct debug_store *ds = per_cpu(cpu_hw_counters, cpu).ds; | ||
| 755 | |||
| 756 | if (!ds) | ||
| 757 | continue; | ||
| 758 | |||
| 759 | per_cpu(cpu_hw_counters, cpu).ds = NULL; | ||
| 760 | |||
| 761 | kfree((void *)(unsigned long)ds->bts_buffer_base); | ||
| 762 | kfree(ds); | ||
| 763 | } | ||
| 764 | |||
| 765 | put_online_cpus(); | ||
| 766 | } | ||
| 767 | |||
| 768 | static int reserve_bts_hardware(void) | ||
| 769 | { | ||
| 770 | int cpu, err = 0; | ||
| 771 | |||
| 772 | if (!bts_available()) | ||
| 773 | return 0; | ||
| 774 | |||
| 775 | get_online_cpus(); | ||
| 776 | |||
| 777 | for_each_possible_cpu(cpu) { | ||
| 778 | struct debug_store *ds; | ||
| 779 | void *buffer; | ||
| 780 | |||
| 781 | err = -ENOMEM; | ||
| 782 | buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL); | ||
| 783 | if (unlikely(!buffer)) | ||
| 784 | break; | ||
| 785 | |||
| 786 | ds = kzalloc(sizeof(*ds), GFP_KERNEL); | ||
| 787 | if (unlikely(!ds)) { | ||
| 788 | kfree(buffer); | ||
| 789 | break; | ||
| 790 | } | ||
| 791 | |||
| 792 | ds->bts_buffer_base = (u64)(unsigned long)buffer; | ||
| 793 | ds->bts_index = ds->bts_buffer_base; | ||
| 794 | ds->bts_absolute_maximum = | ||
| 795 | ds->bts_buffer_base + BTS_BUFFER_SIZE; | ||
| 796 | ds->bts_interrupt_threshold = | ||
| 797 | ds->bts_absolute_maximum - BTS_OVFL_TH; | ||
| 798 | |||
| 799 | per_cpu(cpu_hw_counters, cpu).ds = ds; | ||
| 800 | err = 0; | ||
| 801 | } | ||
| 802 | |||
| 803 | if (err) | ||
| 804 | release_bts_hardware(); | ||
| 805 | else { | ||
| 806 | for_each_online_cpu(cpu) | ||
| 807 | init_debug_store_on_cpu(cpu); | ||
| 808 | } | ||
| 809 | |||
| 810 | put_online_cpus(); | ||
| 811 | |||
| 812 | return err; | ||
| 813 | } | ||
| 814 | |||
| 669 | static void hw_perf_counter_destroy(struct perf_counter *counter) | 815 | static void hw_perf_counter_destroy(struct perf_counter *counter) |
| 670 | { | 816 | { |
| 671 | if (atomic_dec_and_mutex_lock(&active_counters, &pmc_reserve_mutex)) { | 817 | if (atomic_dec_and_mutex_lock(&active_counters, &pmc_reserve_mutex)) { |
| 672 | release_pmc_hardware(); | 818 | release_pmc_hardware(); |
| 819 | release_bts_hardware(); | ||
| 673 | mutex_unlock(&pmc_reserve_mutex); | 820 | mutex_unlock(&pmc_reserve_mutex); |
| 674 | } | 821 | } |
| 675 | } | 822 | } |
| @@ -712,6 +859,42 @@ set_ext_hw_attr(struct hw_perf_counter *hwc, struct perf_counter_attr *attr) | |||
| 712 | return 0; | 859 | return 0; |
| 713 | } | 860 | } |
| 714 | 861 | ||
| 862 | static void intel_pmu_enable_bts(u64 config) | ||
| 863 | { | ||
| 864 | unsigned long debugctlmsr; | ||
| 865 | |||
| 866 | debugctlmsr = get_debugctlmsr(); | ||
| 867 | |||
| 868 | debugctlmsr |= X86_DEBUGCTL_TR; | ||
| 869 | debugctlmsr |= X86_DEBUGCTL_BTS; | ||
| 870 | debugctlmsr |= X86_DEBUGCTL_BTINT; | ||
| 871 | |||
| 872 | if (!(config & ARCH_PERFMON_EVENTSEL_OS)) | ||
| 873 | debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS; | ||
| 874 | |||
| 875 | if (!(config & ARCH_PERFMON_EVENTSEL_USR)) | ||
| 876 | debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR; | ||
| 877 | |||
| 878 | update_debugctlmsr(debugctlmsr); | ||
| 879 | } | ||
| 880 | |||
| 881 | static void intel_pmu_disable_bts(void) | ||
| 882 | { | ||
| 883 | struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); | ||
| 884 | unsigned long debugctlmsr; | ||
| 885 | |||
| 886 | if (!cpuc->ds) | ||
| 887 | return; | ||
| 888 | |||
| 889 | debugctlmsr = get_debugctlmsr(); | ||
| 890 | |||
| 891 | debugctlmsr &= | ||
| 892 | ~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT | | ||
| 893 | X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR); | ||
| 894 | |||
| 895 | update_debugctlmsr(debugctlmsr); | ||
| 896 | } | ||
| 897 | |||
| 715 | /* | 898 | /* |
| 716 | * Setup the hardware configuration for a given attr_type | 899 | * Setup the hardware configuration for a given attr_type |
| 717 | */ | 900 | */ |
| @@ -728,9 +911,13 @@ static int __hw_perf_counter_init(struct perf_counter *counter) | |||
| 728 | err = 0; | 911 | err = 0; |
| 729 | if (!atomic_inc_not_zero(&active_counters)) { | 912 | if (!atomic_inc_not_zero(&active_counters)) { |
| 730 | mutex_lock(&pmc_reserve_mutex); | 913 | mutex_lock(&pmc_reserve_mutex); |
| 731 | if (atomic_read(&active_counters) == 0 && !reserve_pmc_hardware()) | 914 | if (atomic_read(&active_counters) == 0) { |
| 732 | err = -EBUSY; | 915 | if (!reserve_pmc_hardware()) |
| 733 | else | 916 | err = -EBUSY; |
| 917 | else | ||
| 918 | err = reserve_bts_hardware(); | ||
| 919 | } | ||
| 920 | if (!err) | ||
| 734 | atomic_inc(&active_counters); | 921 | atomic_inc(&active_counters); |
| 735 | mutex_unlock(&pmc_reserve_mutex); | 922 | mutex_unlock(&pmc_reserve_mutex); |
| 736 | } | 923 | } |
| @@ -793,6 +980,20 @@ static int __hw_perf_counter_init(struct perf_counter *counter) | |||
| 793 | if (config == -1LL) | 980 | if (config == -1LL) |
| 794 | return -EINVAL; | 981 | return -EINVAL; |
| 795 | 982 | ||
| 983 | /* | ||
| 984 | * Branch tracing: | ||
| 985 | */ | ||
| 986 | if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) && | ||
| 987 | (hwc->sample_period == 1)) { | ||
| 988 | /* BTS is not supported by this architecture. */ | ||
| 989 | if (!bts_available()) | ||
| 990 | return -EOPNOTSUPP; | ||
| 991 | |||
| 992 | /* BTS is currently only allowed for user-mode. */ | ||
| 993 | if (hwc->config & ARCH_PERFMON_EVENTSEL_OS) | ||
| 994 | return -EOPNOTSUPP; | ||
| 995 | } | ||
| 996 | |||
| 796 | hwc->config |= config; | 997 | hwc->config |= config; |
| 797 | 998 | ||
| 798 | return 0; | 999 | return 0; |
| @@ -817,7 +1018,18 @@ static void p6_pmu_disable_all(void) | |||
| 817 | 1018 | ||
| 818 | static void intel_pmu_disable_all(void) | 1019 | static void intel_pmu_disable_all(void) |
| 819 | { | 1020 | { |
| 1021 | struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); | ||
| 1022 | |||
| 1023 | if (!cpuc->enabled) | ||
| 1024 | return; | ||
| 1025 | |||
| 1026 | cpuc->enabled = 0; | ||
| 1027 | barrier(); | ||
| 1028 | |||
| 820 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); | 1029 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); |
| 1030 | |||
| 1031 | if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) | ||
| 1032 | intel_pmu_disable_bts(); | ||
| 821 | } | 1033 | } |
| 822 | 1034 | ||
| 823 | static void amd_pmu_disable_all(void) | 1035 | static void amd_pmu_disable_all(void) |
| @@ -875,7 +1087,25 @@ static void p6_pmu_enable_all(void) | |||
| 875 | 1087 | ||
| 876 | static void intel_pmu_enable_all(void) | 1088 | static void intel_pmu_enable_all(void) |
| 877 | { | 1089 | { |
| 1090 | struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); | ||
| 1091 | |||
| 1092 | if (cpuc->enabled) | ||
| 1093 | return; | ||
| 1094 | |||
| 1095 | cpuc->enabled = 1; | ||
| 1096 | barrier(); | ||
| 1097 | |||
| 878 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl); | 1098 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl); |
| 1099 | |||
| 1100 | if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) { | ||
| 1101 | struct perf_counter *counter = | ||
| 1102 | cpuc->counters[X86_PMC_IDX_FIXED_BTS]; | ||
| 1103 | |||
| 1104 | if (WARN_ON_ONCE(!counter)) | ||
| 1105 | return; | ||
| 1106 | |||
| 1107 | intel_pmu_enable_bts(counter->hw.config); | ||
| 1108 | } | ||
| 879 | } | 1109 | } |
| 880 | 1110 | ||
| 881 | static void amd_pmu_enable_all(void) | 1111 | static void amd_pmu_enable_all(void) |
| @@ -962,6 +1192,11 @@ p6_pmu_disable_counter(struct hw_perf_counter *hwc, int idx) | |||
| 962 | static inline void | 1192 | static inline void |
| 963 | intel_pmu_disable_counter(struct hw_perf_counter *hwc, int idx) | 1193 | intel_pmu_disable_counter(struct hw_perf_counter *hwc, int idx) |
| 964 | { | 1194 | { |
| 1195 | if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) { | ||
| 1196 | intel_pmu_disable_bts(); | ||
| 1197 | return; | ||
| 1198 | } | ||
| 1199 | |||
| 965 | if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { | 1200 | if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { |
| 966 | intel_pmu_disable_fixed(hwc, idx); | 1201 | intel_pmu_disable_fixed(hwc, idx); |
| 967 | return; | 1202 | return; |
| @@ -990,6 +1225,9 @@ x86_perf_counter_set_period(struct perf_counter *counter, | |||
| 990 | s64 period = hwc->sample_period; | 1225 | s64 period = hwc->sample_period; |
| 991 | int err, ret = 0; | 1226 | int err, ret = 0; |
| 992 | 1227 | ||
| 1228 | if (idx == X86_PMC_IDX_FIXED_BTS) | ||
| 1229 | return 0; | ||
| 1230 | |||
| 993 | /* | 1231 | /* |
| 994 | * If we are way outside a reasoable range then just skip forward: | 1232 | * If we are way outside a reasoable range then just skip forward: |
| 995 | */ | 1233 | */ |
| @@ -1072,6 +1310,14 @@ static void p6_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) | |||
| 1072 | 1310 | ||
| 1073 | static void intel_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) | 1311 | static void intel_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) |
| 1074 | { | 1312 | { |
| 1313 | if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) { | ||
| 1314 | if (!__get_cpu_var(cpu_hw_counters).enabled) | ||
| 1315 | return; | ||
| 1316 | |||
| 1317 | intel_pmu_enable_bts(hwc->config); | ||
| 1318 | return; | ||
| 1319 | } | ||
| 1320 | |||
| 1075 | if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { | 1321 | if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { |
| 1076 | intel_pmu_enable_fixed(hwc, idx); | 1322 | intel_pmu_enable_fixed(hwc, idx); |
| 1077 | return; | 1323 | return; |
| @@ -1093,11 +1339,16 @@ fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc) | |||
| 1093 | { | 1339 | { |
| 1094 | unsigned int event; | 1340 | unsigned int event; |
| 1095 | 1341 | ||
| 1342 | event = hwc->config & ARCH_PERFMON_EVENT_MASK; | ||
| 1343 | |||
| 1344 | if (unlikely((event == | ||
| 1345 | x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS)) && | ||
| 1346 | (hwc->sample_period == 1))) | ||
| 1347 | return X86_PMC_IDX_FIXED_BTS; | ||
| 1348 | |||
| 1096 | if (!x86_pmu.num_counters_fixed) | 1349 | if (!x86_pmu.num_counters_fixed) |
| 1097 | return -1; | 1350 | return -1; |
| 1098 | 1351 | ||
| 1099 | event = hwc->config & ARCH_PERFMON_EVENT_MASK; | ||
| 1100 | |||
| 1101 | if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS))) | 1352 | if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS))) |
| 1102 | return X86_PMC_IDX_FIXED_INSTRUCTIONS; | 1353 | return X86_PMC_IDX_FIXED_INSTRUCTIONS; |
| 1103 | if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_CPU_CYCLES))) | 1354 | if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_CPU_CYCLES))) |
| @@ -1118,7 +1369,15 @@ static int x86_pmu_enable(struct perf_counter *counter) | |||
| 1118 | int idx; | 1369 | int idx; |
| 1119 | 1370 | ||
| 1120 | idx = fixed_mode_idx(counter, hwc); | 1371 | idx = fixed_mode_idx(counter, hwc); |
| 1121 | if (idx >= 0) { | 1372 | if (idx == X86_PMC_IDX_FIXED_BTS) { |
| 1373 | /* BTS is already occupied. */ | ||
| 1374 | if (test_and_set_bit(idx, cpuc->used_mask)) | ||
| 1375 | return -EAGAIN; | ||
| 1376 | |||
| 1377 | hwc->config_base = 0; | ||
| 1378 | hwc->counter_base = 0; | ||
| 1379 | hwc->idx = idx; | ||
| 1380 | } else if (idx >= 0) { | ||
| 1122 | /* | 1381 | /* |
| 1123 | * Try to get the fixed counter, if that is already taken | 1382 | * Try to get the fixed counter, if that is already taken |
| 1124 | * then try to get a generic counter: | 1383 | * then try to get a generic counter: |
| @@ -1229,6 +1488,44 @@ void perf_counter_print_debug(void) | |||
| 1229 | local_irq_restore(flags); | 1488 | local_irq_restore(flags); |
| 1230 | } | 1489 | } |
| 1231 | 1490 | ||
| 1491 | static void intel_pmu_drain_bts_buffer(struct cpu_hw_counters *cpuc, | ||
| 1492 | struct perf_sample_data *data) | ||
| 1493 | { | ||
| 1494 | struct debug_store *ds = cpuc->ds; | ||
| 1495 | struct bts_record { | ||
| 1496 | u64 from; | ||
| 1497 | u64 to; | ||
| 1498 | u64 flags; | ||
| 1499 | }; | ||
| 1500 | struct perf_counter *counter = cpuc->counters[X86_PMC_IDX_FIXED_BTS]; | ||
| 1501 | unsigned long orig_ip = data->regs->ip; | ||
| 1502 | struct bts_record *at, *top; | ||
| 1503 | |||
| 1504 | if (!counter) | ||
| 1505 | return; | ||
| 1506 | |||
| 1507 | if (!ds) | ||
| 1508 | return; | ||
| 1509 | |||
| 1510 | at = (struct bts_record *)(unsigned long)ds->bts_buffer_base; | ||
| 1511 | top = (struct bts_record *)(unsigned long)ds->bts_index; | ||
| 1512 | |||
| 1513 | ds->bts_index = ds->bts_buffer_base; | ||
| 1514 | |||
| 1515 | for (; at < top; at++) { | ||
| 1516 | data->regs->ip = at->from; | ||
| 1517 | data->addr = at->to; | ||
| 1518 | |||
| 1519 | perf_counter_output(counter, 1, data); | ||
| 1520 | } | ||
| 1521 | |||
| 1522 | data->regs->ip = orig_ip; | ||
| 1523 | data->addr = 0; | ||
| 1524 | |||
| 1525 | /* There's new data available. */ | ||
| 1526 | counter->pending_kill = POLL_IN; | ||
| 1527 | } | ||
| 1528 | |||
| 1232 | static void x86_pmu_disable(struct perf_counter *counter) | 1529 | static void x86_pmu_disable(struct perf_counter *counter) |
| 1233 | { | 1530 | { |
| 1234 | struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); | 1531 | struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); |
| @@ -1253,6 +1550,15 @@ static void x86_pmu_disable(struct perf_counter *counter) | |||
| 1253 | * that we are disabling: | 1550 | * that we are disabling: |
| 1254 | */ | 1551 | */ |
| 1255 | x86_perf_counter_update(counter, hwc, idx); | 1552 | x86_perf_counter_update(counter, hwc, idx); |
| 1553 | |||
| 1554 | /* Drain the remaining BTS records. */ | ||
| 1555 | if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) { | ||
| 1556 | struct perf_sample_data data; | ||
| 1557 | struct pt_regs regs; | ||
| 1558 | |||
| 1559 | data.regs = ®s; | ||
| 1560 | intel_pmu_drain_bts_buffer(cpuc, &data); | ||
| 1561 | } | ||
| 1256 | cpuc->counters[idx] = NULL; | 1562 | cpuc->counters[idx] = NULL; |
| 1257 | clear_bit(idx, cpuc->used_mask); | 1563 | clear_bit(idx, cpuc->used_mask); |
| 1258 | 1564 | ||
| @@ -1280,6 +1586,7 @@ static int intel_pmu_save_and_restart(struct perf_counter *counter) | |||
| 1280 | 1586 | ||
| 1281 | static void intel_pmu_reset(void) | 1587 | static void intel_pmu_reset(void) |
| 1282 | { | 1588 | { |
| 1589 | struct debug_store *ds = __get_cpu_var(cpu_hw_counters).ds; | ||
| 1283 | unsigned long flags; | 1590 | unsigned long flags; |
| 1284 | int idx; | 1591 | int idx; |
| 1285 | 1592 | ||
| @@ -1297,6 +1604,8 @@ static void intel_pmu_reset(void) | |||
| 1297 | for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) { | 1604 | for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) { |
| 1298 | checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); | 1605 | checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); |
| 1299 | } | 1606 | } |
| 1607 | if (ds) | ||
| 1608 | ds->bts_index = ds->bts_buffer_base; | ||
| 1300 | 1609 | ||
| 1301 | local_irq_restore(flags); | 1610 | local_irq_restore(flags); |
| 1302 | } | 1611 | } |
| @@ -1362,6 +1671,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) | |||
| 1362 | cpuc = &__get_cpu_var(cpu_hw_counters); | 1671 | cpuc = &__get_cpu_var(cpu_hw_counters); |
| 1363 | 1672 | ||
| 1364 | perf_disable(); | 1673 | perf_disable(); |
| 1674 | intel_pmu_drain_bts_buffer(cpuc, &data); | ||
| 1365 | status = intel_pmu_get_status(); | 1675 | status = intel_pmu_get_status(); |
| 1366 | if (!status) { | 1676 | if (!status) { |
| 1367 | perf_enable(); | 1677 | perf_enable(); |
| @@ -1571,6 +1881,8 @@ static struct x86_pmu intel_pmu = { | |||
| 1571 | * the generic counter period: | 1881 | * the generic counter period: |
| 1572 | */ | 1882 | */ |
| 1573 | .max_period = (1ULL << 31) - 1, | 1883 | .max_period = (1ULL << 31) - 1, |
| 1884 | .enable_bts = intel_pmu_enable_bts, | ||
| 1885 | .disable_bts = intel_pmu_disable_bts, | ||
| 1574 | }; | 1886 | }; |
| 1575 | 1887 | ||
| 1576 | static struct x86_pmu amd_pmu = { | 1888 | static struct x86_pmu amd_pmu = { |
| @@ -1962,3 +2274,8 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | |||
| 1962 | 2274 | ||
| 1963 | return entry; | 2275 | return entry; |
| 1964 | } | 2276 | } |
| 2277 | |||
| 2278 | void hw_perf_counter_setup_online(int cpu) | ||
| 2279 | { | ||
| 2280 | init_debug_store_on_cpu(cpu); | ||
| 2281 | } | ||
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c index e60ed740d2b3..392bea43b890 100644 --- a/arch/x86/kernel/cpu/perfctr-watchdog.c +++ b/arch/x86/kernel/cpu/perfctr-watchdog.c | |||
| @@ -68,16 +68,16 @@ static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) | |||
| 68 | /* returns the bit offset of the performance counter register */ | 68 | /* returns the bit offset of the performance counter register */ |
| 69 | switch (boot_cpu_data.x86_vendor) { | 69 | switch (boot_cpu_data.x86_vendor) { |
| 70 | case X86_VENDOR_AMD: | 70 | case X86_VENDOR_AMD: |
| 71 | return (msr - MSR_K7_PERFCTR0); | 71 | return msr - MSR_K7_PERFCTR0; |
| 72 | case X86_VENDOR_INTEL: | 72 | case X86_VENDOR_INTEL: |
| 73 | if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) | 73 | if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) |
| 74 | return (msr - MSR_ARCH_PERFMON_PERFCTR0); | 74 | return msr - MSR_ARCH_PERFMON_PERFCTR0; |
| 75 | 75 | ||
| 76 | switch (boot_cpu_data.x86) { | 76 | switch (boot_cpu_data.x86) { |
| 77 | case 6: | 77 | case 6: |
| 78 | return (msr - MSR_P6_PERFCTR0); | 78 | return msr - MSR_P6_PERFCTR0; |
| 79 | case 15: | 79 | case 15: |
| 80 | return (msr - MSR_P4_BPU_PERFCTR0); | 80 | return msr - MSR_P4_BPU_PERFCTR0; |
| 81 | } | 81 | } |
| 82 | } | 82 | } |
| 83 | return 0; | 83 | return 0; |
| @@ -92,16 +92,16 @@ static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) | |||
| 92 | /* returns the bit offset of the event selection register */ | 92 | /* returns the bit offset of the event selection register */ |
| 93 | switch (boot_cpu_data.x86_vendor) { | 93 | switch (boot_cpu_data.x86_vendor) { |
| 94 | case X86_VENDOR_AMD: | 94 | case X86_VENDOR_AMD: |
| 95 | return (msr - MSR_K7_EVNTSEL0); | 95 | return msr - MSR_K7_EVNTSEL0; |
| 96 | case X86_VENDOR_INTEL: | 96 | case X86_VENDOR_INTEL: |
| 97 | if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) | 97 | if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) |
| 98 | return (msr - MSR_ARCH_PERFMON_EVENTSEL0); | 98 | return msr - MSR_ARCH_PERFMON_EVENTSEL0; |
| 99 | 99 | ||
| 100 | switch (boot_cpu_data.x86) { | 100 | switch (boot_cpu_data.x86) { |
| 101 | case 6: | 101 | case 6: |
| 102 | return (msr - MSR_P6_EVNTSEL0); | 102 | return msr - MSR_P6_EVNTSEL0; |
| 103 | case 15: | 103 | case 15: |
| 104 | return (msr - MSR_P4_BSU_ESCR0); | 104 | return msr - MSR_P4_BSU_ESCR0; |
| 105 | } | 105 | } |
| 106 | } | 106 | } |
| 107 | return 0; | 107 | return 0; |
| @@ -113,7 +113,7 @@ int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) | |||
| 113 | { | 113 | { |
| 114 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); | 114 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); |
| 115 | 115 | ||
| 116 | return (!test_bit(counter, perfctr_nmi_owner)); | 116 | return !test_bit(counter, perfctr_nmi_owner); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | /* checks the an msr for availability */ | 119 | /* checks the an msr for availability */ |
| @@ -124,7 +124,7 @@ int avail_to_resrv_perfctr_nmi(unsigned int msr) | |||
| 124 | counter = nmi_perfctr_msr_to_bit(msr); | 124 | counter = nmi_perfctr_msr_to_bit(msr); |
| 125 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); | 125 | BUG_ON(counter > NMI_MAX_COUNTER_BITS); |
| 126 | 126 | ||
| 127 | return (!test_bit(counter, perfctr_nmi_owner)); | 127 | return !test_bit(counter, perfctr_nmi_owner); |
| 128 | } | 128 | } |
| 129 | EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); | 129 | EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); |
| 130 | 130 | ||
| @@ -237,7 +237,7 @@ static unsigned int adjust_for_32bit_ctr(unsigned int hz) | |||
| 237 | */ | 237 | */ |
| 238 | counter_val = (u64)cpu_khz * 1000; | 238 | counter_val = (u64)cpu_khz * 1000; |
| 239 | do_div(counter_val, retval); | 239 | do_div(counter_val, retval); |
| 240 | if (counter_val > 0x7fffffffULL) { | 240 | if (counter_val > 0x7fffffffULL) { |
| 241 | u64 count = (u64)cpu_khz * 1000; | 241 | u64 count = (u64)cpu_khz * 1000; |
| 242 | do_div(count, 0x7fffffffUL); | 242 | do_div(count, 0x7fffffffUL); |
| 243 | retval = count + 1; | 243 | retval = count + 1; |
| @@ -251,7 +251,7 @@ static void write_watchdog_counter(unsigned int perfctr_msr, | |||
| 251 | u64 count = (u64)cpu_khz * 1000; | 251 | u64 count = (u64)cpu_khz * 1000; |
| 252 | 252 | ||
| 253 | do_div(count, nmi_hz); | 253 | do_div(count, nmi_hz); |
| 254 | if(descr) | 254 | if (descr) |
| 255 | pr_debug("setting %s to -0x%08Lx\n", descr, count); | 255 | pr_debug("setting %s to -0x%08Lx\n", descr, count); |
| 256 | wrmsrl(perfctr_msr, 0 - count); | 256 | wrmsrl(perfctr_msr, 0 - count); |
| 257 | } | 257 | } |
| @@ -262,7 +262,7 @@ static void write_watchdog_counter32(unsigned int perfctr_msr, | |||
| 262 | u64 count = (u64)cpu_khz * 1000; | 262 | u64 count = (u64)cpu_khz * 1000; |
| 263 | 263 | ||
| 264 | do_div(count, nmi_hz); | 264 | do_div(count, nmi_hz); |
| 265 | if(descr) | 265 | if (descr) |
| 266 | pr_debug("setting %s to -0x%08Lx\n", descr, count); | 266 | pr_debug("setting %s to -0x%08Lx\n", descr, count); |
| 267 | wrmsr(perfctr_msr, (u32)(-count), 0); | 267 | wrmsr(perfctr_msr, (u32)(-count), 0); |
| 268 | } | 268 | } |
| @@ -296,7 +296,7 @@ static int setup_k7_watchdog(unsigned nmi_hz) | |||
| 296 | 296 | ||
| 297 | /* setup the timer */ | 297 | /* setup the timer */ |
| 298 | wrmsr(evntsel_msr, evntsel, 0); | 298 | wrmsr(evntsel_msr, evntsel, 0); |
| 299 | write_watchdog_counter(perfctr_msr, "K7_PERFCTR0",nmi_hz); | 299 | write_watchdog_counter(perfctr_msr, "K7_PERFCTR0", nmi_hz); |
| 300 | 300 | ||
| 301 | /* initialize the wd struct before enabling */ | 301 | /* initialize the wd struct before enabling */ |
| 302 | wd->perfctr_msr = perfctr_msr; | 302 | wd->perfctr_msr = perfctr_msr; |
| @@ -387,7 +387,7 @@ static int setup_p6_watchdog(unsigned nmi_hz) | |||
| 387 | /* setup the timer */ | 387 | /* setup the timer */ |
| 388 | wrmsr(evntsel_msr, evntsel, 0); | 388 | wrmsr(evntsel_msr, evntsel, 0); |
| 389 | nmi_hz = adjust_for_32bit_ctr(nmi_hz); | 389 | nmi_hz = adjust_for_32bit_ctr(nmi_hz); |
| 390 | write_watchdog_counter32(perfctr_msr, "P6_PERFCTR0",nmi_hz); | 390 | write_watchdog_counter32(perfctr_msr, "P6_PERFCTR0", nmi_hz); |
| 391 | 391 | ||
| 392 | /* initialize the wd struct before enabling */ | 392 | /* initialize the wd struct before enabling */ |
| 393 | wd->perfctr_msr = perfctr_msr; | 393 | wd->perfctr_msr = perfctr_msr; |
| @@ -415,7 +415,7 @@ static void __kprobes p6_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz) | |||
| 415 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 415 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
| 416 | 416 | ||
| 417 | /* P6/ARCH_PERFMON has 32 bit counter write */ | 417 | /* P6/ARCH_PERFMON has 32 bit counter write */ |
| 418 | write_watchdog_counter32(wd->perfctr_msr, NULL,nmi_hz); | 418 | write_watchdog_counter32(wd->perfctr_msr, NULL, nmi_hz); |
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | static const struct wd_ops p6_wd_ops = { | 421 | static const struct wd_ops p6_wd_ops = { |
| @@ -490,9 +490,9 @@ static int setup_p4_watchdog(unsigned nmi_hz) | |||
| 490 | if (smp_num_siblings == 2) { | 490 | if (smp_num_siblings == 2) { |
| 491 | unsigned int ebx, apicid; | 491 | unsigned int ebx, apicid; |
| 492 | 492 | ||
| 493 | ebx = cpuid_ebx(1); | 493 | ebx = cpuid_ebx(1); |
| 494 | apicid = (ebx >> 24) & 0xff; | 494 | apicid = (ebx >> 24) & 0xff; |
| 495 | ht_num = apicid & 1; | 495 | ht_num = apicid & 1; |
| 496 | } else | 496 | } else |
| 497 | #endif | 497 | #endif |
| 498 | ht_num = 0; | 498 | ht_num = 0; |
| @@ -544,7 +544,7 @@ static int setup_p4_watchdog(unsigned nmi_hz) | |||
| 544 | } | 544 | } |
| 545 | 545 | ||
| 546 | evntsel = P4_ESCR_EVENT_SELECT(0x3F) | 546 | evntsel = P4_ESCR_EVENT_SELECT(0x3F) |
| 547 | | P4_ESCR_OS | 547 | | P4_ESCR_OS |
| 548 | | P4_ESCR_USR; | 548 | | P4_ESCR_USR; |
| 549 | 549 | ||
| 550 | cccr_val |= P4_CCCR_THRESHOLD(15) | 550 | cccr_val |= P4_CCCR_THRESHOLD(15) |
| @@ -612,7 +612,7 @@ static void __kprobes p4_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz) | |||
| 612 | { | 612 | { |
| 613 | unsigned dummy; | 613 | unsigned dummy; |
| 614 | /* | 614 | /* |
| 615 | * P4 quirks: | 615 | * P4 quirks: |
| 616 | * - An overflown perfctr will assert its interrupt | 616 | * - An overflown perfctr will assert its interrupt |
| 617 | * until the OVF flag in its CCCR is cleared. | 617 | * until the OVF flag in its CCCR is cleared. |
| 618 | * - LVTPC is masked on interrupt and must be | 618 | * - LVTPC is masked on interrupt and must be |
| @@ -662,7 +662,8 @@ static int setup_intel_arch_watchdog(unsigned nmi_hz) | |||
| 662 | * NOTE: Corresponding bit = 0 in ebx indicates event present. | 662 | * NOTE: Corresponding bit = 0 in ebx indicates event present. |
| 663 | */ | 663 | */ |
| 664 | cpuid(10, &(eax.full), &ebx, &unused, &unused); | 664 | cpuid(10, &(eax.full), &ebx, &unused, &unused); |
| 665 | if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || | 665 | if ((eax.split.mask_length < |
| 666 | (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || | ||
| 666 | (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) | 667 | (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) |
| 667 | return 0; | 668 | return 0; |
| 668 | 669 | ||
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index d5e30397246b..62ac8cb6ba27 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c | |||
| @@ -116,11 +116,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
| 116 | seq_printf(m, "TLB size\t: %d 4K pages\n", c->x86_tlbsize); | 116 | seq_printf(m, "TLB size\t: %d 4K pages\n", c->x86_tlbsize); |
| 117 | #endif | 117 | #endif |
| 118 | seq_printf(m, "clflush size\t: %u\n", c->x86_clflush_size); | 118 | seq_printf(m, "clflush size\t: %u\n", c->x86_clflush_size); |
| 119 | #ifdef CONFIG_X86_64 | ||
| 120 | seq_printf(m, "cache_alignment\t: %d\n", c->x86_cache_alignment); | 119 | seq_printf(m, "cache_alignment\t: %d\n", c->x86_cache_alignment); |
| 121 | seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n", | 120 | seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n", |
| 122 | c->x86_phys_bits, c->x86_virt_bits); | 121 | c->x86_phys_bits, c->x86_virt_bits); |
| 123 | #endif | ||
| 124 | 122 | ||
| 125 | seq_printf(m, "power management:"); | 123 | seq_printf(m, "power management:"); |
| 126 | for (i = 0; i < 32; i++) { | 124 | for (i = 0; i < 32; i++) { |
| @@ -128,7 +126,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
| 128 | if (i < ARRAY_SIZE(x86_power_flags) && | 126 | if (i < ARRAY_SIZE(x86_power_flags) && |
| 129 | x86_power_flags[i]) | 127 | x86_power_flags[i]) |
| 130 | seq_printf(m, "%s%s", | 128 | seq_printf(m, "%s%s", |
| 131 | x86_power_flags[i][0]?" ":"", | 129 | x86_power_flags[i][0] ? " " : "", |
| 132 | x86_power_flags[i]); | 130 | x86_power_flags[i]); |
| 133 | else | 131 | else |
| 134 | seq_printf(m, " [%d]", i); | 132 | seq_printf(m, " [%d]", i); |
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 284c399e3234..bc24f514ec93 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c | |||
| @@ -49,17 +49,17 @@ static inline int __vmware_platform(void) | |||
| 49 | 49 | ||
| 50 | static unsigned long __vmware_get_tsc_khz(void) | 50 | static unsigned long __vmware_get_tsc_khz(void) |
| 51 | { | 51 | { |
| 52 | uint64_t tsc_hz; | 52 | uint64_t tsc_hz; |
| 53 | uint32_t eax, ebx, ecx, edx; | 53 | uint32_t eax, ebx, ecx, edx; |
| 54 | 54 | ||
| 55 | VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); | 55 | VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); |
| 56 | 56 | ||
| 57 | if (ebx == UINT_MAX) | 57 | if (ebx == UINT_MAX) |
| 58 | return 0; | 58 | return 0; |
| 59 | tsc_hz = eax | (((uint64_t)ebx) << 32); | 59 | tsc_hz = eax | (((uint64_t)ebx) << 32); |
| 60 | do_div(tsc_hz, 1000); | 60 | do_div(tsc_hz, 1000); |
| 61 | BUG_ON(tsc_hz >> 32); | 61 | BUG_ON(tsc_hz >> 32); |
| 62 | return tsc_hz; | 62 | return tsc_hz; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | /* | 65 | /* |
diff --git a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c index b4f14c6c09d9..37250fe490b1 100644 --- a/arch/x86/kernel/doublefault_32.c +++ b/arch/x86/kernel/doublefault_32.c | |||
| @@ -27,9 +27,7 @@ static void doublefault_fn(void) | |||
| 27 | 27 | ||
| 28 | if (ptr_ok(gdt)) { | 28 | if (ptr_ok(gdt)) { |
| 29 | gdt += GDT_ENTRY_TSS << 3; | 29 | gdt += GDT_ENTRY_TSS << 3; |
| 30 | tss = *(u16 *)(gdt+2); | 30 | tss = get_desc_base((struct desc_struct *)gdt); |
| 31 | tss += *(u8 *)(gdt+4) << 16; | ||
| 32 | tss += *(u8 *)(gdt+7) << 24; | ||
| 33 | printk(KERN_EMERG "double fault, tss at %08lx\n", tss); | 31 | printk(KERN_EMERG "double fault, tss at %08lx\n", tss); |
| 34 | 32 | ||
| 35 | if (ptr_ok(tss)) { | 33 | if (ptr_ok(tss)) { |
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c index 48bfe1386038..ef42a038f1a6 100644 --- a/arch/x86/kernel/ds.c +++ b/arch/x86/kernel/ds.c | |||
| @@ -509,15 +509,15 @@ enum bts_field { | |||
| 509 | bts_escape = ((unsigned long)-1 & ~bts_qual_mask) | 509 | bts_escape = ((unsigned long)-1 & ~bts_qual_mask) |
| 510 | }; | 510 | }; |
| 511 | 511 | ||
| 512 | static inline unsigned long bts_get(const char *base, enum bts_field field) | 512 | static inline unsigned long bts_get(const char *base, unsigned long field) |
| 513 | { | 513 | { |
| 514 | base += (ds_cfg.sizeof_ptr_field * field); | 514 | base += (ds_cfg.sizeof_ptr_field * field); |
| 515 | return *(unsigned long *)base; | 515 | return *(unsigned long *)base; |
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | static inline void bts_set(char *base, enum bts_field field, unsigned long val) | 518 | static inline void bts_set(char *base, unsigned long field, unsigned long val) |
| 519 | { | 519 | { |
| 520 | base += (ds_cfg.sizeof_ptr_field * field);; | 520 | base += (ds_cfg.sizeof_ptr_field * field); |
| 521 | (*(unsigned long *)base) = val; | 521 | (*(unsigned long *)base) = val; |
| 522 | } | 522 | } |
| 523 | 523 | ||
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index c8405718a4c3..2d8a371d4339 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include <linux/bug.h> | 15 | #include <linux/bug.h> |
| 16 | #include <linux/nmi.h> | 16 | #include <linux/nmi.h> |
| 17 | #include <linux/sysfs.h> | 17 | #include <linux/sysfs.h> |
| 18 | #include <linux/ftrace.h> | ||
| 19 | 18 | ||
| 20 | #include <asm/stacktrace.h> | 19 | #include <asm/stacktrace.h> |
| 21 | 20 | ||
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 5cb5725b2bae..147005a1cc3c 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
| @@ -115,7 +115,7 @@ static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size, | |||
| 115 | { | 115 | { |
| 116 | int x = e820x->nr_map; | 116 | int x = e820x->nr_map; |
| 117 | 117 | ||
| 118 | if (x == ARRAY_SIZE(e820x->map)) { | 118 | if (x >= ARRAY_SIZE(e820x->map)) { |
| 119 | printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); | 119 | printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); |
| 120 | return; | 120 | return; |
| 121 | } | 121 | } |
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index d94e1ea3b9fe..9dbb527e1652 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
| @@ -417,10 +417,6 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, | |||
| 417 | unsigned long return_hooker = (unsigned long) | 417 | unsigned long return_hooker = (unsigned long) |
| 418 | &return_to_handler; | 418 | &return_to_handler; |
| 419 | 419 | ||
| 420 | /* Nmi's are currently unsupported */ | ||
| 421 | if (unlikely(in_nmi())) | ||
| 422 | return; | ||
| 423 | |||
| 424 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) | 420 | if (unlikely(atomic_read(¤t->tracing_graph_pause))) |
| 425 | return; | 421 | return; |
| 426 | 422 | ||
| @@ -498,37 +494,56 @@ static struct syscall_metadata *find_syscall_meta(unsigned long *syscall) | |||
| 498 | 494 | ||
| 499 | struct syscall_metadata *syscall_nr_to_meta(int nr) | 495 | struct syscall_metadata *syscall_nr_to_meta(int nr) |
| 500 | { | 496 | { |
| 501 | if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0) | 497 | if (!syscalls_metadata || nr >= NR_syscalls || nr < 0) |
| 502 | return NULL; | 498 | return NULL; |
| 503 | 499 | ||
| 504 | return syscalls_metadata[nr]; | 500 | return syscalls_metadata[nr]; |
| 505 | } | 501 | } |
| 506 | 502 | ||
| 507 | void arch_init_ftrace_syscalls(void) | 503 | int syscall_name_to_nr(char *name) |
| 504 | { | ||
| 505 | int i; | ||
| 506 | |||
| 507 | if (!syscalls_metadata) | ||
| 508 | return -1; | ||
| 509 | |||
| 510 | for (i = 0; i < NR_syscalls; i++) { | ||
| 511 | if (syscalls_metadata[i]) { | ||
| 512 | if (!strcmp(syscalls_metadata[i]->name, name)) | ||
| 513 | return i; | ||
| 514 | } | ||
| 515 | } | ||
| 516 | return -1; | ||
| 517 | } | ||
| 518 | |||
| 519 | void set_syscall_enter_id(int num, int id) | ||
| 520 | { | ||
| 521 | syscalls_metadata[num]->enter_id = id; | ||
| 522 | } | ||
| 523 | |||
| 524 | void set_syscall_exit_id(int num, int id) | ||
| 525 | { | ||
| 526 | syscalls_metadata[num]->exit_id = id; | ||
| 527 | } | ||
| 528 | |||
| 529 | static int __init arch_init_ftrace_syscalls(void) | ||
| 508 | { | 530 | { |
| 509 | int i; | 531 | int i; |
| 510 | struct syscall_metadata *meta; | 532 | struct syscall_metadata *meta; |
| 511 | unsigned long **psys_syscall_table = &sys_call_table; | 533 | unsigned long **psys_syscall_table = &sys_call_table; |
| 512 | static atomic_t refs; | ||
| 513 | |||
| 514 | if (atomic_inc_return(&refs) != 1) | ||
| 515 | goto end; | ||
| 516 | 534 | ||
| 517 | syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * | 535 | syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * |
| 518 | FTRACE_SYSCALL_MAX, GFP_KERNEL); | 536 | NR_syscalls, GFP_KERNEL); |
| 519 | if (!syscalls_metadata) { | 537 | if (!syscalls_metadata) { |
| 520 | WARN_ON(1); | 538 | WARN_ON(1); |
| 521 | return; | 539 | return -ENOMEM; |
| 522 | } | 540 | } |
| 523 | 541 | ||
| 524 | for (i = 0; i < FTRACE_SYSCALL_MAX; i++) { | 542 | for (i = 0; i < NR_syscalls; i++) { |
| 525 | meta = find_syscall_meta(psys_syscall_table[i]); | 543 | meta = find_syscall_meta(psys_syscall_table[i]); |
| 526 | syscalls_metadata[i] = meta; | 544 | syscalls_metadata[i] = meta; |
| 527 | } | 545 | } |
| 528 | return; | 546 | return 0; |
| 529 | |||
| 530 | /* Paranoid: avoid overflow */ | ||
| 531 | end: | ||
| 532 | atomic_dec(&refs); | ||
| 533 | } | 547 | } |
| 548 | arch_initcall(arch_init_ftrace_syscalls); | ||
| 534 | #endif | 549 | #endif |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 0d98a01cbdb2..7ffec6b3b331 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
| @@ -261,9 +261,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20); | |||
| 261 | * which will be freed later | 261 | * which will be freed later |
| 262 | */ | 262 | */ |
| 263 | 263 | ||
| 264 | #ifndef CONFIG_HOTPLUG_CPU | 264 | __CPUINIT |
| 265 | .section .init.text,"ax",@progbits | ||
| 266 | #endif | ||
| 267 | 265 | ||
| 268 | #ifdef CONFIG_SMP | 266 | #ifdef CONFIG_SMP |
| 269 | ENTRY(startup_32_smp) | 267 | ENTRY(startup_32_smp) |
| @@ -441,7 +439,6 @@ is386: movl $2,%ecx # set MP | |||
| 441 | jne 1f | 439 | jne 1f |
| 442 | movl $per_cpu__gdt_page,%eax | 440 | movl $per_cpu__gdt_page,%eax |
| 443 | movl $per_cpu__stack_canary,%ecx | 441 | movl $per_cpu__stack_canary,%ecx |
| 444 | subl $20, %ecx | ||
| 445 | movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax) | 442 | movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax) |
| 446 | shrl $16, %ecx | 443 | shrl $16, %ecx |
| 447 | movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax) | 444 | movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax) |
| @@ -602,11 +599,7 @@ ignore_int: | |||
| 602 | #endif | 599 | #endif |
| 603 | iret | 600 | iret |
| 604 | 601 | ||
| 605 | #ifndef CONFIG_HOTPLUG_CPU | ||
| 606 | __CPUINITDATA | ||
| 607 | #else | ||
| 608 | __REFDATA | 602 | __REFDATA |
| 609 | #endif | ||
| 610 | .align 4 | 603 | .align 4 |
| 611 | ENTRY(initial_code) | 604 | ENTRY(initial_code) |
| 612 | .long i386_start_kernel | 605 | .long i386_start_kernel |
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index 3b09634a5153..7d35d0fe2329 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c | |||
| @@ -218,7 +218,6 @@ bool handle_irq(unsigned irq, struct pt_regs *regs) | |||
| 218 | void fixup_irqs(void) | 218 | void fixup_irqs(void) |
| 219 | { | 219 | { |
| 220 | unsigned int irq; | 220 | unsigned int irq; |
| 221 | static int warned; | ||
| 222 | struct irq_desc *desc; | 221 | struct irq_desc *desc; |
| 223 | 222 | ||
| 224 | for_each_irq_desc(irq, desc) { | 223 | for_each_irq_desc(irq, desc) { |
| @@ -236,8 +235,8 @@ void fixup_irqs(void) | |||
| 236 | } | 235 | } |
| 237 | if (desc->chip->set_affinity) | 236 | if (desc->chip->set_affinity) |
| 238 | desc->chip->set_affinity(irq, affinity); | 237 | desc->chip->set_affinity(irq, affinity); |
| 239 | else if (desc->action && !(warned++)) | 238 | else if (desc->action) |
| 240 | printk("Cannot set affinity for irq %i\n", irq); | 239 | printk_once("Cannot set affinity for irq %i\n", irq); |
| 241 | } | 240 | } |
| 242 | 241 | ||
| 243 | #if 0 | 242 | #if 0 |
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index c664d515f613..63b0ec8d3d4a 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | struct kvm_para_state { | 34 | struct kvm_para_state { |
| 35 | u8 mmu_queue[MMU_QUEUE_SIZE]; | 35 | u8 mmu_queue[MMU_QUEUE_SIZE]; |
| 36 | int mmu_queue_len; | 36 | int mmu_queue_len; |
| 37 | enum paravirt_lazy_mode mode; | ||
| 38 | }; | 37 | }; |
| 39 | 38 | ||
| 40 | static DEFINE_PER_CPU(struct kvm_para_state, para_state); | 39 | static DEFINE_PER_CPU(struct kvm_para_state, para_state); |
| @@ -77,7 +76,7 @@ static void kvm_deferred_mmu_op(void *buffer, int len) | |||
| 77 | { | 76 | { |
| 78 | struct kvm_para_state *state = kvm_para_state(); | 77 | struct kvm_para_state *state = kvm_para_state(); |
| 79 | 78 | ||
| 80 | if (state->mode != PARAVIRT_LAZY_MMU) { | 79 | if (paravirt_get_lazy_mode() != PARAVIRT_LAZY_MMU) { |
| 81 | kvm_mmu_op(buffer, len); | 80 | kvm_mmu_op(buffer, len); |
| 82 | return; | 81 | return; |
| 83 | } | 82 | } |
| @@ -185,10 +184,7 @@ static void kvm_release_pt(unsigned long pfn) | |||
| 185 | 184 | ||
| 186 | static void kvm_enter_lazy_mmu(void) | 185 | static void kvm_enter_lazy_mmu(void) |
| 187 | { | 186 | { |
| 188 | struct kvm_para_state *state = kvm_para_state(); | ||
| 189 | |||
| 190 | paravirt_enter_lazy_mmu(); | 187 | paravirt_enter_lazy_mmu(); |
| 191 | state->mode = paravirt_get_lazy_mode(); | ||
| 192 | } | 188 | } |
| 193 | 189 | ||
| 194 | static void kvm_leave_lazy_mmu(void) | 190 | static void kvm_leave_lazy_mmu(void) |
| @@ -197,7 +193,6 @@ static void kvm_leave_lazy_mmu(void) | |||
| 197 | 193 | ||
| 198 | mmu_queue_flush(state); | 194 | mmu_queue_flush(state); |
| 199 | paravirt_leave_lazy_mmu(); | 195 | paravirt_leave_lazy_mmu(); |
| 200 | state->mode = paravirt_get_lazy_mode(); | ||
| 201 | } | 196 | } |
| 202 | 197 | ||
| 203 | static void __init paravirt_ops_setup(void) | 198 | static void __init paravirt_ops_setup(void) |
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 223af43f1526..e5efcdcca31b 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c | |||
| @@ -50,8 +50,8 @@ static unsigned long kvm_get_wallclock(void) | |||
| 50 | struct timespec ts; | 50 | struct timespec ts; |
| 51 | int low, high; | 51 | int low, high; |
| 52 | 52 | ||
| 53 | low = (int)__pa(&wall_clock); | 53 | low = (int)__pa_symbol(&wall_clock); |
| 54 | high = ((u64)__pa(&wall_clock) >> 32); | 54 | high = ((u64)__pa_symbol(&wall_clock) >> 32); |
| 55 | native_write_msr(MSR_KVM_WALL_CLOCK, low, high); | 55 | native_write_msr(MSR_KVM_WALL_CLOCK, low, high); |
| 56 | 56 | ||
| 57 | vcpu_time = &get_cpu_var(hv_clock); | 57 | vcpu_time = &get_cpu_var(hv_clock); |
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 651c93b28862..fcd513bf2846 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
| @@ -482,11 +482,11 @@ static void __init construct_ioapic_table(int mpc_default_type) | |||
| 482 | MP_bus_info(&bus); | 482 | MP_bus_info(&bus); |
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | ioapic.type = MP_IOAPIC; | 485 | ioapic.type = MP_IOAPIC; |
| 486 | ioapic.apicid = 2; | 486 | ioapic.apicid = 2; |
| 487 | ioapic.apicver = mpc_default_type > 4 ? 0x10 : 0x01; | 487 | ioapic.apicver = mpc_default_type > 4 ? 0x10 : 0x01; |
| 488 | ioapic.flags = MPC_APIC_USABLE; | 488 | ioapic.flags = MPC_APIC_USABLE; |
| 489 | ioapic.apicaddr = 0xFEC00000; | 489 | ioapic.apicaddr = IO_APIC_DEFAULT_PHYS_BASE; |
| 490 | MP_ioapic_info(&ioapic); | 490 | MP_ioapic_info(&ioapic); |
| 491 | 491 | ||
| 492 | /* | 492 | /* |
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 98fd6cd4e3a4..7dd950094178 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* ----------------------------------------------------------------------- * | 1 | /* ----------------------------------------------------------------------- * |
| 2 | * | 2 | * |
| 3 | * Copyright 2000-2008 H. Peter Anvin - All Rights Reserved | 3 | * Copyright 2000-2008 H. Peter Anvin - All Rights Reserved |
| 4 | * Copyright 2009 Intel Corporation; author: H. Peter Anvin | ||
| 4 | * | 5 | * |
| 5 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| @@ -80,11 +81,8 @@ static ssize_t msr_read(struct file *file, char __user *buf, | |||
| 80 | 81 | ||
| 81 | for (; count; count -= 8) { | 82 | for (; count; count -= 8) { |
| 82 | err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]); | 83 | err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]); |
| 83 | if (err) { | 84 | if (err) |
| 84 | if (err == -EFAULT) /* Fix idiotic error code */ | ||
| 85 | err = -EIO; | ||
| 86 | break; | 85 | break; |
| 87 | } | ||
| 88 | if (copy_to_user(tmp, &data, 8)) { | 86 | if (copy_to_user(tmp, &data, 8)) { |
| 89 | err = -EFAULT; | 87 | err = -EFAULT; |
| 90 | break; | 88 | break; |
| @@ -115,11 +113,8 @@ static ssize_t msr_write(struct file *file, const char __user *buf, | |||
| 115 | break; | 113 | break; |
| 116 | } | 114 | } |
| 117 | err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]); | 115 | err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]); |
| 118 | if (err) { | 116 | if (err) |
| 119 | if (err == -EFAULT) /* Fix idiotic error code */ | ||
| 120 | err = -EIO; | ||
| 121 | break; | 117 | break; |
| 122 | } | ||
| 123 | tmp += 2; | 118 | tmp += 2; |
| 124 | bytes += 8; | 119 | bytes += 8; |
| 125 | } | 120 | } |
| @@ -127,6 +122,54 @@ static ssize_t msr_write(struct file *file, const char __user *buf, | |||
| 127 | return bytes ? bytes : err; | 122 | return bytes ? bytes : err; |
| 128 | } | 123 | } |
| 129 | 124 | ||
| 125 | static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg) | ||
| 126 | { | ||
| 127 | u32 __user *uregs = (u32 __user *)arg; | ||
| 128 | u32 regs[8]; | ||
| 129 | int cpu = iminor(file->f_path.dentry->d_inode); | ||
| 130 | int err; | ||
| 131 | |||
| 132 | switch (ioc) { | ||
| 133 | case X86_IOC_RDMSR_REGS: | ||
| 134 | if (!(file->f_mode & FMODE_READ)) { | ||
| 135 | err = -EBADF; | ||
| 136 | break; | ||
| 137 | } | ||
| 138 | if (copy_from_user(®s, uregs, sizeof regs)) { | ||
| 139 | err = -EFAULT; | ||
| 140 | break; | ||
| 141 | } | ||
| 142 | err = rdmsr_safe_regs_on_cpu(cpu, regs); | ||
| 143 | if (err) | ||
| 144 | break; | ||
| 145 | if (copy_to_user(uregs, ®s, sizeof regs)) | ||
| 146 | err = -EFAULT; | ||
| 147 | break; | ||
| 148 | |||
| 149 | case X86_IOC_WRMSR_REGS: | ||
| 150 | if (!(file->f_mode & FMODE_WRITE)) { | ||
| 151 | err = -EBADF; | ||
| 152 | break; | ||
| 153 | } | ||
| 154 | if (copy_from_user(®s, uregs, sizeof regs)) { | ||
| 155 | err = -EFAULT; | ||
| 156 | break; | ||
| 157 | } | ||
| 158 | err = wrmsr_safe_regs_on_cpu(cpu, regs); | ||
| 159 | if (err) | ||
| 160 | break; | ||
| 161 | if (copy_to_user(uregs, ®s, sizeof regs)) | ||
| 162 | err = -EFAULT; | ||
| 163 | break; | ||
| 164 | |||
| 165 | default: | ||
| 166 | err = -ENOTTY; | ||
| 167 | break; | ||
| 168 | } | ||
| 169 | |||
| 170 | return err; | ||
| 171 | } | ||
| 172 | |||
| 130 | static int msr_open(struct inode *inode, struct file *file) | 173 | static int msr_open(struct inode *inode, struct file *file) |
| 131 | { | 174 | { |
| 132 | unsigned int cpu = iminor(file->f_path.dentry->d_inode); | 175 | unsigned int cpu = iminor(file->f_path.dentry->d_inode); |
| @@ -157,6 +200,8 @@ static const struct file_operations msr_fops = { | |||
| 157 | .read = msr_read, | 200 | .read = msr_read, |
| 158 | .write = msr_write, | 201 | .write = msr_write, |
| 159 | .open = msr_open, | 202 | .open = msr_open, |
| 203 | .unlocked_ioctl = msr_ioctl, | ||
| 204 | .compat_ioctl = msr_ioctl, | ||
| 160 | }; | 205 | }; |
| 161 | 206 | ||
| 162 | static int __cpuinit msr_device_create(int cpu) | 207 | static int __cpuinit msr_device_create(int cpu) |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 70ec9b951d76..f5b0b4a01fb2 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
| @@ -362,8 +362,9 @@ struct pv_cpu_ops pv_cpu_ops = { | |||
| 362 | #endif | 362 | #endif |
| 363 | .wbinvd = native_wbinvd, | 363 | .wbinvd = native_wbinvd, |
| 364 | .read_msr = native_read_msr_safe, | 364 | .read_msr = native_read_msr_safe, |
| 365 | .read_msr_amd = native_read_msr_amd_safe, | 365 | .rdmsr_regs = native_rdmsr_safe_regs, |
| 366 | .write_msr = native_write_msr_safe, | 366 | .write_msr = native_write_msr_safe, |
| 367 | .wrmsr_regs = native_wrmsr_safe_regs, | ||
| 367 | .read_tsc = native_read_tsc, | 368 | .read_tsc = native_read_tsc, |
| 368 | .read_pmc = native_read_pmc, | 369 | .read_pmc = native_read_pmc, |
| 369 | .read_tscp = native_read_tscp, | 370 | .read_tscp = native_read_tscp, |
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 1a041bcf506b..d71c8655905b 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | #include <linux/dmar.h> | 3 | #include <linux/dmar.h> |
| 4 | #include <linux/bootmem.h> | 4 | #include <linux/bootmem.h> |
| 5 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
| 6 | #include <linux/kmemleak.h> | ||
| 6 | 7 | ||
| 7 | #include <asm/proto.h> | 8 | #include <asm/proto.h> |
| 8 | #include <asm/dma.h> | 9 | #include <asm/dma.h> |
| @@ -32,7 +33,14 @@ int no_iommu __read_mostly; | |||
| 32 | /* Set this to 1 if there is a HW IOMMU in the system */ | 33 | /* Set this to 1 if there is a HW IOMMU in the system */ |
| 33 | int iommu_detected __read_mostly = 0; | 34 | int iommu_detected __read_mostly = 0; |
| 34 | 35 | ||
| 35 | int iommu_pass_through; | 36 | /* |
| 37 | * This variable becomes 1 if iommu=pt is passed on the kernel command line. | ||
| 38 | * If this variable is 1, IOMMU implementations do no DMA ranslation for | ||
| 39 | * devices and allow every device to access to whole physical memory. This is | ||
| 40 | * useful if a user want to use an IOMMU only for KVM device assignment to | ||
| 41 | * guests and not for driver dma translation. | ||
| 42 | */ | ||
| 43 | int iommu_pass_through __read_mostly; | ||
| 36 | 44 | ||
| 37 | dma_addr_t bad_dma_address __read_mostly = 0; | 45 | dma_addr_t bad_dma_address __read_mostly = 0; |
| 38 | EXPORT_SYMBOL(bad_dma_address); | 46 | EXPORT_SYMBOL(bad_dma_address); |
| @@ -88,6 +96,11 @@ void __init dma32_reserve_bootmem(void) | |||
| 88 | size = roundup(dma32_bootmem_size, align); | 96 | size = roundup(dma32_bootmem_size, align); |
| 89 | dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align, | 97 | dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align, |
| 90 | 512ULL<<20); | 98 | 512ULL<<20); |
| 99 | /* | ||
| 100 | * Kmemleak should not scan this block as it may not be mapped via the | ||
| 101 | * kernel direct mapping. | ||
| 102 | */ | ||
| 103 | kmemleak_ignore(dma32_bootmem_ptr); | ||
| 91 | if (dma32_bootmem_ptr) | 104 | if (dma32_bootmem_ptr) |
| 92 | dma32_bootmem_size = size; | 105 | dma32_bootmem_size = size; |
| 93 | else | 106 | else |
| @@ -147,7 +160,7 @@ again: | |||
| 147 | return NULL; | 160 | return NULL; |
| 148 | 161 | ||
| 149 | addr = page_to_phys(page); | 162 | addr = page_to_phys(page); |
| 150 | if (!is_buffer_dma_capable(dma_mask, addr, size)) { | 163 | if (addr + size > dma_mask) { |
| 151 | __free_pages(page, get_order(size)); | 164 | __free_pages(page, get_order(size)); |
| 152 | 165 | ||
| 153 | if (dma_mask < DMA_BIT_MASK(32) && !(flag & GFP_DMA)) { | 166 | if (dma_mask < DMA_BIT_MASK(32) && !(flag & GFP_DMA)) { |
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index d2e56b8f48e7..98a827ee9ed7 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
| @@ -190,14 +190,13 @@ static void iommu_full(struct device *dev, size_t size, int dir) | |||
| 190 | static inline int | 190 | static inline int |
| 191 | need_iommu(struct device *dev, unsigned long addr, size_t size) | 191 | need_iommu(struct device *dev, unsigned long addr, size_t size) |
| 192 | { | 192 | { |
| 193 | return force_iommu || | 193 | return force_iommu || !dma_capable(dev, addr, size); |
| 194 | !is_buffer_dma_capable(*dev->dma_mask, addr, size); | ||
| 195 | } | 194 | } |
| 196 | 195 | ||
| 197 | static inline int | 196 | static inline int |
| 198 | nonforced_iommu(struct device *dev, unsigned long addr, size_t size) | 197 | nonforced_iommu(struct device *dev, unsigned long addr, size_t size) |
| 199 | { | 198 | { |
| 200 | return !is_buffer_dma_capable(*dev->dma_mask, addr, size); | 199 | return !dma_capable(dev, addr, size); |
| 201 | } | 200 | } |
| 202 | 201 | ||
| 203 | /* Map a single continuous physical area into the IOMMU. | 202 | /* Map a single continuous physical area into the IOMMU. |
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index 71d412a09f30..a3933d4330cd 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | static int | 14 | static int |
| 15 | check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) | 15 | check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) |
| 16 | { | 16 | { |
| 17 | if (hwdev && !is_buffer_dma_capable(*hwdev->dma_mask, bus, size)) { | 17 | if (hwdev && !dma_capable(hwdev, bus, size)) { |
| 18 | if (*hwdev->dma_mask >= DMA_BIT_MASK(32)) | 18 | if (*hwdev->dma_mask >= DMA_BIT_MASK(32)) |
| 19 | printk(KERN_ERR | 19 | printk(KERN_ERR |
| 20 | "nommu_%s: overflow %Lx+%zu of device mask %Lx\n", | 20 | "nommu_%s: overflow %Lx+%zu of device mask %Lx\n", |
| @@ -79,12 +79,29 @@ static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr, | |||
| 79 | free_pages((unsigned long)vaddr, get_order(size)); | 79 | free_pages((unsigned long)vaddr, get_order(size)); |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | static void nommu_sync_single_for_device(struct device *dev, | ||
| 83 | dma_addr_t addr, size_t size, | ||
| 84 | enum dma_data_direction dir) | ||
| 85 | { | ||
| 86 | flush_write_buffers(); | ||
| 87 | } | ||
| 88 | |||
| 89 | |||
| 90 | static void nommu_sync_sg_for_device(struct device *dev, | ||
| 91 | struct scatterlist *sg, int nelems, | ||
| 92 | enum dma_data_direction dir) | ||
| 93 | { | ||
| 94 | flush_write_buffers(); | ||
| 95 | } | ||
| 96 | |||
| 82 | struct dma_map_ops nommu_dma_ops = { | 97 | struct dma_map_ops nommu_dma_ops = { |
| 83 | .alloc_coherent = dma_generic_alloc_coherent, | 98 | .alloc_coherent = dma_generic_alloc_coherent, |
| 84 | .free_coherent = nommu_free_coherent, | 99 | .free_coherent = nommu_free_coherent, |
| 85 | .map_sg = nommu_map_sg, | 100 | .map_sg = nommu_map_sg, |
| 86 | .map_page = nommu_map_page, | 101 | .map_page = nommu_map_page, |
| 87 | .is_phys = 1, | 102 | .sync_single_for_device = nommu_sync_single_for_device, |
| 103 | .sync_sg_for_device = nommu_sync_sg_for_device, | ||
| 104 | .is_phys = 1, | ||
| 88 | }; | 105 | }; |
| 89 | 106 | ||
| 90 | void __init no_iommu_init(void) | 107 | void __init no_iommu_init(void) |
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c index 6af96ee44200..e8a35016115f 100644 --- a/arch/x86/kernel/pci-swiotlb.c +++ b/arch/x86/kernel/pci-swiotlb.c | |||
| @@ -13,31 +13,6 @@ | |||
| 13 | 13 | ||
| 14 | int swiotlb __read_mostly; | 14 | int swiotlb __read_mostly; |
| 15 | 15 | ||
| 16 | void * __init swiotlb_alloc_boot(size_t size, unsigned long nslabs) | ||
| 17 | { | ||
| 18 | return alloc_bootmem_low_pages(size); | ||
| 19 | } | ||
| 20 | |||
| 21 | void *swiotlb_alloc(unsigned order, unsigned long nslabs) | ||
| 22 | { | ||
| 23 | return (void *)__get_free_pages(GFP_DMA | __GFP_NOWARN, order); | ||
| 24 | } | ||
| 25 | |||
| 26 | dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr) | ||
| 27 | { | ||
| 28 | return paddr; | ||
| 29 | } | ||
| 30 | |||
| 31 | phys_addr_t swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr) | ||
| 32 | { | ||
| 33 | return baddr; | ||
| 34 | } | ||
| 35 | |||
| 36 | int __weak swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size) | ||
| 37 | { | ||
| 38 | return 0; | ||
| 39 | } | ||
| 40 | |||
| 41 | static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | 16 | static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, |
| 42 | dma_addr_t *dma_handle, gfp_t flags) | 17 | dma_addr_t *dma_handle, gfp_t flags) |
| 43 | { | 18 | { |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 994dd6a4a2a0..071166a4ba83 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
| @@ -519,16 +519,12 @@ static void c1e_idle(void) | |||
| 519 | if (!cpumask_test_cpu(cpu, c1e_mask)) { | 519 | if (!cpumask_test_cpu(cpu, c1e_mask)) { |
| 520 | cpumask_set_cpu(cpu, c1e_mask); | 520 | cpumask_set_cpu(cpu, c1e_mask); |
| 521 | /* | 521 | /* |
| 522 | * Force broadcast so ACPI can not interfere. Needs | 522 | * Force broadcast so ACPI can not interfere. |
| 523 | * to run with interrupts enabled as it uses | ||
| 524 | * smp_function_call. | ||
| 525 | */ | 523 | */ |
| 526 | local_irq_enable(); | ||
| 527 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, | 524 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, |
| 528 | &cpu); | 525 | &cpu); |
| 529 | printk(KERN_INFO "Switch to broadcast mode on CPU%d\n", | 526 | printk(KERN_INFO "Switch to broadcast mode on CPU%d\n", |
| 530 | cpu); | 527 | cpu); |
| 531 | local_irq_disable(); | ||
| 532 | } | 528 | } |
| 533 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); | 529 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); |
| 534 | 530 | ||
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 59f4524984af..4cf79567cdab 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
| @@ -61,9 +61,6 @@ | |||
| 61 | 61 | ||
| 62 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 62 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
| 63 | 63 | ||
| 64 | DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; | ||
| 65 | EXPORT_PER_CPU_SYMBOL(current_task); | ||
| 66 | |||
| 67 | /* | 64 | /* |
| 68 | * Return saved PC of a blocked thread. | 65 | * Return saved PC of a blocked thread. |
| 69 | */ | 66 | */ |
| @@ -350,14 +347,21 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
| 350 | *next = &next_p->thread; | 347 | *next = &next_p->thread; |
| 351 | int cpu = smp_processor_id(); | 348 | int cpu = smp_processor_id(); |
| 352 | struct tss_struct *tss = &per_cpu(init_tss, cpu); | 349 | struct tss_struct *tss = &per_cpu(init_tss, cpu); |
| 350 | bool preload_fpu; | ||
| 353 | 351 | ||
| 354 | /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ | 352 | /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ |
| 355 | 353 | ||
| 356 | __unlazy_fpu(prev_p); | 354 | /* |
| 355 | * If the task has used fpu the last 5 timeslices, just do a full | ||
| 356 | * restore of the math state immediately to avoid the trap; the | ||
| 357 | * chances of needing FPU soon are obviously high now | ||
| 358 | */ | ||
| 359 | preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5; | ||
| 357 | 360 | ||
| 361 | __unlazy_fpu(prev_p); | ||
| 358 | 362 | ||
| 359 | /* we're going to use this soon, after a few expensive things */ | 363 | /* we're going to use this soon, after a few expensive things */ |
| 360 | if (next_p->fpu_counter > 5) | 364 | if (preload_fpu) |
| 361 | prefetch(next->xstate); | 365 | prefetch(next->xstate); |
| 362 | 366 | ||
| 363 | /* | 367 | /* |
| @@ -398,6 +402,11 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
| 398 | task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT)) | 402 | task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT)) |
| 399 | __switch_to_xtra(prev_p, next_p, tss); | 403 | __switch_to_xtra(prev_p, next_p, tss); |
| 400 | 404 | ||
| 405 | /* If we're going to preload the fpu context, make sure clts | ||
| 406 | is run while we're batching the cpu state updates. */ | ||
| 407 | if (preload_fpu) | ||
| 408 | clts(); | ||
| 409 | |||
| 401 | /* | 410 | /* |
| 402 | * Leave lazy mode, flushing any hypercalls made here. | 411 | * Leave lazy mode, flushing any hypercalls made here. |
| 403 | * This must be done before restoring TLS segments so | 412 | * This must be done before restoring TLS segments so |
| @@ -407,15 +416,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
| 407 | */ | 416 | */ |
| 408 | arch_end_context_switch(next_p); | 417 | arch_end_context_switch(next_p); |
| 409 | 418 | ||
| 410 | /* If the task has used fpu the last 5 timeslices, just do a full | 419 | if (preload_fpu) |
| 411 | * restore of the math state immediately to avoid the trap; the | 420 | __math_state_restore(); |
| 412 | * chances of needing FPU soon are obviously high now | ||
| 413 | * | ||
| 414 | * tsk_used_math() checks prevent calling math_state_restore(), | ||
| 415 | * which can sleep in the case of !tsk_used_math() | ||
| 416 | */ | ||
| 417 | if (tsk_used_math(next_p) && next_p->fpu_counter > 5) | ||
| 418 | math_state_restore(); | ||
| 419 | 421 | ||
| 420 | /* | 422 | /* |
| 421 | * Restore %gs if needed (which is common) | 423 | * Restore %gs if needed (which is common) |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index ebefb5407b9d..ad535b683170 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
| @@ -55,9 +55,6 @@ | |||
| 55 | 55 | ||
| 56 | asmlinkage extern void ret_from_fork(void); | 56 | asmlinkage extern void ret_from_fork(void); |
| 57 | 57 | ||
| 58 | DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; | ||
| 59 | EXPORT_PER_CPU_SYMBOL(current_task); | ||
| 60 | |||
| 61 | DEFINE_PER_CPU(unsigned long, old_rsp); | 58 | DEFINE_PER_CPU(unsigned long, old_rsp); |
| 62 | static DEFINE_PER_CPU(unsigned char, is_idle); | 59 | static DEFINE_PER_CPU(unsigned char, is_idle); |
| 63 | 60 | ||
| @@ -386,9 +383,17 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
| 386 | int cpu = smp_processor_id(); | 383 | int cpu = smp_processor_id(); |
| 387 | struct tss_struct *tss = &per_cpu(init_tss, cpu); | 384 | struct tss_struct *tss = &per_cpu(init_tss, cpu); |
| 388 | unsigned fsindex, gsindex; | 385 | unsigned fsindex, gsindex; |
| 386 | bool preload_fpu; | ||
| 387 | |||
| 388 | /* | ||
| 389 | * If the task has used fpu the last 5 timeslices, just do a full | ||
| 390 | * restore of the math state immediately to avoid the trap; the | ||
| 391 | * chances of needing FPU soon are obviously high now | ||
| 392 | */ | ||
| 393 | preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5; | ||
| 389 | 394 | ||
| 390 | /* we're going to use this soon, after a few expensive things */ | 395 | /* we're going to use this soon, after a few expensive things */ |
| 391 | if (next_p->fpu_counter > 5) | 396 | if (preload_fpu) |
| 392 | prefetch(next->xstate); | 397 | prefetch(next->xstate); |
| 393 | 398 | ||
| 394 | /* | 399 | /* |
| @@ -419,6 +424,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
| 419 | 424 | ||
| 420 | load_TLS(next, cpu); | 425 | load_TLS(next, cpu); |
| 421 | 426 | ||
| 427 | /* Must be after DS reload */ | ||
| 428 | unlazy_fpu(prev_p); | ||
| 429 | |||
| 430 | /* Make sure cpu is ready for new context */ | ||
| 431 | if (preload_fpu) | ||
| 432 | clts(); | ||
| 433 | |||
| 422 | /* | 434 | /* |
| 423 | * Leave lazy mode, flushing any hypercalls made here. | 435 | * Leave lazy mode, flushing any hypercalls made here. |
| 424 | * This must be done before restoring TLS segments so | 436 | * This must be done before restoring TLS segments so |
| @@ -459,9 +471,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
| 459 | wrmsrl(MSR_KERNEL_GS_BASE, next->gs); | 471 | wrmsrl(MSR_KERNEL_GS_BASE, next->gs); |
| 460 | prev->gsindex = gsindex; | 472 | prev->gsindex = gsindex; |
| 461 | 473 | ||
| 462 | /* Must be after DS reload */ | ||
| 463 | unlazy_fpu(prev_p); | ||
| 464 | |||
| 465 | /* | 474 | /* |
| 466 | * Switch the PDA and FPU contexts. | 475 | * Switch the PDA and FPU contexts. |
| 467 | */ | 476 | */ |
| @@ -480,15 +489,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
| 480 | task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV)) | 489 | task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV)) |
| 481 | __switch_to_xtra(prev_p, next_p, tss); | 490 | __switch_to_xtra(prev_p, next_p, tss); |
| 482 | 491 | ||
| 483 | /* If the task has used fpu the last 5 timeslices, just do a full | 492 | /* |
| 484 | * restore of the math state immediately to avoid the trap; the | 493 | * Preload the FPU context, now that we've determined that the |
| 485 | * chances of needing FPU soon are obviously high now | 494 | * task is likely to be using it. |
| 486 | * | ||
| 487 | * tsk_used_math() checks prevent calling math_state_restore(), | ||
| 488 | * which can sleep in the case of !tsk_used_math() | ||
| 489 | */ | 495 | */ |
| 490 | if (tsk_used_math(next_p) && next_p->fpu_counter > 5) | 496 | if (preload_fpu) |
| 491 | math_state_restore(); | 497 | __math_state_restore(); |
| 492 | return prev_p; | 498 | return prev_p; |
| 493 | } | 499 | } |
| 494 | 500 | ||
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 09ecbde91c13..8d7d5c9c1be3 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
| @@ -35,10 +35,11 @@ | |||
| 35 | #include <asm/proto.h> | 35 | #include <asm/proto.h> |
| 36 | #include <asm/ds.h> | 36 | #include <asm/ds.h> |
| 37 | 37 | ||
| 38 | #include <trace/syscall.h> | ||
| 39 | |||
| 40 | #include "tls.h" | 38 | #include "tls.h" |
| 41 | 39 | ||
| 40 | #define CREATE_TRACE_POINTS | ||
| 41 | #include <trace/events/syscalls.h> | ||
| 42 | |||
| 42 | enum x86_regset { | 43 | enum x86_regset { |
| 43 | REGSET_GENERAL, | 44 | REGSET_GENERAL, |
| 44 | REGSET_FP, | 45 | REGSET_FP, |
| @@ -1497,8 +1498,8 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs) | |||
| 1497 | tracehook_report_syscall_entry(regs)) | 1498 | tracehook_report_syscall_entry(regs)) |
| 1498 | ret = -1L; | 1499 | ret = -1L; |
| 1499 | 1500 | ||
| 1500 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) | 1501 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
| 1501 | ftrace_syscall_enter(regs); | 1502 | trace_sys_enter(regs, regs->orig_ax); |
| 1502 | 1503 | ||
| 1503 | if (unlikely(current->audit_context)) { | 1504 | if (unlikely(current->audit_context)) { |
| 1504 | if (IS_IA32) | 1505 | if (IS_IA32) |
| @@ -1523,8 +1524,8 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) | |||
| 1523 | if (unlikely(current->audit_context)) | 1524 | if (unlikely(current->audit_context)) |
| 1524 | audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); | 1525 | audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); |
| 1525 | 1526 | ||
| 1526 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) | 1527 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
| 1527 | ftrace_syscall_exit(regs); | 1528 | trace_sys_exit(regs, regs->ax); |
| 1528 | 1529 | ||
| 1529 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 1530 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
| 1530 | tracehook_report_syscall_exit(regs, 0); | 1531 | tracehook_report_syscall_exit(regs, 0); |
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 4c578751e94e..81e58238c4ce 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
| @@ -869,6 +869,8 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) | |||
| 869 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 869 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
| 870 | clear_thread_flag(TIF_NOTIFY_RESUME); | 870 | clear_thread_flag(TIF_NOTIFY_RESUME); |
| 871 | tracehook_notify_resume(regs); | 871 | tracehook_notify_resume(regs); |
| 872 | if (current->replacement_session_keyring) | ||
| 873 | key_replace_session_keyring(); | ||
| 872 | } | 874 | } |
| 873 | 875 | ||
| 874 | #ifdef CONFIG_X86_32 | 876 | #ifdef CONFIG_X86_32 |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 2fecda69ee64..c36cc1452cdc 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
| @@ -434,7 +434,8 @@ const struct cpumask *cpu_coregroup_mask(int cpu) | |||
| 434 | * For perf, we return last level cache shared map. | 434 | * For perf, we return last level cache shared map. |
| 435 | * And for power savings, we return cpu_core_map | 435 | * And for power savings, we return cpu_core_map |
| 436 | */ | 436 | */ |
| 437 | if (sched_mc_power_savings || sched_smt_power_savings) | 437 | if ((sched_mc_power_savings || sched_smt_power_savings) && |
| 438 | !(cpu_has(c, X86_FEATURE_AMD_DCM))) | ||
| 438 | return cpu_core_mask(cpu); | 439 | return cpu_core_mask(cpu); |
| 439 | else | 440 | else |
| 440 | return c->llc_shared_map; | 441 | return c->llc_shared_map; |
diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c index e8b9863ef8c4..3149032ff107 100644 --- a/arch/x86/kernel/step.c +++ b/arch/x86/kernel/step.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
| 5 | #include <linux/mm.h> | 5 | #include <linux/mm.h> |
| 6 | #include <linux/ptrace.h> | 6 | #include <linux/ptrace.h> |
| 7 | #include <asm/desc.h> | ||
| 7 | 8 | ||
| 8 | unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs) | 9 | unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs) |
| 9 | { | 10 | { |
| @@ -23,7 +24,7 @@ unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *re | |||
| 23 | * and APM bios ones we just ignore here. | 24 | * and APM bios ones we just ignore here. |
| 24 | */ | 25 | */ |
| 25 | if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) { | 26 | if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) { |
| 26 | u32 *desc; | 27 | struct desc_struct *desc; |
| 27 | unsigned long base; | 28 | unsigned long base; |
| 28 | 29 | ||
| 29 | seg &= ~7UL; | 30 | seg &= ~7UL; |
| @@ -33,12 +34,10 @@ unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *re | |||
| 33 | addr = -1L; /* bogus selector, access would fault */ | 34 | addr = -1L; /* bogus selector, access would fault */ |
| 34 | else { | 35 | else { |
| 35 | desc = child->mm->context.ldt + seg; | 36 | desc = child->mm->context.ldt + seg; |
| 36 | base = ((desc[0] >> 16) | | 37 | base = get_desc_base(desc); |
| 37 | ((desc[1] & 0xff) << 16) | | ||
| 38 | (desc[1] & 0xff000000)); | ||
| 39 | 38 | ||
| 40 | /* 16-bit code segment? */ | 39 | /* 16-bit code segment? */ |
| 41 | if (!((desc[1] >> 22) & 1)) | 40 | if (!desc->d) |
| 42 | addr &= 0xffff; | 41 | addr &= 0xffff; |
| 43 | addr += base; | 42 | addr += base; |
| 44 | } | 43 | } |
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c index 6bc211accf08..45e00eb09c3a 100644 --- a/arch/x86/kernel/sys_x86_64.c +++ b/arch/x86/kernel/sys_x86_64.c | |||
| @@ -18,9 +18,9 @@ | |||
| 18 | #include <asm/ia32.h> | 18 | #include <asm/ia32.h> |
| 19 | #include <asm/syscalls.h> | 19 | #include <asm/syscalls.h> |
| 20 | 20 | ||
| 21 | asmlinkage long sys_mmap(unsigned long addr, unsigned long len, | 21 | SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, |
| 22 | unsigned long prot, unsigned long flags, | 22 | unsigned long, prot, unsigned long, flags, |
| 23 | unsigned long fd, unsigned long off) | 23 | unsigned long, fd, unsigned long, off) |
| 24 | { | 24 | { |
| 25 | long error; | 25 | long error; |
| 26 | struct file *file; | 26 | struct file *file; |
| @@ -226,7 +226,7 @@ bottomup: | |||
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | 228 | ||
| 229 | asmlinkage long sys_uname(struct new_utsname __user *name) | 229 | SYSCALL_DEFINE1(uname, struct new_utsname __user *, name) |
| 230 | { | 230 | { |
| 231 | int err; | 231 | int err; |
| 232 | down_read(&uts_sem); | 232 | down_read(&uts_sem); |
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index 77b9689f8edb..503c1f2e8835 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c | |||
| @@ -640,13 +640,13 @@ static int __init uv_ptc_init(void) | |||
| 640 | if (!is_uv_system()) | 640 | if (!is_uv_system()) |
| 641 | return 0; | 641 | return 0; |
| 642 | 642 | ||
| 643 | proc_uv_ptc = create_proc_entry(UV_PTC_BASENAME, 0444, NULL); | 643 | proc_uv_ptc = proc_create(UV_PTC_BASENAME, 0444, NULL, |
| 644 | &proc_uv_ptc_operations); | ||
| 644 | if (!proc_uv_ptc) { | 645 | if (!proc_uv_ptc) { |
| 645 | printk(KERN_ERR "unable to create %s proc entry\n", | 646 | printk(KERN_ERR "unable to create %s proc entry\n", |
| 646 | UV_PTC_BASENAME); | 647 | UV_PTC_BASENAME); |
| 647 | return -EINVAL; | 648 | return -EINVAL; |
| 648 | } | 649 | } |
| 649 | proc_uv_ptc->proc_fops = &proc_uv_ptc_operations; | ||
| 650 | return 0; | 650 | return 0; |
| 651 | } | 651 | } |
| 652 | 652 | ||
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 5204332f475d..83264922a878 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
| @@ -76,7 +76,7 @@ char ignore_fpu_irq; | |||
| 76 | * F0 0F bug workaround.. We have a special link segment | 76 | * F0 0F bug workaround.. We have a special link segment |
| 77 | * for this. | 77 | * for this. |
| 78 | */ | 78 | */ |
| 79 | gate_desc idt_table[256] | 79 | gate_desc idt_table[NR_VECTORS] |
| 80 | __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; | 80 | __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; |
| 81 | #endif | 81 | #endif |
| 82 | 82 | ||
| @@ -786,33 +786,34 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) | |||
| 786 | #endif | 786 | #endif |
| 787 | } | 787 | } |
| 788 | 788 | ||
| 789 | #ifdef CONFIG_X86_32 | 789 | asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void) |
| 790 | unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp) | ||
| 791 | { | 790 | { |
| 792 | struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id()); | ||
| 793 | unsigned long base = (kesp - uesp) & -THREAD_SIZE; | ||
| 794 | unsigned long new_kesp = kesp - base; | ||
| 795 | unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT; | ||
| 796 | __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS]; | ||
| 797 | |||
| 798 | /* Set up base for espfix segment */ | ||
| 799 | desc &= 0x00f0ff0000000000ULL; | ||
| 800 | desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) | | ||
| 801 | ((((__u64)base) << 32) & 0xff00000000000000ULL) | | ||
| 802 | ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) | | ||
| 803 | (lim_pages & 0xffff); | ||
| 804 | *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc; | ||
| 805 | |||
| 806 | return new_kesp; | ||
| 807 | } | 791 | } |
| 808 | #endif | ||
| 809 | 792 | ||
| 810 | asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void) | 793 | asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void) |
| 811 | { | 794 | { |
| 812 | } | 795 | } |
| 813 | 796 | ||
| 814 | asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void) | 797 | /* |
| 798 | * __math_state_restore assumes that cr0.TS is already clear and the | ||
| 799 | * fpu state is all ready for use. Used during context switch. | ||
| 800 | */ | ||
| 801 | void __math_state_restore(void) | ||
| 815 | { | 802 | { |
| 803 | struct thread_info *thread = current_thread_info(); | ||
| 804 | struct task_struct *tsk = thread->task; | ||
| 805 | |||
| 806 | /* | ||
| 807 | * Paranoid restore. send a SIGSEGV if we fail to restore the state. | ||
| 808 | */ | ||
| 809 | if (unlikely(restore_fpu_checking(tsk))) { | ||
| 810 | stts(); | ||
| 811 | force_sig(SIGSEGV, tsk); | ||
| 812 | return; | ||
| 813 | } | ||
| 814 | |||
| 815 | thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ | ||
| 816 | tsk->fpu_counter++; | ||
| 816 | } | 817 | } |
| 817 | 818 | ||
| 818 | /* | 819 | /* |
| @@ -846,17 +847,8 @@ asmlinkage void math_state_restore(void) | |||
| 846 | } | 847 | } |
| 847 | 848 | ||
| 848 | clts(); /* Allow maths ops (or we recurse) */ | 849 | clts(); /* Allow maths ops (or we recurse) */ |
| 849 | /* | ||
| 850 | * Paranoid restore. send a SIGSEGV if we fail to restore the state. | ||
| 851 | */ | ||
| 852 | if (unlikely(restore_fpu_checking(tsk))) { | ||
| 853 | stts(); | ||
| 854 | force_sig(SIGSEGV, tsk); | ||
| 855 | return; | ||
| 856 | } | ||
| 857 | 850 | ||
| 858 | thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ | 851 | __math_state_restore(); |
| 859 | tsk->fpu_counter++; | ||
| 860 | } | 852 | } |
| 861 | EXPORT_SYMBOL_GPL(math_state_restore); | 853 | EXPORT_SYMBOL_GPL(math_state_restore); |
| 862 | 854 | ||
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 78d185d797de..9fc178255c04 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S | |||
| @@ -46,11 +46,10 @@ PHDRS { | |||
| 46 | data PT_LOAD FLAGS(7); /* RWE */ | 46 | data PT_LOAD FLAGS(7); /* RWE */ |
| 47 | #ifdef CONFIG_X86_64 | 47 | #ifdef CONFIG_X86_64 |
| 48 | user PT_LOAD FLAGS(7); /* RWE */ | 48 | user PT_LOAD FLAGS(7); /* RWE */ |
| 49 | data.init PT_LOAD FLAGS(7); /* RWE */ | ||
| 50 | #ifdef CONFIG_SMP | 49 | #ifdef CONFIG_SMP |
| 51 | percpu PT_LOAD FLAGS(7); /* RWE */ | 50 | percpu PT_LOAD FLAGS(7); /* RWE */ |
| 52 | #endif | 51 | #endif |
| 53 | data.init2 PT_LOAD FLAGS(7); /* RWE */ | 52 | init PT_LOAD FLAGS(7); /* RWE */ |
| 54 | #endif | 53 | #endif |
| 55 | note PT_NOTE FLAGS(0); /* ___ */ | 54 | note PT_NOTE FLAGS(0); /* ___ */ |
| 56 | } | 55 | } |
| @@ -103,65 +102,43 @@ SECTIONS | |||
| 103 | __stop___ex_table = .; | 102 | __stop___ex_table = .; |
| 104 | } :text = 0x9090 | 103 | } :text = 0x9090 |
| 105 | 104 | ||
| 106 | RODATA | 105 | RO_DATA(PAGE_SIZE) |
| 107 | 106 | ||
| 108 | /* Data */ | 107 | /* Data */ |
| 109 | . = ALIGN(PAGE_SIZE); | ||
| 110 | .data : AT(ADDR(.data) - LOAD_OFFSET) { | 108 | .data : AT(ADDR(.data) - LOAD_OFFSET) { |
| 111 | /* Start of data section */ | 109 | /* Start of data section */ |
| 112 | _sdata = .; | 110 | _sdata = .; |
| 113 | DATA_DATA | 111 | |
| 114 | CONSTRUCTORS | 112 | /* init_task */ |
| 115 | } :data | 113 | INIT_TASK_DATA(THREAD_SIZE) |
| 116 | 114 | ||
| 117 | #ifdef CONFIG_X86_32 | 115 | #ifdef CONFIG_X86_32 |
| 118 | /* 32 bit has nosave before _edata */ | 116 | /* 32 bit has nosave before _edata */ |
| 119 | . = ALIGN(PAGE_SIZE); | 117 | NOSAVE_DATA |
| 120 | .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { | ||
| 121 | __nosave_begin = .; | ||
| 122 | *(.data.nosave) | ||
| 123 | . = ALIGN(PAGE_SIZE); | ||
| 124 | __nosave_end = .; | ||
| 125 | } | ||
| 126 | #endif | 118 | #endif |
| 127 | 119 | ||
| 128 | . = ALIGN(PAGE_SIZE); | 120 | PAGE_ALIGNED_DATA(PAGE_SIZE) |
| 129 | .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { | ||
| 130 | *(.data.page_aligned) | ||
| 131 | *(.data.idt) | 121 | *(.data.idt) |
| 132 | } | ||
| 133 | 122 | ||
| 134 | #ifdef CONFIG_X86_32 | 123 | CACHELINE_ALIGNED_DATA(CONFIG_X86_L1_CACHE_BYTES) |
| 135 | . = ALIGN(32); | ||
| 136 | #else | ||
| 137 | . = ALIGN(PAGE_SIZE); | ||
| 138 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); | ||
| 139 | #endif | ||
| 140 | .data.cacheline_aligned : | ||
| 141 | AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { | ||
| 142 | *(.data.cacheline_aligned) | ||
| 143 | } | ||
| 144 | 124 | ||
| 145 | /* rarely changed data like cpu maps */ | 125 | DATA_DATA |
| 146 | #ifdef CONFIG_X86_32 | 126 | CONSTRUCTORS |
| 147 | . = ALIGN(32); | 127 | |
| 148 | #else | 128 | /* rarely changed data like cpu maps */ |
| 149 | . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES); | 129 | READ_MOSTLY_DATA(CONFIG_X86_INTERNODE_CACHE_BYTES) |
| 150 | #endif | ||
| 151 | .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { | ||
| 152 | *(.data.read_mostly) | ||
| 153 | 130 | ||
| 154 | /* End of data section */ | 131 | /* End of data section */ |
| 155 | _edata = .; | 132 | _edata = .; |
| 156 | } | 133 | } :data |
| 157 | 134 | ||
| 158 | #ifdef CONFIG_X86_64 | 135 | #ifdef CONFIG_X86_64 |
| 159 | 136 | ||
| 160 | #define VSYSCALL_ADDR (-10*1024*1024) | 137 | #define VSYSCALL_ADDR (-10*1024*1024) |
| 161 | #define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + \ | 138 | #define VSYSCALL_PHYS_ADDR ((LOADADDR(.data) + SIZEOF(.data) + \ |
| 162 | SIZEOF(.data.read_mostly) + 4095) & ~(4095)) | 139 | PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) |
| 163 | #define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + \ | 140 | #define VSYSCALL_VIRT_ADDR ((ADDR(.data) + SIZEOF(.data) + \ |
| 164 | SIZEOF(.data.read_mostly) + 4095) & ~(4095)) | 141 | PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) |
| 165 | 142 | ||
| 166 | #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR) | 143 | #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR) |
| 167 | #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET) | 144 | #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET) |
| @@ -227,35 +204,29 @@ SECTIONS | |||
| 227 | 204 | ||
| 228 | #endif /* CONFIG_X86_64 */ | 205 | #endif /* CONFIG_X86_64 */ |
| 229 | 206 | ||
| 230 | /* init_task */ | 207 | /* Init code and data - will be freed after init */ |
| 231 | . = ALIGN(THREAD_SIZE); | 208 | . = ALIGN(PAGE_SIZE); |
| 232 | .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { | 209 | .init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) { |
| 233 | *(.data.init_task) | 210 | __init_begin = .; /* paired with __init_end */ |
| 234 | } | 211 | } |
| 235 | #ifdef CONFIG_X86_64 | ||
| 236 | :data.init | ||
| 237 | #endif | ||
| 238 | 212 | ||
| 213 | #if defined(CONFIG_X86_64) && defined(CONFIG_SMP) | ||
| 239 | /* | 214 | /* |
| 240 | * smp_locks might be freed after init | 215 | * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the |
| 241 | * start/end must be page aligned | 216 | * output PHDR, so the next output section - .init.text - should |
| 217 | * start another segment - init. | ||
| 242 | */ | 218 | */ |
| 243 | . = ALIGN(PAGE_SIZE); | 219 | PERCPU_VADDR(0, :percpu) |
| 244 | .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { | 220 | #endif |
| 245 | __smp_locks = .; | ||
| 246 | *(.smp_locks) | ||
| 247 | __smp_locks_end = .; | ||
| 248 | . = ALIGN(PAGE_SIZE); | ||
| 249 | } | ||
| 250 | 221 | ||
| 251 | /* Init code and data - will be freed after init */ | ||
| 252 | . = ALIGN(PAGE_SIZE); | ||
| 253 | .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { | 222 | .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { |
| 254 | __init_begin = .; /* paired with __init_end */ | ||
| 255 | _sinittext = .; | 223 | _sinittext = .; |
| 256 | INIT_TEXT | 224 | INIT_TEXT |
| 257 | _einittext = .; | 225 | _einittext = .; |
| 258 | } | 226 | } |
| 227 | #ifdef CONFIG_X86_64 | ||
| 228 | :init | ||
| 229 | #endif | ||
| 259 | 230 | ||
| 260 | .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { | 231 | .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { |
| 261 | INIT_DATA | 232 | INIT_DATA |
| @@ -326,17 +297,7 @@ SECTIONS | |||
| 326 | } | 297 | } |
| 327 | #endif | 298 | #endif |
| 328 | 299 | ||
| 329 | #if defined(CONFIG_X86_64) && defined(CONFIG_SMP) | 300 | #if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP) |
| 330 | /* | ||
| 331 | * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the | ||
| 332 | * output PHDR, so the next output section - __data_nosave - should | ||
| 333 | * start another section data.init2. Also, pda should be at the head of | ||
| 334 | * percpu area. Preallocate it and define the percpu offset symbol | ||
| 335 | * so that it can be accessed as a percpu variable. | ||
| 336 | */ | ||
| 337 | . = ALIGN(PAGE_SIZE); | ||
| 338 | PERCPU_VADDR(0, :percpu) | ||
| 339 | #else | ||
| 340 | PERCPU(PAGE_SIZE) | 301 | PERCPU(PAGE_SIZE) |
| 341 | #endif | 302 | #endif |
| 342 | 303 | ||
| @@ -347,15 +308,22 @@ SECTIONS | |||
| 347 | __init_end = .; | 308 | __init_end = .; |
| 348 | } | 309 | } |
| 349 | 310 | ||
| 311 | /* | ||
| 312 | * smp_locks might be freed after init | ||
| 313 | * start/end must be page aligned | ||
| 314 | */ | ||
| 315 | . = ALIGN(PAGE_SIZE); | ||
| 316 | .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { | ||
| 317 | __smp_locks = .; | ||
| 318 | *(.smp_locks) | ||
| 319 | __smp_locks_end = .; | ||
| 320 | . = ALIGN(PAGE_SIZE); | ||
| 321 | } | ||
| 322 | |||
| 350 | #ifdef CONFIG_X86_64 | 323 | #ifdef CONFIG_X86_64 |
| 351 | .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { | 324 | .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { |
| 352 | . = ALIGN(PAGE_SIZE); | 325 | NOSAVE_DATA |
| 353 | __nosave_begin = .; | 326 | } |
| 354 | *(.data.nosave) | ||
| 355 | . = ALIGN(PAGE_SIZE); | ||
| 356 | __nosave_end = .; | ||
| 357 | } :data.init2 | ||
| 358 | /* use another section data.init2, see PERCPU_VADDR() above */ | ||
| 359 | #endif | 327 | #endif |
| 360 | 328 | ||
| 361 | /* BSS */ | 329 | /* BSS */ |
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 8600a09e0c6c..b84e571f4175 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig | |||
| @@ -1,12 +1,8 @@ | |||
| 1 | # | 1 | # |
| 2 | # KVM configuration | 2 | # KVM configuration |
| 3 | # | 3 | # |
| 4 | config HAVE_KVM | ||
| 5 | bool | ||
| 6 | 4 | ||
| 7 | config HAVE_KVM_IRQCHIP | 5 | source "virt/kvm/Kconfig" |
| 8 | bool | ||
| 9 | default y | ||
| 10 | 6 | ||
| 11 | menuconfig VIRTUALIZATION | 7 | menuconfig VIRTUALIZATION |
| 12 | bool "Virtualization" | 8 | bool "Virtualization" |
| @@ -29,6 +25,9 @@ config KVM | |||
| 29 | select PREEMPT_NOTIFIERS | 25 | select PREEMPT_NOTIFIERS |
| 30 | select MMU_NOTIFIER | 26 | select MMU_NOTIFIER |
| 31 | select ANON_INODES | 27 | select ANON_INODES |
| 28 | select HAVE_KVM_IRQCHIP | ||
| 29 | select HAVE_KVM_EVENTFD | ||
| 30 | select KVM_APIC_ARCHITECTURE | ||
| 32 | ---help--- | 31 | ---help--- |
| 33 | Support hosting fully virtualized guest machines using hardware | 32 | Support hosting fully virtualized guest machines using hardware |
| 34 | virtualization extensions. You will need a fairly recent | 33 | virtualization extensions. You will need a fairly recent |
| @@ -63,18 +62,6 @@ config KVM_AMD | |||
| 63 | To compile this as a module, choose M here: the module | 62 | To compile this as a module, choose M here: the module |
| 64 | will be called kvm-amd. | 63 | will be called kvm-amd. |
| 65 | 64 | ||
| 66 | config KVM_TRACE | ||
| 67 | bool "KVM trace support" | ||
| 68 | depends on KVM && SYSFS | ||
| 69 | select MARKERS | ||
| 70 | select RELAY | ||
| 71 | select DEBUG_FS | ||
| 72 | default n | ||
| 73 | ---help--- | ||
| 74 | This option allows reading a trace of kvm-related events through | ||
| 75 | relayfs. Note the ABI is not considered stable and will be | ||
| 76 | modified in future updates. | ||
| 77 | |||
| 78 | # OK, it's a little counter-intuitive to do this, but it puts it neatly under | 65 | # OK, it's a little counter-intuitive to do this, but it puts it neatly under |
| 79 | # the virtualization menu. | 66 | # the virtualization menu. |
| 80 | source drivers/lguest/Kconfig | 67 | source drivers/lguest/Kconfig |
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index b43c4efafe80..0e7fe78d0f74 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile | |||
| @@ -1,22 +1,19 @@ | |||
| 1 | # | ||
| 2 | # Makefile for Kernel-based Virtual Machine module | ||
| 3 | # | ||
| 4 | |||
| 5 | common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ | ||
| 6 | coalesced_mmio.o irq_comm.o) | ||
| 7 | ifeq ($(CONFIG_KVM_TRACE),y) | ||
| 8 | common-objs += $(addprefix ../../../virt/kvm/, kvm_trace.o) | ||
| 9 | endif | ||
| 10 | ifeq ($(CONFIG_IOMMU_API),y) | ||
| 11 | common-objs += $(addprefix ../../../virt/kvm/, iommu.o) | ||
| 12 | endif | ||
| 13 | 1 | ||
| 14 | EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm | 2 | EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm |
| 15 | 3 | ||
| 16 | kvm-objs := $(common-objs) x86.o mmu.o x86_emulate.o i8259.o irq.o lapic.o \ | 4 | CFLAGS_x86.o := -I. |
| 17 | i8254.o timer.o | 5 | CFLAGS_svm.o := -I. |
| 18 | obj-$(CONFIG_KVM) += kvm.o | 6 | CFLAGS_vmx.o := -I. |
| 19 | kvm-intel-objs = vmx.o | 7 | |
| 20 | obj-$(CONFIG_KVM_INTEL) += kvm-intel.o | 8 | kvm-y += $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \ |
| 21 | kvm-amd-objs = svm.o | 9 | coalesced_mmio.o irq_comm.o eventfd.o) |
| 22 | obj-$(CONFIG_KVM_AMD) += kvm-amd.o | 10 | kvm-$(CONFIG_IOMMU_API) += $(addprefix ../../../virt/kvm/, iommu.o) |
| 11 | |||
| 12 | kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ | ||
| 13 | i8254.o timer.o | ||
| 14 | kvm-intel-y += vmx.o | ||
| 15 | kvm-amd-y += svm.o | ||
| 16 | |||
| 17 | obj-$(CONFIG_KVM) += kvm.o | ||
| 18 | obj-$(CONFIG_KVM_INTEL) += kvm-intel.o | ||
| 19 | obj-$(CONFIG_KVM_AMD) += kvm-amd.o | ||
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/emulate.c index 616de4628d60..1be5cd640e93 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/emulate.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /****************************************************************************** | 1 | /****************************************************************************** |
| 2 | * x86_emulate.c | 2 | * emulate.c |
| 3 | * | 3 | * |
| 4 | * Generic x86 (32-bit and 64-bit) instruction decoder and emulator. | 4 | * Generic x86 (32-bit and 64-bit) instruction decoder and emulator. |
| 5 | * | 5 | * |
| @@ -30,7 +30,9 @@ | |||
| 30 | #define DPRINTF(x...) do {} while (0) | 30 | #define DPRINTF(x...) do {} while (0) |
| 31 | #endif | 31 | #endif |
| 32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
| 33 | #include <asm/kvm_x86_emulate.h> | 33 | #include <asm/kvm_emulate.h> |
| 34 | |||
| 35 | #include "mmu.h" /* for is_long_mode() */ | ||
| 34 | 36 | ||
| 35 | /* | 37 | /* |
| 36 | * Opcode effective-address decode tables. | 38 | * Opcode effective-address decode tables. |
| @@ -60,6 +62,7 @@ | |||
| 60 | #define SrcImmByte (6<<4) /* 8-bit sign-extended immediate operand. */ | 62 | #define SrcImmByte (6<<4) /* 8-bit sign-extended immediate operand. */ |
| 61 | #define SrcOne (7<<4) /* Implied '1' */ | 63 | #define SrcOne (7<<4) /* Implied '1' */ |
| 62 | #define SrcImmUByte (8<<4) /* 8-bit unsigned immediate operand. */ | 64 | #define SrcImmUByte (8<<4) /* 8-bit unsigned immediate operand. */ |
| 65 | #define SrcImmU (9<<4) /* Immediate operand, unsigned */ | ||
| 63 | #define SrcMask (0xf<<4) | 66 | #define SrcMask (0xf<<4) |
| 64 | /* Generic ModRM decode. */ | 67 | /* Generic ModRM decode. */ |
| 65 | #define ModRM (1<<8) | 68 | #define ModRM (1<<8) |
| @@ -97,11 +100,11 @@ static u32 opcode_table[256] = { | |||
| 97 | /* 0x10 - 0x17 */ | 100 | /* 0x10 - 0x17 */ |
| 98 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 101 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, |
| 99 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 102 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
| 100 | 0, 0, 0, 0, | 103 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0, |
| 101 | /* 0x18 - 0x1F */ | 104 | /* 0x18 - 0x1F */ |
| 102 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 105 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, |
| 103 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 106 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
| 104 | 0, 0, 0, 0, | 107 | ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0, |
| 105 | /* 0x20 - 0x27 */ | 108 | /* 0x20 - 0x27 */ |
| 106 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, | 109 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, |
| 107 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, | 110 | ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM, |
| @@ -195,7 +198,7 @@ static u32 opcode_table[256] = { | |||
| 195 | ByteOp | SrcImmUByte, SrcImmUByte, | 198 | ByteOp | SrcImmUByte, SrcImmUByte, |
| 196 | /* 0xE8 - 0xEF */ | 199 | /* 0xE8 - 0xEF */ |
| 197 | SrcImm | Stack, SrcImm | ImplicitOps, | 200 | SrcImm | Stack, SrcImm | ImplicitOps, |
| 198 | SrcImm | Src2Imm16, SrcImmByte | ImplicitOps, | 201 | SrcImmU | Src2Imm16, SrcImmByte | ImplicitOps, |
| 199 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | 202 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, |
| 200 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, | 203 | SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps, |
| 201 | /* 0xF0 - 0xF7 */ | 204 | /* 0xF0 - 0xF7 */ |
| @@ -208,7 +211,7 @@ static u32 opcode_table[256] = { | |||
| 208 | 211 | ||
| 209 | static u32 twobyte_table[256] = { | 212 | static u32 twobyte_table[256] = { |
| 210 | /* 0x00 - 0x0F */ | 213 | /* 0x00 - 0x0F */ |
| 211 | 0, Group | GroupDual | Group7, 0, 0, 0, 0, ImplicitOps, 0, | 214 | 0, Group | GroupDual | Group7, 0, 0, 0, ImplicitOps, ImplicitOps, 0, |
| 212 | ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, | 215 | ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, |
| 213 | /* 0x10 - 0x1F */ | 216 | /* 0x10 - 0x1F */ |
| 214 | 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, | 217 | 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, |
| @@ -216,7 +219,9 @@ static u32 twobyte_table[256] = { | |||
| 216 | ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0, | 219 | ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0, |
| 217 | 0, 0, 0, 0, 0, 0, 0, 0, | 220 | 0, 0, 0, 0, 0, 0, 0, 0, |
| 218 | /* 0x30 - 0x3F */ | 221 | /* 0x30 - 0x3F */ |
| 219 | ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 222 | ImplicitOps, 0, ImplicitOps, 0, |
| 223 | ImplicitOps, ImplicitOps, 0, 0, | ||
| 224 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 220 | /* 0x40 - 0x47 */ | 225 | /* 0x40 - 0x47 */ |
| 221 | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, | 226 | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, |
| 222 | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, | 227 | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, |
| @@ -319,8 +324,11 @@ static u32 group2_table[] = { | |||
| 319 | }; | 324 | }; |
| 320 | 325 | ||
| 321 | /* EFLAGS bit definitions. */ | 326 | /* EFLAGS bit definitions. */ |
| 327 | #define EFLG_VM (1<<17) | ||
| 328 | #define EFLG_RF (1<<16) | ||
| 322 | #define EFLG_OF (1<<11) | 329 | #define EFLG_OF (1<<11) |
| 323 | #define EFLG_DF (1<<10) | 330 | #define EFLG_DF (1<<10) |
| 331 | #define EFLG_IF (1<<9) | ||
| 324 | #define EFLG_SF (1<<7) | 332 | #define EFLG_SF (1<<7) |
| 325 | #define EFLG_ZF (1<<6) | 333 | #define EFLG_ZF (1<<6) |
| 326 | #define EFLG_AF (1<<4) | 334 | #define EFLG_AF (1<<4) |
| @@ -1027,6 +1035,7 @@ done_prefixes: | |||
| 1027 | c->src.type = OP_MEM; | 1035 | c->src.type = OP_MEM; |
| 1028 | break; | 1036 | break; |
| 1029 | case SrcImm: | 1037 | case SrcImm: |
| 1038 | case SrcImmU: | ||
| 1030 | c->src.type = OP_IMM; | 1039 | c->src.type = OP_IMM; |
| 1031 | c->src.ptr = (unsigned long *)c->eip; | 1040 | c->src.ptr = (unsigned long *)c->eip; |
| 1032 | c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; | 1041 | c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; |
| @@ -1044,6 +1053,19 @@ done_prefixes: | |||
| 1044 | c->src.val = insn_fetch(s32, 4, c->eip); | 1053 | c->src.val = insn_fetch(s32, 4, c->eip); |
| 1045 | break; | 1054 | break; |
| 1046 | } | 1055 | } |
| 1056 | if ((c->d & SrcMask) == SrcImmU) { | ||
| 1057 | switch (c->src.bytes) { | ||
| 1058 | case 1: | ||
| 1059 | c->src.val &= 0xff; | ||
| 1060 | break; | ||
| 1061 | case 2: | ||
| 1062 | c->src.val &= 0xffff; | ||
| 1063 | break; | ||
| 1064 | case 4: | ||
| 1065 | c->src.val &= 0xffffffff; | ||
| 1066 | break; | ||
| 1067 | } | ||
| 1068 | } | ||
| 1047 | break; | 1069 | break; |
| 1048 | case SrcImmByte: | 1070 | case SrcImmByte: |
| 1049 | case SrcImmUByte: | 1071 | case SrcImmUByte: |
| @@ -1375,6 +1397,217 @@ static void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask) | |||
| 1375 | ctxt->interruptibility = mask; | 1397 | ctxt->interruptibility = mask; |
| 1376 | } | 1398 | } |
| 1377 | 1399 | ||
| 1400 | static inline void | ||
| 1401 | setup_syscalls_segments(struct x86_emulate_ctxt *ctxt, | ||
| 1402 | struct kvm_segment *cs, struct kvm_segment *ss) | ||
| 1403 | { | ||
| 1404 | memset(cs, 0, sizeof(struct kvm_segment)); | ||
| 1405 | kvm_x86_ops->get_segment(ctxt->vcpu, cs, VCPU_SREG_CS); | ||
| 1406 | memset(ss, 0, sizeof(struct kvm_segment)); | ||
| 1407 | |||
| 1408 | cs->l = 0; /* will be adjusted later */ | ||
| 1409 | cs->base = 0; /* flat segment */ | ||
| 1410 | cs->g = 1; /* 4kb granularity */ | ||
| 1411 | cs->limit = 0xffffffff; /* 4GB limit */ | ||
| 1412 | cs->type = 0x0b; /* Read, Execute, Accessed */ | ||
| 1413 | cs->s = 1; | ||
| 1414 | cs->dpl = 0; /* will be adjusted later */ | ||
| 1415 | cs->present = 1; | ||
| 1416 | cs->db = 1; | ||
| 1417 | |||
| 1418 | ss->unusable = 0; | ||
| 1419 | ss->base = 0; /* flat segment */ | ||
| 1420 | ss->limit = 0xffffffff; /* 4GB limit */ | ||
| 1421 | ss->g = 1; /* 4kb granularity */ | ||
| 1422 | ss->s = 1; | ||
| 1423 | ss->type = 0x03; /* Read/Write, Accessed */ | ||
| 1424 | ss->db = 1; /* 32bit stack segment */ | ||
| 1425 | ss->dpl = 0; | ||
| 1426 | ss->present = 1; | ||
| 1427 | } | ||
| 1428 | |||
| 1429 | static int | ||
| 1430 | emulate_syscall(struct x86_emulate_ctxt *ctxt) | ||
| 1431 | { | ||
| 1432 | struct decode_cache *c = &ctxt->decode; | ||
| 1433 | struct kvm_segment cs, ss; | ||
| 1434 | u64 msr_data; | ||
| 1435 | |||
| 1436 | /* syscall is not available in real mode */ | ||
| 1437 | if (c->lock_prefix || ctxt->mode == X86EMUL_MODE_REAL | ||
| 1438 | || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) | ||
| 1439 | return -1; | ||
| 1440 | |||
| 1441 | setup_syscalls_segments(ctxt, &cs, &ss); | ||
| 1442 | |||
| 1443 | kvm_x86_ops->get_msr(ctxt->vcpu, MSR_STAR, &msr_data); | ||
| 1444 | msr_data >>= 32; | ||
| 1445 | cs.selector = (u16)(msr_data & 0xfffc); | ||
| 1446 | ss.selector = (u16)(msr_data + 8); | ||
| 1447 | |||
| 1448 | if (is_long_mode(ctxt->vcpu)) { | ||
| 1449 | cs.db = 0; | ||
| 1450 | cs.l = 1; | ||
| 1451 | } | ||
| 1452 | kvm_x86_ops->set_segment(ctxt->vcpu, &cs, VCPU_SREG_CS); | ||
| 1453 | kvm_x86_ops->set_segment(ctxt->vcpu, &ss, VCPU_SREG_SS); | ||
| 1454 | |||
| 1455 | c->regs[VCPU_REGS_RCX] = c->eip; | ||
| 1456 | if (is_long_mode(ctxt->vcpu)) { | ||
| 1457 | #ifdef CONFIG_X86_64 | ||
| 1458 | c->regs[VCPU_REGS_R11] = ctxt->eflags & ~EFLG_RF; | ||
| 1459 | |||
| 1460 | kvm_x86_ops->get_msr(ctxt->vcpu, | ||
| 1461 | ctxt->mode == X86EMUL_MODE_PROT64 ? | ||
| 1462 | MSR_LSTAR : MSR_CSTAR, &msr_data); | ||
| 1463 | c->eip = msr_data; | ||
| 1464 | |||
| 1465 | kvm_x86_ops->get_msr(ctxt->vcpu, MSR_SYSCALL_MASK, &msr_data); | ||
| 1466 | ctxt->eflags &= ~(msr_data | EFLG_RF); | ||
| 1467 | #endif | ||
| 1468 | } else { | ||
| 1469 | /* legacy mode */ | ||
| 1470 | kvm_x86_ops->get_msr(ctxt->vcpu, MSR_STAR, &msr_data); | ||
| 1471 | c->eip = (u32)msr_data; | ||
| 1472 | |||
| 1473 | ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF); | ||
| 1474 | } | ||
| 1475 | |||
| 1476 | return 0; | ||
| 1477 | } | ||
| 1478 | |||
| 1479 | static int | ||
| 1480 | emulate_sysenter(struct x86_emulate_ctxt *ctxt) | ||
| 1481 | { | ||
| 1482 | struct decode_cache *c = &ctxt->decode; | ||
| 1483 | struct kvm_segment cs, ss; | ||
| 1484 | u64 msr_data; | ||
| 1485 | |||
| 1486 | /* inject #UD if LOCK prefix is used */ | ||
| 1487 | if (c->lock_prefix) | ||
| 1488 | return -1; | ||
| 1489 | |||
| 1490 | /* inject #GP if in real mode or paging is disabled */ | ||
| 1491 | if (ctxt->mode == X86EMUL_MODE_REAL || | ||
| 1492 | !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) { | ||
| 1493 | kvm_inject_gp(ctxt->vcpu, 0); | ||
| 1494 | return -1; | ||
| 1495 | } | ||
| 1496 | |||
| 1497 | /* XXX sysenter/sysexit have not been tested in 64bit mode. | ||
| 1498 | * Therefore, we inject an #UD. | ||
| 1499 | */ | ||
| 1500 | if (ctxt->mode == X86EMUL_MODE_PROT64) | ||
| 1501 | return -1; | ||
| 1502 | |||
| 1503 | setup_syscalls_segments(ctxt, &cs, &ss); | ||
| 1504 | |||
| 1505 | kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_CS, &msr_data); | ||
| 1506 | switch (ctxt->mode) { | ||
| 1507 | case X86EMUL_MODE_PROT32: | ||
| 1508 | if ((msr_data & 0xfffc) == 0x0) { | ||
| 1509 | kvm_inject_gp(ctxt->vcpu, 0); | ||
| 1510 | return -1; | ||
| 1511 | } | ||
| 1512 | break; | ||
| 1513 | case X86EMUL_MODE_PROT64: | ||
| 1514 | if (msr_data == 0x0) { | ||
| 1515 | kvm_inject_gp(ctxt->vcpu, 0); | ||
| 1516 | return -1; | ||
| 1517 | } | ||
| 1518 | break; | ||
| 1519 | } | ||
| 1520 | |||
| 1521 | ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF); | ||
| 1522 | cs.selector = (u16)msr_data; | ||
| 1523 | cs.selector &= ~SELECTOR_RPL_MASK; | ||
| 1524 | ss.selector = cs.selector + 8; | ||
| 1525 | ss.selector &= ~SELECTOR_RPL_MASK; | ||
| 1526 | if (ctxt->mode == X86EMUL_MODE_PROT64 | ||
| 1527 | || is_long_mode(ctxt->vcpu)) { | ||
| 1528 | cs.db = 0; | ||
| 1529 | cs.l = 1; | ||
| 1530 | } | ||
| 1531 | |||
| 1532 | kvm_x86_ops->set_segment(ctxt->vcpu, &cs, VCPU_SREG_CS); | ||
| 1533 | kvm_x86_ops->set_segment(ctxt->vcpu, &ss, VCPU_SREG_SS); | ||
| 1534 | |||
| 1535 | kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_EIP, &msr_data); | ||
| 1536 | c->eip = msr_data; | ||
| 1537 | |||
| 1538 | kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_ESP, &msr_data); | ||
| 1539 | c->regs[VCPU_REGS_RSP] = msr_data; | ||
| 1540 | |||
| 1541 | return 0; | ||
| 1542 | } | ||
| 1543 | |||
| 1544 | static int | ||
| 1545 | emulate_sysexit(struct x86_emulate_ctxt *ctxt) | ||
| 1546 | { | ||
| 1547 | struct decode_cache *c = &ctxt->decode; | ||
| 1548 | struct kvm_segment cs, ss; | ||
| 1549 | u64 msr_data; | ||
| 1550 | int usermode; | ||
| 1551 | |||
| 1552 | /* inject #UD if LOCK prefix is used */ | ||
| 1553 | if (c->lock_prefix) | ||
| 1554 | return -1; | ||
| 1555 | |||
| 1556 | /* inject #GP if in real mode or paging is disabled */ | ||
| 1557 | if (ctxt->mode == X86EMUL_MODE_REAL | ||
| 1558 | || !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) { | ||
| 1559 | kvm_inject_gp(ctxt->vcpu, 0); | ||
| 1560 | return -1; | ||
| 1561 | } | ||
| 1562 | |||
| 1563 | /* sysexit must be called from CPL 0 */ | ||
| 1564 | if (kvm_x86_ops->get_cpl(ctxt->vcpu) != 0) { | ||
| 1565 | kvm_inject_gp(ctxt->vcpu, 0); | ||
| 1566 | return -1; | ||
| 1567 | } | ||
| 1568 | |||
| 1569 | setup_syscalls_segments(ctxt, &cs, &ss); | ||
| 1570 | |||
| 1571 | if ((c->rex_prefix & 0x8) != 0x0) | ||
| 1572 | usermode = X86EMUL_MODE_PROT64; | ||
| 1573 | else | ||
| 1574 | usermode = X86EMUL_MODE_PROT32; | ||
| 1575 | |||
| 1576 | cs.dpl = 3; | ||
| 1577 | ss.dpl = 3; | ||
| 1578 | kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_CS, &msr_data); | ||
| 1579 | switch (usermode) { | ||
| 1580 | case X86EMUL_MODE_PROT32: | ||
| 1581 | cs.selector = (u16)(msr_data + 16); | ||
| 1582 | if ((msr_data & 0xfffc) == 0x0) { | ||
| 1583 | kvm_inject_gp(ctxt->vcpu, 0); | ||
| 1584 | return -1; | ||
| 1585 | } | ||
| 1586 | ss.selector = (u16)(msr_data + 24); | ||
| 1587 | break; | ||
| 1588 | case X86EMUL_MODE_PROT64: | ||
| 1589 | cs.selector = (u16)(msr_data + 32); | ||
| 1590 | if (msr_data == 0x0) { | ||
| 1591 | kvm_inject_gp(ctxt->vcpu, 0); | ||
| 1592 | return -1; | ||
| 1593 | } | ||
| 1594 | ss.selector = cs.selector + 8; | ||
| 1595 | cs.db = 0; | ||
| 1596 | cs.l = 1; | ||
| 1597 | break; | ||
| 1598 | } | ||
| 1599 | cs.selector |= SELECTOR_RPL_MASK; | ||
| 1600 | ss.selector |= SELECTOR_RPL_MASK; | ||
| 1601 | |||
| 1602 | kvm_x86_ops->set_segment(ctxt->vcpu, &cs, VCPU_SREG_CS); | ||
| 1603 | kvm_x86_ops->set_segment(ctxt->vcpu, &ss, VCPU_SREG_SS); | ||
| 1604 | |||
| 1605 | c->eip = ctxt->vcpu->arch.regs[VCPU_REGS_RDX]; | ||
| 1606 | c->regs[VCPU_REGS_RSP] = ctxt->vcpu->arch.regs[VCPU_REGS_RCX]; | ||
| 1607 | |||
| 1608 | return 0; | ||
| 1609 | } | ||
| 1610 | |||
| 1378 | int | 1611 | int |
| 1379 | x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | 1612 | x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) |
| 1380 | { | 1613 | { |
| @@ -1970,6 +2203,12 @@ twobyte_insn: | |||
| 1970 | goto cannot_emulate; | 2203 | goto cannot_emulate; |
| 1971 | } | 2204 | } |
| 1972 | break; | 2205 | break; |
| 2206 | case 0x05: /* syscall */ | ||
| 2207 | if (emulate_syscall(ctxt) == -1) | ||
| 2208 | goto cannot_emulate; | ||
| 2209 | else | ||
| 2210 | goto writeback; | ||
| 2211 | break; | ||
| 1973 | case 0x06: | 2212 | case 0x06: |
| 1974 | emulate_clts(ctxt->vcpu); | 2213 | emulate_clts(ctxt->vcpu); |
| 1975 | c->dst.type = OP_NONE; | 2214 | c->dst.type = OP_NONE; |
| @@ -2036,6 +2275,18 @@ twobyte_insn: | |||
| 2036 | rc = X86EMUL_CONTINUE; | 2275 | rc = X86EMUL_CONTINUE; |
| 2037 | c->dst.type = OP_NONE; | 2276 | c->dst.type = OP_NONE; |
| 2038 | break; | 2277 | break; |
| 2278 | case 0x34: /* sysenter */ | ||
| 2279 | if (emulate_sysenter(ctxt) == -1) | ||
| 2280 | goto cannot_emulate; | ||
| 2281 | else | ||
| 2282 | goto writeback; | ||
| 2283 | break; | ||
| 2284 | case 0x35: /* sysexit */ | ||
| 2285 | if (emulate_sysexit(ctxt) == -1) | ||
| 2286 | goto cannot_emulate; | ||
| 2287 | else | ||
| 2288 | goto writeback; | ||
| 2289 | break; | ||
| 2039 | case 0x40 ... 0x4f: /* cmov */ | 2290 | case 0x40 ... 0x4f: /* cmov */ |
| 2040 | c->dst.val = c->dst.orig_val = c->src.val; | 2291 | c->dst.val = c->dst.orig_val = c->src.val; |
| 2041 | if (!test_cc(c->b, ctxt->eflags)) | 2292 | if (!test_cc(c->b, ctxt->eflags)) |
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 21f68e00524f..82ad523b4901 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c | |||
| @@ -231,7 +231,7 @@ int pit_has_pending_timer(struct kvm_vcpu *vcpu) | |||
| 231 | { | 231 | { |
| 232 | struct kvm_pit *pit = vcpu->kvm->arch.vpit; | 232 | struct kvm_pit *pit = vcpu->kvm->arch.vpit; |
| 233 | 233 | ||
| 234 | if (pit && vcpu->vcpu_id == 0 && pit->pit_state.irq_ack) | 234 | if (pit && kvm_vcpu_is_bsp(vcpu) && pit->pit_state.irq_ack) |
| 235 | return atomic_read(&pit->pit_state.pit_timer.pending); | 235 | return atomic_read(&pit->pit_state.pit_timer.pending); |
| 236 | return 0; | 236 | return 0; |
| 237 | } | 237 | } |
| @@ -252,7 +252,7 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu) | |||
| 252 | struct kvm_pit *pit = vcpu->kvm->arch.vpit; | 252 | struct kvm_pit *pit = vcpu->kvm->arch.vpit; |
| 253 | struct hrtimer *timer; | 253 | struct hrtimer *timer; |
| 254 | 254 | ||
| 255 | if (vcpu->vcpu_id != 0 || !pit) | 255 | if (!kvm_vcpu_is_bsp(vcpu) || !pit) |
| 256 | return; | 256 | return; |
| 257 | 257 | ||
| 258 | timer = &pit->pit_state.pit_timer.timer; | 258 | timer = &pit->pit_state.pit_timer.timer; |
| @@ -294,7 +294,7 @@ static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period) | |||
| 294 | pt->timer.function = kvm_timer_fn; | 294 | pt->timer.function = kvm_timer_fn; |
| 295 | pt->t_ops = &kpit_ops; | 295 | pt->t_ops = &kpit_ops; |
| 296 | pt->kvm = ps->pit->kvm; | 296 | pt->kvm = ps->pit->kvm; |
| 297 | pt->vcpu_id = 0; | 297 | pt->vcpu = pt->kvm->bsp_vcpu; |
| 298 | 298 | ||
| 299 | atomic_set(&pt->pending, 0); | 299 | atomic_set(&pt->pending, 0); |
| 300 | ps->irq_ack = 1; | 300 | ps->irq_ack = 1; |
| @@ -332,33 +332,62 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val) | |||
| 332 | case 1: | 332 | case 1: |
| 333 | /* FIXME: enhance mode 4 precision */ | 333 | /* FIXME: enhance mode 4 precision */ |
| 334 | case 4: | 334 | case 4: |
| 335 | create_pit_timer(ps, val, 0); | 335 | if (!(ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)) { |
| 336 | create_pit_timer(ps, val, 0); | ||
| 337 | } | ||
| 336 | break; | 338 | break; |
| 337 | case 2: | 339 | case 2: |
| 338 | case 3: | 340 | case 3: |
| 339 | create_pit_timer(ps, val, 1); | 341 | if (!(ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)){ |
| 342 | create_pit_timer(ps, val, 1); | ||
| 343 | } | ||
| 340 | break; | 344 | break; |
| 341 | default: | 345 | default: |
| 342 | destroy_pit_timer(&ps->pit_timer); | 346 | destroy_pit_timer(&ps->pit_timer); |
| 343 | } | 347 | } |
| 344 | } | 348 | } |
| 345 | 349 | ||
| 346 | void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val) | 350 | void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val, int hpet_legacy_start) |
| 351 | { | ||
| 352 | u8 saved_mode; | ||
| 353 | if (hpet_legacy_start) { | ||
| 354 | /* save existing mode for later reenablement */ | ||
| 355 | saved_mode = kvm->arch.vpit->pit_state.channels[0].mode; | ||
| 356 | kvm->arch.vpit->pit_state.channels[0].mode = 0xff; /* disable timer */ | ||
| 357 | pit_load_count(kvm, channel, val); | ||
| 358 | kvm->arch.vpit->pit_state.channels[0].mode = saved_mode; | ||
| 359 | } else { | ||
| 360 | pit_load_count(kvm, channel, val); | ||
| 361 | } | ||
| 362 | } | ||
| 363 | |||
| 364 | static inline struct kvm_pit *dev_to_pit(struct kvm_io_device *dev) | ||
| 365 | { | ||
| 366 | return container_of(dev, struct kvm_pit, dev); | ||
| 367 | } | ||
| 368 | |||
| 369 | static inline struct kvm_pit *speaker_to_pit(struct kvm_io_device *dev) | ||
| 347 | { | 370 | { |
| 348 | mutex_lock(&kvm->arch.vpit->pit_state.lock); | 371 | return container_of(dev, struct kvm_pit, speaker_dev); |
| 349 | pit_load_count(kvm, channel, val); | ||
| 350 | mutex_unlock(&kvm->arch.vpit->pit_state.lock); | ||
| 351 | } | 372 | } |
| 352 | 373 | ||
| 353 | static void pit_ioport_write(struct kvm_io_device *this, | 374 | static inline int pit_in_range(gpa_t addr) |
| 354 | gpa_t addr, int len, const void *data) | ||
| 355 | { | 375 | { |
| 356 | struct kvm_pit *pit = (struct kvm_pit *)this->private; | 376 | return ((addr >= KVM_PIT_BASE_ADDRESS) && |
| 377 | (addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH)); | ||
| 378 | } | ||
| 379 | |||
| 380 | static int pit_ioport_write(struct kvm_io_device *this, | ||
| 381 | gpa_t addr, int len, const void *data) | ||
| 382 | { | ||
| 383 | struct kvm_pit *pit = dev_to_pit(this); | ||
| 357 | struct kvm_kpit_state *pit_state = &pit->pit_state; | 384 | struct kvm_kpit_state *pit_state = &pit->pit_state; |
| 358 | struct kvm *kvm = pit->kvm; | 385 | struct kvm *kvm = pit->kvm; |
| 359 | int channel, access; | 386 | int channel, access; |
| 360 | struct kvm_kpit_channel_state *s; | 387 | struct kvm_kpit_channel_state *s; |
| 361 | u32 val = *(u32 *) data; | 388 | u32 val = *(u32 *) data; |
| 389 | if (!pit_in_range(addr)) | ||
| 390 | return -EOPNOTSUPP; | ||
| 362 | 391 | ||
| 363 | val &= 0xff; | 392 | val &= 0xff; |
| 364 | addr &= KVM_PIT_CHANNEL_MASK; | 393 | addr &= KVM_PIT_CHANNEL_MASK; |
| @@ -421,16 +450,19 @@ static void pit_ioport_write(struct kvm_io_device *this, | |||
| 421 | } | 450 | } |
| 422 | 451 | ||
| 423 | mutex_unlock(&pit_state->lock); | 452 | mutex_unlock(&pit_state->lock); |
| 453 | return 0; | ||
| 424 | } | 454 | } |
| 425 | 455 | ||
| 426 | static void pit_ioport_read(struct kvm_io_device *this, | 456 | static int pit_ioport_read(struct kvm_io_device *this, |
| 427 | gpa_t addr, int len, void *data) | 457 | gpa_t addr, int len, void *data) |
| 428 | { | 458 | { |
| 429 | struct kvm_pit *pit = (struct kvm_pit *)this->private; | 459 | struct kvm_pit *pit = dev_to_pit(this); |
| 430 | struct kvm_kpit_state *pit_state = &pit->pit_state; | 460 | struct kvm_kpit_state *pit_state = &pit->pit_state; |
| 431 | struct kvm *kvm = pit->kvm; | 461 | struct kvm *kvm = pit->kvm; |
| 432 | int ret, count; | 462 | int ret, count; |
| 433 | struct kvm_kpit_channel_state *s; | 463 | struct kvm_kpit_channel_state *s; |
| 464 | if (!pit_in_range(addr)) | ||
| 465 | return -EOPNOTSUPP; | ||
| 434 | 466 | ||
| 435 | addr &= KVM_PIT_CHANNEL_MASK; | 467 | addr &= KVM_PIT_CHANNEL_MASK; |
| 436 | s = &pit_state->channels[addr]; | 468 | s = &pit_state->channels[addr]; |
| @@ -485,37 +517,36 @@ static void pit_ioport_read(struct kvm_io_device *this, | |||
| 485 | memcpy(data, (char *)&ret, len); | 517 | memcpy(data, (char *)&ret, len); |
| 486 | 518 | ||
| 487 | mutex_unlock(&pit_state->lock); | 519 | mutex_unlock(&pit_state->lock); |
| 520 | return 0; | ||
| 488 | } | 521 | } |
| 489 | 522 | ||
| 490 | static int pit_in_range(struct kvm_io_device *this, gpa_t addr, | 523 | static int speaker_ioport_write(struct kvm_io_device *this, |
| 491 | int len, int is_write) | 524 | gpa_t addr, int len, const void *data) |
| 492 | { | ||
| 493 | return ((addr >= KVM_PIT_BASE_ADDRESS) && | ||
| 494 | (addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH)); | ||
| 495 | } | ||
| 496 | |||
| 497 | static void speaker_ioport_write(struct kvm_io_device *this, | ||
| 498 | gpa_t addr, int len, const void *data) | ||
| 499 | { | 525 | { |
| 500 | struct kvm_pit *pit = (struct kvm_pit *)this->private; | 526 | struct kvm_pit *pit = speaker_to_pit(this); |
| 501 | struct kvm_kpit_state *pit_state = &pit->pit_state; | 527 | struct kvm_kpit_state *pit_state = &pit->pit_state; |
| 502 | struct kvm *kvm = pit->kvm; | 528 | struct kvm *kvm = pit->kvm; |
| 503 | u32 val = *(u32 *) data; | 529 | u32 val = *(u32 *) data; |
| 530 | if (addr != KVM_SPEAKER_BASE_ADDRESS) | ||
| 531 | return -EOPNOTSUPP; | ||
| 504 | 532 | ||
| 505 | mutex_lock(&pit_state->lock); | 533 | mutex_lock(&pit_state->lock); |
| 506 | pit_state->speaker_data_on = (val >> 1) & 1; | 534 | pit_state->speaker_data_on = (val >> 1) & 1; |
| 507 | pit_set_gate(kvm, 2, val & 1); | 535 | pit_set_gate(kvm, 2, val & 1); |
| 508 | mutex_unlock(&pit_state->lock); | 536 | mutex_unlock(&pit_state->lock); |
| 537 | return 0; | ||
| 509 | } | 538 | } |
| 510 | 539 | ||
| 511 | static void speaker_ioport_read(struct kvm_io_device *this, | 540 | static int speaker_ioport_read(struct kvm_io_device *this, |
| 512 | gpa_t addr, int len, void *data) | 541 | gpa_t addr, int len, void *data) |
| 513 | { | 542 | { |
| 514 | struct kvm_pit *pit = (struct kvm_pit *)this->private; | 543 | struct kvm_pit *pit = speaker_to_pit(this); |
| 515 | struct kvm_kpit_state *pit_state = &pit->pit_state; | 544 | struct kvm_kpit_state *pit_state = &pit->pit_state; |
| 516 | struct kvm *kvm = pit->kvm; | 545 | struct kvm *kvm = pit->kvm; |
| 517 | unsigned int refresh_clock; | 546 | unsigned int refresh_clock; |
| 518 | int ret; | 547 | int ret; |
| 548 | if (addr != KVM_SPEAKER_BASE_ADDRESS) | ||
| 549 | return -EOPNOTSUPP; | ||
| 519 | 550 | ||
| 520 | /* Refresh clock toggles at about 15us. We approximate as 2^14ns. */ | 551 | /* Refresh clock toggles at about 15us. We approximate as 2^14ns. */ |
| 521 | refresh_clock = ((unsigned int)ktime_to_ns(ktime_get()) >> 14) & 1; | 552 | refresh_clock = ((unsigned int)ktime_to_ns(ktime_get()) >> 14) & 1; |
| @@ -527,12 +558,7 @@ static void speaker_ioport_read(struct kvm_io_device *this, | |||
| 527 | len = sizeof(ret); | 558 | len = sizeof(ret); |
| 528 | memcpy(data, (char *)&ret, len); | 559 | memcpy(data, (char *)&ret, len); |
| 529 | mutex_unlock(&pit_state->lock); | 560 | mutex_unlock(&pit_state->lock); |
| 530 | } | 561 | return 0; |
| 531 | |||
| 532 | static int speaker_in_range(struct kvm_io_device *this, gpa_t addr, | ||
| 533 | int len, int is_write) | ||
| 534 | { | ||
| 535 | return (addr == KVM_SPEAKER_BASE_ADDRESS); | ||
| 536 | } | 562 | } |
| 537 | 563 | ||
| 538 | void kvm_pit_reset(struct kvm_pit *pit) | 564 | void kvm_pit_reset(struct kvm_pit *pit) |
| @@ -541,6 +567,7 @@ void kvm_pit_reset(struct kvm_pit *pit) | |||
| 541 | struct kvm_kpit_channel_state *c; | 567 | struct kvm_kpit_channel_state *c; |
| 542 | 568 | ||
| 543 | mutex_lock(&pit->pit_state.lock); | 569 | mutex_lock(&pit->pit_state.lock); |
| 570 | pit->pit_state.flags = 0; | ||
| 544 | for (i = 0; i < 3; i++) { | 571 | for (i = 0; i < 3; i++) { |
| 545 | c = &pit->pit_state.channels[i]; | 572 | c = &pit->pit_state.channels[i]; |
| 546 | c->mode = 0xff; | 573 | c->mode = 0xff; |
| @@ -563,10 +590,22 @@ static void pit_mask_notifer(struct kvm_irq_mask_notifier *kimn, bool mask) | |||
| 563 | } | 590 | } |
| 564 | } | 591 | } |
| 565 | 592 | ||
| 566 | struct kvm_pit *kvm_create_pit(struct kvm *kvm) | 593 | static const struct kvm_io_device_ops pit_dev_ops = { |
| 594 | .read = pit_ioport_read, | ||
| 595 | .write = pit_ioport_write, | ||
| 596 | }; | ||
| 597 | |||
| 598 | static const struct kvm_io_device_ops speaker_dev_ops = { | ||
| 599 | .read = speaker_ioport_read, | ||
| 600 | .write = speaker_ioport_write, | ||
| 601 | }; | ||
| 602 | |||
| 603 | /* Caller must have writers lock on slots_lock */ | ||
| 604 | struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags) | ||
| 567 | { | 605 | { |
| 568 | struct kvm_pit *pit; | 606 | struct kvm_pit *pit; |
| 569 | struct kvm_kpit_state *pit_state; | 607 | struct kvm_kpit_state *pit_state; |
| 608 | int ret; | ||
| 570 | 609 | ||
| 571 | pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL); | 610 | pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL); |
| 572 | if (!pit) | 611 | if (!pit) |
| @@ -582,19 +621,6 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm) | |||
| 582 | mutex_lock(&pit->pit_state.lock); | 621 | mutex_lock(&pit->pit_state.lock); |
| 583 | spin_lock_init(&pit->pit_state.inject_lock); | 622 | spin_lock_init(&pit->pit_state.inject_lock); |
| 584 | 623 | ||
| 585 | /* Initialize PIO device */ | ||
| 586 | pit->dev.read = pit_ioport_read; | ||
| 587 | pit->dev.write = pit_ioport_write; | ||
| 588 | pit->dev.in_range = pit_in_range; | ||
| 589 | pit->dev.private = pit; | ||
| 590 | kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev); | ||
| 591 | |||
| 592 | pit->speaker_dev.read = speaker_ioport_read; | ||
| 593 | pit->speaker_dev.write = speaker_ioport_write; | ||
| 594 | pit->speaker_dev.in_range = speaker_in_range; | ||
| 595 | pit->speaker_dev.private = pit; | ||
| 596 | kvm_io_bus_register_dev(&kvm->pio_bus, &pit->speaker_dev); | ||
| 597 | |||
| 598 | kvm->arch.vpit = pit; | 624 | kvm->arch.vpit = pit; |
| 599 | pit->kvm = kvm; | 625 | pit->kvm = kvm; |
| 600 | 626 | ||
| @@ -613,7 +639,30 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm) | |||
| 613 | pit->mask_notifier.func = pit_mask_notifer; | 639 | pit->mask_notifier.func = pit_mask_notifer; |
| 614 | kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier); | 640 | kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier); |
| 615 | 641 | ||
| 642 | kvm_iodevice_init(&pit->dev, &pit_dev_ops); | ||
| 643 | ret = __kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev); | ||
| 644 | if (ret < 0) | ||
| 645 | goto fail; | ||
| 646 | |||
| 647 | if (flags & KVM_PIT_SPEAKER_DUMMY) { | ||
| 648 | kvm_iodevice_init(&pit->speaker_dev, &speaker_dev_ops); | ||
| 649 | ret = __kvm_io_bus_register_dev(&kvm->pio_bus, | ||
| 650 | &pit->speaker_dev); | ||
| 651 | if (ret < 0) | ||
| 652 | goto fail_unregister; | ||
| 653 | } | ||
| 654 | |||
| 616 | return pit; | 655 | return pit; |
| 656 | |||
| 657 | fail_unregister: | ||
| 658 | __kvm_io_bus_unregister_dev(&kvm->pio_bus, &pit->dev); | ||
| 659 | |||
| 660 | fail: | ||
| 661 | if (pit->irq_source_id >= 0) | ||
| 662 | kvm_free_irq_source_id(kvm, pit->irq_source_id); | ||
| 663 | |||
| 664 | kfree(pit); | ||
| 665 | return NULL; | ||
| 617 | } | 666 | } |
| 618 | 667 | ||
| 619 | void kvm_free_pit(struct kvm *kvm) | 668 | void kvm_free_pit(struct kvm *kvm) |
| @@ -623,6 +672,8 @@ void kvm_free_pit(struct kvm *kvm) | |||
| 623 | if (kvm->arch.vpit) { | 672 | if (kvm->arch.vpit) { |
| 624 | kvm_unregister_irq_mask_notifier(kvm, 0, | 673 | kvm_unregister_irq_mask_notifier(kvm, 0, |
| 625 | &kvm->arch.vpit->mask_notifier); | 674 | &kvm->arch.vpit->mask_notifier); |
| 675 | kvm_unregister_irq_ack_notifier(kvm, | ||
| 676 | &kvm->arch.vpit->pit_state.irq_ack_notifier); | ||
| 626 | mutex_lock(&kvm->arch.vpit->pit_state.lock); | 677 | mutex_lock(&kvm->arch.vpit->pit_state.lock); |
| 627 | timer = &kvm->arch.vpit->pit_state.pit_timer.timer; | 678 | timer = &kvm->arch.vpit->pit_state.pit_timer.timer; |
| 628 | hrtimer_cancel(timer); | 679 | hrtimer_cancel(timer); |
| @@ -637,10 +688,10 @@ static void __inject_pit_timer_intr(struct kvm *kvm) | |||
| 637 | struct kvm_vcpu *vcpu; | 688 | struct kvm_vcpu *vcpu; |
| 638 | int i; | 689 | int i; |
| 639 | 690 | ||
| 640 | mutex_lock(&kvm->lock); | 691 | mutex_lock(&kvm->irq_lock); |
| 641 | kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 1); | 692 | kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 1); |
| 642 | kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 0); | 693 | kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 0); |
| 643 | mutex_unlock(&kvm->lock); | 694 | mutex_unlock(&kvm->irq_lock); |
| 644 | 695 | ||
| 645 | /* | 696 | /* |
| 646 | * Provides NMI watchdog support via Virtual Wire mode. | 697 | * Provides NMI watchdog support via Virtual Wire mode. |
| @@ -652,11 +703,8 @@ static void __inject_pit_timer_intr(struct kvm *kvm) | |||
| 652 | * VCPU0, and only if its LVT0 is in EXTINT mode. | 703 | * VCPU0, and only if its LVT0 is in EXTINT mode. |
| 653 | */ | 704 | */ |
| 654 | if (kvm->arch.vapics_in_nmi_mode > 0) | 705 | if (kvm->arch.vapics_in_nmi_mode > 0) |
| 655 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | 706 | kvm_for_each_vcpu(i, vcpu, kvm) |
| 656 | vcpu = kvm->vcpus[i]; | 707 | kvm_apic_nmi_wd_deliver(vcpu); |
| 657 | if (vcpu) | ||
| 658 | kvm_apic_nmi_wd_deliver(vcpu); | ||
| 659 | } | ||
| 660 | } | 708 | } |
| 661 | 709 | ||
| 662 | void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu) | 710 | void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu) |
| @@ -665,7 +713,7 @@ void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu) | |||
| 665 | struct kvm *kvm = vcpu->kvm; | 713 | struct kvm *kvm = vcpu->kvm; |
| 666 | struct kvm_kpit_state *ps; | 714 | struct kvm_kpit_state *ps; |
| 667 | 715 | ||
| 668 | if (vcpu && pit) { | 716 | if (pit) { |
| 669 | int inject = 0; | 717 | int inject = 0; |
| 670 | ps = &pit->pit_state; | 718 | ps = &pit->pit_state; |
| 671 | 719 | ||
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h index bbd863ff60b7..d4c1c7ffdc09 100644 --- a/arch/x86/kvm/i8254.h +++ b/arch/x86/kvm/i8254.h | |||
| @@ -21,6 +21,7 @@ struct kvm_kpit_channel_state { | |||
| 21 | 21 | ||
| 22 | struct kvm_kpit_state { | 22 | struct kvm_kpit_state { |
| 23 | struct kvm_kpit_channel_state channels[3]; | 23 | struct kvm_kpit_channel_state channels[3]; |
| 24 | u32 flags; | ||
| 24 | struct kvm_timer pit_timer; | 25 | struct kvm_timer pit_timer; |
| 25 | bool is_periodic; | 26 | bool is_periodic; |
| 26 | u32 speaker_data_on; | 27 | u32 speaker_data_on; |
| @@ -49,8 +50,8 @@ struct kvm_pit { | |||
| 49 | #define KVM_PIT_CHANNEL_MASK 0x3 | 50 | #define KVM_PIT_CHANNEL_MASK 0x3 |
| 50 | 51 | ||
| 51 | void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu); | 52 | void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu); |
| 52 | void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val); | 53 | void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val, int hpet_legacy_start); |
| 53 | struct kvm_pit *kvm_create_pit(struct kvm *kvm); | 54 | struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags); |
| 54 | void kvm_free_pit(struct kvm *kvm); | 55 | void kvm_free_pit(struct kvm *kvm); |
| 55 | void kvm_pit_reset(struct kvm_pit *pit); | 56 | void kvm_pit_reset(struct kvm_pit *pit); |
| 56 | 57 | ||
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index 1ccb50c74f18..01f151682802 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c | |||
| @@ -30,50 +30,24 @@ | |||
| 30 | #include "irq.h" | 30 | #include "irq.h" |
| 31 | 31 | ||
| 32 | #include <linux/kvm_host.h> | 32 | #include <linux/kvm_host.h> |
| 33 | 33 | #include "trace.h" | |
| 34 | static void pic_lock(struct kvm_pic *s) | ||
| 35 | __acquires(&s->lock) | ||
| 36 | { | ||
| 37 | spin_lock(&s->lock); | ||
| 38 | } | ||
| 39 | |||
| 40 | static void pic_unlock(struct kvm_pic *s) | ||
| 41 | __releases(&s->lock) | ||
| 42 | { | ||
| 43 | struct kvm *kvm = s->kvm; | ||
| 44 | unsigned acks = s->pending_acks; | ||
| 45 | bool wakeup = s->wakeup_needed; | ||
| 46 | struct kvm_vcpu *vcpu; | ||
| 47 | |||
| 48 | s->pending_acks = 0; | ||
| 49 | s->wakeup_needed = false; | ||
| 50 | |||
| 51 | spin_unlock(&s->lock); | ||
| 52 | |||
| 53 | while (acks) { | ||
| 54 | kvm_notify_acked_irq(kvm, SELECT_PIC(__ffs(acks)), | ||
| 55 | __ffs(acks)); | ||
| 56 | acks &= acks - 1; | ||
| 57 | } | ||
| 58 | |||
| 59 | if (wakeup) { | ||
| 60 | vcpu = s->kvm->vcpus[0]; | ||
| 61 | if (vcpu) | ||
| 62 | kvm_vcpu_kick(vcpu); | ||
| 63 | } | ||
| 64 | } | ||
| 65 | 34 | ||
| 66 | static void pic_clear_isr(struct kvm_kpic_state *s, int irq) | 35 | static void pic_clear_isr(struct kvm_kpic_state *s, int irq) |
| 67 | { | 36 | { |
| 68 | s->isr &= ~(1 << irq); | 37 | s->isr &= ~(1 << irq); |
| 69 | s->isr_ack |= (1 << irq); | 38 | s->isr_ack |= (1 << irq); |
| 39 | if (s != &s->pics_state->pics[0]) | ||
| 40 | irq += 8; | ||
| 41 | kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq); | ||
| 70 | } | 42 | } |
| 71 | 43 | ||
| 72 | void kvm_pic_clear_isr_ack(struct kvm *kvm) | 44 | void kvm_pic_clear_isr_ack(struct kvm *kvm) |
| 73 | { | 45 | { |
| 74 | struct kvm_pic *s = pic_irqchip(kvm); | 46 | struct kvm_pic *s = pic_irqchip(kvm); |
| 47 | spin_lock(&s->lock); | ||
| 75 | s->pics[0].isr_ack = 0xff; | 48 | s->pics[0].isr_ack = 0xff; |
| 76 | s->pics[1].isr_ack = 0xff; | 49 | s->pics[1].isr_ack = 0xff; |
| 50 | spin_unlock(&s->lock); | ||
| 77 | } | 51 | } |
| 78 | 52 | ||
| 79 | /* | 53 | /* |
| @@ -174,9 +148,9 @@ static void pic_update_irq(struct kvm_pic *s) | |||
| 174 | 148 | ||
| 175 | void kvm_pic_update_irq(struct kvm_pic *s) | 149 | void kvm_pic_update_irq(struct kvm_pic *s) |
| 176 | { | 150 | { |
| 177 | pic_lock(s); | 151 | spin_lock(&s->lock); |
| 178 | pic_update_irq(s); | 152 | pic_update_irq(s); |
| 179 | pic_unlock(s); | 153 | spin_unlock(&s->lock); |
| 180 | } | 154 | } |
| 181 | 155 | ||
| 182 | int kvm_pic_set_irq(void *opaque, int irq, int level) | 156 | int kvm_pic_set_irq(void *opaque, int irq, int level) |
| @@ -184,12 +158,14 @@ int kvm_pic_set_irq(void *opaque, int irq, int level) | |||
| 184 | struct kvm_pic *s = opaque; | 158 | struct kvm_pic *s = opaque; |
| 185 | int ret = -1; | 159 | int ret = -1; |
| 186 | 160 | ||
| 187 | pic_lock(s); | 161 | spin_lock(&s->lock); |
| 188 | if (irq >= 0 && irq < PIC_NUM_PINS) { | 162 | if (irq >= 0 && irq < PIC_NUM_PINS) { |
| 189 | ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); | 163 | ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); |
| 190 | pic_update_irq(s); | 164 | pic_update_irq(s); |
| 165 | trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr, | ||
| 166 | s->pics[irq >> 3].imr, ret == 0); | ||
| 191 | } | 167 | } |
| 192 | pic_unlock(s); | 168 | spin_unlock(&s->lock); |
| 193 | 169 | ||
| 194 | return ret; | 170 | return ret; |
| 195 | } | 171 | } |
| @@ -217,7 +193,7 @@ int kvm_pic_read_irq(struct kvm *kvm) | |||
| 217 | int irq, irq2, intno; | 193 | int irq, irq2, intno; |
| 218 | struct kvm_pic *s = pic_irqchip(kvm); | 194 | struct kvm_pic *s = pic_irqchip(kvm); |
| 219 | 195 | ||
| 220 | pic_lock(s); | 196 | spin_lock(&s->lock); |
| 221 | irq = pic_get_irq(&s->pics[0]); | 197 | irq = pic_get_irq(&s->pics[0]); |
| 222 | if (irq >= 0) { | 198 | if (irq >= 0) { |
| 223 | pic_intack(&s->pics[0], irq); | 199 | pic_intack(&s->pics[0], irq); |
| @@ -242,8 +218,7 @@ int kvm_pic_read_irq(struct kvm *kvm) | |||
| 242 | intno = s->pics[0].irq_base + irq; | 218 | intno = s->pics[0].irq_base + irq; |
| 243 | } | 219 | } |
| 244 | pic_update_irq(s); | 220 | pic_update_irq(s); |
| 245 | pic_unlock(s); | 221 | spin_unlock(&s->lock); |
| 246 | kvm_notify_acked_irq(kvm, SELECT_PIC(irq), irq); | ||
| 247 | 222 | ||
| 248 | return intno; | 223 | return intno; |
| 249 | } | 224 | } |
| @@ -252,7 +227,7 @@ void kvm_pic_reset(struct kvm_kpic_state *s) | |||
| 252 | { | 227 | { |
| 253 | int irq, irqbase, n; | 228 | int irq, irqbase, n; |
| 254 | struct kvm *kvm = s->pics_state->irq_request_opaque; | 229 | struct kvm *kvm = s->pics_state->irq_request_opaque; |
| 255 | struct kvm_vcpu *vcpu0 = kvm->vcpus[0]; | 230 | struct kvm_vcpu *vcpu0 = kvm->bsp_vcpu; |
| 256 | 231 | ||
| 257 | if (s == &s->pics_state->pics[0]) | 232 | if (s == &s->pics_state->pics[0]) |
| 258 | irqbase = 0; | 233 | irqbase = 0; |
| @@ -263,7 +238,7 @@ void kvm_pic_reset(struct kvm_kpic_state *s) | |||
| 263 | if (vcpu0 && kvm_apic_accept_pic_intr(vcpu0)) | 238 | if (vcpu0 && kvm_apic_accept_pic_intr(vcpu0)) |
| 264 | if (s->irr & (1 << irq) || s->isr & (1 << irq)) { | 239 | if (s->irr & (1 << irq) || s->isr & (1 << irq)) { |
| 265 | n = irq + irqbase; | 240 | n = irq + irqbase; |
| 266 | s->pics_state->pending_acks |= 1 << n; | 241 | kvm_notify_acked_irq(kvm, SELECT_PIC(n), n); |
| 267 | } | 242 | } |
| 268 | } | 243 | } |
| 269 | s->last_irr = 0; | 244 | s->last_irr = 0; |
| @@ -428,8 +403,7 @@ static u32 elcr_ioport_read(void *opaque, u32 addr1) | |||
| 428 | return s->elcr; | 403 | return s->elcr; |
| 429 | } | 404 | } |
| 430 | 405 | ||
| 431 | static int picdev_in_range(struct kvm_io_device *this, gpa_t addr, | 406 | static int picdev_in_range(gpa_t addr) |
| 432 | int len, int is_write) | ||
| 433 | { | 407 | { |
| 434 | switch (addr) { | 408 | switch (addr) { |
| 435 | case 0x20: | 409 | case 0x20: |
| @@ -444,18 +418,25 @@ static int picdev_in_range(struct kvm_io_device *this, gpa_t addr, | |||
| 444 | } | 418 | } |
| 445 | } | 419 | } |
| 446 | 420 | ||
| 447 | static void picdev_write(struct kvm_io_device *this, | 421 | static inline struct kvm_pic *to_pic(struct kvm_io_device *dev) |
| 422 | { | ||
| 423 | return container_of(dev, struct kvm_pic, dev); | ||
| 424 | } | ||
| 425 | |||
| 426 | static int picdev_write(struct kvm_io_device *this, | ||
| 448 | gpa_t addr, int len, const void *val) | 427 | gpa_t addr, int len, const void *val) |
| 449 | { | 428 | { |
| 450 | struct kvm_pic *s = this->private; | 429 | struct kvm_pic *s = to_pic(this); |
| 451 | unsigned char data = *(unsigned char *)val; | 430 | unsigned char data = *(unsigned char *)val; |
| 431 | if (!picdev_in_range(addr)) | ||
| 432 | return -EOPNOTSUPP; | ||
| 452 | 433 | ||
| 453 | if (len != 1) { | 434 | if (len != 1) { |
| 454 | if (printk_ratelimit()) | 435 | if (printk_ratelimit()) |
| 455 | printk(KERN_ERR "PIC: non byte write\n"); | 436 | printk(KERN_ERR "PIC: non byte write\n"); |
| 456 | return; | 437 | return 0; |
| 457 | } | 438 | } |
| 458 | pic_lock(s); | 439 | spin_lock(&s->lock); |
| 459 | switch (addr) { | 440 | switch (addr) { |
| 460 | case 0x20: | 441 | case 0x20: |
| 461 | case 0x21: | 442 | case 0x21: |
| @@ -468,21 +449,24 @@ static void picdev_write(struct kvm_io_device *this, | |||
| 468 | elcr_ioport_write(&s->pics[addr & 1], addr, data); | 449 | elcr_ioport_write(&s->pics[addr & 1], addr, data); |
| 469 | break; | 450 | break; |
| 470 | } | 451 | } |
| 471 | pic_unlock(s); | 452 | spin_unlock(&s->lock); |
| 453 | return 0; | ||
| 472 | } | 454 | } |
| 473 | 455 | ||
| 474 | static void picdev_read(struct kvm_io_device *this, | 456 | static int picdev_read(struct kvm_io_device *this, |
| 475 | gpa_t addr, int len, void *val) | 457 | gpa_t addr, int len, void *val) |
| 476 | { | 458 | { |
| 477 | struct kvm_pic *s = this->private; | 459 | struct kvm_pic *s = to_pic(this); |
| 478 | unsigned char data = 0; | 460 | unsigned char data = 0; |
| 461 | if (!picdev_in_range(addr)) | ||
| 462 | return -EOPNOTSUPP; | ||
| 479 | 463 | ||
| 480 | if (len != 1) { | 464 | if (len != 1) { |
| 481 | if (printk_ratelimit()) | 465 | if (printk_ratelimit()) |
| 482 | printk(KERN_ERR "PIC: non byte read\n"); | 466 | printk(KERN_ERR "PIC: non byte read\n"); |
| 483 | return; | 467 | return 0; |
| 484 | } | 468 | } |
| 485 | pic_lock(s); | 469 | spin_lock(&s->lock); |
| 486 | switch (addr) { | 470 | switch (addr) { |
| 487 | case 0x20: | 471 | case 0x20: |
| 488 | case 0x21: | 472 | case 0x21: |
| @@ -496,7 +480,8 @@ static void picdev_read(struct kvm_io_device *this, | |||
| 496 | break; | 480 | break; |
| 497 | } | 481 | } |
| 498 | *(unsigned char *)val = data; | 482 | *(unsigned char *)val = data; |
| 499 | pic_unlock(s); | 483 | spin_unlock(&s->lock); |
| 484 | return 0; | ||
| 500 | } | 485 | } |
| 501 | 486 | ||
| 502 | /* | 487 | /* |
| @@ -505,20 +490,27 @@ static void picdev_read(struct kvm_io_device *this, | |||
| 505 | static void pic_irq_request(void *opaque, int level) | 490 | static void pic_irq_request(void *opaque, int level) |
| 506 | { | 491 | { |
| 507 | struct kvm *kvm = opaque; | 492 | struct kvm *kvm = opaque; |
| 508 | struct kvm_vcpu *vcpu = kvm->vcpus[0]; | 493 | struct kvm_vcpu *vcpu = kvm->bsp_vcpu; |
| 509 | struct kvm_pic *s = pic_irqchip(kvm); | 494 | struct kvm_pic *s = pic_irqchip(kvm); |
| 510 | int irq = pic_get_irq(&s->pics[0]); | 495 | int irq = pic_get_irq(&s->pics[0]); |
| 511 | 496 | ||
| 512 | s->output = level; | 497 | s->output = level; |
| 513 | if (vcpu && level && (s->pics[0].isr_ack & (1 << irq))) { | 498 | if (vcpu && level && (s->pics[0].isr_ack & (1 << irq))) { |
| 514 | s->pics[0].isr_ack &= ~(1 << irq); | 499 | s->pics[0].isr_ack &= ~(1 << irq); |
| 515 | s->wakeup_needed = true; | 500 | kvm_vcpu_kick(vcpu); |
| 516 | } | 501 | } |
| 517 | } | 502 | } |
| 518 | 503 | ||
| 504 | static const struct kvm_io_device_ops picdev_ops = { | ||
| 505 | .read = picdev_read, | ||
| 506 | .write = picdev_write, | ||
| 507 | }; | ||
| 508 | |||
| 519 | struct kvm_pic *kvm_create_pic(struct kvm *kvm) | 509 | struct kvm_pic *kvm_create_pic(struct kvm *kvm) |
| 520 | { | 510 | { |
| 521 | struct kvm_pic *s; | 511 | struct kvm_pic *s; |
| 512 | int ret; | ||
| 513 | |||
| 522 | s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL); | 514 | s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL); |
| 523 | if (!s) | 515 | if (!s) |
| 524 | return NULL; | 516 | return NULL; |
| @@ -534,10 +526,12 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm) | |||
| 534 | /* | 526 | /* |
| 535 | * Initialize PIO device | 527 | * Initialize PIO device |
| 536 | */ | 528 | */ |
| 537 | s->dev.read = picdev_read; | 529 | kvm_iodevice_init(&s->dev, &picdev_ops); |
| 538 | s->dev.write = picdev_write; | 530 | ret = kvm_io_bus_register_dev(kvm, &kvm->pio_bus, &s->dev); |
| 539 | s->dev.in_range = picdev_in_range; | 531 | if (ret < 0) { |
| 540 | s->dev.private = s; | 532 | kfree(s); |
| 541 | kvm_io_bus_register_dev(&kvm->pio_bus, &s->dev); | 533 | return NULL; |
| 534 | } | ||
| 535 | |||
| 542 | return s; | 536 | return s; |
| 543 | } | 537 | } |
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h index 9f593188129e..7d6058a2fd38 100644 --- a/arch/x86/kvm/irq.h +++ b/arch/x86/kvm/irq.h | |||
| @@ -63,7 +63,6 @@ struct kvm_kpic_state { | |||
| 63 | 63 | ||
| 64 | struct kvm_pic { | 64 | struct kvm_pic { |
| 65 | spinlock_t lock; | 65 | spinlock_t lock; |
| 66 | bool wakeup_needed; | ||
| 67 | unsigned pending_acks; | 66 | unsigned pending_acks; |
| 68 | struct kvm *kvm; | 67 | struct kvm *kvm; |
| 69 | struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */ | 68 | struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */ |
diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h index 1ff819dce7d3..7bcc5b6a4403 100644 --- a/arch/x86/kvm/kvm_cache_regs.h +++ b/arch/x86/kvm/kvm_cache_regs.h | |||
| @@ -29,4 +29,13 @@ static inline void kvm_rip_write(struct kvm_vcpu *vcpu, unsigned long val) | |||
| 29 | kvm_register_write(vcpu, VCPU_REGS_RIP, val); | 29 | kvm_register_write(vcpu, VCPU_REGS_RIP, val); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | static inline u64 kvm_pdptr_read(struct kvm_vcpu *vcpu, int index) | ||
| 33 | { | ||
| 34 | if (!test_bit(VCPU_EXREG_PDPTR, | ||
| 35 | (unsigned long *)&vcpu->arch.regs_avail)) | ||
| 36 | kvm_x86_ops->cache_reg(vcpu, VCPU_EXREG_PDPTR); | ||
| 37 | |||
| 38 | return vcpu->arch.pdptrs[index]; | ||
| 39 | } | ||
| 40 | |||
| 32 | #endif | 41 | #endif |
diff --git a/arch/x86/kvm/kvm_svm.h b/arch/x86/kvm/kvm_svm.h deleted file mode 100644 index ed66e4c078dc..000000000000 --- a/arch/x86/kvm/kvm_svm.h +++ /dev/null | |||
| @@ -1,51 +0,0 @@ | |||
| 1 | #ifndef __KVM_SVM_H | ||
| 2 | #define __KVM_SVM_H | ||
| 3 | |||
| 4 | #include <linux/kernel.h> | ||
| 5 | #include <linux/types.h> | ||
| 6 | #include <linux/list.h> | ||
| 7 | #include <linux/kvm_host.h> | ||
| 8 | #include <asm/msr.h> | ||
| 9 | |||
| 10 | #include <asm/svm.h> | ||
| 11 | |||
| 12 | static const u32 host_save_user_msrs[] = { | ||
| 13 | #ifdef CONFIG_X86_64 | ||
| 14 | MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE, | ||
| 15 | MSR_FS_BASE, | ||
| 16 | #endif | ||
| 17 | MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, | ||
| 18 | }; | ||
| 19 | |||
| 20 | #define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs) | ||
| 21 | |||
| 22 | struct kvm_vcpu; | ||
| 23 | |||
| 24 | struct vcpu_svm { | ||
| 25 | struct kvm_vcpu vcpu; | ||
| 26 | struct vmcb *vmcb; | ||
| 27 | unsigned long vmcb_pa; | ||
| 28 | struct svm_cpu_data *svm_data; | ||
| 29 | uint64_t asid_generation; | ||
| 30 | |||
| 31 | u64 next_rip; | ||
| 32 | |||
| 33 | u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS]; | ||
| 34 | u64 host_gs_base; | ||
| 35 | unsigned long host_cr2; | ||
| 36 | |||
| 37 | u32 *msrpm; | ||
| 38 | struct vmcb *hsave; | ||
| 39 | u64 hsave_msr; | ||
| 40 | |||
| 41 | u64 nested_vmcb; | ||
| 42 | |||
| 43 | /* These are the merged vectors */ | ||
| 44 | u32 *nested_msrpm; | ||
| 45 | |||
| 46 | /* gpa pointers to the real vectors */ | ||
| 47 | u64 nested_vmcb_msrpm; | ||
| 48 | }; | ||
| 49 | |||
| 50 | #endif | ||
| 51 | |||
diff --git a/arch/x86/kvm/kvm_timer.h b/arch/x86/kvm/kvm_timer.h index 26bd6ba74e1c..55c7524dda54 100644 --- a/arch/x86/kvm/kvm_timer.h +++ b/arch/x86/kvm/kvm_timer.h | |||
| @@ -6,7 +6,7 @@ struct kvm_timer { | |||
| 6 | bool reinject; | 6 | bool reinject; |
| 7 | struct kvm_timer_ops *t_ops; | 7 | struct kvm_timer_ops *t_ops; |
| 8 | struct kvm *kvm; | 8 | struct kvm *kvm; |
| 9 | int vcpu_id; | 9 | struct kvm_vcpu *vcpu; |
| 10 | }; | 10 | }; |
| 11 | 11 | ||
| 12 | struct kvm_timer_ops { | 12 | struct kvm_timer_ops { |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index ae99d83f81a3..1ae5ceba7eb2 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
| @@ -32,8 +32,11 @@ | |||
| 32 | #include <asm/current.h> | 32 | #include <asm/current.h> |
| 33 | #include <asm/apicdef.h> | 33 | #include <asm/apicdef.h> |
| 34 | #include <asm/atomic.h> | 34 | #include <asm/atomic.h> |
| 35 | #include <asm/apicdef.h> | ||
| 35 | #include "kvm_cache_regs.h" | 36 | #include "kvm_cache_regs.h" |
| 36 | #include "irq.h" | 37 | #include "irq.h" |
| 38 | #include "trace.h" | ||
| 39 | #include "x86.h" | ||
| 37 | 40 | ||
| 38 | #ifndef CONFIG_X86_64 | 41 | #ifndef CONFIG_X86_64 |
| 39 | #define mod_64(x, y) ((x) - (y) * div64_u64(x, y)) | 42 | #define mod_64(x, y) ((x) - (y) * div64_u64(x, y)) |
| @@ -141,6 +144,26 @@ static inline int apic_lvt_nmi_mode(u32 lvt_val) | |||
| 141 | return (lvt_val & (APIC_MODE_MASK | APIC_LVT_MASKED)) == APIC_DM_NMI; | 144 | return (lvt_val & (APIC_MODE_MASK | APIC_LVT_MASKED)) == APIC_DM_NMI; |
| 142 | } | 145 | } |
| 143 | 146 | ||
| 147 | void kvm_apic_set_version(struct kvm_vcpu *vcpu) | ||
| 148 | { | ||
| 149 | struct kvm_lapic *apic = vcpu->arch.apic; | ||
| 150 | struct kvm_cpuid_entry2 *feat; | ||
| 151 | u32 v = APIC_VERSION; | ||
| 152 | |||
| 153 | if (!irqchip_in_kernel(vcpu->kvm)) | ||
| 154 | return; | ||
| 155 | |||
| 156 | feat = kvm_find_cpuid_entry(apic->vcpu, 0x1, 0); | ||
| 157 | if (feat && (feat->ecx & (1 << (X86_FEATURE_X2APIC & 31)))) | ||
| 158 | v |= APIC_LVR_DIRECTED_EOI; | ||
| 159 | apic_set_reg(apic, APIC_LVR, v); | ||
| 160 | } | ||
| 161 | |||
| 162 | static inline int apic_x2apic_mode(struct kvm_lapic *apic) | ||
| 163 | { | ||
| 164 | return apic->vcpu->arch.apic_base & X2APIC_ENABLE; | ||
| 165 | } | ||
| 166 | |||
| 144 | static unsigned int apic_lvt_mask[APIC_LVT_NUM] = { | 167 | static unsigned int apic_lvt_mask[APIC_LVT_NUM] = { |
| 145 | LVT_MASK | APIC_LVT_TIMER_PERIODIC, /* LVTT */ | 168 | LVT_MASK | APIC_LVT_TIMER_PERIODIC, /* LVTT */ |
| 146 | LVT_MASK | APIC_MODE_MASK, /* LVTTHMR */ | 169 | LVT_MASK | APIC_MODE_MASK, /* LVTTHMR */ |
| @@ -165,36 +188,52 @@ static int find_highest_vector(void *bitmap) | |||
| 165 | 188 | ||
| 166 | static inline int apic_test_and_set_irr(int vec, struct kvm_lapic *apic) | 189 | static inline int apic_test_and_set_irr(int vec, struct kvm_lapic *apic) |
| 167 | { | 190 | { |
| 191 | apic->irr_pending = true; | ||
| 168 | return apic_test_and_set_vector(vec, apic->regs + APIC_IRR); | 192 | return apic_test_and_set_vector(vec, apic->regs + APIC_IRR); |
| 169 | } | 193 | } |
| 170 | 194 | ||
| 171 | static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) | 195 | static inline int apic_search_irr(struct kvm_lapic *apic) |
| 172 | { | 196 | { |
| 173 | apic_clear_vector(vec, apic->regs + APIC_IRR); | 197 | return find_highest_vector(apic->regs + APIC_IRR); |
| 174 | } | 198 | } |
| 175 | 199 | ||
| 176 | static inline int apic_find_highest_irr(struct kvm_lapic *apic) | 200 | static inline int apic_find_highest_irr(struct kvm_lapic *apic) |
| 177 | { | 201 | { |
| 178 | int result; | 202 | int result; |
| 179 | 203 | ||
| 180 | result = find_highest_vector(apic->regs + APIC_IRR); | 204 | if (!apic->irr_pending) |
| 205 | return -1; | ||
| 206 | |||
| 207 | result = apic_search_irr(apic); | ||
| 181 | ASSERT(result == -1 || result >= 16); | 208 | ASSERT(result == -1 || result >= 16); |
| 182 | 209 | ||
| 183 | return result; | 210 | return result; |
| 184 | } | 211 | } |
| 185 | 212 | ||
| 213 | static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) | ||
| 214 | { | ||
| 215 | apic->irr_pending = false; | ||
| 216 | apic_clear_vector(vec, apic->regs + APIC_IRR); | ||
| 217 | if (apic_search_irr(apic) != -1) | ||
| 218 | apic->irr_pending = true; | ||
| 219 | } | ||
| 220 | |||
| 186 | int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu) | 221 | int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu) |
| 187 | { | 222 | { |
| 188 | struct kvm_lapic *apic = vcpu->arch.apic; | 223 | struct kvm_lapic *apic = vcpu->arch.apic; |
| 189 | int highest_irr; | 224 | int highest_irr; |
| 190 | 225 | ||
| 226 | /* This may race with setting of irr in __apic_accept_irq() and | ||
| 227 | * value returned may be wrong, but kvm_vcpu_kick() in __apic_accept_irq | ||
| 228 | * will cause vmexit immediately and the value will be recalculated | ||
| 229 | * on the next vmentry. | ||
| 230 | */ | ||
| 191 | if (!apic) | 231 | if (!apic) |
| 192 | return 0; | 232 | return 0; |
| 193 | highest_irr = apic_find_highest_irr(apic); | 233 | highest_irr = apic_find_highest_irr(apic); |
| 194 | 234 | ||
| 195 | return highest_irr; | 235 | return highest_irr; |
| 196 | } | 236 | } |
| 197 | EXPORT_SYMBOL_GPL(kvm_lapic_find_highest_irr); | ||
| 198 | 237 | ||
| 199 | static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | 238 | static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, |
| 200 | int vector, int level, int trig_mode); | 239 | int vector, int level, int trig_mode); |
| @@ -251,7 +290,12 @@ int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest) | |||
| 251 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) | 290 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) |
| 252 | { | 291 | { |
| 253 | int result = 0; | 292 | int result = 0; |
| 254 | u8 logical_id; | 293 | u32 logical_id; |
| 294 | |||
| 295 | if (apic_x2apic_mode(apic)) { | ||
| 296 | logical_id = apic_get_reg(apic, APIC_LDR); | ||
| 297 | return logical_id & mda; | ||
| 298 | } | ||
| 255 | 299 | ||
| 256 | logical_id = GET_APIC_LOGICAL_ID(apic_get_reg(apic, APIC_LDR)); | 300 | logical_id = GET_APIC_LOGICAL_ID(apic_get_reg(apic, APIC_LDR)); |
| 257 | 301 | ||
| @@ -331,6 +375,8 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
| 331 | break; | 375 | break; |
| 332 | 376 | ||
| 333 | result = !apic_test_and_set_irr(vector, apic); | 377 | result = !apic_test_and_set_irr(vector, apic); |
| 378 | trace_kvm_apic_accept_irq(vcpu->vcpu_id, delivery_mode, | ||
| 379 | trig_mode, vector, !result); | ||
| 334 | if (!result) { | 380 | if (!result) { |
| 335 | if (trig_mode) | 381 | if (trig_mode) |
| 336 | apic_debug("level trig mode repeatedly for " | 382 | apic_debug("level trig mode repeatedly for " |
| @@ -425,7 +471,11 @@ static void apic_set_eoi(struct kvm_lapic *apic) | |||
| 425 | trigger_mode = IOAPIC_LEVEL_TRIG; | 471 | trigger_mode = IOAPIC_LEVEL_TRIG; |
| 426 | else | 472 | else |
| 427 | trigger_mode = IOAPIC_EDGE_TRIG; | 473 | trigger_mode = IOAPIC_EDGE_TRIG; |
| 428 | kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); | 474 | if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI)) { |
| 475 | mutex_lock(&apic->vcpu->kvm->irq_lock); | ||
| 476 | kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); | ||
| 477 | mutex_unlock(&apic->vcpu->kvm->irq_lock); | ||
| 478 | } | ||
| 429 | } | 479 | } |
| 430 | 480 | ||
| 431 | static void apic_send_ipi(struct kvm_lapic *apic) | 481 | static void apic_send_ipi(struct kvm_lapic *apic) |
| @@ -440,7 +490,12 @@ static void apic_send_ipi(struct kvm_lapic *apic) | |||
| 440 | irq.level = icr_low & APIC_INT_ASSERT; | 490 | irq.level = icr_low & APIC_INT_ASSERT; |
| 441 | irq.trig_mode = icr_low & APIC_INT_LEVELTRIG; | 491 | irq.trig_mode = icr_low & APIC_INT_LEVELTRIG; |
| 442 | irq.shorthand = icr_low & APIC_SHORT_MASK; | 492 | irq.shorthand = icr_low & APIC_SHORT_MASK; |
| 443 | irq.dest_id = GET_APIC_DEST_FIELD(icr_high); | 493 | if (apic_x2apic_mode(apic)) |
| 494 | irq.dest_id = icr_high; | ||
| 495 | else | ||
| 496 | irq.dest_id = GET_APIC_DEST_FIELD(icr_high); | ||
| 497 | |||
| 498 | trace_kvm_apic_ipi(icr_low, irq.dest_id); | ||
| 444 | 499 | ||
| 445 | apic_debug("icr_high 0x%x, icr_low 0x%x, " | 500 | apic_debug("icr_high 0x%x, icr_low 0x%x, " |
| 446 | "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, " | 501 | "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, " |
| @@ -449,7 +504,9 @@ static void apic_send_ipi(struct kvm_lapic *apic) | |||
| 449 | irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode, | 504 | irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode, |
| 450 | irq.vector); | 505 | irq.vector); |
| 451 | 506 | ||
| 507 | mutex_lock(&apic->vcpu->kvm->irq_lock); | ||
| 452 | kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq); | 508 | kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq); |
| 509 | mutex_unlock(&apic->vcpu->kvm->irq_lock); | ||
| 453 | } | 510 | } |
| 454 | 511 | ||
| 455 | static u32 apic_get_tmcct(struct kvm_lapic *apic) | 512 | static u32 apic_get_tmcct(struct kvm_lapic *apic) |
| @@ -495,12 +552,16 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset) | |||
| 495 | { | 552 | { |
| 496 | u32 val = 0; | 553 | u32 val = 0; |
| 497 | 554 | ||
| 498 | KVMTRACE_1D(APIC_ACCESS, apic->vcpu, (u32)offset, handler); | ||
| 499 | |||
| 500 | if (offset >= LAPIC_MMIO_LENGTH) | 555 | if (offset >= LAPIC_MMIO_LENGTH) |
| 501 | return 0; | 556 | return 0; |
| 502 | 557 | ||
| 503 | switch (offset) { | 558 | switch (offset) { |
| 559 | case APIC_ID: | ||
| 560 | if (apic_x2apic_mode(apic)) | ||
| 561 | val = kvm_apic_id(apic); | ||
| 562 | else | ||
| 563 | val = kvm_apic_id(apic) << 24; | ||
| 564 | break; | ||
| 504 | case APIC_ARBPRI: | 565 | case APIC_ARBPRI: |
| 505 | printk(KERN_WARNING "Access APIC ARBPRI register " | 566 | printk(KERN_WARNING "Access APIC ARBPRI register " |
| 506 | "which is for P6\n"); | 567 | "which is for P6\n"); |
| @@ -522,21 +583,35 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset) | |||
| 522 | return val; | 583 | return val; |
| 523 | } | 584 | } |
| 524 | 585 | ||
| 525 | static void apic_mmio_read(struct kvm_io_device *this, | 586 | static inline struct kvm_lapic *to_lapic(struct kvm_io_device *dev) |
| 526 | gpa_t address, int len, void *data) | 587 | { |
| 588 | return container_of(dev, struct kvm_lapic, dev); | ||
| 589 | } | ||
| 590 | |||
| 591 | static int apic_reg_read(struct kvm_lapic *apic, u32 offset, int len, | ||
| 592 | void *data) | ||
| 527 | { | 593 | { |
| 528 | struct kvm_lapic *apic = (struct kvm_lapic *)this->private; | ||
| 529 | unsigned int offset = address - apic->base_address; | ||
| 530 | unsigned char alignment = offset & 0xf; | 594 | unsigned char alignment = offset & 0xf; |
| 531 | u32 result; | 595 | u32 result; |
| 596 | /* this bitmask has a bit cleared for each reserver register */ | ||
| 597 | static const u64 rmask = 0x43ff01ffffffe70cULL; | ||
| 532 | 598 | ||
| 533 | if ((alignment + len) > 4) { | 599 | if ((alignment + len) > 4) { |
| 534 | printk(KERN_ERR "KVM_APIC_READ: alignment error %lx %d", | 600 | apic_debug("KVM_APIC_READ: alignment error %x %d\n", |
| 535 | (unsigned long)address, len); | 601 | offset, len); |
| 536 | return; | 602 | return 1; |
| 537 | } | 603 | } |
| 604 | |||
| 605 | if (offset > 0x3f0 || !(rmask & (1ULL << (offset >> 4)))) { | ||
| 606 | apic_debug("KVM_APIC_READ: read reserved register %x\n", | ||
| 607 | offset); | ||
| 608 | return 1; | ||
| 609 | } | ||
| 610 | |||
| 538 | result = __apic_read(apic, offset & ~0xf); | 611 | result = __apic_read(apic, offset & ~0xf); |
| 539 | 612 | ||
| 613 | trace_kvm_apic_read(offset, result); | ||
| 614 | |||
| 540 | switch (len) { | 615 | switch (len) { |
| 541 | case 1: | 616 | case 1: |
| 542 | case 2: | 617 | case 2: |
| @@ -548,6 +623,28 @@ static void apic_mmio_read(struct kvm_io_device *this, | |||
| 548 | "should be 1,2, or 4 instead\n", len); | 623 | "should be 1,2, or 4 instead\n", len); |
| 549 | break; | 624 | break; |
| 550 | } | 625 | } |
| 626 | return 0; | ||
| 627 | } | ||
| 628 | |||
| 629 | static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr) | ||
| 630 | { | ||
| 631 | return apic_hw_enabled(apic) && | ||
| 632 | addr >= apic->base_address && | ||
| 633 | addr < apic->base_address + LAPIC_MMIO_LENGTH; | ||
| 634 | } | ||
| 635 | |||
| 636 | static int apic_mmio_read(struct kvm_io_device *this, | ||
| 637 | gpa_t address, int len, void *data) | ||
| 638 | { | ||
| 639 | struct kvm_lapic *apic = to_lapic(this); | ||
| 640 | u32 offset = address - apic->base_address; | ||
| 641 | |||
| 642 | if (!apic_mmio_in_range(apic, address)) | ||
| 643 | return -EOPNOTSUPP; | ||
| 644 | |||
| 645 | apic_reg_read(apic, offset, len, data); | ||
| 646 | |||
| 647 | return 0; | ||
| 551 | } | 648 | } |
| 552 | 649 | ||
| 553 | static void update_divide_count(struct kvm_lapic *apic) | 650 | static void update_divide_count(struct kvm_lapic *apic) |
| @@ -573,6 +670,15 @@ static void start_apic_timer(struct kvm_lapic *apic) | |||
| 573 | 670 | ||
| 574 | if (!apic->lapic_timer.period) | 671 | if (!apic->lapic_timer.period) |
| 575 | return; | 672 | return; |
| 673 | /* | ||
| 674 | * Do not allow the guest to program periodic timers with small | ||
| 675 | * interval, since the hrtimers are not throttled by the host | ||
| 676 | * scheduler. | ||
| 677 | */ | ||
| 678 | if (apic_lvtt_period(apic)) { | ||
| 679 | if (apic->lapic_timer.period < NSEC_PER_MSEC/2) | ||
| 680 | apic->lapic_timer.period = NSEC_PER_MSEC/2; | ||
| 681 | } | ||
| 576 | 682 | ||
| 577 | hrtimer_start(&apic->lapic_timer.timer, | 683 | hrtimer_start(&apic->lapic_timer.timer, |
| 578 | ktime_add_ns(now, apic->lapic_timer.period), | 684 | ktime_add_ns(now, apic->lapic_timer.period), |
| @@ -603,40 +709,18 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val) | |||
| 603 | apic->vcpu->kvm->arch.vapics_in_nmi_mode--; | 709 | apic->vcpu->kvm->arch.vapics_in_nmi_mode--; |
| 604 | } | 710 | } |
| 605 | 711 | ||
| 606 | static void apic_mmio_write(struct kvm_io_device *this, | 712 | static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) |
| 607 | gpa_t address, int len, const void *data) | ||
| 608 | { | 713 | { |
| 609 | struct kvm_lapic *apic = (struct kvm_lapic *)this->private; | 714 | int ret = 0; |
| 610 | unsigned int offset = address - apic->base_address; | ||
| 611 | unsigned char alignment = offset & 0xf; | ||
| 612 | u32 val; | ||
| 613 | |||
| 614 | /* | ||
| 615 | * APIC register must be aligned on 128-bits boundary. | ||
| 616 | * 32/64/128 bits registers must be accessed thru 32 bits. | ||
| 617 | * Refer SDM 8.4.1 | ||
| 618 | */ | ||
| 619 | if (len != 4 || alignment) { | ||
| 620 | /* Don't shout loud, $infamous_os would cause only noise. */ | ||
| 621 | apic_debug("apic write: bad size=%d %lx\n", | ||
| 622 | len, (long)address); | ||
| 623 | return; | ||
| 624 | } | ||
| 625 | |||
| 626 | val = *(u32 *) data; | ||
| 627 | |||
| 628 | /* too common printing */ | ||
| 629 | if (offset != APIC_EOI) | ||
| 630 | apic_debug("%s: offset 0x%x with length 0x%x, and value is " | ||
| 631 | "0x%x\n", __func__, offset, len, val); | ||
| 632 | |||
| 633 | offset &= 0xff0; | ||
| 634 | 715 | ||
| 635 | KVMTRACE_1D(APIC_ACCESS, apic->vcpu, (u32)offset, handler); | 716 | trace_kvm_apic_write(reg, val); |
| 636 | 717 | ||
| 637 | switch (offset) { | 718 | switch (reg) { |
| 638 | case APIC_ID: /* Local APIC ID */ | 719 | case APIC_ID: /* Local APIC ID */ |
| 639 | apic_set_reg(apic, APIC_ID, val); | 720 | if (!apic_x2apic_mode(apic)) |
| 721 | apic_set_reg(apic, APIC_ID, val); | ||
| 722 | else | ||
| 723 | ret = 1; | ||
| 640 | break; | 724 | break; |
| 641 | 725 | ||
| 642 | case APIC_TASKPRI: | 726 | case APIC_TASKPRI: |
| @@ -649,15 +733,24 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
| 649 | break; | 733 | break; |
| 650 | 734 | ||
| 651 | case APIC_LDR: | 735 | case APIC_LDR: |
| 652 | apic_set_reg(apic, APIC_LDR, val & APIC_LDR_MASK); | 736 | if (!apic_x2apic_mode(apic)) |
| 737 | apic_set_reg(apic, APIC_LDR, val & APIC_LDR_MASK); | ||
| 738 | else | ||
| 739 | ret = 1; | ||
| 653 | break; | 740 | break; |
| 654 | 741 | ||
| 655 | case APIC_DFR: | 742 | case APIC_DFR: |
| 656 | apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF); | 743 | if (!apic_x2apic_mode(apic)) |
| 744 | apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF); | ||
| 745 | else | ||
| 746 | ret = 1; | ||
| 657 | break; | 747 | break; |
| 658 | 748 | ||
| 659 | case APIC_SPIV: | 749 | case APIC_SPIV: { |
| 660 | apic_set_reg(apic, APIC_SPIV, val & 0x3ff); | 750 | u32 mask = 0x3ff; |
| 751 | if (apic_get_reg(apic, APIC_LVR) & APIC_LVR_DIRECTED_EOI) | ||
| 752 | mask |= APIC_SPIV_DIRECTED_EOI; | ||
| 753 | apic_set_reg(apic, APIC_SPIV, val & mask); | ||
| 661 | if (!(val & APIC_SPIV_APIC_ENABLED)) { | 754 | if (!(val & APIC_SPIV_APIC_ENABLED)) { |
| 662 | int i; | 755 | int i; |
| 663 | u32 lvt_val; | 756 | u32 lvt_val; |
| @@ -672,7 +765,7 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
| 672 | 765 | ||
| 673 | } | 766 | } |
| 674 | break; | 767 | break; |
| 675 | 768 | } | |
| 676 | case APIC_ICR: | 769 | case APIC_ICR: |
| 677 | /* No delay here, so we always clear the pending bit */ | 770 | /* No delay here, so we always clear the pending bit */ |
| 678 | apic_set_reg(apic, APIC_ICR, val & ~(1 << 12)); | 771 | apic_set_reg(apic, APIC_ICR, val & ~(1 << 12)); |
| @@ -680,7 +773,9 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
| 680 | break; | 773 | break; |
| 681 | 774 | ||
| 682 | case APIC_ICR2: | 775 | case APIC_ICR2: |
| 683 | apic_set_reg(apic, APIC_ICR2, val & 0xff000000); | 776 | if (!apic_x2apic_mode(apic)) |
| 777 | val &= 0xff000000; | ||
| 778 | apic_set_reg(apic, APIC_ICR2, val); | ||
| 684 | break; | 779 | break; |
| 685 | 780 | ||
| 686 | case APIC_LVT0: | 781 | case APIC_LVT0: |
| @@ -694,8 +789,8 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
| 694 | if (!apic_sw_enabled(apic)) | 789 | if (!apic_sw_enabled(apic)) |
| 695 | val |= APIC_LVT_MASKED; | 790 | val |= APIC_LVT_MASKED; |
| 696 | 791 | ||
| 697 | val &= apic_lvt_mask[(offset - APIC_LVTT) >> 4]; | 792 | val &= apic_lvt_mask[(reg - APIC_LVTT) >> 4]; |
| 698 | apic_set_reg(apic, offset, val); | 793 | apic_set_reg(apic, reg, val); |
| 699 | 794 | ||
| 700 | break; | 795 | break; |
| 701 | 796 | ||
| @@ -703,7 +798,7 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
| 703 | hrtimer_cancel(&apic->lapic_timer.timer); | 798 | hrtimer_cancel(&apic->lapic_timer.timer); |
| 704 | apic_set_reg(apic, APIC_TMICT, val); | 799 | apic_set_reg(apic, APIC_TMICT, val); |
| 705 | start_apic_timer(apic); | 800 | start_apic_timer(apic); |
| 706 | return; | 801 | break; |
| 707 | 802 | ||
| 708 | case APIC_TDCR: | 803 | case APIC_TDCR: |
| 709 | if (val & 4) | 804 | if (val & 4) |
| @@ -712,27 +807,59 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
| 712 | update_divide_count(apic); | 807 | update_divide_count(apic); |
| 713 | break; | 808 | break; |
| 714 | 809 | ||
| 810 | case APIC_ESR: | ||
| 811 | if (apic_x2apic_mode(apic) && val != 0) { | ||
| 812 | printk(KERN_ERR "KVM_WRITE:ESR not zero %x\n", val); | ||
| 813 | ret = 1; | ||
| 814 | } | ||
| 815 | break; | ||
| 816 | |||
| 817 | case APIC_SELF_IPI: | ||
| 818 | if (apic_x2apic_mode(apic)) { | ||
| 819 | apic_reg_write(apic, APIC_ICR, 0x40000 | (val & 0xff)); | ||
| 820 | } else | ||
| 821 | ret = 1; | ||
| 822 | break; | ||
| 715 | default: | 823 | default: |
| 716 | apic_debug("Local APIC Write to read-only register %x\n", | 824 | ret = 1; |
| 717 | offset); | ||
| 718 | break; | 825 | break; |
| 719 | } | 826 | } |
| 720 | 827 | if (ret) | |
| 828 | apic_debug("Local APIC Write to read-only register %x\n", reg); | ||
| 829 | return ret; | ||
| 721 | } | 830 | } |
| 722 | 831 | ||
| 723 | static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr, | 832 | static int apic_mmio_write(struct kvm_io_device *this, |
| 724 | int len, int size) | 833 | gpa_t address, int len, const void *data) |
| 725 | { | 834 | { |
| 726 | struct kvm_lapic *apic = (struct kvm_lapic *)this->private; | 835 | struct kvm_lapic *apic = to_lapic(this); |
| 727 | int ret = 0; | 836 | unsigned int offset = address - apic->base_address; |
| 837 | u32 val; | ||
| 728 | 838 | ||
| 839 | if (!apic_mmio_in_range(apic, address)) | ||
| 840 | return -EOPNOTSUPP; | ||
| 729 | 841 | ||
| 730 | if (apic_hw_enabled(apic) && | 842 | /* |
| 731 | (addr >= apic->base_address) && | 843 | * APIC register must be aligned on 128-bits boundary. |
| 732 | (addr < (apic->base_address + LAPIC_MMIO_LENGTH))) | 844 | * 32/64/128 bits registers must be accessed thru 32 bits. |
| 733 | ret = 1; | 845 | * Refer SDM 8.4.1 |
| 846 | */ | ||
| 847 | if (len != 4 || (offset & 0xf)) { | ||
| 848 | /* Don't shout loud, $infamous_os would cause only noise. */ | ||
| 849 | apic_debug("apic write: bad size=%d %lx\n", len, (long)address); | ||
| 850 | return 0; | ||
| 851 | } | ||
| 734 | 852 | ||
| 735 | return ret; | 853 | val = *(u32*)data; |
| 854 | |||
| 855 | /* too common printing */ | ||
| 856 | if (offset != APIC_EOI) | ||
| 857 | apic_debug("%s: offset 0x%x with length 0x%x, and value is " | ||
| 858 | "0x%x\n", __func__, offset, len, val); | ||
| 859 | |||
| 860 | apic_reg_write(apic, offset & 0xff0, val); | ||
| 861 | |||
| 862 | return 0; | ||
| 736 | } | 863 | } |
| 737 | 864 | ||
| 738 | void kvm_free_lapic(struct kvm_vcpu *vcpu) | 865 | void kvm_free_lapic(struct kvm_vcpu *vcpu) |
| @@ -763,7 +890,6 @@ void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8) | |||
| 763 | apic_set_tpr(apic, ((cr8 & 0x0f) << 4) | 890 | apic_set_tpr(apic, ((cr8 & 0x0f) << 4) |
| 764 | | (apic_get_reg(apic, APIC_TASKPRI) & 4)); | 891 | | (apic_get_reg(apic, APIC_TASKPRI) & 4)); |
| 765 | } | 892 | } |
| 766 | EXPORT_SYMBOL_GPL(kvm_lapic_set_tpr); | ||
| 767 | 893 | ||
| 768 | u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu) | 894 | u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu) |
| 769 | { | 895 | { |
| @@ -776,7 +902,6 @@ u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu) | |||
| 776 | 902 | ||
| 777 | return (tpr & 0xf0) >> 4; | 903 | return (tpr & 0xf0) >> 4; |
| 778 | } | 904 | } |
| 779 | EXPORT_SYMBOL_GPL(kvm_lapic_get_cr8); | ||
| 780 | 905 | ||
| 781 | void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) | 906 | void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) |
| 782 | { | 907 | { |
| @@ -787,10 +912,16 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) | |||
| 787 | vcpu->arch.apic_base = value; | 912 | vcpu->arch.apic_base = value; |
| 788 | return; | 913 | return; |
| 789 | } | 914 | } |
| 790 | if (apic->vcpu->vcpu_id) | 915 | |
| 916 | if (!kvm_vcpu_is_bsp(apic->vcpu)) | ||
| 791 | value &= ~MSR_IA32_APICBASE_BSP; | 917 | value &= ~MSR_IA32_APICBASE_BSP; |
| 792 | 918 | ||
| 793 | vcpu->arch.apic_base = value; | 919 | vcpu->arch.apic_base = value; |
| 920 | if (apic_x2apic_mode(apic)) { | ||
| 921 | u32 id = kvm_apic_id(apic); | ||
| 922 | u32 ldr = ((id & ~0xf) << 16) | (1 << (id & 0xf)); | ||
| 923 | apic_set_reg(apic, APIC_LDR, ldr); | ||
| 924 | } | ||
| 794 | apic->base_address = apic->vcpu->arch.apic_base & | 925 | apic->base_address = apic->vcpu->arch.apic_base & |
| 795 | MSR_IA32_APICBASE_BASE; | 926 | MSR_IA32_APICBASE_BASE; |
| 796 | 927 | ||
| @@ -800,12 +931,6 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) | |||
| 800 | 931 | ||
| 801 | } | 932 | } |
| 802 | 933 | ||
| 803 | u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu) | ||
| 804 | { | ||
| 805 | return vcpu->arch.apic_base; | ||
| 806 | } | ||
| 807 | EXPORT_SYMBOL_GPL(kvm_lapic_get_base); | ||
| 808 | |||
| 809 | void kvm_lapic_reset(struct kvm_vcpu *vcpu) | 934 | void kvm_lapic_reset(struct kvm_vcpu *vcpu) |
| 810 | { | 935 | { |
| 811 | struct kvm_lapic *apic; | 936 | struct kvm_lapic *apic; |
| @@ -821,7 +946,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) | |||
| 821 | hrtimer_cancel(&apic->lapic_timer.timer); | 946 | hrtimer_cancel(&apic->lapic_timer.timer); |
| 822 | 947 | ||
| 823 | apic_set_reg(apic, APIC_ID, vcpu->vcpu_id << 24); | 948 | apic_set_reg(apic, APIC_ID, vcpu->vcpu_id << 24); |
| 824 | apic_set_reg(apic, APIC_LVR, APIC_VERSION); | 949 | kvm_apic_set_version(apic->vcpu); |
| 825 | 950 | ||
| 826 | for (i = 0; i < APIC_LVT_NUM; i++) | 951 | for (i = 0; i < APIC_LVT_NUM; i++) |
| 827 | apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); | 952 | apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); |
| @@ -842,9 +967,10 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) | |||
| 842 | apic_set_reg(apic, APIC_ISR + 0x10 * i, 0); | 967 | apic_set_reg(apic, APIC_ISR + 0x10 * i, 0); |
| 843 | apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); | 968 | apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); |
| 844 | } | 969 | } |
| 970 | apic->irr_pending = false; | ||
| 845 | update_divide_count(apic); | 971 | update_divide_count(apic); |
| 846 | atomic_set(&apic->lapic_timer.pending, 0); | 972 | atomic_set(&apic->lapic_timer.pending, 0); |
| 847 | if (vcpu->vcpu_id == 0) | 973 | if (kvm_vcpu_is_bsp(vcpu)) |
| 848 | vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; | 974 | vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; |
| 849 | apic_update_ppr(apic); | 975 | apic_update_ppr(apic); |
| 850 | 976 | ||
| @@ -855,7 +981,6 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) | |||
| 855 | vcpu, kvm_apic_id(apic), | 981 | vcpu, kvm_apic_id(apic), |
| 856 | vcpu->arch.apic_base, apic->base_address); | 982 | vcpu->arch.apic_base, apic->base_address); |
| 857 | } | 983 | } |
| 858 | EXPORT_SYMBOL_GPL(kvm_lapic_reset); | ||
| 859 | 984 | ||
| 860 | bool kvm_apic_present(struct kvm_vcpu *vcpu) | 985 | bool kvm_apic_present(struct kvm_vcpu *vcpu) |
| 861 | { | 986 | { |
| @@ -866,7 +991,6 @@ int kvm_lapic_enabled(struct kvm_vcpu *vcpu) | |||
| 866 | { | 991 | { |
| 867 | return kvm_apic_present(vcpu) && apic_sw_enabled(vcpu->arch.apic); | 992 | return kvm_apic_present(vcpu) && apic_sw_enabled(vcpu->arch.apic); |
| 868 | } | 993 | } |
| 869 | EXPORT_SYMBOL_GPL(kvm_lapic_enabled); | ||
| 870 | 994 | ||
| 871 | /* | 995 | /* |
| 872 | *---------------------------------------------------------------------- | 996 | *---------------------------------------------------------------------- |
| @@ -917,6 +1041,11 @@ static struct kvm_timer_ops lapic_timer_ops = { | |||
| 917 | .is_periodic = lapic_is_periodic, | 1041 | .is_periodic = lapic_is_periodic, |
| 918 | }; | 1042 | }; |
| 919 | 1043 | ||
| 1044 | static const struct kvm_io_device_ops apic_mmio_ops = { | ||
| 1045 | .read = apic_mmio_read, | ||
| 1046 | .write = apic_mmio_write, | ||
| 1047 | }; | ||
| 1048 | |||
| 920 | int kvm_create_lapic(struct kvm_vcpu *vcpu) | 1049 | int kvm_create_lapic(struct kvm_vcpu *vcpu) |
| 921 | { | 1050 | { |
| 922 | struct kvm_lapic *apic; | 1051 | struct kvm_lapic *apic; |
| @@ -945,16 +1074,13 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu) | |||
| 945 | apic->lapic_timer.timer.function = kvm_timer_fn; | 1074 | apic->lapic_timer.timer.function = kvm_timer_fn; |
| 946 | apic->lapic_timer.t_ops = &lapic_timer_ops; | 1075 | apic->lapic_timer.t_ops = &lapic_timer_ops; |
| 947 | apic->lapic_timer.kvm = vcpu->kvm; | 1076 | apic->lapic_timer.kvm = vcpu->kvm; |
| 948 | apic->lapic_timer.vcpu_id = vcpu->vcpu_id; | 1077 | apic->lapic_timer.vcpu = vcpu; |
| 949 | 1078 | ||
| 950 | apic->base_address = APIC_DEFAULT_PHYS_BASE; | 1079 | apic->base_address = APIC_DEFAULT_PHYS_BASE; |
| 951 | vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE; | 1080 | vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE; |
| 952 | 1081 | ||
| 953 | kvm_lapic_reset(vcpu); | 1082 | kvm_lapic_reset(vcpu); |
| 954 | apic->dev.read = apic_mmio_read; | 1083 | kvm_iodevice_init(&apic->dev, &apic_mmio_ops); |
| 955 | apic->dev.write = apic_mmio_write; | ||
| 956 | apic->dev.in_range = apic_mmio_range; | ||
| 957 | apic->dev.private = apic; | ||
| 958 | 1084 | ||
| 959 | return 0; | 1085 | return 0; |
| 960 | nomem_free_apic: | 1086 | nomem_free_apic: |
| @@ -962,7 +1088,6 @@ nomem_free_apic: | |||
| 962 | nomem: | 1088 | nomem: |
| 963 | return -ENOMEM; | 1089 | return -ENOMEM; |
| 964 | } | 1090 | } |
| 965 | EXPORT_SYMBOL_GPL(kvm_create_lapic); | ||
| 966 | 1091 | ||
| 967 | int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu) | 1092 | int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu) |
| 968 | { | 1093 | { |
| @@ -985,7 +1110,7 @@ int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu) | |||
| 985 | u32 lvt0 = apic_get_reg(vcpu->arch.apic, APIC_LVT0); | 1110 | u32 lvt0 = apic_get_reg(vcpu->arch.apic, APIC_LVT0); |
| 986 | int r = 0; | 1111 | int r = 0; |
| 987 | 1112 | ||
| 988 | if (vcpu->vcpu_id == 0) { | 1113 | if (kvm_vcpu_is_bsp(vcpu)) { |
| 989 | if (!apic_hw_enabled(vcpu->arch.apic)) | 1114 | if (!apic_hw_enabled(vcpu->arch.apic)) |
| 990 | r = 1; | 1115 | r = 1; |
| 991 | if ((lvt0 & APIC_LVT_MASKED) == 0 && | 1116 | if ((lvt0 & APIC_LVT_MASKED) == 0 && |
| @@ -1025,7 +1150,8 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu) | |||
| 1025 | 1150 | ||
| 1026 | apic->base_address = vcpu->arch.apic_base & | 1151 | apic->base_address = vcpu->arch.apic_base & |
| 1027 | MSR_IA32_APICBASE_BASE; | 1152 | MSR_IA32_APICBASE_BASE; |
| 1028 | apic_set_reg(apic, APIC_LVR, APIC_VERSION); | 1153 | kvm_apic_set_version(vcpu); |
| 1154 | |||
| 1029 | apic_update_ppr(apic); | 1155 | apic_update_ppr(apic); |
| 1030 | hrtimer_cancel(&apic->lapic_timer.timer); | 1156 | hrtimer_cancel(&apic->lapic_timer.timer); |
| 1031 | update_divide_count(apic); | 1157 | update_divide_count(apic); |
| @@ -1092,3 +1218,35 @@ void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr) | |||
| 1092 | 1218 | ||
| 1093 | vcpu->arch.apic->vapic_addr = vapic_addr; | 1219 | vcpu->arch.apic->vapic_addr = vapic_addr; |
| 1094 | } | 1220 | } |
| 1221 | |||
| 1222 | int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data) | ||
| 1223 | { | ||
| 1224 | struct kvm_lapic *apic = vcpu->arch.apic; | ||
| 1225 | u32 reg = (msr - APIC_BASE_MSR) << 4; | ||
| 1226 | |||
| 1227 | if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic)) | ||
| 1228 | return 1; | ||
| 1229 | |||
| 1230 | /* if this is ICR write vector before command */ | ||
| 1231 | if (msr == 0x830) | ||
| 1232 | apic_reg_write(apic, APIC_ICR2, (u32)(data >> 32)); | ||
| 1233 | return apic_reg_write(apic, reg, (u32)data); | ||
| 1234 | } | ||
| 1235 | |||
| 1236 | int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data) | ||
| 1237 | { | ||
| 1238 | struct kvm_lapic *apic = vcpu->arch.apic; | ||
| 1239 | u32 reg = (msr - APIC_BASE_MSR) << 4, low, high = 0; | ||
| 1240 | |||
| 1241 | if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic)) | ||
| 1242 | return 1; | ||
| 1243 | |||
| 1244 | if (apic_reg_read(apic, reg, 4, &low)) | ||
| 1245 | return 1; | ||
| 1246 | if (msr == 0x830) | ||
| 1247 | apic_reg_read(apic, APIC_ICR2, 4, &high); | ||
| 1248 | |||
| 1249 | *data = (((u64)high) << 32) | low; | ||
| 1250 | |||
| 1251 | return 0; | ||
| 1252 | } | ||
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index a587f8349c46..40010b09c4aa 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h | |||
| @@ -12,6 +12,7 @@ struct kvm_lapic { | |||
| 12 | struct kvm_timer lapic_timer; | 12 | struct kvm_timer lapic_timer; |
| 13 | u32 divide_count; | 13 | u32 divide_count; |
| 14 | struct kvm_vcpu *vcpu; | 14 | struct kvm_vcpu *vcpu; |
| 15 | bool irr_pending; | ||
| 15 | struct page *regs_page; | 16 | struct page *regs_page; |
| 16 | void *regs; | 17 | void *regs; |
| 17 | gpa_t vapic_addr; | 18 | gpa_t vapic_addr; |
| @@ -28,6 +29,7 @@ u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu); | |||
| 28 | void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8); | 29 | void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8); |
| 29 | void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value); | 30 | void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value); |
| 30 | u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu); | 31 | u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu); |
| 32 | void kvm_apic_set_version(struct kvm_vcpu *vcpu); | ||
| 31 | 33 | ||
| 32 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); | 34 | int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); |
| 33 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); | 35 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); |
| @@ -44,4 +46,6 @@ void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); | |||
| 44 | void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu); | 46 | void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu); |
| 45 | void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu); | 47 | void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu); |
| 46 | 48 | ||
| 49 | int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data); | ||
| 50 | int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data); | ||
| 47 | #endif | 51 | #endif |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 0ef5bb2b4043..eca41ae9f453 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include "mmu.h" | 20 | #include "mmu.h" |
| 21 | #include "kvm_cache_regs.h" | ||
| 21 | 22 | ||
| 22 | #include <linux/kvm_host.h> | 23 | #include <linux/kvm_host.h> |
| 23 | #include <linux/types.h> | 24 | #include <linux/types.h> |
| @@ -107,6 +108,9 @@ module_param(oos_shadow, bool, 0644); | |||
| 107 | 108 | ||
| 108 | #define PT32_LEVEL_MASK(level) \ | 109 | #define PT32_LEVEL_MASK(level) \ |
| 109 | (((1ULL << PT32_LEVEL_BITS) - 1) << PT32_LEVEL_SHIFT(level)) | 110 | (((1ULL << PT32_LEVEL_BITS) - 1) << PT32_LEVEL_SHIFT(level)) |
| 111 | #define PT32_LVL_OFFSET_MASK(level) \ | ||
| 112 | (PT32_BASE_ADDR_MASK & ((1ULL << (PAGE_SHIFT + (((level) - 1) \ | ||
| 113 | * PT32_LEVEL_BITS))) - 1)) | ||
| 110 | 114 | ||
| 111 | #define PT32_INDEX(address, level)\ | 115 | #define PT32_INDEX(address, level)\ |
| 112 | (((address) >> PT32_LEVEL_SHIFT(level)) & ((1 << PT32_LEVEL_BITS) - 1)) | 116 | (((address) >> PT32_LEVEL_SHIFT(level)) & ((1 << PT32_LEVEL_BITS) - 1)) |
| @@ -115,10 +119,19 @@ module_param(oos_shadow, bool, 0644); | |||
| 115 | #define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1)) | 119 | #define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1)) |
| 116 | #define PT64_DIR_BASE_ADDR_MASK \ | 120 | #define PT64_DIR_BASE_ADDR_MASK \ |
| 117 | (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + PT64_LEVEL_BITS)) - 1)) | 121 | (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + PT64_LEVEL_BITS)) - 1)) |
| 122 | #define PT64_LVL_ADDR_MASK(level) \ | ||
| 123 | (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \ | ||
| 124 | * PT64_LEVEL_BITS))) - 1)) | ||
| 125 | #define PT64_LVL_OFFSET_MASK(level) \ | ||
| 126 | (PT64_BASE_ADDR_MASK & ((1ULL << (PAGE_SHIFT + (((level) - 1) \ | ||
| 127 | * PT64_LEVEL_BITS))) - 1)) | ||
| 118 | 128 | ||
| 119 | #define PT32_BASE_ADDR_MASK PAGE_MASK | 129 | #define PT32_BASE_ADDR_MASK PAGE_MASK |
| 120 | #define PT32_DIR_BASE_ADDR_MASK \ | 130 | #define PT32_DIR_BASE_ADDR_MASK \ |
| 121 | (PAGE_MASK & ~((1ULL << (PAGE_SHIFT + PT32_LEVEL_BITS)) - 1)) | 131 | (PAGE_MASK & ~((1ULL << (PAGE_SHIFT + PT32_LEVEL_BITS)) - 1)) |
| 132 | #define PT32_LVL_ADDR_MASK(level) \ | ||
| 133 | (PAGE_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \ | ||
| 134 | * PT32_LEVEL_BITS))) - 1)) | ||
| 122 | 135 | ||
| 123 | #define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \ | 136 | #define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \ |
| 124 | | PT64_NX_MASK) | 137 | | PT64_NX_MASK) |
| @@ -129,6 +142,7 @@ module_param(oos_shadow, bool, 0644); | |||
| 129 | #define PFERR_RSVD_MASK (1U << 3) | 142 | #define PFERR_RSVD_MASK (1U << 3) |
| 130 | #define PFERR_FETCH_MASK (1U << 4) | 143 | #define PFERR_FETCH_MASK (1U << 4) |
| 131 | 144 | ||
| 145 | #define PT_PDPE_LEVEL 3 | ||
| 132 | #define PT_DIRECTORY_LEVEL 2 | 146 | #define PT_DIRECTORY_LEVEL 2 |
| 133 | #define PT_PAGE_TABLE_LEVEL 1 | 147 | #define PT_PAGE_TABLE_LEVEL 1 |
| 134 | 148 | ||
| @@ -139,10 +153,13 @@ module_param(oos_shadow, bool, 0644); | |||
| 139 | #define ACC_USER_MASK PT_USER_MASK | 153 | #define ACC_USER_MASK PT_USER_MASK |
| 140 | #define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK) | 154 | #define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK) |
| 141 | 155 | ||
| 156 | #define CREATE_TRACE_POINTS | ||
| 157 | #include "mmutrace.h" | ||
| 158 | |||
| 142 | #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level) | 159 | #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level) |
| 143 | 160 | ||
| 144 | struct kvm_rmap_desc { | 161 | struct kvm_rmap_desc { |
| 145 | u64 *shadow_ptes[RMAP_EXT]; | 162 | u64 *sptes[RMAP_EXT]; |
| 146 | struct kvm_rmap_desc *more; | 163 | struct kvm_rmap_desc *more; |
| 147 | }; | 164 | }; |
| 148 | 165 | ||
| @@ -239,16 +256,25 @@ static int is_writeble_pte(unsigned long pte) | |||
| 239 | return pte & PT_WRITABLE_MASK; | 256 | return pte & PT_WRITABLE_MASK; |
| 240 | } | 257 | } |
| 241 | 258 | ||
| 242 | static int is_dirty_pte(unsigned long pte) | 259 | static int is_dirty_gpte(unsigned long pte) |
| 243 | { | 260 | { |
| 244 | return pte & shadow_dirty_mask; | 261 | return pte & PT_DIRTY_MASK; |
| 245 | } | 262 | } |
| 246 | 263 | ||
| 247 | static int is_rmap_pte(u64 pte) | 264 | static int is_rmap_spte(u64 pte) |
| 248 | { | 265 | { |
| 249 | return is_shadow_present_pte(pte); | 266 | return is_shadow_present_pte(pte); |
| 250 | } | 267 | } |
| 251 | 268 | ||
| 269 | static int is_last_spte(u64 pte, int level) | ||
| 270 | { | ||
| 271 | if (level == PT_PAGE_TABLE_LEVEL) | ||
| 272 | return 1; | ||
| 273 | if (is_large_pte(pte)) | ||
| 274 | return 1; | ||
| 275 | return 0; | ||
| 276 | } | ||
| 277 | |||
| 252 | static pfn_t spte_to_pfn(u64 pte) | 278 | static pfn_t spte_to_pfn(u64 pte) |
| 253 | { | 279 | { |
| 254 | return (pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; | 280 | return (pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; |
| @@ -261,7 +287,7 @@ static gfn_t pse36_gfn_delta(u32 gpte) | |||
| 261 | return (gpte & PT32_DIR_PSE36_MASK) << shift; | 287 | return (gpte & PT32_DIR_PSE36_MASK) << shift; |
| 262 | } | 288 | } |
| 263 | 289 | ||
| 264 | static void set_shadow_pte(u64 *sptep, u64 spte) | 290 | static void __set_spte(u64 *sptep, u64 spte) |
| 265 | { | 291 | { |
| 266 | #ifdef CONFIG_X86_64 | 292 | #ifdef CONFIG_X86_64 |
| 267 | set_64bit((unsigned long *)sptep, spte); | 293 | set_64bit((unsigned long *)sptep, spte); |
| @@ -380,37 +406,52 @@ static void mmu_free_rmap_desc(struct kvm_rmap_desc *rd) | |||
| 380 | * Return the pointer to the largepage write count for a given | 406 | * Return the pointer to the largepage write count for a given |
| 381 | * gfn, handling slots that are not large page aligned. | 407 | * gfn, handling slots that are not large page aligned. |
| 382 | */ | 408 | */ |
| 383 | static int *slot_largepage_idx(gfn_t gfn, struct kvm_memory_slot *slot) | 409 | static int *slot_largepage_idx(gfn_t gfn, |
| 410 | struct kvm_memory_slot *slot, | ||
| 411 | int level) | ||
| 384 | { | 412 | { |
| 385 | unsigned long idx; | 413 | unsigned long idx; |
| 386 | 414 | ||
| 387 | idx = (gfn / KVM_PAGES_PER_HPAGE) - | 415 | idx = (gfn / KVM_PAGES_PER_HPAGE(level)) - |
| 388 | (slot->base_gfn / KVM_PAGES_PER_HPAGE); | 416 | (slot->base_gfn / KVM_PAGES_PER_HPAGE(level)); |
| 389 | return &slot->lpage_info[idx].write_count; | 417 | return &slot->lpage_info[level - 2][idx].write_count; |
| 390 | } | 418 | } |
| 391 | 419 | ||
| 392 | static void account_shadowed(struct kvm *kvm, gfn_t gfn) | 420 | static void account_shadowed(struct kvm *kvm, gfn_t gfn) |
| 393 | { | 421 | { |
| 422 | struct kvm_memory_slot *slot; | ||
| 394 | int *write_count; | 423 | int *write_count; |
| 424 | int i; | ||
| 395 | 425 | ||
| 396 | gfn = unalias_gfn(kvm, gfn); | 426 | gfn = unalias_gfn(kvm, gfn); |
| 397 | write_count = slot_largepage_idx(gfn, | 427 | |
| 398 | gfn_to_memslot_unaliased(kvm, gfn)); | 428 | slot = gfn_to_memslot_unaliased(kvm, gfn); |
| 399 | *write_count += 1; | 429 | for (i = PT_DIRECTORY_LEVEL; |
| 430 | i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) { | ||
| 431 | write_count = slot_largepage_idx(gfn, slot, i); | ||
| 432 | *write_count += 1; | ||
| 433 | } | ||
| 400 | } | 434 | } |
| 401 | 435 | ||
| 402 | static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn) | 436 | static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn) |
| 403 | { | 437 | { |
| 438 | struct kvm_memory_slot *slot; | ||
| 404 | int *write_count; | 439 | int *write_count; |
| 440 | int i; | ||
| 405 | 441 | ||
| 406 | gfn = unalias_gfn(kvm, gfn); | 442 | gfn = unalias_gfn(kvm, gfn); |
| 407 | write_count = slot_largepage_idx(gfn, | 443 | for (i = PT_DIRECTORY_LEVEL; |
| 408 | gfn_to_memslot_unaliased(kvm, gfn)); | 444 | i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) { |
| 409 | *write_count -= 1; | 445 | slot = gfn_to_memslot_unaliased(kvm, gfn); |
| 410 | WARN_ON(*write_count < 0); | 446 | write_count = slot_largepage_idx(gfn, slot, i); |
| 447 | *write_count -= 1; | ||
| 448 | WARN_ON(*write_count < 0); | ||
| 449 | } | ||
| 411 | } | 450 | } |
| 412 | 451 | ||
| 413 | static int has_wrprotected_page(struct kvm *kvm, gfn_t gfn) | 452 | static int has_wrprotected_page(struct kvm *kvm, |
| 453 | gfn_t gfn, | ||
| 454 | int level) | ||
| 414 | { | 455 | { |
| 415 | struct kvm_memory_slot *slot; | 456 | struct kvm_memory_slot *slot; |
| 416 | int *largepage_idx; | 457 | int *largepage_idx; |
| @@ -418,47 +459,67 @@ static int has_wrprotected_page(struct kvm *kvm, gfn_t gfn) | |||
| 418 | gfn = unalias_gfn(kvm, gfn); | 459 | gfn = unalias_gfn(kvm, gfn); |
| 419 | slot = gfn_to_memslot_unaliased(kvm, gfn); | 460 | slot = gfn_to_memslot_unaliased(kvm, gfn); |
| 420 | if (slot) { | 461 | if (slot) { |
| 421 | largepage_idx = slot_largepage_idx(gfn, slot); | 462 | largepage_idx = slot_largepage_idx(gfn, slot, level); |
| 422 | return *largepage_idx; | 463 | return *largepage_idx; |
| 423 | } | 464 | } |
| 424 | 465 | ||
| 425 | return 1; | 466 | return 1; |
| 426 | } | 467 | } |
| 427 | 468 | ||
| 428 | static int host_largepage_backed(struct kvm *kvm, gfn_t gfn) | 469 | static int host_mapping_level(struct kvm *kvm, gfn_t gfn) |
| 429 | { | 470 | { |
| 471 | unsigned long page_size = PAGE_SIZE; | ||
| 430 | struct vm_area_struct *vma; | 472 | struct vm_area_struct *vma; |
| 431 | unsigned long addr; | 473 | unsigned long addr; |
| 432 | int ret = 0; | 474 | int i, ret = 0; |
| 433 | 475 | ||
| 434 | addr = gfn_to_hva(kvm, gfn); | 476 | addr = gfn_to_hva(kvm, gfn); |
| 435 | if (kvm_is_error_hva(addr)) | 477 | if (kvm_is_error_hva(addr)) |
| 436 | return ret; | 478 | return page_size; |
| 437 | 479 | ||
| 438 | down_read(¤t->mm->mmap_sem); | 480 | down_read(¤t->mm->mmap_sem); |
| 439 | vma = find_vma(current->mm, addr); | 481 | vma = find_vma(current->mm, addr); |
| 440 | if (vma && is_vm_hugetlb_page(vma)) | 482 | if (!vma) |
| 441 | ret = 1; | 483 | goto out; |
| 484 | |||
| 485 | page_size = vma_kernel_pagesize(vma); | ||
| 486 | |||
| 487 | out: | ||
| 442 | up_read(¤t->mm->mmap_sem); | 488 | up_read(¤t->mm->mmap_sem); |
| 443 | 489 | ||
| 490 | for (i = PT_PAGE_TABLE_LEVEL; | ||
| 491 | i < (PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES); ++i) { | ||
| 492 | if (page_size >= KVM_HPAGE_SIZE(i)) | ||
| 493 | ret = i; | ||
| 494 | else | ||
| 495 | break; | ||
| 496 | } | ||
| 497 | |||
| 444 | return ret; | 498 | return ret; |
| 445 | } | 499 | } |
| 446 | 500 | ||
| 447 | static int is_largepage_backed(struct kvm_vcpu *vcpu, gfn_t large_gfn) | 501 | static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn) |
| 448 | { | 502 | { |
| 449 | struct kvm_memory_slot *slot; | 503 | struct kvm_memory_slot *slot; |
| 450 | 504 | int host_level; | |
| 451 | if (has_wrprotected_page(vcpu->kvm, large_gfn)) | 505 | int level = PT_PAGE_TABLE_LEVEL; |
| 452 | return 0; | ||
| 453 | |||
| 454 | if (!host_largepage_backed(vcpu->kvm, large_gfn)) | ||
| 455 | return 0; | ||
| 456 | 506 | ||
| 457 | slot = gfn_to_memslot(vcpu->kvm, large_gfn); | 507 | slot = gfn_to_memslot(vcpu->kvm, large_gfn); |
| 458 | if (slot && slot->dirty_bitmap) | 508 | if (slot && slot->dirty_bitmap) |
| 459 | return 0; | 509 | return PT_PAGE_TABLE_LEVEL; |
| 460 | 510 | ||
| 461 | return 1; | 511 | host_level = host_mapping_level(vcpu->kvm, large_gfn); |
| 512 | |||
| 513 | if (host_level == PT_PAGE_TABLE_LEVEL) | ||
| 514 | return host_level; | ||
| 515 | |||
| 516 | for (level = PT_DIRECTORY_LEVEL; level <= host_level; ++level) { | ||
| 517 | |||
| 518 | if (has_wrprotected_page(vcpu->kvm, large_gfn, level)) | ||
| 519 | break; | ||
| 520 | } | ||
| 521 | |||
| 522 | return level - 1; | ||
| 462 | } | 523 | } |
| 463 | 524 | ||
| 464 | /* | 525 | /* |
| @@ -466,19 +527,19 @@ static int is_largepage_backed(struct kvm_vcpu *vcpu, gfn_t large_gfn) | |||
| 466 | * Note: gfn must be unaliased before this function get called | 527 | * Note: gfn must be unaliased before this function get called |
| 467 | */ | 528 | */ |
| 468 | 529 | ||
| 469 | static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int lpage) | 530 | static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int level) |
| 470 | { | 531 | { |
| 471 | struct kvm_memory_slot *slot; | 532 | struct kvm_memory_slot *slot; |
| 472 | unsigned long idx; | 533 | unsigned long idx; |
| 473 | 534 | ||
| 474 | slot = gfn_to_memslot(kvm, gfn); | 535 | slot = gfn_to_memslot(kvm, gfn); |
| 475 | if (!lpage) | 536 | if (likely(level == PT_PAGE_TABLE_LEVEL)) |
| 476 | return &slot->rmap[gfn - slot->base_gfn]; | 537 | return &slot->rmap[gfn - slot->base_gfn]; |
| 477 | 538 | ||
| 478 | idx = (gfn / KVM_PAGES_PER_HPAGE) - | 539 | idx = (gfn / KVM_PAGES_PER_HPAGE(level)) - |
| 479 | (slot->base_gfn / KVM_PAGES_PER_HPAGE); | 540 | (slot->base_gfn / KVM_PAGES_PER_HPAGE(level)); |
| 480 | 541 | ||
| 481 | return &slot->lpage_info[idx].rmap_pde; | 542 | return &slot->lpage_info[level - 2][idx].rmap_pde; |
| 482 | } | 543 | } |
| 483 | 544 | ||
| 484 | /* | 545 | /* |
| @@ -494,42 +555,42 @@ static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int lpage) | |||
| 494 | * the spte was not added. | 555 | * the spte was not added. |
| 495 | * | 556 | * |
| 496 | */ | 557 | */ |
| 497 | static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn, int lpage) | 558 | static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn) |
| 498 | { | 559 | { |
| 499 | struct kvm_mmu_page *sp; | 560 | struct kvm_mmu_page *sp; |
| 500 | struct kvm_rmap_desc *desc; | 561 | struct kvm_rmap_desc *desc; |
| 501 | unsigned long *rmapp; | 562 | unsigned long *rmapp; |
| 502 | int i, count = 0; | 563 | int i, count = 0; |
| 503 | 564 | ||
| 504 | if (!is_rmap_pte(*spte)) | 565 | if (!is_rmap_spte(*spte)) |
| 505 | return count; | 566 | return count; |
| 506 | gfn = unalias_gfn(vcpu->kvm, gfn); | 567 | gfn = unalias_gfn(vcpu->kvm, gfn); |
| 507 | sp = page_header(__pa(spte)); | 568 | sp = page_header(__pa(spte)); |
| 508 | sp->gfns[spte - sp->spt] = gfn; | 569 | sp->gfns[spte - sp->spt] = gfn; |
| 509 | rmapp = gfn_to_rmap(vcpu->kvm, gfn, lpage); | 570 | rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level); |
| 510 | if (!*rmapp) { | 571 | if (!*rmapp) { |
| 511 | rmap_printk("rmap_add: %p %llx 0->1\n", spte, *spte); | 572 | rmap_printk("rmap_add: %p %llx 0->1\n", spte, *spte); |
| 512 | *rmapp = (unsigned long)spte; | 573 | *rmapp = (unsigned long)spte; |
| 513 | } else if (!(*rmapp & 1)) { | 574 | } else if (!(*rmapp & 1)) { |
| 514 | rmap_printk("rmap_add: %p %llx 1->many\n", spte, *spte); | 575 | rmap_printk("rmap_add: %p %llx 1->many\n", spte, *spte); |
| 515 | desc = mmu_alloc_rmap_desc(vcpu); | 576 | desc = mmu_alloc_rmap_desc(vcpu); |
| 516 | desc->shadow_ptes[0] = (u64 *)*rmapp; | 577 | desc->sptes[0] = (u64 *)*rmapp; |
| 517 | desc->shadow_ptes[1] = spte; | 578 | desc->sptes[1] = spte; |
| 518 | *rmapp = (unsigned long)desc | 1; | 579 | *rmapp = (unsigned long)desc | 1; |
| 519 | } else { | 580 | } else { |
| 520 | rmap_printk("rmap_add: %p %llx many->many\n", spte, *spte); | 581 | rmap_printk("rmap_add: %p %llx many->many\n", spte, *spte); |
| 521 | desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul); | 582 | desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul); |
| 522 | while (desc->shadow_ptes[RMAP_EXT-1] && desc->more) { | 583 | while (desc->sptes[RMAP_EXT-1] && desc->more) { |
| 523 | desc = desc->more; | 584 | desc = desc->more; |
| 524 | count += RMAP_EXT; | 585 | count += RMAP_EXT; |
| 525 | } | 586 | } |
| 526 | if (desc->shadow_ptes[RMAP_EXT-1]) { | 587 | if (desc->sptes[RMAP_EXT-1]) { |
| 527 | desc->more = mmu_alloc_rmap_desc(vcpu); | 588 | desc->more = mmu_alloc_rmap_desc(vcpu); |
| 528 | desc = desc->more; | 589 | desc = desc->more; |
| 529 | } | 590 | } |
| 530 | for (i = 0; desc->shadow_ptes[i]; ++i) | 591 | for (i = 0; desc->sptes[i]; ++i) |
| 531 | ; | 592 | ; |
| 532 | desc->shadow_ptes[i] = spte; | 593 | desc->sptes[i] = spte; |
| 533 | } | 594 | } |
| 534 | return count; | 595 | return count; |
| 535 | } | 596 | } |
| @@ -541,14 +602,14 @@ static void rmap_desc_remove_entry(unsigned long *rmapp, | |||
| 541 | { | 602 | { |
| 542 | int j; | 603 | int j; |
| 543 | 604 | ||
| 544 | for (j = RMAP_EXT - 1; !desc->shadow_ptes[j] && j > i; --j) | 605 | for (j = RMAP_EXT - 1; !desc->sptes[j] && j > i; --j) |
| 545 | ; | 606 | ; |
| 546 | desc->shadow_ptes[i] = desc->shadow_ptes[j]; | 607 | desc->sptes[i] = desc->sptes[j]; |
| 547 | desc->shadow_ptes[j] = NULL; | 608 | desc->sptes[j] = NULL; |
| 548 | if (j != 0) | 609 | if (j != 0) |
| 549 | return; | 610 | return; |
| 550 | if (!prev_desc && !desc->more) | 611 | if (!prev_desc && !desc->more) |
| 551 | *rmapp = (unsigned long)desc->shadow_ptes[0]; | 612 | *rmapp = (unsigned long)desc->sptes[0]; |
| 552 | else | 613 | else |
| 553 | if (prev_desc) | 614 | if (prev_desc) |
| 554 | prev_desc->more = desc->more; | 615 | prev_desc->more = desc->more; |
| @@ -566,7 +627,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte) | |||
| 566 | unsigned long *rmapp; | 627 | unsigned long *rmapp; |
| 567 | int i; | 628 | int i; |
| 568 | 629 | ||
| 569 | if (!is_rmap_pte(*spte)) | 630 | if (!is_rmap_spte(*spte)) |
| 570 | return; | 631 | return; |
| 571 | sp = page_header(__pa(spte)); | 632 | sp = page_header(__pa(spte)); |
| 572 | pfn = spte_to_pfn(*spte); | 633 | pfn = spte_to_pfn(*spte); |
| @@ -576,7 +637,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte) | |||
| 576 | kvm_release_pfn_dirty(pfn); | 637 | kvm_release_pfn_dirty(pfn); |
| 577 | else | 638 | else |
| 578 | kvm_release_pfn_clean(pfn); | 639 | kvm_release_pfn_clean(pfn); |
| 579 | rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt], is_large_pte(*spte)); | 640 | rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt], sp->role.level); |
| 580 | if (!*rmapp) { | 641 | if (!*rmapp) { |
| 581 | printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte); | 642 | printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte); |
| 582 | BUG(); | 643 | BUG(); |
| @@ -593,8 +654,8 @@ static void rmap_remove(struct kvm *kvm, u64 *spte) | |||
| 593 | desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul); | 654 | desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul); |
| 594 | prev_desc = NULL; | 655 | prev_desc = NULL; |
| 595 | while (desc) { | 656 | while (desc) { |
| 596 | for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i) | 657 | for (i = 0; i < RMAP_EXT && desc->sptes[i]; ++i) |
| 597 | if (desc->shadow_ptes[i] == spte) { | 658 | if (desc->sptes[i] == spte) { |
| 598 | rmap_desc_remove_entry(rmapp, | 659 | rmap_desc_remove_entry(rmapp, |
| 599 | desc, i, | 660 | desc, i, |
| 600 | prev_desc); | 661 | prev_desc); |
| @@ -625,10 +686,10 @@ static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte) | |||
| 625 | prev_desc = NULL; | 686 | prev_desc = NULL; |
| 626 | prev_spte = NULL; | 687 | prev_spte = NULL; |
| 627 | while (desc) { | 688 | while (desc) { |
| 628 | for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i) { | 689 | for (i = 0; i < RMAP_EXT && desc->sptes[i]; ++i) { |
| 629 | if (prev_spte == spte) | 690 | if (prev_spte == spte) |
| 630 | return desc->shadow_ptes[i]; | 691 | return desc->sptes[i]; |
| 631 | prev_spte = desc->shadow_ptes[i]; | 692 | prev_spte = desc->sptes[i]; |
| 632 | } | 693 | } |
| 633 | desc = desc->more; | 694 | desc = desc->more; |
| 634 | } | 695 | } |
| @@ -639,10 +700,10 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn) | |||
| 639 | { | 700 | { |
| 640 | unsigned long *rmapp; | 701 | unsigned long *rmapp; |
| 641 | u64 *spte; | 702 | u64 *spte; |
| 642 | int write_protected = 0; | 703 | int i, write_protected = 0; |
| 643 | 704 | ||
| 644 | gfn = unalias_gfn(kvm, gfn); | 705 | gfn = unalias_gfn(kvm, gfn); |
| 645 | rmapp = gfn_to_rmap(kvm, gfn, 0); | 706 | rmapp = gfn_to_rmap(kvm, gfn, PT_PAGE_TABLE_LEVEL); |
| 646 | 707 | ||
| 647 | spte = rmap_next(kvm, rmapp, NULL); | 708 | spte = rmap_next(kvm, rmapp, NULL); |
| 648 | while (spte) { | 709 | while (spte) { |
| @@ -650,7 +711,7 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn) | |||
| 650 | BUG_ON(!(*spte & PT_PRESENT_MASK)); | 711 | BUG_ON(!(*spte & PT_PRESENT_MASK)); |
| 651 | rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte); | 712 | rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte); |
| 652 | if (is_writeble_pte(*spte)) { | 713 | if (is_writeble_pte(*spte)) { |
| 653 | set_shadow_pte(spte, *spte & ~PT_WRITABLE_MASK); | 714 | __set_spte(spte, *spte & ~PT_WRITABLE_MASK); |
| 654 | write_protected = 1; | 715 | write_protected = 1; |
| 655 | } | 716 | } |
| 656 | spte = rmap_next(kvm, rmapp, spte); | 717 | spte = rmap_next(kvm, rmapp, spte); |
| @@ -664,21 +725,24 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn) | |||
| 664 | } | 725 | } |
| 665 | 726 | ||
| 666 | /* check for huge page mappings */ | 727 | /* check for huge page mappings */ |
| 667 | rmapp = gfn_to_rmap(kvm, gfn, 1); | 728 | for (i = PT_DIRECTORY_LEVEL; |
| 668 | spte = rmap_next(kvm, rmapp, NULL); | 729 | i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) { |
| 669 | while (spte) { | 730 | rmapp = gfn_to_rmap(kvm, gfn, i); |
| 670 | BUG_ON(!spte); | 731 | spte = rmap_next(kvm, rmapp, NULL); |
| 671 | BUG_ON(!(*spte & PT_PRESENT_MASK)); | 732 | while (spte) { |
| 672 | BUG_ON((*spte & (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)) != (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)); | 733 | BUG_ON(!spte); |
| 673 | pgprintk("rmap_write_protect(large): spte %p %llx %lld\n", spte, *spte, gfn); | 734 | BUG_ON(!(*spte & PT_PRESENT_MASK)); |
| 674 | if (is_writeble_pte(*spte)) { | 735 | BUG_ON((*spte & (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)) != (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)); |
| 675 | rmap_remove(kvm, spte); | 736 | pgprintk("rmap_write_protect(large): spte %p %llx %lld\n", spte, *spte, gfn); |
| 676 | --kvm->stat.lpages; | 737 | if (is_writeble_pte(*spte)) { |
| 677 | set_shadow_pte(spte, shadow_trap_nonpresent_pte); | 738 | rmap_remove(kvm, spte); |
| 678 | spte = NULL; | 739 | --kvm->stat.lpages; |
| 679 | write_protected = 1; | 740 | __set_spte(spte, shadow_trap_nonpresent_pte); |
| 741 | spte = NULL; | ||
| 742 | write_protected = 1; | ||
| 743 | } | ||
| 744 | spte = rmap_next(kvm, rmapp, spte); | ||
| 680 | } | 745 | } |
| 681 | spte = rmap_next(kvm, rmapp, spte); | ||
| 682 | } | 746 | } |
| 683 | 747 | ||
| 684 | return write_protected; | 748 | return write_protected; |
| @@ -693,7 +757,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp) | |||
| 693 | BUG_ON(!(*spte & PT_PRESENT_MASK)); | 757 | BUG_ON(!(*spte & PT_PRESENT_MASK)); |
| 694 | rmap_printk("kvm_rmap_unmap_hva: spte %p %llx\n", spte, *spte); | 758 | rmap_printk("kvm_rmap_unmap_hva: spte %p %llx\n", spte, *spte); |
| 695 | rmap_remove(kvm, spte); | 759 | rmap_remove(kvm, spte); |
| 696 | set_shadow_pte(spte, shadow_trap_nonpresent_pte); | 760 | __set_spte(spte, shadow_trap_nonpresent_pte); |
| 697 | need_tlb_flush = 1; | 761 | need_tlb_flush = 1; |
| 698 | } | 762 | } |
| 699 | return need_tlb_flush; | 763 | return need_tlb_flush; |
| @@ -702,7 +766,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp) | |||
| 702 | static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, | 766 | static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, |
| 703 | int (*handler)(struct kvm *kvm, unsigned long *rmapp)) | 767 | int (*handler)(struct kvm *kvm, unsigned long *rmapp)) |
| 704 | { | 768 | { |
| 705 | int i; | 769 | int i, j; |
| 706 | int retval = 0; | 770 | int retval = 0; |
| 707 | 771 | ||
| 708 | /* | 772 | /* |
| @@ -721,11 +785,15 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, | |||
| 721 | end = start + (memslot->npages << PAGE_SHIFT); | 785 | end = start + (memslot->npages << PAGE_SHIFT); |
| 722 | if (hva >= start && hva < end) { | 786 | if (hva >= start && hva < end) { |
| 723 | gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT; | 787 | gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT; |
| 788 | |||
| 724 | retval |= handler(kvm, &memslot->rmap[gfn_offset]); | 789 | retval |= handler(kvm, &memslot->rmap[gfn_offset]); |
| 725 | retval |= handler(kvm, | 790 | |
| 726 | &memslot->lpage_info[ | 791 | for (j = 0; j < KVM_NR_PAGE_SIZES - 1; ++j) { |
| 727 | gfn_offset / | 792 | int idx = gfn_offset; |
| 728 | KVM_PAGES_PER_HPAGE].rmap_pde); | 793 | idx /= KVM_PAGES_PER_HPAGE(PT_DIRECTORY_LEVEL + j); |
| 794 | retval |= handler(kvm, | ||
| 795 | &memslot->lpage_info[j][idx].rmap_pde); | ||
| 796 | } | ||
| 729 | } | 797 | } |
| 730 | } | 798 | } |
| 731 | 799 | ||
| @@ -763,12 +831,15 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp) | |||
| 763 | 831 | ||
| 764 | #define RMAP_RECYCLE_THRESHOLD 1000 | 832 | #define RMAP_RECYCLE_THRESHOLD 1000 |
| 765 | 833 | ||
| 766 | static void rmap_recycle(struct kvm_vcpu *vcpu, gfn_t gfn, int lpage) | 834 | static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn) |
| 767 | { | 835 | { |
| 768 | unsigned long *rmapp; | 836 | unsigned long *rmapp; |
| 837 | struct kvm_mmu_page *sp; | ||
| 838 | |||
| 839 | sp = page_header(__pa(spte)); | ||
| 769 | 840 | ||
| 770 | gfn = unalias_gfn(vcpu->kvm, gfn); | 841 | gfn = unalias_gfn(vcpu->kvm, gfn); |
| 771 | rmapp = gfn_to_rmap(vcpu->kvm, gfn, lpage); | 842 | rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level); |
| 772 | 843 | ||
| 773 | kvm_unmap_rmapp(vcpu->kvm, rmapp); | 844 | kvm_unmap_rmapp(vcpu->kvm, rmapp); |
| 774 | kvm_flush_remote_tlbs(vcpu->kvm); | 845 | kvm_flush_remote_tlbs(vcpu->kvm); |
| @@ -1109,6 +1180,7 @@ static int kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) | |||
| 1109 | return 1; | 1180 | return 1; |
| 1110 | } | 1181 | } |
| 1111 | 1182 | ||
| 1183 | trace_kvm_mmu_sync_page(sp); | ||
| 1112 | if (rmap_write_protect(vcpu->kvm, sp->gfn)) | 1184 | if (rmap_write_protect(vcpu->kvm, sp->gfn)) |
| 1113 | kvm_flush_remote_tlbs(vcpu->kvm); | 1185 | kvm_flush_remote_tlbs(vcpu->kvm); |
| 1114 | kvm_unlink_unsync_page(vcpu->kvm, sp); | 1186 | kvm_unlink_unsync_page(vcpu->kvm, sp); |
| @@ -1231,8 +1303,6 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, | |||
| 1231 | quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1; | 1303 | quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1; |
| 1232 | role.quadrant = quadrant; | 1304 | role.quadrant = quadrant; |
| 1233 | } | 1305 | } |
| 1234 | pgprintk("%s: looking gfn %lx role %x\n", __func__, | ||
| 1235 | gfn, role.word); | ||
| 1236 | index = kvm_page_table_hashfn(gfn); | 1306 | index = kvm_page_table_hashfn(gfn); |
| 1237 | bucket = &vcpu->kvm->arch.mmu_page_hash[index]; | 1307 | bucket = &vcpu->kvm->arch.mmu_page_hash[index]; |
| 1238 | hlist_for_each_entry_safe(sp, node, tmp, bucket, hash_link) | 1308 | hlist_for_each_entry_safe(sp, node, tmp, bucket, hash_link) |
| @@ -1249,14 +1319,13 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, | |||
| 1249 | set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests); | 1319 | set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests); |
| 1250 | kvm_mmu_mark_parents_unsync(vcpu, sp); | 1320 | kvm_mmu_mark_parents_unsync(vcpu, sp); |
| 1251 | } | 1321 | } |
| 1252 | pgprintk("%s: found\n", __func__); | 1322 | trace_kvm_mmu_get_page(sp, false); |
| 1253 | return sp; | 1323 | return sp; |
| 1254 | } | 1324 | } |
| 1255 | ++vcpu->kvm->stat.mmu_cache_miss; | 1325 | ++vcpu->kvm->stat.mmu_cache_miss; |
| 1256 | sp = kvm_mmu_alloc_page(vcpu, parent_pte); | 1326 | sp = kvm_mmu_alloc_page(vcpu, parent_pte); |
| 1257 | if (!sp) | 1327 | if (!sp) |
| 1258 | return sp; | 1328 | return sp; |
| 1259 | pgprintk("%s: adding gfn %lx role %x\n", __func__, gfn, role.word); | ||
| 1260 | sp->gfn = gfn; | 1329 | sp->gfn = gfn; |
| 1261 | sp->role = role; | 1330 | sp->role = role; |
| 1262 | hlist_add_head(&sp->hash_link, bucket); | 1331 | hlist_add_head(&sp->hash_link, bucket); |
| @@ -1269,6 +1338,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, | |||
| 1269 | vcpu->arch.mmu.prefetch_page(vcpu, sp); | 1338 | vcpu->arch.mmu.prefetch_page(vcpu, sp); |
| 1270 | else | 1339 | else |
| 1271 | nonpaging_prefetch_page(vcpu, sp); | 1340 | nonpaging_prefetch_page(vcpu, sp); |
| 1341 | trace_kvm_mmu_get_page(sp, true); | ||
| 1272 | return sp; | 1342 | return sp; |
| 1273 | } | 1343 | } |
| 1274 | 1344 | ||
| @@ -1292,6 +1362,11 @@ static bool shadow_walk_okay(struct kvm_shadow_walk_iterator *iterator) | |||
| 1292 | { | 1362 | { |
| 1293 | if (iterator->level < PT_PAGE_TABLE_LEVEL) | 1363 | if (iterator->level < PT_PAGE_TABLE_LEVEL) |
| 1294 | return false; | 1364 | return false; |
| 1365 | |||
| 1366 | if (iterator->level == PT_PAGE_TABLE_LEVEL) | ||
| 1367 | if (is_large_pte(*iterator->sptep)) | ||
| 1368 | return false; | ||
| 1369 | |||
| 1295 | iterator->index = SHADOW_PT_INDEX(iterator->addr, iterator->level); | 1370 | iterator->index = SHADOW_PT_INDEX(iterator->addr, iterator->level); |
| 1296 | iterator->sptep = ((u64 *)__va(iterator->shadow_addr)) + iterator->index; | 1371 | iterator->sptep = ((u64 *)__va(iterator->shadow_addr)) + iterator->index; |
| 1297 | return true; | 1372 | return true; |
| @@ -1312,25 +1387,17 @@ static void kvm_mmu_page_unlink_children(struct kvm *kvm, | |||
| 1312 | 1387 | ||
| 1313 | pt = sp->spt; | 1388 | pt = sp->spt; |
| 1314 | 1389 | ||
| 1315 | if (sp->role.level == PT_PAGE_TABLE_LEVEL) { | ||
| 1316 | for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { | ||
| 1317 | if (is_shadow_present_pte(pt[i])) | ||
| 1318 | rmap_remove(kvm, &pt[i]); | ||
| 1319 | pt[i] = shadow_trap_nonpresent_pte; | ||
| 1320 | } | ||
| 1321 | return; | ||
| 1322 | } | ||
| 1323 | |||
| 1324 | for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { | 1390 | for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { |
| 1325 | ent = pt[i]; | 1391 | ent = pt[i]; |
| 1326 | 1392 | ||
| 1327 | if (is_shadow_present_pte(ent)) { | 1393 | if (is_shadow_present_pte(ent)) { |
| 1328 | if (!is_large_pte(ent)) { | 1394 | if (!is_last_spte(ent, sp->role.level)) { |
| 1329 | ent &= PT64_BASE_ADDR_MASK; | 1395 | ent &= PT64_BASE_ADDR_MASK; |
| 1330 | mmu_page_remove_parent_pte(page_header(ent), | 1396 | mmu_page_remove_parent_pte(page_header(ent), |
| 1331 | &pt[i]); | 1397 | &pt[i]); |
| 1332 | } else { | 1398 | } else { |
| 1333 | --kvm->stat.lpages; | 1399 | if (is_large_pte(ent)) |
| 1400 | --kvm->stat.lpages; | ||
| 1334 | rmap_remove(kvm, &pt[i]); | 1401 | rmap_remove(kvm, &pt[i]); |
| 1335 | } | 1402 | } |
| 1336 | } | 1403 | } |
| @@ -1346,10 +1413,10 @@ static void kvm_mmu_put_page(struct kvm_mmu_page *sp, u64 *parent_pte) | |||
| 1346 | static void kvm_mmu_reset_last_pte_updated(struct kvm *kvm) | 1413 | static void kvm_mmu_reset_last_pte_updated(struct kvm *kvm) |
| 1347 | { | 1414 | { |
| 1348 | int i; | 1415 | int i; |
| 1416 | struct kvm_vcpu *vcpu; | ||
| 1349 | 1417 | ||
| 1350 | for (i = 0; i < KVM_MAX_VCPUS; ++i) | 1418 | kvm_for_each_vcpu(i, vcpu, kvm) |
| 1351 | if (kvm->vcpus[i]) | 1419 | vcpu->arch.last_pte_updated = NULL; |
| 1352 | kvm->vcpus[i]->arch.last_pte_updated = NULL; | ||
| 1353 | } | 1420 | } |
| 1354 | 1421 | ||
| 1355 | static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp) | 1422 | static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp) |
| @@ -1368,7 +1435,7 @@ static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp) | |||
| 1368 | } | 1435 | } |
| 1369 | BUG_ON(!parent_pte); | 1436 | BUG_ON(!parent_pte); |
| 1370 | kvm_mmu_put_page(sp, parent_pte); | 1437 | kvm_mmu_put_page(sp, parent_pte); |
| 1371 | set_shadow_pte(parent_pte, shadow_trap_nonpresent_pte); | 1438 | __set_spte(parent_pte, shadow_trap_nonpresent_pte); |
| 1372 | } | 1439 | } |
| 1373 | } | 1440 | } |
| 1374 | 1441 | ||
| @@ -1400,6 +1467,8 @@ static int mmu_zap_unsync_children(struct kvm *kvm, | |||
| 1400 | static int kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp) | 1467 | static int kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp) |
| 1401 | { | 1468 | { |
| 1402 | int ret; | 1469 | int ret; |
| 1470 | |||
| 1471 | trace_kvm_mmu_zap_page(sp); | ||
| 1403 | ++kvm->stat.mmu_shadow_zapped; | 1472 | ++kvm->stat.mmu_shadow_zapped; |
| 1404 | ret = mmu_zap_unsync_children(kvm, sp); | 1473 | ret = mmu_zap_unsync_children(kvm, sp); |
| 1405 | kvm_mmu_page_unlink_children(kvm, sp); | 1474 | kvm_mmu_page_unlink_children(kvm, sp); |
| @@ -1516,7 +1585,7 @@ static void mmu_convert_notrap(struct kvm_mmu_page *sp) | |||
| 1516 | 1585 | ||
| 1517 | for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { | 1586 | for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { |
| 1518 | if (pt[i] == shadow_notrap_nonpresent_pte) | 1587 | if (pt[i] == shadow_notrap_nonpresent_pte) |
| 1519 | set_shadow_pte(&pt[i], shadow_trap_nonpresent_pte); | 1588 | __set_spte(&pt[i], shadow_trap_nonpresent_pte); |
| 1520 | } | 1589 | } |
| 1521 | } | 1590 | } |
| 1522 | 1591 | ||
| @@ -1646,6 +1715,7 @@ static int kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) | |||
| 1646 | struct kvm_mmu_page *s; | 1715 | struct kvm_mmu_page *s; |
| 1647 | struct hlist_node *node, *n; | 1716 | struct hlist_node *node, *n; |
| 1648 | 1717 | ||
| 1718 | trace_kvm_mmu_unsync_page(sp); | ||
| 1649 | index = kvm_page_table_hashfn(sp->gfn); | 1719 | index = kvm_page_table_hashfn(sp->gfn); |
| 1650 | bucket = &vcpu->kvm->arch.mmu_page_hash[index]; | 1720 | bucket = &vcpu->kvm->arch.mmu_page_hash[index]; |
| 1651 | /* don't unsync if pagetable is shadowed with multiple roles */ | 1721 | /* don't unsync if pagetable is shadowed with multiple roles */ |
| @@ -1682,9 +1752,9 @@ static int mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn, | |||
| 1682 | return 0; | 1752 | return 0; |
| 1683 | } | 1753 | } |
| 1684 | 1754 | ||
| 1685 | static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, | 1755 | static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, |
| 1686 | unsigned pte_access, int user_fault, | 1756 | unsigned pte_access, int user_fault, |
| 1687 | int write_fault, int dirty, int largepage, | 1757 | int write_fault, int dirty, int level, |
| 1688 | gfn_t gfn, pfn_t pfn, bool speculative, | 1758 | gfn_t gfn, pfn_t pfn, bool speculative, |
| 1689 | bool can_unsync) | 1759 | bool can_unsync) |
| 1690 | { | 1760 | { |
| @@ -1707,7 +1777,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, | |||
| 1707 | spte |= shadow_nx_mask; | 1777 | spte |= shadow_nx_mask; |
| 1708 | if (pte_access & ACC_USER_MASK) | 1778 | if (pte_access & ACC_USER_MASK) |
| 1709 | spte |= shadow_user_mask; | 1779 | spte |= shadow_user_mask; |
| 1710 | if (largepage) | 1780 | if (level > PT_PAGE_TABLE_LEVEL) |
| 1711 | spte |= PT_PAGE_SIZE_MASK; | 1781 | spte |= PT_PAGE_SIZE_MASK; |
| 1712 | if (tdp_enabled) | 1782 | if (tdp_enabled) |
| 1713 | spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn, | 1783 | spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn, |
| @@ -1718,7 +1788,8 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, | |||
| 1718 | if ((pte_access & ACC_WRITE_MASK) | 1788 | if ((pte_access & ACC_WRITE_MASK) |
| 1719 | || (write_fault && !is_write_protection(vcpu) && !user_fault)) { | 1789 | || (write_fault && !is_write_protection(vcpu) && !user_fault)) { |
| 1720 | 1790 | ||
| 1721 | if (largepage && has_wrprotected_page(vcpu->kvm, gfn)) { | 1791 | if (level > PT_PAGE_TABLE_LEVEL && |
| 1792 | has_wrprotected_page(vcpu->kvm, gfn, level)) { | ||
| 1722 | ret = 1; | 1793 | ret = 1; |
| 1723 | spte = shadow_trap_nonpresent_pte; | 1794 | spte = shadow_trap_nonpresent_pte; |
| 1724 | goto set_pte; | 1795 | goto set_pte; |
| @@ -1732,7 +1803,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, | |||
| 1732 | * is responsibility of mmu_get_page / kvm_sync_page. | 1803 | * is responsibility of mmu_get_page / kvm_sync_page. |
| 1733 | * Same reasoning can be applied to dirty page accounting. | 1804 | * Same reasoning can be applied to dirty page accounting. |
| 1734 | */ | 1805 | */ |
| 1735 | if (!can_unsync && is_writeble_pte(*shadow_pte)) | 1806 | if (!can_unsync && is_writeble_pte(*sptep)) |
| 1736 | goto set_pte; | 1807 | goto set_pte; |
| 1737 | 1808 | ||
| 1738 | if (mmu_need_write_protect(vcpu, gfn, can_unsync)) { | 1809 | if (mmu_need_write_protect(vcpu, gfn, can_unsync)) { |
| @@ -1749,65 +1820,67 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, | |||
| 1749 | mark_page_dirty(vcpu->kvm, gfn); | 1820 | mark_page_dirty(vcpu->kvm, gfn); |
| 1750 | 1821 | ||
| 1751 | set_pte: | 1822 | set_pte: |
| 1752 | set_shadow_pte(shadow_pte, spte); | 1823 | __set_spte(sptep, spte); |
| 1753 | return ret; | 1824 | return ret; |
| 1754 | } | 1825 | } |
| 1755 | 1826 | ||
| 1756 | static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, | 1827 | static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep, |
| 1757 | unsigned pt_access, unsigned pte_access, | 1828 | unsigned pt_access, unsigned pte_access, |
| 1758 | int user_fault, int write_fault, int dirty, | 1829 | int user_fault, int write_fault, int dirty, |
| 1759 | int *ptwrite, int largepage, gfn_t gfn, | 1830 | int *ptwrite, int level, gfn_t gfn, |
| 1760 | pfn_t pfn, bool speculative) | 1831 | pfn_t pfn, bool speculative) |
| 1761 | { | 1832 | { |
| 1762 | int was_rmapped = 0; | 1833 | int was_rmapped = 0; |
| 1763 | int was_writeble = is_writeble_pte(*shadow_pte); | 1834 | int was_writeble = is_writeble_pte(*sptep); |
| 1764 | int rmap_count; | 1835 | int rmap_count; |
| 1765 | 1836 | ||
| 1766 | pgprintk("%s: spte %llx access %x write_fault %d" | 1837 | pgprintk("%s: spte %llx access %x write_fault %d" |
| 1767 | " user_fault %d gfn %lx\n", | 1838 | " user_fault %d gfn %lx\n", |
| 1768 | __func__, *shadow_pte, pt_access, | 1839 | __func__, *sptep, pt_access, |
| 1769 | write_fault, user_fault, gfn); | 1840 | write_fault, user_fault, gfn); |
| 1770 | 1841 | ||
| 1771 | if (is_rmap_pte(*shadow_pte)) { | 1842 | if (is_rmap_spte(*sptep)) { |
| 1772 | /* | 1843 | /* |
| 1773 | * If we overwrite a PTE page pointer with a 2MB PMD, unlink | 1844 | * If we overwrite a PTE page pointer with a 2MB PMD, unlink |
| 1774 | * the parent of the now unreachable PTE. | 1845 | * the parent of the now unreachable PTE. |
| 1775 | */ | 1846 | */ |
| 1776 | if (largepage && !is_large_pte(*shadow_pte)) { | 1847 | if (level > PT_PAGE_TABLE_LEVEL && |
| 1848 | !is_large_pte(*sptep)) { | ||
| 1777 | struct kvm_mmu_page *child; | 1849 | struct kvm_mmu_page *child; |
| 1778 | u64 pte = *shadow_pte; | 1850 | u64 pte = *sptep; |
| 1779 | 1851 | ||
| 1780 | child = page_header(pte & PT64_BASE_ADDR_MASK); | 1852 | child = page_header(pte & PT64_BASE_ADDR_MASK); |
| 1781 | mmu_page_remove_parent_pte(child, shadow_pte); | 1853 | mmu_page_remove_parent_pte(child, sptep); |
| 1782 | } else if (pfn != spte_to_pfn(*shadow_pte)) { | 1854 | } else if (pfn != spte_to_pfn(*sptep)) { |
| 1783 | pgprintk("hfn old %lx new %lx\n", | 1855 | pgprintk("hfn old %lx new %lx\n", |
| 1784 | spte_to_pfn(*shadow_pte), pfn); | 1856 | spte_to_pfn(*sptep), pfn); |
| 1785 | rmap_remove(vcpu->kvm, shadow_pte); | 1857 | rmap_remove(vcpu->kvm, sptep); |
| 1786 | } else | 1858 | } else |
| 1787 | was_rmapped = 1; | 1859 | was_rmapped = 1; |
| 1788 | } | 1860 | } |
| 1789 | if (set_spte(vcpu, shadow_pte, pte_access, user_fault, write_fault, | 1861 | |
| 1790 | dirty, largepage, gfn, pfn, speculative, true)) { | 1862 | if (set_spte(vcpu, sptep, pte_access, user_fault, write_fault, |
| 1863 | dirty, level, gfn, pfn, speculative, true)) { | ||
| 1791 | if (write_fault) | 1864 | if (write_fault) |
| 1792 | *ptwrite = 1; | 1865 | *ptwrite = 1; |
| 1793 | kvm_x86_ops->tlb_flush(vcpu); | 1866 | kvm_x86_ops->tlb_flush(vcpu); |
| 1794 | } | 1867 | } |
| 1795 | 1868 | ||
| 1796 | pgprintk("%s: setting spte %llx\n", __func__, *shadow_pte); | 1869 | pgprintk("%s: setting spte %llx\n", __func__, *sptep); |
| 1797 | pgprintk("instantiating %s PTE (%s) at %ld (%llx) addr %p\n", | 1870 | pgprintk("instantiating %s PTE (%s) at %ld (%llx) addr %p\n", |
| 1798 | is_large_pte(*shadow_pte)? "2MB" : "4kB", | 1871 | is_large_pte(*sptep)? "2MB" : "4kB", |
| 1799 | is_present_pte(*shadow_pte)?"RW":"R", gfn, | 1872 | *sptep & PT_PRESENT_MASK ?"RW":"R", gfn, |
| 1800 | *shadow_pte, shadow_pte); | 1873 | *sptep, sptep); |
| 1801 | if (!was_rmapped && is_large_pte(*shadow_pte)) | 1874 | if (!was_rmapped && is_large_pte(*sptep)) |
| 1802 | ++vcpu->kvm->stat.lpages; | 1875 | ++vcpu->kvm->stat.lpages; |
| 1803 | 1876 | ||
| 1804 | page_header_update_slot(vcpu->kvm, shadow_pte, gfn); | 1877 | page_header_update_slot(vcpu->kvm, sptep, gfn); |
| 1805 | if (!was_rmapped) { | 1878 | if (!was_rmapped) { |
| 1806 | rmap_count = rmap_add(vcpu, shadow_pte, gfn, largepage); | 1879 | rmap_count = rmap_add(vcpu, sptep, gfn); |
| 1807 | if (!is_rmap_pte(*shadow_pte)) | 1880 | if (!is_rmap_spte(*sptep)) |
| 1808 | kvm_release_pfn_clean(pfn); | 1881 | kvm_release_pfn_clean(pfn); |
| 1809 | if (rmap_count > RMAP_RECYCLE_THRESHOLD) | 1882 | if (rmap_count > RMAP_RECYCLE_THRESHOLD) |
| 1810 | rmap_recycle(vcpu, gfn, largepage); | 1883 | rmap_recycle(vcpu, sptep, gfn); |
| 1811 | } else { | 1884 | } else { |
| 1812 | if (was_writeble) | 1885 | if (was_writeble) |
| 1813 | kvm_release_pfn_dirty(pfn); | 1886 | kvm_release_pfn_dirty(pfn); |
| @@ -1815,7 +1888,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, | |||
| 1815 | kvm_release_pfn_clean(pfn); | 1888 | kvm_release_pfn_clean(pfn); |
| 1816 | } | 1889 | } |
| 1817 | if (speculative) { | 1890 | if (speculative) { |
| 1818 | vcpu->arch.last_pte_updated = shadow_pte; | 1891 | vcpu->arch.last_pte_updated = sptep; |
| 1819 | vcpu->arch.last_pte_gfn = gfn; | 1892 | vcpu->arch.last_pte_gfn = gfn; |
| 1820 | } | 1893 | } |
| 1821 | } | 1894 | } |
| @@ -1825,7 +1898,7 @@ static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) | |||
| 1825 | } | 1898 | } |
| 1826 | 1899 | ||
| 1827 | static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, | 1900 | static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, |
| 1828 | int largepage, gfn_t gfn, pfn_t pfn) | 1901 | int level, gfn_t gfn, pfn_t pfn) |
| 1829 | { | 1902 | { |
| 1830 | struct kvm_shadow_walk_iterator iterator; | 1903 | struct kvm_shadow_walk_iterator iterator; |
| 1831 | struct kvm_mmu_page *sp; | 1904 | struct kvm_mmu_page *sp; |
| @@ -1833,11 +1906,10 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, | |||
| 1833 | gfn_t pseudo_gfn; | 1906 | gfn_t pseudo_gfn; |
| 1834 | 1907 | ||
| 1835 | for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) { | 1908 | for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) { |
| 1836 | if (iterator.level == PT_PAGE_TABLE_LEVEL | 1909 | if (iterator.level == level) { |
| 1837 | || (largepage && iterator.level == PT_DIRECTORY_LEVEL)) { | ||
| 1838 | mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL, | 1910 | mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL, |
| 1839 | 0, write, 1, &pt_write, | 1911 | 0, write, 1, &pt_write, |
| 1840 | largepage, gfn, pfn, false); | 1912 | level, gfn, pfn, false); |
| 1841 | ++vcpu->stat.pf_fixed; | 1913 | ++vcpu->stat.pf_fixed; |
| 1842 | break; | 1914 | break; |
| 1843 | } | 1915 | } |
| @@ -1853,10 +1925,10 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, | |||
| 1853 | return -ENOMEM; | 1925 | return -ENOMEM; |
| 1854 | } | 1926 | } |
| 1855 | 1927 | ||
| 1856 | set_shadow_pte(iterator.sptep, | 1928 | __set_spte(iterator.sptep, |
| 1857 | __pa(sp->spt) | 1929 | __pa(sp->spt) |
| 1858 | | PT_PRESENT_MASK | PT_WRITABLE_MASK | 1930 | | PT_PRESENT_MASK | PT_WRITABLE_MASK |
| 1859 | | shadow_user_mask | shadow_x_mask); | 1931 | | shadow_user_mask | shadow_x_mask); |
| 1860 | } | 1932 | } |
| 1861 | } | 1933 | } |
| 1862 | return pt_write; | 1934 | return pt_write; |
| @@ -1865,14 +1937,20 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, | |||
| 1865 | static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn) | 1937 | static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn) |
| 1866 | { | 1938 | { |
| 1867 | int r; | 1939 | int r; |
| 1868 | int largepage = 0; | 1940 | int level; |
| 1869 | pfn_t pfn; | 1941 | pfn_t pfn; |
| 1870 | unsigned long mmu_seq; | 1942 | unsigned long mmu_seq; |
| 1871 | 1943 | ||
| 1872 | if (is_largepage_backed(vcpu, gfn & ~(KVM_PAGES_PER_HPAGE-1))) { | 1944 | level = mapping_level(vcpu, gfn); |
| 1873 | gfn &= ~(KVM_PAGES_PER_HPAGE-1); | 1945 | |
| 1874 | largepage = 1; | 1946 | /* |
| 1875 | } | 1947 | * This path builds a PAE pagetable - so we can map 2mb pages at |
| 1948 | * maximum. Therefore check if the level is larger than that. | ||
| 1949 | */ | ||
| 1950 | if (level > PT_DIRECTORY_LEVEL) | ||
| 1951 | level = PT_DIRECTORY_LEVEL; | ||
| 1952 | |||
| 1953 | gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1); | ||
| 1876 | 1954 | ||
| 1877 | mmu_seq = vcpu->kvm->mmu_notifier_seq; | 1955 | mmu_seq = vcpu->kvm->mmu_notifier_seq; |
| 1878 | smp_rmb(); | 1956 | smp_rmb(); |
| @@ -1888,7 +1966,7 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn) | |||
| 1888 | if (mmu_notifier_retry(vcpu, mmu_seq)) | 1966 | if (mmu_notifier_retry(vcpu, mmu_seq)) |
| 1889 | goto out_unlock; | 1967 | goto out_unlock; |
| 1890 | kvm_mmu_free_some_pages(vcpu); | 1968 | kvm_mmu_free_some_pages(vcpu); |
| 1891 | r = __direct_map(vcpu, v, write, largepage, gfn, pfn); | 1969 | r = __direct_map(vcpu, v, write, level, gfn, pfn); |
| 1892 | spin_unlock(&vcpu->kvm->mmu_lock); | 1970 | spin_unlock(&vcpu->kvm->mmu_lock); |
| 1893 | 1971 | ||
| 1894 | 1972 | ||
| @@ -1954,6 +2032,7 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu) | |||
| 1954 | gfn_t root_gfn; | 2032 | gfn_t root_gfn; |
| 1955 | struct kvm_mmu_page *sp; | 2033 | struct kvm_mmu_page *sp; |
| 1956 | int direct = 0; | 2034 | int direct = 0; |
| 2035 | u64 pdptr; | ||
| 1957 | 2036 | ||
| 1958 | root_gfn = vcpu->arch.cr3 >> PAGE_SHIFT; | 2037 | root_gfn = vcpu->arch.cr3 >> PAGE_SHIFT; |
| 1959 | 2038 | ||
| @@ -1981,11 +2060,12 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu) | |||
| 1981 | 2060 | ||
| 1982 | ASSERT(!VALID_PAGE(root)); | 2061 | ASSERT(!VALID_PAGE(root)); |
| 1983 | if (vcpu->arch.mmu.root_level == PT32E_ROOT_LEVEL) { | 2062 | if (vcpu->arch.mmu.root_level == PT32E_ROOT_LEVEL) { |
| 1984 | if (!is_present_pte(vcpu->arch.pdptrs[i])) { | 2063 | pdptr = kvm_pdptr_read(vcpu, i); |
| 2064 | if (!is_present_gpte(pdptr)) { | ||
| 1985 | vcpu->arch.mmu.pae_root[i] = 0; | 2065 | vcpu->arch.mmu.pae_root[i] = 0; |
| 1986 | continue; | 2066 | continue; |
| 1987 | } | 2067 | } |
| 1988 | root_gfn = vcpu->arch.pdptrs[i] >> PAGE_SHIFT; | 2068 | root_gfn = pdptr >> PAGE_SHIFT; |
| 1989 | } else if (vcpu->arch.mmu.root_level == 0) | 2069 | } else if (vcpu->arch.mmu.root_level == 0) |
| 1990 | root_gfn = 0; | 2070 | root_gfn = 0; |
| 1991 | if (mmu_check_root(vcpu, root_gfn)) | 2071 | if (mmu_check_root(vcpu, root_gfn)) |
| @@ -2062,7 +2142,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, | |||
| 2062 | { | 2142 | { |
| 2063 | pfn_t pfn; | 2143 | pfn_t pfn; |
| 2064 | int r; | 2144 | int r; |
| 2065 | int largepage = 0; | 2145 | int level; |
| 2066 | gfn_t gfn = gpa >> PAGE_SHIFT; | 2146 | gfn_t gfn = gpa >> PAGE_SHIFT; |
| 2067 | unsigned long mmu_seq; | 2147 | unsigned long mmu_seq; |
| 2068 | 2148 | ||
| @@ -2073,10 +2153,10 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, | |||
| 2073 | if (r) | 2153 | if (r) |
| 2074 | return r; | 2154 | return r; |
| 2075 | 2155 | ||
| 2076 | if (is_largepage_backed(vcpu, gfn & ~(KVM_PAGES_PER_HPAGE-1))) { | 2156 | level = mapping_level(vcpu, gfn); |
| 2077 | gfn &= ~(KVM_PAGES_PER_HPAGE-1); | 2157 | |
| 2078 | largepage = 1; | 2158 | gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1); |
| 2079 | } | 2159 | |
| 2080 | mmu_seq = vcpu->kvm->mmu_notifier_seq; | 2160 | mmu_seq = vcpu->kvm->mmu_notifier_seq; |
| 2081 | smp_rmb(); | 2161 | smp_rmb(); |
| 2082 | pfn = gfn_to_pfn(vcpu->kvm, gfn); | 2162 | pfn = gfn_to_pfn(vcpu->kvm, gfn); |
| @@ -2089,7 +2169,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, | |||
| 2089 | goto out_unlock; | 2169 | goto out_unlock; |
| 2090 | kvm_mmu_free_some_pages(vcpu); | 2170 | kvm_mmu_free_some_pages(vcpu); |
| 2091 | r = __direct_map(vcpu, gpa, error_code & PFERR_WRITE_MASK, | 2171 | r = __direct_map(vcpu, gpa, error_code & PFERR_WRITE_MASK, |
| 2092 | largepage, gfn, pfn); | 2172 | level, gfn, pfn); |
| 2093 | spin_unlock(&vcpu->kvm->mmu_lock); | 2173 | spin_unlock(&vcpu->kvm->mmu_lock); |
| 2094 | 2174 | ||
| 2095 | return r; | 2175 | return r; |
| @@ -2206,7 +2286,9 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) | |||
| 2206 | context->rsvd_bits_mask[0][0] = exb_bit_rsvd | | 2286 | context->rsvd_bits_mask[0][0] = exb_bit_rsvd | |
| 2207 | rsvd_bits(maxphyaddr, 51); | 2287 | rsvd_bits(maxphyaddr, 51); |
| 2208 | context->rsvd_bits_mask[1][3] = context->rsvd_bits_mask[0][3]; | 2288 | context->rsvd_bits_mask[1][3] = context->rsvd_bits_mask[0][3]; |
| 2209 | context->rsvd_bits_mask[1][2] = context->rsvd_bits_mask[0][2]; | 2289 | context->rsvd_bits_mask[1][2] = exb_bit_rsvd | |
| 2290 | rsvd_bits(maxphyaddr, 51) | | ||
| 2291 | rsvd_bits(13, 29); | ||
| 2210 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | | 2292 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | |
| 2211 | rsvd_bits(maxphyaddr, 51) | | 2293 | rsvd_bits(maxphyaddr, 51) | |
| 2212 | rsvd_bits(13, 20); /* large page */ | 2294 | rsvd_bits(13, 20); /* large page */ |
| @@ -2357,8 +2439,8 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu) | |||
| 2357 | spin_unlock(&vcpu->kvm->mmu_lock); | 2439 | spin_unlock(&vcpu->kvm->mmu_lock); |
| 2358 | if (r) | 2440 | if (r) |
| 2359 | goto out; | 2441 | goto out; |
| 2442 | /* set_cr3() should ensure TLB has been flushed */ | ||
| 2360 | kvm_x86_ops->set_cr3(vcpu, vcpu->arch.mmu.root_hpa); | 2443 | kvm_x86_ops->set_cr3(vcpu, vcpu->arch.mmu.root_hpa); |
| 2361 | kvm_mmu_flush_tlb(vcpu); | ||
| 2362 | out: | 2444 | out: |
| 2363 | return r; | 2445 | return r; |
| 2364 | } | 2446 | } |
| @@ -2378,15 +2460,14 @@ static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu, | |||
| 2378 | 2460 | ||
| 2379 | pte = *spte; | 2461 | pte = *spte; |
| 2380 | if (is_shadow_present_pte(pte)) { | 2462 | if (is_shadow_present_pte(pte)) { |
| 2381 | if (sp->role.level == PT_PAGE_TABLE_LEVEL || | 2463 | if (is_last_spte(pte, sp->role.level)) |
| 2382 | is_large_pte(pte)) | ||
| 2383 | rmap_remove(vcpu->kvm, spte); | 2464 | rmap_remove(vcpu->kvm, spte); |
| 2384 | else { | 2465 | else { |
| 2385 | child = page_header(pte & PT64_BASE_ADDR_MASK); | 2466 | child = page_header(pte & PT64_BASE_ADDR_MASK); |
| 2386 | mmu_page_remove_parent_pte(child, spte); | 2467 | mmu_page_remove_parent_pte(child, spte); |
| 2387 | } | 2468 | } |
| 2388 | } | 2469 | } |
| 2389 | set_shadow_pte(spte, shadow_trap_nonpresent_pte); | 2470 | __set_spte(spte, shadow_trap_nonpresent_pte); |
| 2390 | if (is_large_pte(pte)) | 2471 | if (is_large_pte(pte)) |
| 2391 | --vcpu->kvm->stat.lpages; | 2472 | --vcpu->kvm->stat.lpages; |
| 2392 | } | 2473 | } |
| @@ -2397,11 +2478,8 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu, | |||
| 2397 | const void *new) | 2478 | const void *new) |
| 2398 | { | 2479 | { |
| 2399 | if (sp->role.level != PT_PAGE_TABLE_LEVEL) { | 2480 | if (sp->role.level != PT_PAGE_TABLE_LEVEL) { |
| 2400 | if (!vcpu->arch.update_pte.largepage || | 2481 | ++vcpu->kvm->stat.mmu_pde_zapped; |
| 2401 | sp->role.glevels == PT32_ROOT_LEVEL) { | 2482 | return; |
| 2402 | ++vcpu->kvm->stat.mmu_pde_zapped; | ||
| 2403 | return; | ||
| 2404 | } | ||
| 2405 | } | 2483 | } |
| 2406 | 2484 | ||
| 2407 | ++vcpu->kvm->stat.mmu_pte_updated; | 2485 | ++vcpu->kvm->stat.mmu_pte_updated; |
| @@ -2447,8 +2525,6 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
| 2447 | u64 gpte = 0; | 2525 | u64 gpte = 0; |
| 2448 | pfn_t pfn; | 2526 | pfn_t pfn; |
| 2449 | 2527 | ||
| 2450 | vcpu->arch.update_pte.largepage = 0; | ||
| 2451 | |||
| 2452 | if (bytes != 4 && bytes != 8) | 2528 | if (bytes != 4 && bytes != 8) |
| 2453 | return; | 2529 | return; |
| 2454 | 2530 | ||
| @@ -2472,14 +2548,10 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
| 2472 | if ((bytes == 4) && (gpa % 4 == 0)) | 2548 | if ((bytes == 4) && (gpa % 4 == 0)) |
| 2473 | memcpy((void *)&gpte, new, 4); | 2549 | memcpy((void *)&gpte, new, 4); |
| 2474 | } | 2550 | } |
| 2475 | if (!is_present_pte(gpte)) | 2551 | if (!is_present_gpte(gpte)) |
| 2476 | return; | 2552 | return; |
| 2477 | gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; | 2553 | gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; |
| 2478 | 2554 | ||
| 2479 | if (is_large_pte(gpte) && is_largepage_backed(vcpu, gfn)) { | ||
| 2480 | gfn &= ~(KVM_PAGES_PER_HPAGE-1); | ||
| 2481 | vcpu->arch.update_pte.largepage = 1; | ||
| 2482 | } | ||
| 2483 | vcpu->arch.update_pte.mmu_seq = vcpu->kvm->mmu_notifier_seq; | 2555 | vcpu->arch.update_pte.mmu_seq = vcpu->kvm->mmu_notifier_seq; |
| 2484 | smp_rmb(); | 2556 | smp_rmb(); |
| 2485 | pfn = gfn_to_pfn(vcpu->kvm, gfn); | 2557 | pfn = gfn_to_pfn(vcpu->kvm, gfn); |
| @@ -2622,6 +2694,9 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva) | |||
| 2622 | gpa_t gpa; | 2694 | gpa_t gpa; |
| 2623 | int r; | 2695 | int r; |
| 2624 | 2696 | ||
| 2697 | if (tdp_enabled) | ||
| 2698 | return 0; | ||
| 2699 | |||
| 2625 | gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva); | 2700 | gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva); |
| 2626 | 2701 | ||
| 2627 | spin_lock(&vcpu->kvm->mmu_lock); | 2702 | spin_lock(&vcpu->kvm->mmu_lock); |
| @@ -2633,7 +2708,8 @@ EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page_virt); | |||
| 2633 | 2708 | ||
| 2634 | void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) | 2709 | void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) |
| 2635 | { | 2710 | { |
| 2636 | while (vcpu->kvm->arch.n_free_mmu_pages < KVM_REFILL_PAGES) { | 2711 | while (vcpu->kvm->arch.n_free_mmu_pages < KVM_REFILL_PAGES && |
| 2712 | !list_empty(&vcpu->kvm->arch.active_mmu_pages)) { | ||
| 2637 | struct kvm_mmu_page *sp; | 2713 | struct kvm_mmu_page *sp; |
| 2638 | 2714 | ||
| 2639 | sp = container_of(vcpu->kvm->arch.active_mmu_pages.prev, | 2715 | sp = container_of(vcpu->kvm->arch.active_mmu_pages.prev, |
| @@ -2670,8 +2746,9 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code) | |||
| 2670 | ++vcpu->stat.mmio_exits; | 2746 | ++vcpu->stat.mmio_exits; |
| 2671 | return 0; | 2747 | return 0; |
| 2672 | case EMULATE_FAIL: | 2748 | case EMULATE_FAIL: |
| 2673 | kvm_report_emulation_failure(vcpu, "pagetable"); | 2749 | vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; |
| 2674 | return 1; | 2750 | vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; |
| 2751 | return 0; | ||
| 2675 | default: | 2752 | default: |
| 2676 | BUG(); | 2753 | BUG(); |
| 2677 | } | 2754 | } |
| @@ -2712,12 +2789,6 @@ static int alloc_mmu_pages(struct kvm_vcpu *vcpu) | |||
| 2712 | 2789 | ||
| 2713 | ASSERT(vcpu); | 2790 | ASSERT(vcpu); |
| 2714 | 2791 | ||
| 2715 | if (vcpu->kvm->arch.n_requested_mmu_pages) | ||
| 2716 | vcpu->kvm->arch.n_free_mmu_pages = | ||
| 2717 | vcpu->kvm->arch.n_requested_mmu_pages; | ||
| 2718 | else | ||
| 2719 | vcpu->kvm->arch.n_free_mmu_pages = | ||
| 2720 | vcpu->kvm->arch.n_alloc_mmu_pages; | ||
| 2721 | /* | 2792 | /* |
| 2722 | * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64. | 2793 | * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64. |
| 2723 | * Therefore we need to allocate shadow page tables in the first | 2794 | * Therefore we need to allocate shadow page tables in the first |
| @@ -3029,6 +3100,24 @@ out: | |||
| 3029 | return r; | 3100 | return r; |
| 3030 | } | 3101 | } |
| 3031 | 3102 | ||
| 3103 | int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]) | ||
| 3104 | { | ||
| 3105 | struct kvm_shadow_walk_iterator iterator; | ||
| 3106 | int nr_sptes = 0; | ||
| 3107 | |||
| 3108 | spin_lock(&vcpu->kvm->mmu_lock); | ||
| 3109 | for_each_shadow_entry(vcpu, addr, iterator) { | ||
| 3110 | sptes[iterator.level-1] = *iterator.sptep; | ||
| 3111 | nr_sptes++; | ||
| 3112 | if (!is_shadow_present_pte(*iterator.sptep)) | ||
| 3113 | break; | ||
| 3114 | } | ||
| 3115 | spin_unlock(&vcpu->kvm->mmu_lock); | ||
| 3116 | |||
| 3117 | return nr_sptes; | ||
| 3118 | } | ||
| 3119 | EXPORT_SYMBOL_GPL(kvm_mmu_get_spte_hierarchy); | ||
| 3120 | |||
| 3032 | #ifdef AUDIT | 3121 | #ifdef AUDIT |
| 3033 | 3122 | ||
| 3034 | static const char *audit_msg; | 3123 | static const char *audit_msg; |
| @@ -3041,6 +3130,54 @@ static gva_t canonicalize(gva_t gva) | |||
| 3041 | return gva; | 3130 | return gva; |
| 3042 | } | 3131 | } |
| 3043 | 3132 | ||
| 3133 | |||
| 3134 | typedef void (*inspect_spte_fn) (struct kvm *kvm, struct kvm_mmu_page *sp, | ||
| 3135 | u64 *sptep); | ||
| 3136 | |||
| 3137 | static void __mmu_spte_walk(struct kvm *kvm, struct kvm_mmu_page *sp, | ||
| 3138 | inspect_spte_fn fn) | ||
| 3139 | { | ||
| 3140 | int i; | ||
| 3141 | |||
| 3142 | for (i = 0; i < PT64_ENT_PER_PAGE; ++i) { | ||
| 3143 | u64 ent = sp->spt[i]; | ||
| 3144 | |||
| 3145 | if (is_shadow_present_pte(ent)) { | ||
| 3146 | if (!is_last_spte(ent, sp->role.level)) { | ||
| 3147 | struct kvm_mmu_page *child; | ||
| 3148 | child = page_header(ent & PT64_BASE_ADDR_MASK); | ||
| 3149 | __mmu_spte_walk(kvm, child, fn); | ||
| 3150 | } else | ||
| 3151 | fn(kvm, sp, &sp->spt[i]); | ||
| 3152 | } | ||
| 3153 | } | ||
| 3154 | } | ||
| 3155 | |||
| 3156 | static void mmu_spte_walk(struct kvm_vcpu *vcpu, inspect_spte_fn fn) | ||
| 3157 | { | ||
| 3158 | int i; | ||
| 3159 | struct kvm_mmu_page *sp; | ||
| 3160 | |||
| 3161 | if (!VALID_PAGE(vcpu->arch.mmu.root_hpa)) | ||
| 3162 | return; | ||
| 3163 | if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) { | ||
| 3164 | hpa_t root = vcpu->arch.mmu.root_hpa; | ||
| 3165 | sp = page_header(root); | ||
| 3166 | __mmu_spte_walk(vcpu->kvm, sp, fn); | ||
| 3167 | return; | ||
| 3168 | } | ||
| 3169 | for (i = 0; i < 4; ++i) { | ||
| 3170 | hpa_t root = vcpu->arch.mmu.pae_root[i]; | ||
| 3171 | |||
| 3172 | if (root && VALID_PAGE(root)) { | ||
| 3173 | root &= PT64_BASE_ADDR_MASK; | ||
| 3174 | sp = page_header(root); | ||
| 3175 | __mmu_spte_walk(vcpu->kvm, sp, fn); | ||
| 3176 | } | ||
| 3177 | } | ||
| 3178 | return; | ||
| 3179 | } | ||
| 3180 | |||
| 3044 | static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte, | 3181 | static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte, |
| 3045 | gva_t va, int level) | 3182 | gva_t va, int level) |
| 3046 | { | 3183 | { |
| @@ -3055,20 +3192,19 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte, | |||
| 3055 | continue; | 3192 | continue; |
| 3056 | 3193 | ||
| 3057 | va = canonicalize(va); | 3194 | va = canonicalize(va); |
| 3058 | if (level > 1) { | 3195 | if (is_shadow_present_pte(ent) && !is_last_spte(ent, level)) |
| 3059 | if (ent == shadow_notrap_nonpresent_pte) | 3196 | audit_mappings_page(vcpu, ent, va, level - 1); |
| 3060 | printk(KERN_ERR "audit: (%s) nontrapping pte" | 3197 | else { |
| 3061 | " in nonleaf level: levels %d gva %lx" | ||
| 3062 | " level %d pte %llx\n", audit_msg, | ||
| 3063 | vcpu->arch.mmu.root_level, va, level, ent); | ||
| 3064 | else | ||
| 3065 | audit_mappings_page(vcpu, ent, va, level - 1); | ||
| 3066 | } else { | ||
| 3067 | gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, va); | 3198 | gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, va); |
| 3068 | gfn_t gfn = gpa >> PAGE_SHIFT; | 3199 | gfn_t gfn = gpa >> PAGE_SHIFT; |
| 3069 | pfn_t pfn = gfn_to_pfn(vcpu->kvm, gfn); | 3200 | pfn_t pfn = gfn_to_pfn(vcpu->kvm, gfn); |
| 3070 | hpa_t hpa = (hpa_t)pfn << PAGE_SHIFT; | 3201 | hpa_t hpa = (hpa_t)pfn << PAGE_SHIFT; |
| 3071 | 3202 | ||
| 3203 | if (is_error_pfn(pfn)) { | ||
| 3204 | kvm_release_pfn_clean(pfn); | ||
| 3205 | continue; | ||
| 3206 | } | ||
| 3207 | |||
| 3072 | if (is_shadow_present_pte(ent) | 3208 | if (is_shadow_present_pte(ent) |
| 3073 | && (ent & PT64_BASE_ADDR_MASK) != hpa) | 3209 | && (ent & PT64_BASE_ADDR_MASK) != hpa) |
| 3074 | printk(KERN_ERR "xx audit error: (%s) levels %d" | 3210 | printk(KERN_ERR "xx audit error: (%s) levels %d" |
| @@ -3122,7 +3258,7 @@ static int count_rmaps(struct kvm_vcpu *vcpu) | |||
| 3122 | d = (struct kvm_rmap_desc *)(*rmapp & ~1ul); | 3258 | d = (struct kvm_rmap_desc *)(*rmapp & ~1ul); |
| 3123 | while (d) { | 3259 | while (d) { |
| 3124 | for (k = 0; k < RMAP_EXT; ++k) | 3260 | for (k = 0; k < RMAP_EXT; ++k) |
| 3125 | if (d->shadow_ptes[k]) | 3261 | if (d->sptes[k]) |
| 3126 | ++nmaps; | 3262 | ++nmaps; |
| 3127 | else | 3263 | else |
| 3128 | break; | 3264 | break; |
| @@ -3133,9 +3269,48 @@ static int count_rmaps(struct kvm_vcpu *vcpu) | |||
| 3133 | return nmaps; | 3269 | return nmaps; |
| 3134 | } | 3270 | } |
| 3135 | 3271 | ||
| 3136 | static int count_writable_mappings(struct kvm_vcpu *vcpu) | 3272 | void inspect_spte_has_rmap(struct kvm *kvm, struct kvm_mmu_page *sp, u64 *sptep) |
| 3273 | { | ||
| 3274 | unsigned long *rmapp; | ||
| 3275 | struct kvm_mmu_page *rev_sp; | ||
| 3276 | gfn_t gfn; | ||
| 3277 | |||
| 3278 | if (*sptep & PT_WRITABLE_MASK) { | ||
| 3279 | rev_sp = page_header(__pa(sptep)); | ||
| 3280 | gfn = rev_sp->gfns[sptep - rev_sp->spt]; | ||
| 3281 | |||
| 3282 | if (!gfn_to_memslot(kvm, gfn)) { | ||
| 3283 | if (!printk_ratelimit()) | ||
| 3284 | return; | ||
| 3285 | printk(KERN_ERR "%s: no memslot for gfn %ld\n", | ||
| 3286 | audit_msg, gfn); | ||
| 3287 | printk(KERN_ERR "%s: index %ld of sp (gfn=%lx)\n", | ||
| 3288 | audit_msg, sptep - rev_sp->spt, | ||
| 3289 | rev_sp->gfn); | ||
| 3290 | dump_stack(); | ||
| 3291 | return; | ||
| 3292 | } | ||
| 3293 | |||
| 3294 | rmapp = gfn_to_rmap(kvm, rev_sp->gfns[sptep - rev_sp->spt], | ||
| 3295 | is_large_pte(*sptep)); | ||
| 3296 | if (!*rmapp) { | ||
| 3297 | if (!printk_ratelimit()) | ||
| 3298 | return; | ||
| 3299 | printk(KERN_ERR "%s: no rmap for writable spte %llx\n", | ||
| 3300 | audit_msg, *sptep); | ||
| 3301 | dump_stack(); | ||
| 3302 | } | ||
| 3303 | } | ||
| 3304 | |||
| 3305 | } | ||
| 3306 | |||
| 3307 | void audit_writable_sptes_have_rmaps(struct kvm_vcpu *vcpu) | ||
| 3308 | { | ||
| 3309 | mmu_spte_walk(vcpu, inspect_spte_has_rmap); | ||
| 3310 | } | ||
| 3311 | |||
| 3312 | static void check_writable_mappings_rmap(struct kvm_vcpu *vcpu) | ||
| 3137 | { | 3313 | { |
| 3138 | int nmaps = 0; | ||
| 3139 | struct kvm_mmu_page *sp; | 3314 | struct kvm_mmu_page *sp; |
| 3140 | int i; | 3315 | int i; |
| 3141 | 3316 | ||
| @@ -3152,20 +3327,16 @@ static int count_writable_mappings(struct kvm_vcpu *vcpu) | |||
| 3152 | continue; | 3327 | continue; |
| 3153 | if (!(ent & PT_WRITABLE_MASK)) | 3328 | if (!(ent & PT_WRITABLE_MASK)) |
| 3154 | continue; | 3329 | continue; |
| 3155 | ++nmaps; | 3330 | inspect_spte_has_rmap(vcpu->kvm, sp, &pt[i]); |
| 3156 | } | 3331 | } |
| 3157 | } | 3332 | } |
| 3158 | return nmaps; | 3333 | return; |
| 3159 | } | 3334 | } |
| 3160 | 3335 | ||
| 3161 | static void audit_rmap(struct kvm_vcpu *vcpu) | 3336 | static void audit_rmap(struct kvm_vcpu *vcpu) |
| 3162 | { | 3337 | { |
| 3163 | int n_rmap = count_rmaps(vcpu); | 3338 | check_writable_mappings_rmap(vcpu); |
| 3164 | int n_actual = count_writable_mappings(vcpu); | 3339 | count_rmaps(vcpu); |
| 3165 | |||
| 3166 | if (n_rmap != n_actual) | ||
| 3167 | printk(KERN_ERR "%s: (%s) rmap %d actual %d\n", | ||
| 3168 | __func__, audit_msg, n_rmap, n_actual); | ||
| 3169 | } | 3340 | } |
| 3170 | 3341 | ||
| 3171 | static void audit_write_protection(struct kvm_vcpu *vcpu) | 3342 | static void audit_write_protection(struct kvm_vcpu *vcpu) |
| @@ -3173,20 +3344,28 @@ static void audit_write_protection(struct kvm_vcpu *vcpu) | |||
| 3173 | struct kvm_mmu_page *sp; | 3344 | struct kvm_mmu_page *sp; |
| 3174 | struct kvm_memory_slot *slot; | 3345 | struct kvm_memory_slot *slot; |
| 3175 | unsigned long *rmapp; | 3346 | unsigned long *rmapp; |
| 3347 | u64 *spte; | ||
| 3176 | gfn_t gfn; | 3348 | gfn_t gfn; |
| 3177 | 3349 | ||
| 3178 | list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) { | 3350 | list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) { |
| 3179 | if (sp->role.direct) | 3351 | if (sp->role.direct) |
| 3180 | continue; | 3352 | continue; |
| 3353 | if (sp->unsync) | ||
| 3354 | continue; | ||
| 3181 | 3355 | ||
| 3182 | gfn = unalias_gfn(vcpu->kvm, sp->gfn); | 3356 | gfn = unalias_gfn(vcpu->kvm, sp->gfn); |
| 3183 | slot = gfn_to_memslot_unaliased(vcpu->kvm, sp->gfn); | 3357 | slot = gfn_to_memslot_unaliased(vcpu->kvm, sp->gfn); |
| 3184 | rmapp = &slot->rmap[gfn - slot->base_gfn]; | 3358 | rmapp = &slot->rmap[gfn - slot->base_gfn]; |
| 3185 | if (*rmapp) | 3359 | |
| 3186 | printk(KERN_ERR "%s: (%s) shadow page has writable" | 3360 | spte = rmap_next(vcpu->kvm, rmapp, NULL); |
| 3187 | " mappings: gfn %lx role %x\n", | 3361 | while (spte) { |
| 3362 | if (*spte & PT_WRITABLE_MASK) | ||
| 3363 | printk(KERN_ERR "%s: (%s) shadow page has " | ||
| 3364 | "writable mappings: gfn %lx role %x\n", | ||
| 3188 | __func__, audit_msg, sp->gfn, | 3365 | __func__, audit_msg, sp->gfn, |
| 3189 | sp->role.word); | 3366 | sp->role.word); |
| 3367 | spte = rmap_next(vcpu->kvm, rmapp, spte); | ||
| 3368 | } | ||
| 3190 | } | 3369 | } |
| 3191 | } | 3370 | } |
| 3192 | 3371 | ||
| @@ -3198,7 +3377,9 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) | |||
| 3198 | audit_msg = msg; | 3377 | audit_msg = msg; |
| 3199 | audit_rmap(vcpu); | 3378 | audit_rmap(vcpu); |
| 3200 | audit_write_protection(vcpu); | 3379 | audit_write_protection(vcpu); |
| 3201 | audit_mappings(vcpu); | 3380 | if (strcmp("pre pte write", audit_msg) != 0) |
| 3381 | audit_mappings(vcpu); | ||
| 3382 | audit_writable_sptes_have_rmaps(vcpu); | ||
| 3202 | dbg = olddbg; | 3383 | dbg = olddbg; |
| 3203 | } | 3384 | } |
| 3204 | 3385 | ||
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 3494a2fb136e..61a1b3884b49 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h | |||
| @@ -37,6 +37,8 @@ | |||
| 37 | #define PT32_ROOT_LEVEL 2 | 37 | #define PT32_ROOT_LEVEL 2 |
| 38 | #define PT32E_ROOT_LEVEL 3 | 38 | #define PT32E_ROOT_LEVEL 3 |
| 39 | 39 | ||
| 40 | int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]); | ||
| 41 | |||
| 40 | static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) | 42 | static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) |
| 41 | { | 43 | { |
| 42 | if (unlikely(vcpu->kvm->arch.n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES)) | 44 | if (unlikely(vcpu->kvm->arch.n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES)) |
| @@ -75,7 +77,7 @@ static inline int is_paging(struct kvm_vcpu *vcpu) | |||
| 75 | return vcpu->arch.cr0 & X86_CR0_PG; | 77 | return vcpu->arch.cr0 & X86_CR0_PG; |
| 76 | } | 78 | } |
| 77 | 79 | ||
| 78 | static inline int is_present_pte(unsigned long pte) | 80 | static inline int is_present_gpte(unsigned long pte) |
| 79 | { | 81 | { |
| 80 | return pte & PT_PRESENT_MASK; | 82 | return pte & PT_PRESENT_MASK; |
| 81 | } | 83 | } |
diff --git a/arch/x86/kvm/mmutrace.h b/arch/x86/kvm/mmutrace.h new file mode 100644 index 000000000000..3e4a5c6ca2a9 --- /dev/null +++ b/arch/x86/kvm/mmutrace.h | |||
| @@ -0,0 +1,220 @@ | |||
| 1 | #if !defined(_TRACE_KVMMMU_H) || defined(TRACE_HEADER_MULTI_READ) | ||
| 2 | #define _TRACE_KVMMMU_H | ||
| 3 | |||
| 4 | #include <linux/tracepoint.h> | ||
| 5 | #include <linux/ftrace_event.h> | ||
| 6 | |||
| 7 | #undef TRACE_SYSTEM | ||
| 8 | #define TRACE_SYSTEM kvmmmu | ||
| 9 | #define TRACE_INCLUDE_PATH . | ||
| 10 | #define TRACE_INCLUDE_FILE mmutrace | ||
| 11 | |||
| 12 | #define KVM_MMU_PAGE_FIELDS \ | ||
| 13 | __field(__u64, gfn) \ | ||
| 14 | __field(__u32, role) \ | ||
| 15 | __field(__u32, root_count) \ | ||
| 16 | __field(__u32, unsync) | ||
| 17 | |||
| 18 | #define KVM_MMU_PAGE_ASSIGN(sp) \ | ||
| 19 | __entry->gfn = sp->gfn; \ | ||
| 20 | __entry->role = sp->role.word; \ | ||
| 21 | __entry->root_count = sp->root_count; \ | ||
| 22 | __entry->unsync = sp->unsync; | ||
| 23 | |||
| 24 | #define KVM_MMU_PAGE_PRINTK() ({ \ | ||
| 25 | const char *ret = p->buffer + p->len; \ | ||
| 26 | static const char *access_str[] = { \ | ||
| 27 | "---", "--x", "w--", "w-x", "-u-", "-ux", "wu-", "wux" \ | ||
| 28 | }; \ | ||
| 29 | union kvm_mmu_page_role role; \ | ||
| 30 | \ | ||
| 31 | role.word = __entry->role; \ | ||
| 32 | \ | ||
| 33 | trace_seq_printf(p, "sp gfn %llx %u/%u q%u%s %s%s %spge" \ | ||
| 34 | " %snxe root %u %s%c", \ | ||
| 35 | __entry->gfn, role.level, role.glevels, \ | ||
| 36 | role.quadrant, \ | ||
| 37 | role.direct ? " direct" : "", \ | ||
| 38 | access_str[role.access], \ | ||
| 39 | role.invalid ? " invalid" : "", \ | ||
| 40 | role.cr4_pge ? "" : "!", \ | ||
| 41 | role.nxe ? "" : "!", \ | ||
| 42 | __entry->root_count, \ | ||
| 43 | __entry->unsync ? "unsync" : "sync", 0); \ | ||
| 44 | ret; \ | ||
| 45 | }) | ||
| 46 | |||
| 47 | #define kvm_mmu_trace_pferr_flags \ | ||
| 48 | { PFERR_PRESENT_MASK, "P" }, \ | ||
| 49 | { PFERR_WRITE_MASK, "W" }, \ | ||
| 50 | { PFERR_USER_MASK, "U" }, \ | ||
| 51 | { PFERR_RSVD_MASK, "RSVD" }, \ | ||
| 52 | { PFERR_FETCH_MASK, "F" } | ||
| 53 | |||
| 54 | /* | ||
| 55 | * A pagetable walk has started | ||
| 56 | */ | ||
| 57 | TRACE_EVENT( | ||
| 58 | kvm_mmu_pagetable_walk, | ||
| 59 | TP_PROTO(u64 addr, int write_fault, int user_fault, int fetch_fault), | ||
| 60 | TP_ARGS(addr, write_fault, user_fault, fetch_fault), | ||
| 61 | |||
| 62 | TP_STRUCT__entry( | ||
| 63 | __field(__u64, addr) | ||
| 64 | __field(__u32, pferr) | ||
| 65 | ), | ||
| 66 | |||
| 67 | TP_fast_assign( | ||
| 68 | __entry->addr = addr; | ||
| 69 | __entry->pferr = (!!write_fault << 1) | (!!user_fault << 2) | ||
| 70 | | (!!fetch_fault << 4); | ||
| 71 | ), | ||
| 72 | |||
| 73 | TP_printk("addr %llx pferr %x %s", __entry->addr, __entry->pferr, | ||
| 74 | __print_flags(__entry->pferr, "|", kvm_mmu_trace_pferr_flags)) | ||
| 75 | ); | ||
| 76 | |||
| 77 | |||
| 78 | /* We just walked a paging element */ | ||
| 79 | TRACE_EVENT( | ||
| 80 | kvm_mmu_paging_element, | ||
| 81 | TP_PROTO(u64 pte, int level), | ||
| 82 | TP_ARGS(pte, level), | ||
| 83 | |||
| 84 | TP_STRUCT__entry( | ||
| 85 | __field(__u64, pte) | ||
| 86 | __field(__u32, level) | ||
| 87 | ), | ||
| 88 | |||
| 89 | TP_fast_assign( | ||
| 90 | __entry->pte = pte; | ||
| 91 | __entry->level = level; | ||
| 92 | ), | ||
| 93 | |||
| 94 | TP_printk("pte %llx level %u", __entry->pte, __entry->level) | ||
| 95 | ); | ||
| 96 | |||
| 97 | /* We set a pte accessed bit */ | ||
| 98 | TRACE_EVENT( | ||
| 99 | kvm_mmu_set_accessed_bit, | ||
| 100 | TP_PROTO(unsigned long table_gfn, unsigned index, unsigned size), | ||
| 101 | TP_ARGS(table_gfn, index, size), | ||
| 102 | |||
| 103 | TP_STRUCT__entry( | ||
| 104 | __field(__u64, gpa) | ||
| 105 | ), | ||
| 106 | |||
| 107 | TP_fast_assign( | ||
| 108 | __entry->gpa = ((u64)table_gfn << PAGE_SHIFT) | ||
| 109 | + index * size; | ||
| 110 | ), | ||
| 111 | |||
| 112 | TP_printk("gpa %llx", __entry->gpa) | ||
| 113 | ); | ||
| 114 | |||
| 115 | /* We set a pte dirty bit */ | ||
| 116 | TRACE_EVENT( | ||
| 117 | kvm_mmu_set_dirty_bit, | ||
| 118 | TP_PROTO(unsigned long table_gfn, unsigned index, unsigned size), | ||
| 119 | TP_ARGS(table_gfn, index, size), | ||
| 120 | |||
| 121 | TP_STRUCT__entry( | ||
| 122 | __field(__u64, gpa) | ||
| 123 | ), | ||
| 124 | |||
| 125 | TP_fast_assign( | ||
| 126 | __entry->gpa = ((u64)table_gfn << PAGE_SHIFT) | ||
| 127 | + index * size; | ||
| 128 | ), | ||
| 129 | |||
| 130 | TP_printk("gpa %llx", __entry->gpa) | ||
| 131 | ); | ||
| 132 | |||
| 133 | TRACE_EVENT( | ||
| 134 | kvm_mmu_walker_error, | ||
| 135 | TP_PROTO(u32 pferr), | ||
| 136 | TP_ARGS(pferr), | ||
| 137 | |||
| 138 | TP_STRUCT__entry( | ||
| 139 | __field(__u32, pferr) | ||
| 140 | ), | ||
| 141 | |||
| 142 | TP_fast_assign( | ||
| 143 | __entry->pferr = pferr; | ||
| 144 | ), | ||
| 145 | |||
| 146 | TP_printk("pferr %x %s", __entry->pferr, | ||
| 147 | __print_flags(__entry->pferr, "|", kvm_mmu_trace_pferr_flags)) | ||
| 148 | ); | ||
| 149 | |||
| 150 | TRACE_EVENT( | ||
| 151 | kvm_mmu_get_page, | ||
| 152 | TP_PROTO(struct kvm_mmu_page *sp, bool created), | ||
| 153 | TP_ARGS(sp, created), | ||
| 154 | |||
| 155 | TP_STRUCT__entry( | ||
| 156 | KVM_MMU_PAGE_FIELDS | ||
| 157 | __field(bool, created) | ||
| 158 | ), | ||
| 159 | |||
| 160 | TP_fast_assign( | ||
| 161 | KVM_MMU_PAGE_ASSIGN(sp) | ||
| 162 | __entry->created = created; | ||
| 163 | ), | ||
| 164 | |||
| 165 | TP_printk("%s %s", KVM_MMU_PAGE_PRINTK(), | ||
| 166 | __entry->created ? "new" : "existing") | ||
| 167 | ); | ||
| 168 | |||
| 169 | TRACE_EVENT( | ||
| 170 | kvm_mmu_sync_page, | ||
| 171 | TP_PROTO(struct kvm_mmu_page *sp), | ||
| 172 | TP_ARGS(sp), | ||
| 173 | |||
| 174 | TP_STRUCT__entry( | ||
| 175 | KVM_MMU_PAGE_FIELDS | ||
| 176 | ), | ||
| 177 | |||
| 178 | TP_fast_assign( | ||
| 179 | KVM_MMU_PAGE_ASSIGN(sp) | ||
| 180 | ), | ||
| 181 | |||
| 182 | TP_printk("%s", KVM_MMU_PAGE_PRINTK()) | ||
| 183 | ); | ||
| 184 | |||
| 185 | TRACE_EVENT( | ||
| 186 | kvm_mmu_unsync_page, | ||
| 187 | TP_PROTO(struct kvm_mmu_page *sp), | ||
| 188 | TP_ARGS(sp), | ||
| 189 | |||
| 190 | TP_STRUCT__entry( | ||
| 191 | KVM_MMU_PAGE_FIELDS | ||
| 192 | ), | ||
| 193 | |||
| 194 | TP_fast_assign( | ||
| 195 | KVM_MMU_PAGE_ASSIGN(sp) | ||
| 196 | ), | ||
| 197 | |||
| 198 | TP_printk("%s", KVM_MMU_PAGE_PRINTK()) | ||
| 199 | ); | ||
| 200 | |||
| 201 | TRACE_EVENT( | ||
| 202 | kvm_mmu_zap_page, | ||
| 203 | TP_PROTO(struct kvm_mmu_page *sp), | ||
| 204 | TP_ARGS(sp), | ||
| 205 | |||
| 206 | TP_STRUCT__entry( | ||
| 207 | KVM_MMU_PAGE_FIELDS | ||
| 208 | ), | ||
| 209 | |||
| 210 | TP_fast_assign( | ||
| 211 | KVM_MMU_PAGE_ASSIGN(sp) | ||
| 212 | ), | ||
| 213 | |||
| 214 | TP_printk("%s", KVM_MMU_PAGE_PRINTK()) | ||
| 215 | ); | ||
| 216 | |||
| 217 | #endif /* _TRACE_KVMMMU_H */ | ||
| 218 | |||
| 219 | /* This part must be outside protection */ | ||
| 220 | #include <trace/define_trace.h> | ||
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 67785f635399..d2fec9c12d22 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h | |||
| @@ -27,7 +27,8 @@ | |||
| 27 | #define guest_walker guest_walker64 | 27 | #define guest_walker guest_walker64 |
| 28 | #define FNAME(name) paging##64_##name | 28 | #define FNAME(name) paging##64_##name |
| 29 | #define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK | 29 | #define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK |
| 30 | #define PT_DIR_BASE_ADDR_MASK PT64_DIR_BASE_ADDR_MASK | 30 | #define PT_LVL_ADDR_MASK(lvl) PT64_LVL_ADDR_MASK(lvl) |
| 31 | #define PT_LVL_OFFSET_MASK(lvl) PT64_LVL_OFFSET_MASK(lvl) | ||
| 31 | #define PT_INDEX(addr, level) PT64_INDEX(addr, level) | 32 | #define PT_INDEX(addr, level) PT64_INDEX(addr, level) |
| 32 | #define PT_LEVEL_MASK(level) PT64_LEVEL_MASK(level) | 33 | #define PT_LEVEL_MASK(level) PT64_LEVEL_MASK(level) |
| 33 | #define PT_LEVEL_BITS PT64_LEVEL_BITS | 34 | #define PT_LEVEL_BITS PT64_LEVEL_BITS |
| @@ -43,7 +44,8 @@ | |||
| 43 | #define guest_walker guest_walker32 | 44 | #define guest_walker guest_walker32 |
| 44 | #define FNAME(name) paging##32_##name | 45 | #define FNAME(name) paging##32_##name |
| 45 | #define PT_BASE_ADDR_MASK PT32_BASE_ADDR_MASK | 46 | #define PT_BASE_ADDR_MASK PT32_BASE_ADDR_MASK |
| 46 | #define PT_DIR_BASE_ADDR_MASK PT32_DIR_BASE_ADDR_MASK | 47 | #define PT_LVL_ADDR_MASK(lvl) PT32_LVL_ADDR_MASK(lvl) |
| 48 | #define PT_LVL_OFFSET_MASK(lvl) PT32_LVL_OFFSET_MASK(lvl) | ||
| 47 | #define PT_INDEX(addr, level) PT32_INDEX(addr, level) | 49 | #define PT_INDEX(addr, level) PT32_INDEX(addr, level) |
| 48 | #define PT_LEVEL_MASK(level) PT32_LEVEL_MASK(level) | 50 | #define PT_LEVEL_MASK(level) PT32_LEVEL_MASK(level) |
| 49 | #define PT_LEVEL_BITS PT32_LEVEL_BITS | 51 | #define PT_LEVEL_BITS PT32_LEVEL_BITS |
| @@ -53,8 +55,8 @@ | |||
| 53 | #error Invalid PTTYPE value | 55 | #error Invalid PTTYPE value |
| 54 | #endif | 56 | #endif |
| 55 | 57 | ||
| 56 | #define gpte_to_gfn FNAME(gpte_to_gfn) | 58 | #define gpte_to_gfn_lvl FNAME(gpte_to_gfn_lvl) |
| 57 | #define gpte_to_gfn_pde FNAME(gpte_to_gfn_pde) | 59 | #define gpte_to_gfn(pte) gpte_to_gfn_lvl((pte), PT_PAGE_TABLE_LEVEL) |
| 58 | 60 | ||
| 59 | /* | 61 | /* |
| 60 | * The guest_walker structure emulates the behavior of the hardware page | 62 | * The guest_walker structure emulates the behavior of the hardware page |
| @@ -71,14 +73,9 @@ struct guest_walker { | |||
| 71 | u32 error_code; | 73 | u32 error_code; |
| 72 | }; | 74 | }; |
| 73 | 75 | ||
| 74 | static gfn_t gpte_to_gfn(pt_element_t gpte) | 76 | static gfn_t gpte_to_gfn_lvl(pt_element_t gpte, int lvl) |
| 75 | { | 77 | { |
| 76 | return (gpte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT; | 78 | return (gpte & PT_LVL_ADDR_MASK(lvl)) >> PAGE_SHIFT; |
| 77 | } | ||
| 78 | |||
| 79 | static gfn_t gpte_to_gfn_pde(pt_element_t gpte) | ||
| 80 | { | ||
| 81 | return (gpte & PT_DIR_BASE_ADDR_MASK) >> PAGE_SHIFT; | ||
| 82 | } | 79 | } |
| 83 | 80 | ||
| 84 | static bool FNAME(cmpxchg_gpte)(struct kvm *kvm, | 81 | static bool FNAME(cmpxchg_gpte)(struct kvm *kvm, |
| @@ -125,14 +122,16 @@ static int FNAME(walk_addr)(struct guest_walker *walker, | |||
| 125 | gpa_t pte_gpa; | 122 | gpa_t pte_gpa; |
| 126 | int rsvd_fault = 0; | 123 | int rsvd_fault = 0; |
| 127 | 124 | ||
| 128 | pgprintk("%s: addr %lx\n", __func__, addr); | 125 | trace_kvm_mmu_pagetable_walk(addr, write_fault, user_fault, |
| 126 | fetch_fault); | ||
| 129 | walk: | 127 | walk: |
| 130 | walker->level = vcpu->arch.mmu.root_level; | 128 | walker->level = vcpu->arch.mmu.root_level; |
| 131 | pte = vcpu->arch.cr3; | 129 | pte = vcpu->arch.cr3; |
| 132 | #if PTTYPE == 64 | 130 | #if PTTYPE == 64 |
| 133 | if (!is_long_mode(vcpu)) { | 131 | if (!is_long_mode(vcpu)) { |
| 134 | pte = vcpu->arch.pdptrs[(addr >> 30) & 3]; | 132 | pte = kvm_pdptr_read(vcpu, (addr >> 30) & 3); |
| 135 | if (!is_present_pte(pte)) | 133 | trace_kvm_mmu_paging_element(pte, walker->level); |
| 134 | if (!is_present_gpte(pte)) | ||
| 136 | goto not_present; | 135 | goto not_present; |
| 137 | --walker->level; | 136 | --walker->level; |
| 138 | } | 137 | } |
| @@ -150,12 +149,11 @@ walk: | |||
| 150 | pte_gpa += index * sizeof(pt_element_t); | 149 | pte_gpa += index * sizeof(pt_element_t); |
| 151 | walker->table_gfn[walker->level - 1] = table_gfn; | 150 | walker->table_gfn[walker->level - 1] = table_gfn; |
| 152 | walker->pte_gpa[walker->level - 1] = pte_gpa; | 151 | walker->pte_gpa[walker->level - 1] = pte_gpa; |
| 153 | pgprintk("%s: table_gfn[%d] %lx\n", __func__, | ||
| 154 | walker->level - 1, table_gfn); | ||
| 155 | 152 | ||
| 156 | kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte)); | 153 | kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte)); |
| 154 | trace_kvm_mmu_paging_element(pte, walker->level); | ||
| 157 | 155 | ||
| 158 | if (!is_present_pte(pte)) | 156 | if (!is_present_gpte(pte)) |
| 159 | goto not_present; | 157 | goto not_present; |
| 160 | 158 | ||
| 161 | rsvd_fault = is_rsvd_bits_set(vcpu, pte, walker->level); | 159 | rsvd_fault = is_rsvd_bits_set(vcpu, pte, walker->level); |
| @@ -175,6 +173,8 @@ walk: | |||
| 175 | #endif | 173 | #endif |
| 176 | 174 | ||
| 177 | if (!(pte & PT_ACCESSED_MASK)) { | 175 | if (!(pte & PT_ACCESSED_MASK)) { |
| 176 | trace_kvm_mmu_set_accessed_bit(table_gfn, index, | ||
| 177 | sizeof(pte)); | ||
| 178 | mark_page_dirty(vcpu->kvm, table_gfn); | 178 | mark_page_dirty(vcpu->kvm, table_gfn); |
| 179 | if (FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, | 179 | if (FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, |
| 180 | index, pte, pte|PT_ACCESSED_MASK)) | 180 | index, pte, pte|PT_ACCESSED_MASK)) |
| @@ -186,18 +186,24 @@ walk: | |||
| 186 | 186 | ||
| 187 | walker->ptes[walker->level - 1] = pte; | 187 | walker->ptes[walker->level - 1] = pte; |
| 188 | 188 | ||
| 189 | if (walker->level == PT_PAGE_TABLE_LEVEL) { | 189 | if ((walker->level == PT_PAGE_TABLE_LEVEL) || |
| 190 | walker->gfn = gpte_to_gfn(pte); | 190 | ((walker->level == PT_DIRECTORY_LEVEL) && |
| 191 | break; | 191 | (pte & PT_PAGE_SIZE_MASK) && |
| 192 | } | 192 | (PTTYPE == 64 || is_pse(vcpu))) || |
| 193 | 193 | ((walker->level == PT_PDPE_LEVEL) && | |
| 194 | if (walker->level == PT_DIRECTORY_LEVEL | 194 | (pte & PT_PAGE_SIZE_MASK) && |
| 195 | && (pte & PT_PAGE_SIZE_MASK) | 195 | is_long_mode(vcpu))) { |
| 196 | && (PTTYPE == 64 || is_pse(vcpu))) { | 196 | int lvl = walker->level; |
| 197 | walker->gfn = gpte_to_gfn_pde(pte); | 197 | |
| 198 | walker->gfn += PT_INDEX(addr, PT_PAGE_TABLE_LEVEL); | 198 | walker->gfn = gpte_to_gfn_lvl(pte, lvl); |
| 199 | if (PTTYPE == 32 && is_cpuid_PSE36()) | 199 | walker->gfn += (addr & PT_LVL_OFFSET_MASK(lvl)) |
| 200 | >> PAGE_SHIFT; | ||
| 201 | |||
| 202 | if (PTTYPE == 32 && | ||
| 203 | walker->level == PT_DIRECTORY_LEVEL && | ||
| 204 | is_cpuid_PSE36()) | ||
| 200 | walker->gfn += pse36_gfn_delta(pte); | 205 | walker->gfn += pse36_gfn_delta(pte); |
| 206 | |||
| 201 | break; | 207 | break; |
| 202 | } | 208 | } |
| 203 | 209 | ||
| @@ -205,9 +211,10 @@ walk: | |||
| 205 | --walker->level; | 211 | --walker->level; |
| 206 | } | 212 | } |
| 207 | 213 | ||
| 208 | if (write_fault && !is_dirty_pte(pte)) { | 214 | if (write_fault && !is_dirty_gpte(pte)) { |
| 209 | bool ret; | 215 | bool ret; |
| 210 | 216 | ||
| 217 | trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte)); | ||
| 211 | mark_page_dirty(vcpu->kvm, table_gfn); | 218 | mark_page_dirty(vcpu->kvm, table_gfn); |
| 212 | ret = FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, index, pte, | 219 | ret = FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, index, pte, |
| 213 | pte|PT_DIRTY_MASK); | 220 | pte|PT_DIRTY_MASK); |
| @@ -239,6 +246,7 @@ err: | |||
| 239 | walker->error_code |= PFERR_FETCH_MASK; | 246 | walker->error_code |= PFERR_FETCH_MASK; |
| 240 | if (rsvd_fault) | 247 | if (rsvd_fault) |
| 241 | walker->error_code |= PFERR_RSVD_MASK; | 248 | walker->error_code |= PFERR_RSVD_MASK; |
| 249 | trace_kvm_mmu_walker_error(walker->error_code); | ||
| 242 | return 0; | 250 | return 0; |
| 243 | } | 251 | } |
| 244 | 252 | ||
| @@ -248,12 +256,11 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page, | |||
| 248 | pt_element_t gpte; | 256 | pt_element_t gpte; |
| 249 | unsigned pte_access; | 257 | unsigned pte_access; |
| 250 | pfn_t pfn; | 258 | pfn_t pfn; |
| 251 | int largepage = vcpu->arch.update_pte.largepage; | ||
| 252 | 259 | ||
| 253 | gpte = *(const pt_element_t *)pte; | 260 | gpte = *(const pt_element_t *)pte; |
| 254 | if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) { | 261 | if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) { |
| 255 | if (!is_present_pte(gpte)) | 262 | if (!is_present_gpte(gpte)) |
| 256 | set_shadow_pte(spte, shadow_notrap_nonpresent_pte); | 263 | __set_spte(spte, shadow_notrap_nonpresent_pte); |
| 257 | return; | 264 | return; |
| 258 | } | 265 | } |
| 259 | pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte); | 266 | pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte); |
| @@ -267,7 +274,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page, | |||
| 267 | return; | 274 | return; |
| 268 | kvm_get_pfn(pfn); | 275 | kvm_get_pfn(pfn); |
| 269 | mmu_set_spte(vcpu, spte, page->role.access, pte_access, 0, 0, | 276 | mmu_set_spte(vcpu, spte, page->role.access, pte_access, 0, 0, |
| 270 | gpte & PT_DIRTY_MASK, NULL, largepage, | 277 | gpte & PT_DIRTY_MASK, NULL, PT_PAGE_TABLE_LEVEL, |
| 271 | gpte_to_gfn(gpte), pfn, true); | 278 | gpte_to_gfn(gpte), pfn, true); |
| 272 | } | 279 | } |
| 273 | 280 | ||
| @@ -276,7 +283,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page, | |||
| 276 | */ | 283 | */ |
| 277 | static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, | 284 | static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, |
| 278 | struct guest_walker *gw, | 285 | struct guest_walker *gw, |
| 279 | int user_fault, int write_fault, int largepage, | 286 | int user_fault, int write_fault, int hlevel, |
| 280 | int *ptwrite, pfn_t pfn) | 287 | int *ptwrite, pfn_t pfn) |
| 281 | { | 288 | { |
| 282 | unsigned access = gw->pt_access; | 289 | unsigned access = gw->pt_access; |
| @@ -289,19 +296,18 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, | |||
| 289 | pt_element_t curr_pte; | 296 | pt_element_t curr_pte; |
| 290 | struct kvm_shadow_walk_iterator iterator; | 297 | struct kvm_shadow_walk_iterator iterator; |
| 291 | 298 | ||
| 292 | if (!is_present_pte(gw->ptes[gw->level - 1])) | 299 | if (!is_present_gpte(gw->ptes[gw->level - 1])) |
| 293 | return NULL; | 300 | return NULL; |
| 294 | 301 | ||
| 295 | for_each_shadow_entry(vcpu, addr, iterator) { | 302 | for_each_shadow_entry(vcpu, addr, iterator) { |
| 296 | level = iterator.level; | 303 | level = iterator.level; |
| 297 | sptep = iterator.sptep; | 304 | sptep = iterator.sptep; |
| 298 | if (level == PT_PAGE_TABLE_LEVEL | 305 | if (iterator.level == hlevel) { |
| 299 | || (largepage && level == PT_DIRECTORY_LEVEL)) { | ||
| 300 | mmu_set_spte(vcpu, sptep, access, | 306 | mmu_set_spte(vcpu, sptep, access, |
| 301 | gw->pte_access & access, | 307 | gw->pte_access & access, |
| 302 | user_fault, write_fault, | 308 | user_fault, write_fault, |
| 303 | gw->ptes[gw->level-1] & PT_DIRTY_MASK, | 309 | gw->ptes[gw->level-1] & PT_DIRTY_MASK, |
| 304 | ptwrite, largepage, | 310 | ptwrite, level, |
| 305 | gw->gfn, pfn, false); | 311 | gw->gfn, pfn, false); |
| 306 | break; | 312 | break; |
| 307 | } | 313 | } |
| @@ -311,16 +317,19 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, | |||
| 311 | 317 | ||
| 312 | if (is_large_pte(*sptep)) { | 318 | if (is_large_pte(*sptep)) { |
| 313 | rmap_remove(vcpu->kvm, sptep); | 319 | rmap_remove(vcpu->kvm, sptep); |
| 314 | set_shadow_pte(sptep, shadow_trap_nonpresent_pte); | 320 | __set_spte(sptep, shadow_trap_nonpresent_pte); |
| 315 | kvm_flush_remote_tlbs(vcpu->kvm); | 321 | kvm_flush_remote_tlbs(vcpu->kvm); |
| 316 | } | 322 | } |
| 317 | 323 | ||
| 318 | if (level == PT_DIRECTORY_LEVEL | 324 | if (level <= gw->level) { |
| 319 | && gw->level == PT_DIRECTORY_LEVEL) { | 325 | int delta = level - gw->level + 1; |
| 320 | direct = 1; | 326 | direct = 1; |
| 321 | if (!is_dirty_pte(gw->ptes[level - 1])) | 327 | if (!is_dirty_gpte(gw->ptes[level - delta])) |
| 322 | access &= ~ACC_WRITE_MASK; | 328 | access &= ~ACC_WRITE_MASK; |
| 323 | table_gfn = gpte_to_gfn(gw->ptes[level - 1]); | 329 | table_gfn = gpte_to_gfn(gw->ptes[level - delta]); |
| 330 | /* advance table_gfn when emulating 1gb pages with 4k */ | ||
| 331 | if (delta == 0) | ||
| 332 | table_gfn += PT_INDEX(addr, level); | ||
| 324 | } else { | 333 | } else { |
| 325 | direct = 0; | 334 | direct = 0; |
| 326 | table_gfn = gw->table_gfn[level - 2]; | 335 | table_gfn = gw->table_gfn[level - 2]; |
| @@ -369,11 +378,11 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, | |||
| 369 | int user_fault = error_code & PFERR_USER_MASK; | 378 | int user_fault = error_code & PFERR_USER_MASK; |
| 370 | int fetch_fault = error_code & PFERR_FETCH_MASK; | 379 | int fetch_fault = error_code & PFERR_FETCH_MASK; |
| 371 | struct guest_walker walker; | 380 | struct guest_walker walker; |
| 372 | u64 *shadow_pte; | 381 | u64 *sptep; |
| 373 | int write_pt = 0; | 382 | int write_pt = 0; |
| 374 | int r; | 383 | int r; |
| 375 | pfn_t pfn; | 384 | pfn_t pfn; |
| 376 | int largepage = 0; | 385 | int level = PT_PAGE_TABLE_LEVEL; |
| 377 | unsigned long mmu_seq; | 386 | unsigned long mmu_seq; |
| 378 | 387 | ||
| 379 | pgprintk("%s: addr %lx err %x\n", __func__, addr, error_code); | 388 | pgprintk("%s: addr %lx err %x\n", __func__, addr, error_code); |
| @@ -399,14 +408,11 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, | |||
| 399 | return 0; | 408 | return 0; |
| 400 | } | 409 | } |
| 401 | 410 | ||
| 402 | if (walker.level == PT_DIRECTORY_LEVEL) { | 411 | if (walker.level >= PT_DIRECTORY_LEVEL) { |
| 403 | gfn_t large_gfn; | 412 | level = min(walker.level, mapping_level(vcpu, walker.gfn)); |
| 404 | large_gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE-1); | 413 | walker.gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE(level) - 1); |
| 405 | if (is_largepage_backed(vcpu, large_gfn)) { | ||
| 406 | walker.gfn = large_gfn; | ||
| 407 | largepage = 1; | ||
| 408 | } | ||
| 409 | } | 414 | } |
| 415 | |||
| 410 | mmu_seq = vcpu->kvm->mmu_notifier_seq; | 416 | mmu_seq = vcpu->kvm->mmu_notifier_seq; |
| 411 | smp_rmb(); | 417 | smp_rmb(); |
| 412 | pfn = gfn_to_pfn(vcpu->kvm, walker.gfn); | 418 | pfn = gfn_to_pfn(vcpu->kvm, walker.gfn); |
| @@ -422,11 +428,10 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, | |||
| 422 | if (mmu_notifier_retry(vcpu, mmu_seq)) | 428 | if (mmu_notifier_retry(vcpu, mmu_seq)) |
| 423 | goto out_unlock; | 429 | goto out_unlock; |
| 424 | kvm_mmu_free_some_pages(vcpu); | 430 | kvm_mmu_free_some_pages(vcpu); |
| 425 | shadow_pte = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault, | 431 | sptep = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault, |
| 426 | largepage, &write_pt, pfn); | 432 | level, &write_pt, pfn); |
| 427 | |||
| 428 | pgprintk("%s: shadow pte %p %llx ptwrite %d\n", __func__, | 433 | pgprintk("%s: shadow pte %p %llx ptwrite %d\n", __func__, |
| 429 | shadow_pte, *shadow_pte, write_pt); | 434 | sptep, *sptep, write_pt); |
| 430 | 435 | ||
| 431 | if (!write_pt) | 436 | if (!write_pt) |
| 432 | vcpu->arch.last_pt_write_count = 0; /* reset fork detector */ | 437 | vcpu->arch.last_pt_write_count = 0; /* reset fork detector */ |
| @@ -459,8 +464,9 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) | |||
| 459 | sptep = iterator.sptep; | 464 | sptep = iterator.sptep; |
| 460 | 465 | ||
| 461 | /* FIXME: properly handle invlpg on large guest pages */ | 466 | /* FIXME: properly handle invlpg on large guest pages */ |
| 462 | if (level == PT_PAGE_TABLE_LEVEL || | 467 | if (level == PT_PAGE_TABLE_LEVEL || |
| 463 | ((level == PT_DIRECTORY_LEVEL) && is_large_pte(*sptep))) { | 468 | ((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) || |
| 469 | ((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) { | ||
| 464 | struct kvm_mmu_page *sp = page_header(__pa(sptep)); | 470 | struct kvm_mmu_page *sp = page_header(__pa(sptep)); |
| 465 | 471 | ||
| 466 | pte_gpa = (sp->gfn << PAGE_SHIFT); | 472 | pte_gpa = (sp->gfn << PAGE_SHIFT); |
| @@ -472,7 +478,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) | |||
| 472 | --vcpu->kvm->stat.lpages; | 478 | --vcpu->kvm->stat.lpages; |
| 473 | need_flush = 1; | 479 | need_flush = 1; |
| 474 | } | 480 | } |
| 475 | set_shadow_pte(sptep, shadow_trap_nonpresent_pte); | 481 | __set_spte(sptep, shadow_trap_nonpresent_pte); |
| 476 | break; | 482 | break; |
| 477 | } | 483 | } |
| 478 | 484 | ||
| @@ -489,7 +495,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) | |||
| 489 | if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte, | 495 | if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte, |
| 490 | sizeof(pt_element_t))) | 496 | sizeof(pt_element_t))) |
| 491 | return; | 497 | return; |
| 492 | if (is_present_pte(gpte) && (gpte & PT_ACCESSED_MASK)) { | 498 | if (is_present_gpte(gpte) && (gpte & PT_ACCESSED_MASK)) { |
| 493 | if (mmu_topup_memory_caches(vcpu)) | 499 | if (mmu_topup_memory_caches(vcpu)) |
| 494 | return; | 500 | return; |
| 495 | kvm_mmu_pte_write(vcpu, pte_gpa, (const u8 *)&gpte, | 501 | kvm_mmu_pte_write(vcpu, pte_gpa, (const u8 *)&gpte, |
| @@ -536,7 +542,7 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu, | |||
| 536 | r = kvm_read_guest_atomic(vcpu->kvm, pte_gpa, pt, sizeof pt); | 542 | r = kvm_read_guest_atomic(vcpu->kvm, pte_gpa, pt, sizeof pt); |
| 537 | pte_gpa += ARRAY_SIZE(pt) * sizeof(pt_element_t); | 543 | pte_gpa += ARRAY_SIZE(pt) * sizeof(pt_element_t); |
| 538 | for (j = 0; j < ARRAY_SIZE(pt); ++j) | 544 | for (j = 0; j < ARRAY_SIZE(pt); ++j) |
| 539 | if (r || is_present_pte(pt[j])) | 545 | if (r || is_present_gpte(pt[j])) |
| 540 | sp->spt[i+j] = shadow_trap_nonpresent_pte; | 546 | sp->spt[i+j] = shadow_trap_nonpresent_pte; |
| 541 | else | 547 | else |
| 542 | sp->spt[i+j] = shadow_notrap_nonpresent_pte; | 548 | sp->spt[i+j] = shadow_notrap_nonpresent_pte; |
| @@ -574,23 +580,23 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) | |||
| 574 | sizeof(pt_element_t))) | 580 | sizeof(pt_element_t))) |
| 575 | return -EINVAL; | 581 | return -EINVAL; |
| 576 | 582 | ||
| 577 | if (gpte_to_gfn(gpte) != gfn || !is_present_pte(gpte) || | 583 | if (gpte_to_gfn(gpte) != gfn || !is_present_gpte(gpte) || |
| 578 | !(gpte & PT_ACCESSED_MASK)) { | 584 | !(gpte & PT_ACCESSED_MASK)) { |
| 579 | u64 nonpresent; | 585 | u64 nonpresent; |
| 580 | 586 | ||
| 581 | rmap_remove(vcpu->kvm, &sp->spt[i]); | 587 | rmap_remove(vcpu->kvm, &sp->spt[i]); |
| 582 | if (is_present_pte(gpte)) | 588 | if (is_present_gpte(gpte)) |
| 583 | nonpresent = shadow_trap_nonpresent_pte; | 589 | nonpresent = shadow_trap_nonpresent_pte; |
| 584 | else | 590 | else |
| 585 | nonpresent = shadow_notrap_nonpresent_pte; | 591 | nonpresent = shadow_notrap_nonpresent_pte; |
| 586 | set_shadow_pte(&sp->spt[i], nonpresent); | 592 | __set_spte(&sp->spt[i], nonpresent); |
| 587 | continue; | 593 | continue; |
| 588 | } | 594 | } |
| 589 | 595 | ||
| 590 | nr_present++; | 596 | nr_present++; |
| 591 | pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte); | 597 | pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte); |
| 592 | set_spte(vcpu, &sp->spt[i], pte_access, 0, 0, | 598 | set_spte(vcpu, &sp->spt[i], pte_access, 0, 0, |
| 593 | is_dirty_pte(gpte), 0, gfn, | 599 | is_dirty_gpte(gpte), PT_PAGE_TABLE_LEVEL, gfn, |
| 594 | spte_to_pfn(sp->spt[i]), true, false); | 600 | spte_to_pfn(sp->spt[i]), true, false); |
| 595 | } | 601 | } |
| 596 | 602 | ||
| @@ -603,9 +609,10 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) | |||
| 603 | #undef PT_BASE_ADDR_MASK | 609 | #undef PT_BASE_ADDR_MASK |
| 604 | #undef PT_INDEX | 610 | #undef PT_INDEX |
| 605 | #undef PT_LEVEL_MASK | 611 | #undef PT_LEVEL_MASK |
| 606 | #undef PT_DIR_BASE_ADDR_MASK | 612 | #undef PT_LVL_ADDR_MASK |
| 613 | #undef PT_LVL_OFFSET_MASK | ||
| 607 | #undef PT_LEVEL_BITS | 614 | #undef PT_LEVEL_BITS |
| 608 | #undef PT_MAX_FULL_LEVELS | 615 | #undef PT_MAX_FULL_LEVELS |
| 609 | #undef gpte_to_gfn | 616 | #undef gpte_to_gfn |
| 610 | #undef gpte_to_gfn_pde | 617 | #undef gpte_to_gfn_lvl |
| 611 | #undef CMPXCHG | 618 | #undef CMPXCHG |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index b1f658ad2f06..944cc9c04b3c 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | */ | 15 | */ |
| 16 | #include <linux/kvm_host.h> | 16 | #include <linux/kvm_host.h> |
| 17 | 17 | ||
| 18 | #include "kvm_svm.h" | ||
| 19 | #include "irq.h" | 18 | #include "irq.h" |
| 20 | #include "mmu.h" | 19 | #include "mmu.h" |
| 21 | #include "kvm_cache_regs.h" | 20 | #include "kvm_cache_regs.h" |
| @@ -26,10 +25,12 @@ | |||
| 26 | #include <linux/vmalloc.h> | 25 | #include <linux/vmalloc.h> |
| 27 | #include <linux/highmem.h> | 26 | #include <linux/highmem.h> |
| 28 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
| 28 | #include <linux/ftrace_event.h> | ||
| 29 | 29 | ||
| 30 | #include <asm/desc.h> | 30 | #include <asm/desc.h> |
| 31 | 31 | ||
| 32 | #include <asm/virtext.h> | 32 | #include <asm/virtext.h> |
| 33 | #include "trace.h" | ||
| 33 | 34 | ||
| 34 | #define __ex(x) __kvm_handle_fault_on_reboot(x) | 35 | #define __ex(x) __kvm_handle_fault_on_reboot(x) |
| 35 | 36 | ||
| @@ -46,6 +47,10 @@ MODULE_LICENSE("GPL"); | |||
| 46 | #define SVM_FEATURE_LBRV (1 << 1) | 47 | #define SVM_FEATURE_LBRV (1 << 1) |
| 47 | #define SVM_FEATURE_SVML (1 << 2) | 48 | #define SVM_FEATURE_SVML (1 << 2) |
| 48 | 49 | ||
| 50 | #define NESTED_EXIT_HOST 0 /* Exit handled on host level */ | ||
| 51 | #define NESTED_EXIT_DONE 1 /* Exit caused nested vmexit */ | ||
| 52 | #define NESTED_EXIT_CONTINUE 2 /* Further checks needed */ | ||
| 53 | |||
| 49 | #define DEBUGCTL_RESERVED_BITS (~(0x3fULL)) | 54 | #define DEBUGCTL_RESERVED_BITS (~(0x3fULL)) |
| 50 | 55 | ||
| 51 | /* Turn on to get debugging output*/ | 56 | /* Turn on to get debugging output*/ |
| @@ -57,6 +62,58 @@ MODULE_LICENSE("GPL"); | |||
| 57 | #define nsvm_printk(fmt, args...) do {} while(0) | 62 | #define nsvm_printk(fmt, args...) do {} while(0) |
| 58 | #endif | 63 | #endif |
| 59 | 64 | ||
| 65 | static const u32 host_save_user_msrs[] = { | ||
| 66 | #ifdef CONFIG_X86_64 | ||
| 67 | MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE, | ||
| 68 | MSR_FS_BASE, | ||
| 69 | #endif | ||
| 70 | MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, | ||
| 71 | }; | ||
| 72 | |||
| 73 | #define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs) | ||
| 74 | |||
| 75 | struct kvm_vcpu; | ||
| 76 | |||
| 77 | struct nested_state { | ||
| 78 | struct vmcb *hsave; | ||
| 79 | u64 hsave_msr; | ||
| 80 | u64 vmcb; | ||
| 81 | |||
| 82 | /* These are the merged vectors */ | ||
| 83 | u32 *msrpm; | ||
| 84 | |||
| 85 | /* gpa pointers to the real vectors */ | ||
| 86 | u64 vmcb_msrpm; | ||
| 87 | |||
| 88 | /* cache for intercepts of the guest */ | ||
| 89 | u16 intercept_cr_read; | ||
| 90 | u16 intercept_cr_write; | ||
| 91 | u16 intercept_dr_read; | ||
| 92 | u16 intercept_dr_write; | ||
| 93 | u32 intercept_exceptions; | ||
| 94 | u64 intercept; | ||
| 95 | |||
| 96 | }; | ||
| 97 | |||
| 98 | struct vcpu_svm { | ||
| 99 | struct kvm_vcpu vcpu; | ||
| 100 | struct vmcb *vmcb; | ||
| 101 | unsigned long vmcb_pa; | ||
| 102 | struct svm_cpu_data *svm_data; | ||
| 103 | uint64_t asid_generation; | ||
| 104 | uint64_t sysenter_esp; | ||
| 105 | uint64_t sysenter_eip; | ||
| 106 | |||
| 107 | u64 next_rip; | ||
| 108 | |||
| 109 | u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS]; | ||
| 110 | u64 host_gs_base; | ||
| 111 | |||
| 112 | u32 *msrpm; | ||
| 113 | |||
| 114 | struct nested_state nested; | ||
| 115 | }; | ||
| 116 | |||
| 60 | /* enable NPT for AMD64 and X86 with PAE */ | 117 | /* enable NPT for AMD64 and X86 with PAE */ |
| 61 | #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) | 118 | #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) |
| 62 | static bool npt_enabled = true; | 119 | static bool npt_enabled = true; |
| @@ -67,15 +124,14 @@ static int npt = 1; | |||
| 67 | 124 | ||
| 68 | module_param(npt, int, S_IRUGO); | 125 | module_param(npt, int, S_IRUGO); |
| 69 | 126 | ||
| 70 | static int nested = 0; | 127 | static int nested = 1; |
| 71 | module_param(nested, int, S_IRUGO); | 128 | module_param(nested, int, S_IRUGO); |
| 72 | 129 | ||
| 73 | static void svm_flush_tlb(struct kvm_vcpu *vcpu); | 130 | static void svm_flush_tlb(struct kvm_vcpu *vcpu); |
| 131 | static void svm_complete_interrupts(struct vcpu_svm *svm); | ||
| 74 | 132 | ||
| 75 | static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override); | 133 | static int nested_svm_exit_handled(struct vcpu_svm *svm); |
| 76 | static int nested_svm_vmexit(struct vcpu_svm *svm); | 134 | static int nested_svm_vmexit(struct vcpu_svm *svm); |
| 77 | static int nested_svm_vmsave(struct vcpu_svm *svm, void *nested_vmcb, | ||
| 78 | void *arg2, void *opaque); | ||
| 79 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, | 135 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, |
| 80 | bool has_error_code, u32 error_code); | 136 | bool has_error_code, u32 error_code); |
| 81 | 137 | ||
| @@ -86,7 +142,22 @@ static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu) | |||
| 86 | 142 | ||
| 87 | static inline bool is_nested(struct vcpu_svm *svm) | 143 | static inline bool is_nested(struct vcpu_svm *svm) |
| 88 | { | 144 | { |
| 89 | return svm->nested_vmcb; | 145 | return svm->nested.vmcb; |
| 146 | } | ||
| 147 | |||
| 148 | static inline void enable_gif(struct vcpu_svm *svm) | ||
| 149 | { | ||
| 150 | svm->vcpu.arch.hflags |= HF_GIF_MASK; | ||
| 151 | } | ||
| 152 | |||
| 153 | static inline void disable_gif(struct vcpu_svm *svm) | ||
| 154 | { | ||
| 155 | svm->vcpu.arch.hflags &= ~HF_GIF_MASK; | ||
| 156 | } | ||
| 157 | |||
| 158 | static inline bool gif_set(struct vcpu_svm *svm) | ||
| 159 | { | ||
| 160 | return !!(svm->vcpu.arch.hflags & HF_GIF_MASK); | ||
| 90 | } | 161 | } |
| 91 | 162 | ||
| 92 | static unsigned long iopm_base; | 163 | static unsigned long iopm_base; |
| @@ -147,19 +218,6 @@ static inline void invlpga(unsigned long addr, u32 asid) | |||
| 147 | asm volatile (__ex(SVM_INVLPGA) :: "a"(addr), "c"(asid)); | 218 | asm volatile (__ex(SVM_INVLPGA) :: "a"(addr), "c"(asid)); |
| 148 | } | 219 | } |
| 149 | 220 | ||
| 150 | static inline unsigned long kvm_read_cr2(void) | ||
| 151 | { | ||
| 152 | unsigned long cr2; | ||
| 153 | |||
| 154 | asm volatile ("mov %%cr2, %0" : "=r" (cr2)); | ||
| 155 | return cr2; | ||
| 156 | } | ||
| 157 | |||
| 158 | static inline void kvm_write_cr2(unsigned long val) | ||
| 159 | { | ||
| 160 | asm volatile ("mov %0, %%cr2" :: "r" (val)); | ||
| 161 | } | ||
| 162 | |||
| 163 | static inline void force_new_asid(struct kvm_vcpu *vcpu) | 221 | static inline void force_new_asid(struct kvm_vcpu *vcpu) |
| 164 | { | 222 | { |
| 165 | to_svm(vcpu)->asid_generation--; | 223 | to_svm(vcpu)->asid_generation--; |
| @@ -263,7 +321,7 @@ static void svm_hardware_enable(void *garbage) | |||
| 263 | 321 | ||
| 264 | struct svm_cpu_data *svm_data; | 322 | struct svm_cpu_data *svm_data; |
| 265 | uint64_t efer; | 323 | uint64_t efer; |
| 266 | struct desc_ptr gdt_descr; | 324 | struct descriptor_table gdt_descr; |
| 267 | struct desc_struct *gdt; | 325 | struct desc_struct *gdt; |
| 268 | int me = raw_smp_processor_id(); | 326 | int me = raw_smp_processor_id(); |
| 269 | 327 | ||
| @@ -283,8 +341,8 @@ static void svm_hardware_enable(void *garbage) | |||
| 283 | svm_data->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1; | 341 | svm_data->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1; |
| 284 | svm_data->next_asid = svm_data->max_asid + 1; | 342 | svm_data->next_asid = svm_data->max_asid + 1; |
| 285 | 343 | ||
| 286 | asm volatile ("sgdt %0" : "=m"(gdt_descr)); | 344 | kvm_get_gdt(&gdt_descr); |
| 287 | gdt = (struct desc_struct *)gdt_descr.address; | 345 | gdt = (struct desc_struct *)gdt_descr.base; |
| 288 | svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS); | 346 | svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS); |
| 289 | 347 | ||
| 290 | rdmsrl(MSR_EFER, efer); | 348 | rdmsrl(MSR_EFER, efer); |
| @@ -367,8 +425,6 @@ static void svm_vcpu_init_msrpm(u32 *msrpm) | |||
| 367 | #endif | 425 | #endif |
| 368 | set_msr_interception(msrpm, MSR_K6_STAR, 1, 1); | 426 | set_msr_interception(msrpm, MSR_K6_STAR, 1, 1); |
| 369 | set_msr_interception(msrpm, MSR_IA32_SYSENTER_CS, 1, 1); | 427 | set_msr_interception(msrpm, MSR_IA32_SYSENTER_CS, 1, 1); |
| 370 | set_msr_interception(msrpm, MSR_IA32_SYSENTER_ESP, 1, 1); | ||
| 371 | set_msr_interception(msrpm, MSR_IA32_SYSENTER_EIP, 1, 1); | ||
| 372 | } | 428 | } |
| 373 | 429 | ||
| 374 | static void svm_enable_lbrv(struct vcpu_svm *svm) | 430 | static void svm_enable_lbrv(struct vcpu_svm *svm) |
| @@ -595,8 +651,10 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
| 595 | } | 651 | } |
| 596 | force_new_asid(&svm->vcpu); | 652 | force_new_asid(&svm->vcpu); |
| 597 | 653 | ||
| 598 | svm->nested_vmcb = 0; | 654 | svm->nested.vmcb = 0; |
| 599 | svm->vcpu.arch.hflags = HF_GIF_MASK; | 655 | svm->vcpu.arch.hflags = 0; |
| 656 | |||
| 657 | enable_gif(svm); | ||
| 600 | } | 658 | } |
| 601 | 659 | ||
| 602 | static int svm_vcpu_reset(struct kvm_vcpu *vcpu) | 660 | static int svm_vcpu_reset(struct kvm_vcpu *vcpu) |
| @@ -605,7 +663,7 @@ static int svm_vcpu_reset(struct kvm_vcpu *vcpu) | |||
| 605 | 663 | ||
| 606 | init_vmcb(svm); | 664 | init_vmcb(svm); |
| 607 | 665 | ||
| 608 | if (vcpu->vcpu_id != 0) { | 666 | if (!kvm_vcpu_is_bsp(vcpu)) { |
| 609 | kvm_rip_write(vcpu, 0); | 667 | kvm_rip_write(vcpu, 0); |
| 610 | svm->vmcb->save.cs.base = svm->vcpu.arch.sipi_vector << 12; | 668 | svm->vmcb->save.cs.base = svm->vcpu.arch.sipi_vector << 12; |
| 611 | svm->vmcb->save.cs.selector = svm->vcpu.arch.sipi_vector << 8; | 669 | svm->vmcb->save.cs.selector = svm->vcpu.arch.sipi_vector << 8; |
| @@ -656,9 +714,9 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | |||
| 656 | hsave_page = alloc_page(GFP_KERNEL); | 714 | hsave_page = alloc_page(GFP_KERNEL); |
| 657 | if (!hsave_page) | 715 | if (!hsave_page) |
| 658 | goto uninit; | 716 | goto uninit; |
| 659 | svm->hsave = page_address(hsave_page); | 717 | svm->nested.hsave = page_address(hsave_page); |
| 660 | 718 | ||
| 661 | svm->nested_msrpm = page_address(nested_msrpm_pages); | 719 | svm->nested.msrpm = page_address(nested_msrpm_pages); |
| 662 | 720 | ||
| 663 | svm->vmcb = page_address(page); | 721 | svm->vmcb = page_address(page); |
| 664 | clear_page(svm->vmcb); | 722 | clear_page(svm->vmcb); |
| @@ -669,7 +727,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | |||
| 669 | fx_init(&svm->vcpu); | 727 | fx_init(&svm->vcpu); |
| 670 | svm->vcpu.fpu_active = 1; | 728 | svm->vcpu.fpu_active = 1; |
| 671 | svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; | 729 | svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; |
| 672 | if (svm->vcpu.vcpu_id == 0) | 730 | if (kvm_vcpu_is_bsp(&svm->vcpu)) |
| 673 | svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP; | 731 | svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP; |
| 674 | 732 | ||
| 675 | return &svm->vcpu; | 733 | return &svm->vcpu; |
| @@ -688,8 +746,8 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu) | |||
| 688 | 746 | ||
| 689 | __free_page(pfn_to_page(svm->vmcb_pa >> PAGE_SHIFT)); | 747 | __free_page(pfn_to_page(svm->vmcb_pa >> PAGE_SHIFT)); |
| 690 | __free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER); | 748 | __free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER); |
| 691 | __free_page(virt_to_page(svm->hsave)); | 749 | __free_page(virt_to_page(svm->nested.hsave)); |
| 692 | __free_pages(virt_to_page(svm->nested_msrpm), MSRPM_ALLOC_ORDER); | 750 | __free_pages(virt_to_page(svm->nested.msrpm), MSRPM_ALLOC_ORDER); |
| 693 | kvm_vcpu_uninit(vcpu); | 751 | kvm_vcpu_uninit(vcpu); |
| 694 | kmem_cache_free(kvm_vcpu_cache, svm); | 752 | kmem_cache_free(kvm_vcpu_cache, svm); |
| 695 | } | 753 | } |
| @@ -740,6 +798,18 @@ static void svm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) | |||
| 740 | to_svm(vcpu)->vmcb->save.rflags = rflags; | 798 | to_svm(vcpu)->vmcb->save.rflags = rflags; |
| 741 | } | 799 | } |
| 742 | 800 | ||
| 801 | static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) | ||
| 802 | { | ||
| 803 | switch (reg) { | ||
| 804 | case VCPU_EXREG_PDPTR: | ||
| 805 | BUG_ON(!npt_enabled); | ||
| 806 | load_pdptrs(vcpu, vcpu->arch.cr3); | ||
| 807 | break; | ||
| 808 | default: | ||
| 809 | BUG(); | ||
| 810 | } | ||
| 811 | } | ||
| 812 | |||
| 743 | static void svm_set_vintr(struct vcpu_svm *svm) | 813 | static void svm_set_vintr(struct vcpu_svm *svm) |
| 744 | { | 814 | { |
| 745 | svm->vmcb->control.intercept |= 1ULL << INTERCEPT_VINTR; | 815 | svm->vmcb->control.intercept |= 1ULL << INTERCEPT_VINTR; |
| @@ -1061,7 +1131,6 @@ static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr) | |||
| 1061 | val = 0; | 1131 | val = 0; |
| 1062 | } | 1132 | } |
| 1063 | 1133 | ||
| 1064 | KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler); | ||
| 1065 | return val; | 1134 | return val; |
| 1066 | } | 1135 | } |
| 1067 | 1136 | ||
| @@ -1070,8 +1139,6 @@ static void svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value, | |||
| 1070 | { | 1139 | { |
| 1071 | struct vcpu_svm *svm = to_svm(vcpu); | 1140 | struct vcpu_svm *svm = to_svm(vcpu); |
| 1072 | 1141 | ||
| 1073 | KVMTRACE_2D(DR_WRITE, vcpu, (u32)dr, (u32)value, handler); | ||
| 1074 | |||
| 1075 | *exception = 0; | 1142 | *exception = 0; |
| 1076 | 1143 | ||
| 1077 | switch (dr) { | 1144 | switch (dr) { |
| @@ -1119,25 +1186,9 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
| 1119 | fault_address = svm->vmcb->control.exit_info_2; | 1186 | fault_address = svm->vmcb->control.exit_info_2; |
| 1120 | error_code = svm->vmcb->control.exit_info_1; | 1187 | error_code = svm->vmcb->control.exit_info_1; |
| 1121 | 1188 | ||
| 1122 | if (!npt_enabled) | 1189 | trace_kvm_page_fault(fault_address, error_code); |
| 1123 | KVMTRACE_3D(PAGE_FAULT, &svm->vcpu, error_code, | 1190 | if (!npt_enabled && kvm_event_needs_reinjection(&svm->vcpu)) |
| 1124 | (u32)fault_address, (u32)(fault_address >> 32), | 1191 | kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address); |
| 1125 | handler); | ||
| 1126 | else | ||
| 1127 | KVMTRACE_3D(TDP_FAULT, &svm->vcpu, error_code, | ||
| 1128 | (u32)fault_address, (u32)(fault_address >> 32), | ||
| 1129 | handler); | ||
| 1130 | /* | ||
| 1131 | * FIXME: Tis shouldn't be necessary here, but there is a flush | ||
| 1132 | * missing in the MMU code. Until we find this bug, flush the | ||
| 1133 | * complete TLB here on an NPF | ||
| 1134 | */ | ||
| 1135 | if (npt_enabled) | ||
| 1136 | svm_flush_tlb(&svm->vcpu); | ||
| 1137 | else { | ||
| 1138 | if (kvm_event_needs_reinjection(&svm->vcpu)) | ||
| 1139 | kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address); | ||
| 1140 | } | ||
| 1141 | return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code); | 1192 | return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code); |
| 1142 | } | 1193 | } |
| 1143 | 1194 | ||
| @@ -1253,14 +1304,12 @@ static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
| 1253 | 1304 | ||
| 1254 | static int nmi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | 1305 | static int nmi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) |
| 1255 | { | 1306 | { |
| 1256 | KVMTRACE_0D(NMI, &svm->vcpu, handler); | ||
| 1257 | return 1; | 1307 | return 1; |
| 1258 | } | 1308 | } |
| 1259 | 1309 | ||
| 1260 | static int intr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | 1310 | static int intr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) |
| 1261 | { | 1311 | { |
| 1262 | ++svm->vcpu.stat.irq_exits; | 1312 | ++svm->vcpu.stat.irq_exits; |
| 1263 | KVMTRACE_0D(INTR, &svm->vcpu, handler); | ||
| 1264 | return 1; | 1313 | return 1; |
| 1265 | } | 1314 | } |
| 1266 | 1315 | ||
| @@ -1303,44 +1352,39 @@ static int nested_svm_check_permissions(struct vcpu_svm *svm) | |||
| 1303 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, | 1352 | static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, |
| 1304 | bool has_error_code, u32 error_code) | 1353 | bool has_error_code, u32 error_code) |
| 1305 | { | 1354 | { |
| 1306 | if (is_nested(svm)) { | 1355 | if (!is_nested(svm)) |
| 1307 | svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr; | 1356 | return 0; |
| 1308 | svm->vmcb->control.exit_code_hi = 0; | ||
| 1309 | svm->vmcb->control.exit_info_1 = error_code; | ||
| 1310 | svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2; | ||
| 1311 | if (nested_svm_exit_handled(svm, false)) { | ||
| 1312 | nsvm_printk("VMexit -> EXCP 0x%x\n", nr); | ||
| 1313 | |||
| 1314 | nested_svm_vmexit(svm); | ||
| 1315 | return 1; | ||
| 1316 | } | ||
| 1317 | } | ||
| 1318 | 1357 | ||
| 1319 | return 0; | 1358 | svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr; |
| 1359 | svm->vmcb->control.exit_code_hi = 0; | ||
| 1360 | svm->vmcb->control.exit_info_1 = error_code; | ||
| 1361 | svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2; | ||
| 1362 | |||
| 1363 | return nested_svm_exit_handled(svm); | ||
| 1320 | } | 1364 | } |
| 1321 | 1365 | ||
| 1322 | static inline int nested_svm_intr(struct vcpu_svm *svm) | 1366 | static inline int nested_svm_intr(struct vcpu_svm *svm) |
| 1323 | { | 1367 | { |
| 1324 | if (is_nested(svm)) { | 1368 | if (!is_nested(svm)) |
| 1325 | if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK)) | 1369 | return 0; |
| 1326 | return 0; | ||
| 1327 | 1370 | ||
| 1328 | if (!(svm->vcpu.arch.hflags & HF_HIF_MASK)) | 1371 | if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK)) |
| 1329 | return 0; | 1372 | return 0; |
| 1330 | 1373 | ||
| 1331 | svm->vmcb->control.exit_code = SVM_EXIT_INTR; | 1374 | if (!(svm->vcpu.arch.hflags & HF_HIF_MASK)) |
| 1375 | return 0; | ||
| 1332 | 1376 | ||
| 1333 | if (nested_svm_exit_handled(svm, false)) { | 1377 | svm->vmcb->control.exit_code = SVM_EXIT_INTR; |
| 1334 | nsvm_printk("VMexit -> INTR\n"); | 1378 | |
| 1335 | nested_svm_vmexit(svm); | 1379 | if (nested_svm_exit_handled(svm)) { |
| 1336 | return 1; | 1380 | nsvm_printk("VMexit -> INTR\n"); |
| 1337 | } | 1381 | return 1; |
| 1338 | } | 1382 | } |
| 1339 | 1383 | ||
| 1340 | return 0; | 1384 | return 0; |
| 1341 | } | 1385 | } |
| 1342 | 1386 | ||
| 1343 | static struct page *nested_svm_get_page(struct vcpu_svm *svm, u64 gpa) | 1387 | static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, enum km_type idx) |
| 1344 | { | 1388 | { |
| 1345 | struct page *page; | 1389 | struct page *page; |
| 1346 | 1390 | ||
| @@ -1348,236 +1392,246 @@ static struct page *nested_svm_get_page(struct vcpu_svm *svm, u64 gpa) | |||
| 1348 | page = gfn_to_page(svm->vcpu.kvm, gpa >> PAGE_SHIFT); | 1392 | page = gfn_to_page(svm->vcpu.kvm, gpa >> PAGE_SHIFT); |
| 1349 | up_read(¤t->mm->mmap_sem); | 1393 | up_read(¤t->mm->mmap_sem); |
| 1350 | 1394 | ||
| 1351 | if (is_error_page(page)) { | 1395 | if (is_error_page(page)) |
| 1352 | printk(KERN_INFO "%s: could not find page at 0x%llx\n", | 1396 | goto error; |
| 1353 | __func__, gpa); | 1397 | |
| 1354 | kvm_release_page_clean(page); | 1398 | return kmap_atomic(page, idx); |
| 1355 | kvm_inject_gp(&svm->vcpu, 0); | 1399 | |
| 1356 | return NULL; | 1400 | error: |
| 1357 | } | 1401 | kvm_release_page_clean(page); |
| 1358 | return page; | 1402 | kvm_inject_gp(&svm->vcpu, 0); |
| 1403 | |||
| 1404 | return NULL; | ||
| 1359 | } | 1405 | } |
| 1360 | 1406 | ||
| 1361 | static int nested_svm_do(struct vcpu_svm *svm, | 1407 | static void nested_svm_unmap(void *addr, enum km_type idx) |
| 1362 | u64 arg1_gpa, u64 arg2_gpa, void *opaque, | ||
| 1363 | int (*handler)(struct vcpu_svm *svm, | ||
| 1364 | void *arg1, | ||
| 1365 | void *arg2, | ||
| 1366 | void *opaque)) | ||
| 1367 | { | 1408 | { |
| 1368 | struct page *arg1_page; | 1409 | struct page *page; |
| 1369 | struct page *arg2_page = NULL; | ||
| 1370 | void *arg1; | ||
| 1371 | void *arg2 = NULL; | ||
| 1372 | int retval; | ||
| 1373 | 1410 | ||
| 1374 | arg1_page = nested_svm_get_page(svm, arg1_gpa); | 1411 | if (!addr) |
| 1375 | if(arg1_page == NULL) | 1412 | return; |
| 1376 | return 1; | ||
| 1377 | 1413 | ||
| 1378 | if (arg2_gpa) { | 1414 | page = kmap_atomic_to_page(addr); |
| 1379 | arg2_page = nested_svm_get_page(svm, arg2_gpa); | 1415 | |
| 1380 | if(arg2_page == NULL) { | 1416 | kunmap_atomic(addr, idx); |
| 1381 | kvm_release_page_clean(arg1_page); | 1417 | kvm_release_page_dirty(page); |
| 1382 | return 1; | 1418 | } |
| 1383 | } | 1419 | |
| 1384 | } | 1420 | static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm) |
| 1421 | { | ||
| 1422 | u32 param = svm->vmcb->control.exit_info_1 & 1; | ||
| 1423 | u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; | ||
| 1424 | bool ret = false; | ||
| 1425 | u32 t0, t1; | ||
| 1426 | u8 *msrpm; | ||
| 1385 | 1427 | ||
| 1386 | arg1 = kmap_atomic(arg1_page, KM_USER0); | 1428 | if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT))) |
| 1387 | if (arg2_gpa) | 1429 | return false; |
| 1388 | arg2 = kmap_atomic(arg2_page, KM_USER1); | ||
| 1389 | 1430 | ||
| 1390 | retval = handler(svm, arg1, arg2, opaque); | 1431 | msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0); |
| 1432 | |||
| 1433 | if (!msrpm) | ||
| 1434 | goto out; | ||
| 1435 | |||
| 1436 | switch (msr) { | ||
| 1437 | case 0 ... 0x1fff: | ||
| 1438 | t0 = (msr * 2) % 8; | ||
| 1439 | t1 = msr / 8; | ||
| 1440 | break; | ||
| 1441 | case 0xc0000000 ... 0xc0001fff: | ||
| 1442 | t0 = (8192 + msr - 0xc0000000) * 2; | ||
| 1443 | t1 = (t0 / 8); | ||
| 1444 | t0 %= 8; | ||
| 1445 | break; | ||
| 1446 | case 0xc0010000 ... 0xc0011fff: | ||
| 1447 | t0 = (16384 + msr - 0xc0010000) * 2; | ||
| 1448 | t1 = (t0 / 8); | ||
| 1449 | t0 %= 8; | ||
| 1450 | break; | ||
| 1451 | default: | ||
| 1452 | ret = true; | ||
| 1453 | goto out; | ||
| 1454 | } | ||
| 1391 | 1455 | ||
| 1392 | kunmap_atomic(arg1, KM_USER0); | 1456 | ret = msrpm[t1] & ((1 << param) << t0); |
| 1393 | if (arg2_gpa) | ||
| 1394 | kunmap_atomic(arg2, KM_USER1); | ||
| 1395 | 1457 | ||
| 1396 | kvm_release_page_dirty(arg1_page); | 1458 | out: |
| 1397 | if (arg2_gpa) | 1459 | nested_svm_unmap(msrpm, KM_USER0); |
| 1398 | kvm_release_page_dirty(arg2_page); | ||
| 1399 | 1460 | ||
| 1400 | return retval; | 1461 | return ret; |
| 1401 | } | 1462 | } |
| 1402 | 1463 | ||
| 1403 | static int nested_svm_exit_handled_real(struct vcpu_svm *svm, | 1464 | static int nested_svm_exit_special(struct vcpu_svm *svm) |
| 1404 | void *arg1, | ||
| 1405 | void *arg2, | ||
| 1406 | void *opaque) | ||
| 1407 | { | 1465 | { |
| 1408 | struct vmcb *nested_vmcb = (struct vmcb *)arg1; | ||
| 1409 | bool kvm_overrides = *(bool *)opaque; | ||
| 1410 | u32 exit_code = svm->vmcb->control.exit_code; | 1466 | u32 exit_code = svm->vmcb->control.exit_code; |
| 1411 | 1467 | ||
| 1412 | if (kvm_overrides) { | 1468 | switch (exit_code) { |
| 1413 | switch (exit_code) { | 1469 | case SVM_EXIT_INTR: |
| 1414 | case SVM_EXIT_INTR: | 1470 | case SVM_EXIT_NMI: |
| 1415 | case SVM_EXIT_NMI: | 1471 | return NESTED_EXIT_HOST; |
| 1416 | return 0; | ||
| 1417 | /* For now we are always handling NPFs when using them */ | 1472 | /* For now we are always handling NPFs when using them */ |
| 1418 | case SVM_EXIT_NPF: | 1473 | case SVM_EXIT_NPF: |
| 1419 | if (npt_enabled) | 1474 | if (npt_enabled) |
| 1420 | return 0; | 1475 | return NESTED_EXIT_HOST; |
| 1421 | break; | 1476 | break; |
| 1422 | /* When we're shadowing, trap PFs */ | 1477 | /* When we're shadowing, trap PFs */ |
| 1423 | case SVM_EXIT_EXCP_BASE + PF_VECTOR: | 1478 | case SVM_EXIT_EXCP_BASE + PF_VECTOR: |
| 1424 | if (!npt_enabled) | 1479 | if (!npt_enabled) |
| 1425 | return 0; | 1480 | return NESTED_EXIT_HOST; |
| 1426 | break; | 1481 | break; |
| 1427 | default: | 1482 | default: |
| 1428 | break; | 1483 | break; |
| 1429 | } | ||
| 1430 | } | 1484 | } |
| 1431 | 1485 | ||
| 1486 | return NESTED_EXIT_CONTINUE; | ||
| 1487 | } | ||
| 1488 | |||
| 1489 | /* | ||
| 1490 | * If this function returns true, this #vmexit was already handled | ||
| 1491 | */ | ||
| 1492 | static int nested_svm_exit_handled(struct vcpu_svm *svm) | ||
| 1493 | { | ||
| 1494 | u32 exit_code = svm->vmcb->control.exit_code; | ||
| 1495 | int vmexit = NESTED_EXIT_HOST; | ||
| 1496 | |||
| 1432 | switch (exit_code) { | 1497 | switch (exit_code) { |
| 1498 | case SVM_EXIT_MSR: | ||
| 1499 | vmexit = nested_svm_exit_handled_msr(svm); | ||
| 1500 | break; | ||
| 1433 | case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: { | 1501 | case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: { |
| 1434 | u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0); | 1502 | u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0); |
| 1435 | if (nested_vmcb->control.intercept_cr_read & cr_bits) | 1503 | if (svm->nested.intercept_cr_read & cr_bits) |
| 1436 | return 1; | 1504 | vmexit = NESTED_EXIT_DONE; |
| 1437 | break; | 1505 | break; |
| 1438 | } | 1506 | } |
| 1439 | case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR8: { | 1507 | case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR8: { |
| 1440 | u32 cr_bits = 1 << (exit_code - SVM_EXIT_WRITE_CR0); | 1508 | u32 cr_bits = 1 << (exit_code - SVM_EXIT_WRITE_CR0); |
| 1441 | if (nested_vmcb->control.intercept_cr_write & cr_bits) | 1509 | if (svm->nested.intercept_cr_write & cr_bits) |
| 1442 | return 1; | 1510 | vmexit = NESTED_EXIT_DONE; |
| 1443 | break; | 1511 | break; |
| 1444 | } | 1512 | } |
| 1445 | case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR7: { | 1513 | case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR7: { |
| 1446 | u32 dr_bits = 1 << (exit_code - SVM_EXIT_READ_DR0); | 1514 | u32 dr_bits = 1 << (exit_code - SVM_EXIT_READ_DR0); |
| 1447 | if (nested_vmcb->control.intercept_dr_read & dr_bits) | 1515 | if (svm->nested.intercept_dr_read & dr_bits) |
| 1448 | return 1; | 1516 | vmexit = NESTED_EXIT_DONE; |
| 1449 | break; | 1517 | break; |
| 1450 | } | 1518 | } |
| 1451 | case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR7: { | 1519 | case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR7: { |
| 1452 | u32 dr_bits = 1 << (exit_code - SVM_EXIT_WRITE_DR0); | 1520 | u32 dr_bits = 1 << (exit_code - SVM_EXIT_WRITE_DR0); |
| 1453 | if (nested_vmcb->control.intercept_dr_write & dr_bits) | 1521 | if (svm->nested.intercept_dr_write & dr_bits) |
| 1454 | return 1; | 1522 | vmexit = NESTED_EXIT_DONE; |
| 1455 | break; | 1523 | break; |
| 1456 | } | 1524 | } |
| 1457 | case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 0x1f: { | 1525 | case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 0x1f: { |
| 1458 | u32 excp_bits = 1 << (exit_code - SVM_EXIT_EXCP_BASE); | 1526 | u32 excp_bits = 1 << (exit_code - SVM_EXIT_EXCP_BASE); |
| 1459 | if (nested_vmcb->control.intercept_exceptions & excp_bits) | 1527 | if (svm->nested.intercept_exceptions & excp_bits) |
| 1460 | return 1; | 1528 | vmexit = NESTED_EXIT_DONE; |
| 1461 | break; | 1529 | break; |
| 1462 | } | 1530 | } |
| 1463 | default: { | 1531 | default: { |
| 1464 | u64 exit_bits = 1ULL << (exit_code - SVM_EXIT_INTR); | 1532 | u64 exit_bits = 1ULL << (exit_code - SVM_EXIT_INTR); |
| 1465 | nsvm_printk("exit code: 0x%x\n", exit_code); | 1533 | nsvm_printk("exit code: 0x%x\n", exit_code); |
| 1466 | if (nested_vmcb->control.intercept & exit_bits) | 1534 | if (svm->nested.intercept & exit_bits) |
| 1467 | return 1; | 1535 | vmexit = NESTED_EXIT_DONE; |
| 1468 | } | 1536 | } |
| 1469 | } | 1537 | } |
| 1470 | 1538 | ||
| 1471 | return 0; | 1539 | if (vmexit == NESTED_EXIT_DONE) { |
| 1472 | } | 1540 | nsvm_printk("#VMEXIT reason=%04x\n", exit_code); |
| 1473 | 1541 | nested_svm_vmexit(svm); | |
| 1474 | static int nested_svm_exit_handled_msr(struct vcpu_svm *svm, | ||
| 1475 | void *arg1, void *arg2, | ||
| 1476 | void *opaque) | ||
| 1477 | { | ||
| 1478 | struct vmcb *nested_vmcb = (struct vmcb *)arg1; | ||
| 1479 | u8 *msrpm = (u8 *)arg2; | ||
| 1480 | u32 t0, t1; | ||
| 1481 | u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; | ||
| 1482 | u32 param = svm->vmcb->control.exit_info_1 & 1; | ||
| 1483 | |||
| 1484 | if (!(nested_vmcb->control.intercept & (1ULL << INTERCEPT_MSR_PROT))) | ||
| 1485 | return 0; | ||
| 1486 | |||
| 1487 | switch(msr) { | ||
| 1488 | case 0 ... 0x1fff: | ||
| 1489 | t0 = (msr * 2) % 8; | ||
| 1490 | t1 = msr / 8; | ||
| 1491 | break; | ||
| 1492 | case 0xc0000000 ... 0xc0001fff: | ||
| 1493 | t0 = (8192 + msr - 0xc0000000) * 2; | ||
| 1494 | t1 = (t0 / 8); | ||
| 1495 | t0 %= 8; | ||
| 1496 | break; | ||
| 1497 | case 0xc0010000 ... 0xc0011fff: | ||
| 1498 | t0 = (16384 + msr - 0xc0010000) * 2; | ||
| 1499 | t1 = (t0 / 8); | ||
| 1500 | t0 %= 8; | ||
| 1501 | break; | ||
| 1502 | default: | ||
| 1503 | return 1; | ||
| 1504 | break; | ||
| 1505 | } | 1542 | } |
| 1506 | if (msrpm[t1] & ((1 << param) << t0)) | ||
| 1507 | return 1; | ||
| 1508 | 1543 | ||
| 1509 | return 0; | 1544 | return vmexit; |
| 1545 | } | ||
| 1546 | |||
| 1547 | static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *from_vmcb) | ||
| 1548 | { | ||
| 1549 | struct vmcb_control_area *dst = &dst_vmcb->control; | ||
| 1550 | struct vmcb_control_area *from = &from_vmcb->control; | ||
| 1551 | |||
| 1552 | dst->intercept_cr_read = from->intercept_cr_read; | ||
| 1553 | dst->intercept_cr_write = from->intercept_cr_write; | ||
| 1554 | dst->intercept_dr_read = from->intercept_dr_read; | ||
| 1555 | dst->intercept_dr_write = from->intercept_dr_write; | ||
| 1556 | dst->intercept_exceptions = from->intercept_exceptions; | ||
| 1557 | dst->intercept = from->intercept; | ||
| 1558 | dst->iopm_base_pa = from->iopm_base_pa; | ||
| 1559 | dst->msrpm_base_pa = from->msrpm_base_pa; | ||
| 1560 | dst->tsc_offset = from->tsc_offset; | ||
| 1561 | dst->asid = from->asid; | ||
| 1562 | dst->tlb_ctl = from->tlb_ctl; | ||
| 1563 | dst->int_ctl = from->int_ctl; | ||
| 1564 | dst->int_vector = from->int_vector; | ||
| 1565 | dst->int_state = from->int_state; | ||
| 1566 | dst->exit_code = from->exit_code; | ||
| 1567 | dst->exit_code_hi = from->exit_code_hi; | ||
| 1568 | dst->exit_info_1 = from->exit_info_1; | ||
| 1569 | dst->exit_info_2 = from->exit_info_2; | ||
| 1570 | dst->exit_int_info = from->exit_int_info; | ||
| 1571 | dst->exit_int_info_err = from->exit_int_info_err; | ||
| 1572 | dst->nested_ctl = from->nested_ctl; | ||
| 1573 | dst->event_inj = from->event_inj; | ||
| 1574 | dst->event_inj_err = from->event_inj_err; | ||
| 1575 | dst->nested_cr3 = from->nested_cr3; | ||
| 1576 | dst->lbr_ctl = from->lbr_ctl; | ||
| 1510 | } | 1577 | } |
| 1511 | 1578 | ||
| 1512 | static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override) | 1579 | static int nested_svm_vmexit(struct vcpu_svm *svm) |
| 1513 | { | 1580 | { |
| 1514 | bool k = kvm_override; | 1581 | struct vmcb *nested_vmcb; |
| 1515 | 1582 | struct vmcb *hsave = svm->nested.hsave; | |
| 1516 | switch (svm->vmcb->control.exit_code) { | 1583 | struct vmcb *vmcb = svm->vmcb; |
| 1517 | case SVM_EXIT_MSR: | ||
| 1518 | return nested_svm_do(svm, svm->nested_vmcb, | ||
| 1519 | svm->nested_vmcb_msrpm, NULL, | ||
| 1520 | nested_svm_exit_handled_msr); | ||
| 1521 | default: break; | ||
| 1522 | } | ||
| 1523 | 1584 | ||
| 1524 | return nested_svm_do(svm, svm->nested_vmcb, 0, &k, | 1585 | nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, KM_USER0); |
| 1525 | nested_svm_exit_handled_real); | 1586 | if (!nested_vmcb) |
| 1526 | } | 1587 | return 1; |
| 1527 | |||
| 1528 | static int nested_svm_vmexit_real(struct vcpu_svm *svm, void *arg1, | ||
| 1529 | void *arg2, void *opaque) | ||
| 1530 | { | ||
| 1531 | struct vmcb *nested_vmcb = (struct vmcb *)arg1; | ||
| 1532 | struct vmcb *hsave = svm->hsave; | ||
| 1533 | u64 nested_save[] = { nested_vmcb->save.cr0, | ||
| 1534 | nested_vmcb->save.cr3, | ||
| 1535 | nested_vmcb->save.cr4, | ||
| 1536 | nested_vmcb->save.efer, | ||
| 1537 | nested_vmcb->control.intercept_cr_read, | ||
| 1538 | nested_vmcb->control.intercept_cr_write, | ||
| 1539 | nested_vmcb->control.intercept_dr_read, | ||
| 1540 | nested_vmcb->control.intercept_dr_write, | ||
| 1541 | nested_vmcb->control.intercept_exceptions, | ||
| 1542 | nested_vmcb->control.intercept, | ||
| 1543 | nested_vmcb->control.msrpm_base_pa, | ||
| 1544 | nested_vmcb->control.iopm_base_pa, | ||
| 1545 | nested_vmcb->control.tsc_offset }; | ||
| 1546 | 1588 | ||
| 1547 | /* Give the current vmcb to the guest */ | 1589 | /* Give the current vmcb to the guest */ |
| 1548 | memcpy(nested_vmcb, svm->vmcb, sizeof(struct vmcb)); | 1590 | disable_gif(svm); |
| 1549 | nested_vmcb->save.cr0 = nested_save[0]; | 1591 | |
| 1550 | if (!npt_enabled) | 1592 | nested_vmcb->save.es = vmcb->save.es; |
| 1551 | nested_vmcb->save.cr3 = nested_save[1]; | 1593 | nested_vmcb->save.cs = vmcb->save.cs; |
| 1552 | nested_vmcb->save.cr4 = nested_save[2]; | 1594 | nested_vmcb->save.ss = vmcb->save.ss; |
| 1553 | nested_vmcb->save.efer = nested_save[3]; | 1595 | nested_vmcb->save.ds = vmcb->save.ds; |
| 1554 | nested_vmcb->control.intercept_cr_read = nested_save[4]; | 1596 | nested_vmcb->save.gdtr = vmcb->save.gdtr; |
| 1555 | nested_vmcb->control.intercept_cr_write = nested_save[5]; | 1597 | nested_vmcb->save.idtr = vmcb->save.idtr; |
| 1556 | nested_vmcb->control.intercept_dr_read = nested_save[6]; | 1598 | if (npt_enabled) |
| 1557 | nested_vmcb->control.intercept_dr_write = nested_save[7]; | 1599 | nested_vmcb->save.cr3 = vmcb->save.cr3; |
| 1558 | nested_vmcb->control.intercept_exceptions = nested_save[8]; | 1600 | nested_vmcb->save.cr2 = vmcb->save.cr2; |
| 1559 | nested_vmcb->control.intercept = nested_save[9]; | 1601 | nested_vmcb->save.rflags = vmcb->save.rflags; |
| 1560 | nested_vmcb->control.msrpm_base_pa = nested_save[10]; | 1602 | nested_vmcb->save.rip = vmcb->save.rip; |
| 1561 | nested_vmcb->control.iopm_base_pa = nested_save[11]; | 1603 | nested_vmcb->save.rsp = vmcb->save.rsp; |
| 1562 | nested_vmcb->control.tsc_offset = nested_save[12]; | 1604 | nested_vmcb->save.rax = vmcb->save.rax; |
| 1605 | nested_vmcb->save.dr7 = vmcb->save.dr7; | ||
| 1606 | nested_vmcb->save.dr6 = vmcb->save.dr6; | ||
| 1607 | nested_vmcb->save.cpl = vmcb->save.cpl; | ||
| 1608 | |||
| 1609 | nested_vmcb->control.int_ctl = vmcb->control.int_ctl; | ||
| 1610 | nested_vmcb->control.int_vector = vmcb->control.int_vector; | ||
| 1611 | nested_vmcb->control.int_state = vmcb->control.int_state; | ||
| 1612 | nested_vmcb->control.exit_code = vmcb->control.exit_code; | ||
| 1613 | nested_vmcb->control.exit_code_hi = vmcb->control.exit_code_hi; | ||
| 1614 | nested_vmcb->control.exit_info_1 = vmcb->control.exit_info_1; | ||
| 1615 | nested_vmcb->control.exit_info_2 = vmcb->control.exit_info_2; | ||
| 1616 | nested_vmcb->control.exit_int_info = vmcb->control.exit_int_info; | ||
| 1617 | nested_vmcb->control.exit_int_info_err = vmcb->control.exit_int_info_err; | ||
| 1618 | nested_vmcb->control.tlb_ctl = 0; | ||
| 1619 | nested_vmcb->control.event_inj = 0; | ||
| 1620 | nested_vmcb->control.event_inj_err = 0; | ||
| 1563 | 1621 | ||
| 1564 | /* We always set V_INTR_MASKING and remember the old value in hflags */ | 1622 | /* We always set V_INTR_MASKING and remember the old value in hflags */ |
| 1565 | if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK)) | 1623 | if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK)) |
| 1566 | nested_vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; | 1624 | nested_vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; |
| 1567 | 1625 | ||
| 1568 | if ((nested_vmcb->control.int_ctl & V_IRQ_MASK) && | ||
| 1569 | (nested_vmcb->control.int_vector)) { | ||
| 1570 | nsvm_printk("WARNING: IRQ 0x%x still enabled on #VMEXIT\n", | ||
| 1571 | nested_vmcb->control.int_vector); | ||
| 1572 | } | ||
| 1573 | |||
| 1574 | /* Restore the original control entries */ | 1626 | /* Restore the original control entries */ |
| 1575 | svm->vmcb->control = hsave->control; | 1627 | copy_vmcb_control_area(vmcb, hsave); |
| 1576 | 1628 | ||
| 1577 | /* Kill any pending exceptions */ | 1629 | /* Kill any pending exceptions */ |
| 1578 | if (svm->vcpu.arch.exception.pending == true) | 1630 | if (svm->vcpu.arch.exception.pending == true) |
| 1579 | nsvm_printk("WARNING: Pending Exception\n"); | 1631 | nsvm_printk("WARNING: Pending Exception\n"); |
| 1580 | svm->vcpu.arch.exception.pending = false; | 1632 | |
| 1633 | kvm_clear_exception_queue(&svm->vcpu); | ||
| 1634 | kvm_clear_interrupt_queue(&svm->vcpu); | ||
| 1581 | 1635 | ||
| 1582 | /* Restore selected save entries */ | 1636 | /* Restore selected save entries */ |
| 1583 | svm->vmcb->save.es = hsave->save.es; | 1637 | svm->vmcb->save.es = hsave->save.es; |
| @@ -1603,19 +1657,10 @@ static int nested_svm_vmexit_real(struct vcpu_svm *svm, void *arg1, | |||
| 1603 | svm->vmcb->save.cpl = 0; | 1657 | svm->vmcb->save.cpl = 0; |
| 1604 | svm->vmcb->control.exit_int_info = 0; | 1658 | svm->vmcb->control.exit_int_info = 0; |
| 1605 | 1659 | ||
| 1606 | svm->vcpu.arch.hflags &= ~HF_GIF_MASK; | ||
| 1607 | /* Exit nested SVM mode */ | 1660 | /* Exit nested SVM mode */ |
| 1608 | svm->nested_vmcb = 0; | 1661 | svm->nested.vmcb = 0; |
| 1609 | 1662 | ||
| 1610 | return 0; | 1663 | nested_svm_unmap(nested_vmcb, KM_USER0); |
| 1611 | } | ||
| 1612 | |||
| 1613 | static int nested_svm_vmexit(struct vcpu_svm *svm) | ||
| 1614 | { | ||
| 1615 | nsvm_printk("VMexit\n"); | ||
| 1616 | if (nested_svm_do(svm, svm->nested_vmcb, 0, | ||
| 1617 | NULL, nested_svm_vmexit_real)) | ||
| 1618 | return 1; | ||
| 1619 | 1664 | ||
| 1620 | kvm_mmu_reset_context(&svm->vcpu); | 1665 | kvm_mmu_reset_context(&svm->vcpu); |
| 1621 | kvm_mmu_load(&svm->vcpu); | 1666 | kvm_mmu_load(&svm->vcpu); |
| @@ -1623,38 +1668,63 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
| 1623 | return 0; | 1668 | return 0; |
| 1624 | } | 1669 | } |
| 1625 | 1670 | ||
| 1626 | static int nested_svm_vmrun_msrpm(struct vcpu_svm *svm, void *arg1, | 1671 | static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) |
| 1627 | void *arg2, void *opaque) | ||
| 1628 | { | 1672 | { |
| 1673 | u32 *nested_msrpm; | ||
| 1629 | int i; | 1674 | int i; |
| 1630 | u32 *nested_msrpm = (u32*)arg1; | 1675 | |
| 1676 | nested_msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0); | ||
| 1677 | if (!nested_msrpm) | ||
| 1678 | return false; | ||
| 1679 | |||
| 1631 | for (i=0; i< PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++) | 1680 | for (i=0; i< PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++) |
| 1632 | svm->nested_msrpm[i] = svm->msrpm[i] | nested_msrpm[i]; | 1681 | svm->nested.msrpm[i] = svm->msrpm[i] | nested_msrpm[i]; |
| 1633 | svm->vmcb->control.msrpm_base_pa = __pa(svm->nested_msrpm); | ||
| 1634 | 1682 | ||
| 1635 | return 0; | 1683 | svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm); |
| 1684 | |||
| 1685 | nested_svm_unmap(nested_msrpm, KM_USER0); | ||
| 1686 | |||
| 1687 | return true; | ||
| 1636 | } | 1688 | } |
| 1637 | 1689 | ||
| 1638 | static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1, | 1690 | static bool nested_svm_vmrun(struct vcpu_svm *svm) |
| 1639 | void *arg2, void *opaque) | ||
| 1640 | { | 1691 | { |
| 1641 | struct vmcb *nested_vmcb = (struct vmcb *)arg1; | 1692 | struct vmcb *nested_vmcb; |
| 1642 | struct vmcb *hsave = svm->hsave; | 1693 | struct vmcb *hsave = svm->nested.hsave; |
| 1694 | struct vmcb *vmcb = svm->vmcb; | ||
| 1695 | |||
| 1696 | nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0); | ||
| 1697 | if (!nested_vmcb) | ||
| 1698 | return false; | ||
| 1643 | 1699 | ||
| 1644 | /* nested_vmcb is our indicator if nested SVM is activated */ | 1700 | /* nested_vmcb is our indicator if nested SVM is activated */ |
| 1645 | svm->nested_vmcb = svm->vmcb->save.rax; | 1701 | svm->nested.vmcb = svm->vmcb->save.rax; |
| 1646 | 1702 | ||
| 1647 | /* Clear internal status */ | 1703 | /* Clear internal status */ |
| 1648 | svm->vcpu.arch.exception.pending = false; | 1704 | kvm_clear_exception_queue(&svm->vcpu); |
| 1705 | kvm_clear_interrupt_queue(&svm->vcpu); | ||
| 1649 | 1706 | ||
| 1650 | /* Save the old vmcb, so we don't need to pick what we save, but | 1707 | /* Save the old vmcb, so we don't need to pick what we save, but |
| 1651 | can restore everything when a VMEXIT occurs */ | 1708 | can restore everything when a VMEXIT occurs */ |
| 1652 | memcpy(hsave, svm->vmcb, sizeof(struct vmcb)); | 1709 | hsave->save.es = vmcb->save.es; |
| 1653 | /* We need to remember the original CR3 in the SPT case */ | 1710 | hsave->save.cs = vmcb->save.cs; |
| 1654 | if (!npt_enabled) | 1711 | hsave->save.ss = vmcb->save.ss; |
| 1655 | hsave->save.cr3 = svm->vcpu.arch.cr3; | 1712 | hsave->save.ds = vmcb->save.ds; |
| 1656 | hsave->save.cr4 = svm->vcpu.arch.cr4; | 1713 | hsave->save.gdtr = vmcb->save.gdtr; |
| 1657 | hsave->save.rip = svm->next_rip; | 1714 | hsave->save.idtr = vmcb->save.idtr; |
| 1715 | hsave->save.efer = svm->vcpu.arch.shadow_efer; | ||
| 1716 | hsave->save.cr0 = svm->vcpu.arch.cr0; | ||
| 1717 | hsave->save.cr4 = svm->vcpu.arch.cr4; | ||
| 1718 | hsave->save.rflags = vmcb->save.rflags; | ||
| 1719 | hsave->save.rip = svm->next_rip; | ||
| 1720 | hsave->save.rsp = vmcb->save.rsp; | ||
| 1721 | hsave->save.rax = vmcb->save.rax; | ||
| 1722 | if (npt_enabled) | ||
| 1723 | hsave->save.cr3 = vmcb->save.cr3; | ||
| 1724 | else | ||
| 1725 | hsave->save.cr3 = svm->vcpu.arch.cr3; | ||
| 1726 | |||
| 1727 | copy_vmcb_control_area(hsave, vmcb); | ||
| 1658 | 1728 | ||
| 1659 | if (svm->vmcb->save.rflags & X86_EFLAGS_IF) | 1729 | if (svm->vmcb->save.rflags & X86_EFLAGS_IF) |
| 1660 | svm->vcpu.arch.hflags |= HF_HIF_MASK; | 1730 | svm->vcpu.arch.hflags |= HF_HIF_MASK; |
| @@ -1679,7 +1749,7 @@ static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1, | |||
| 1679 | kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3); | 1749 | kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3); |
| 1680 | kvm_mmu_reset_context(&svm->vcpu); | 1750 | kvm_mmu_reset_context(&svm->vcpu); |
| 1681 | } | 1751 | } |
| 1682 | svm->vmcb->save.cr2 = nested_vmcb->save.cr2; | 1752 | svm->vmcb->save.cr2 = svm->vcpu.arch.cr2 = nested_vmcb->save.cr2; |
| 1683 | kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, nested_vmcb->save.rax); | 1753 | kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, nested_vmcb->save.rax); |
| 1684 | kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, nested_vmcb->save.rsp); | 1754 | kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, nested_vmcb->save.rsp); |
| 1685 | kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, nested_vmcb->save.rip); | 1755 | kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, nested_vmcb->save.rip); |
| @@ -1706,7 +1776,15 @@ static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1, | |||
| 1706 | 1776 | ||
| 1707 | svm->vmcb->control.intercept |= nested_vmcb->control.intercept; | 1777 | svm->vmcb->control.intercept |= nested_vmcb->control.intercept; |
| 1708 | 1778 | ||
| 1709 | svm->nested_vmcb_msrpm = nested_vmcb->control.msrpm_base_pa; | 1779 | svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa; |
| 1780 | |||
| 1781 | /* cache intercepts */ | ||
| 1782 | svm->nested.intercept_cr_read = nested_vmcb->control.intercept_cr_read; | ||
| 1783 | svm->nested.intercept_cr_write = nested_vmcb->control.intercept_cr_write; | ||
| 1784 | svm->nested.intercept_dr_read = nested_vmcb->control.intercept_dr_read; | ||
| 1785 | svm->nested.intercept_dr_write = nested_vmcb->control.intercept_dr_write; | ||
| 1786 | svm->nested.intercept_exceptions = nested_vmcb->control.intercept_exceptions; | ||
| 1787 | svm->nested.intercept = nested_vmcb->control.intercept; | ||
| 1710 | 1788 | ||
| 1711 | force_new_asid(&svm->vcpu); | 1789 | force_new_asid(&svm->vcpu); |
| 1712 | svm->vmcb->control.exit_int_info = nested_vmcb->control.exit_int_info; | 1790 | svm->vmcb->control.exit_int_info = nested_vmcb->control.exit_int_info; |
| @@ -1734,12 +1812,14 @@ static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1, | |||
| 1734 | svm->vmcb->control.event_inj = nested_vmcb->control.event_inj; | 1812 | svm->vmcb->control.event_inj = nested_vmcb->control.event_inj; |
| 1735 | svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err; | 1813 | svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err; |
| 1736 | 1814 | ||
| 1737 | svm->vcpu.arch.hflags |= HF_GIF_MASK; | 1815 | nested_svm_unmap(nested_vmcb, KM_USER0); |
| 1738 | 1816 | ||
| 1739 | return 0; | 1817 | enable_gif(svm); |
| 1818 | |||
| 1819 | return true; | ||
| 1740 | } | 1820 | } |
| 1741 | 1821 | ||
| 1742 | static int nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb) | 1822 | static void nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb) |
| 1743 | { | 1823 | { |
| 1744 | to_vmcb->save.fs = from_vmcb->save.fs; | 1824 | to_vmcb->save.fs = from_vmcb->save.fs; |
| 1745 | to_vmcb->save.gs = from_vmcb->save.gs; | 1825 | to_vmcb->save.gs = from_vmcb->save.gs; |
| @@ -1753,44 +1833,44 @@ static int nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb) | |||
| 1753 | to_vmcb->save.sysenter_cs = from_vmcb->save.sysenter_cs; | 1833 | to_vmcb->save.sysenter_cs = from_vmcb->save.sysenter_cs; |
| 1754 | to_vmcb->save.sysenter_esp = from_vmcb->save.sysenter_esp; | 1834 | to_vmcb->save.sysenter_esp = from_vmcb->save.sysenter_esp; |
| 1755 | to_vmcb->save.sysenter_eip = from_vmcb->save.sysenter_eip; | 1835 | to_vmcb->save.sysenter_eip = from_vmcb->save.sysenter_eip; |
| 1756 | |||
| 1757 | return 1; | ||
| 1758 | } | ||
| 1759 | |||
| 1760 | static int nested_svm_vmload(struct vcpu_svm *svm, void *nested_vmcb, | ||
| 1761 | void *arg2, void *opaque) | ||
| 1762 | { | ||
| 1763 | return nested_svm_vmloadsave((struct vmcb *)nested_vmcb, svm->vmcb); | ||
| 1764 | } | ||
| 1765 | |||
| 1766 | static int nested_svm_vmsave(struct vcpu_svm *svm, void *nested_vmcb, | ||
| 1767 | void *arg2, void *opaque) | ||
| 1768 | { | ||
| 1769 | return nested_svm_vmloadsave(svm->vmcb, (struct vmcb *)nested_vmcb); | ||
| 1770 | } | 1836 | } |
| 1771 | 1837 | ||
| 1772 | static int vmload_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | 1838 | static int vmload_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) |
| 1773 | { | 1839 | { |
| 1840 | struct vmcb *nested_vmcb; | ||
| 1841 | |||
| 1774 | if (nested_svm_check_permissions(svm)) | 1842 | if (nested_svm_check_permissions(svm)) |
| 1775 | return 1; | 1843 | return 1; |
| 1776 | 1844 | ||
| 1777 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | 1845 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; |
| 1778 | skip_emulated_instruction(&svm->vcpu); | 1846 | skip_emulated_instruction(&svm->vcpu); |
| 1779 | 1847 | ||
| 1780 | nested_svm_do(svm, svm->vmcb->save.rax, 0, NULL, nested_svm_vmload); | 1848 | nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0); |
| 1849 | if (!nested_vmcb) | ||
| 1850 | return 1; | ||
| 1851 | |||
| 1852 | nested_svm_vmloadsave(nested_vmcb, svm->vmcb); | ||
| 1853 | nested_svm_unmap(nested_vmcb, KM_USER0); | ||
| 1781 | 1854 | ||
| 1782 | return 1; | 1855 | return 1; |
| 1783 | } | 1856 | } |
| 1784 | 1857 | ||
| 1785 | static int vmsave_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | 1858 | static int vmsave_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) |
| 1786 | { | 1859 | { |
| 1860 | struct vmcb *nested_vmcb; | ||
| 1861 | |||
| 1787 | if (nested_svm_check_permissions(svm)) | 1862 | if (nested_svm_check_permissions(svm)) |
| 1788 | return 1; | 1863 | return 1; |
| 1789 | 1864 | ||
| 1790 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | 1865 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; |
| 1791 | skip_emulated_instruction(&svm->vcpu); | 1866 | skip_emulated_instruction(&svm->vcpu); |
| 1792 | 1867 | ||
| 1793 | nested_svm_do(svm, svm->vmcb->save.rax, 0, NULL, nested_svm_vmsave); | 1868 | nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0); |
| 1869 | if (!nested_vmcb) | ||
| 1870 | return 1; | ||
| 1871 | |||
| 1872 | nested_svm_vmloadsave(svm->vmcb, nested_vmcb); | ||
| 1873 | nested_svm_unmap(nested_vmcb, KM_USER0); | ||
| 1794 | 1874 | ||
| 1795 | return 1; | 1875 | return 1; |
| 1796 | } | 1876 | } |
| @@ -1798,19 +1878,29 @@ static int vmsave_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
| 1798 | static int vmrun_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | 1878 | static int vmrun_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) |
| 1799 | { | 1879 | { |
| 1800 | nsvm_printk("VMrun\n"); | 1880 | nsvm_printk("VMrun\n"); |
| 1881 | |||
| 1801 | if (nested_svm_check_permissions(svm)) | 1882 | if (nested_svm_check_permissions(svm)) |
| 1802 | return 1; | 1883 | return 1; |
| 1803 | 1884 | ||
| 1804 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | 1885 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; |
| 1805 | skip_emulated_instruction(&svm->vcpu); | 1886 | skip_emulated_instruction(&svm->vcpu); |
| 1806 | 1887 | ||
| 1807 | if (nested_svm_do(svm, svm->vmcb->save.rax, 0, | 1888 | if (!nested_svm_vmrun(svm)) |
| 1808 | NULL, nested_svm_vmrun)) | ||
| 1809 | return 1; | 1889 | return 1; |
| 1810 | 1890 | ||
| 1811 | if (nested_svm_do(svm, svm->nested_vmcb_msrpm, 0, | 1891 | if (!nested_svm_vmrun_msrpm(svm)) |
| 1812 | NULL, nested_svm_vmrun_msrpm)) | 1892 | goto failed; |
| 1813 | return 1; | 1893 | |
| 1894 | return 1; | ||
| 1895 | |||
| 1896 | failed: | ||
| 1897 | |||
| 1898 | svm->vmcb->control.exit_code = SVM_EXIT_ERR; | ||
| 1899 | svm->vmcb->control.exit_code_hi = 0; | ||
| 1900 | svm->vmcb->control.exit_info_1 = 0; | ||
| 1901 | svm->vmcb->control.exit_info_2 = 0; | ||
| 1902 | |||
| 1903 | nested_svm_vmexit(svm); | ||
| 1814 | 1904 | ||
| 1815 | return 1; | 1905 | return 1; |
| 1816 | } | 1906 | } |
| @@ -1823,7 +1913,7 @@ static int stgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
| 1823 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | 1913 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; |
| 1824 | skip_emulated_instruction(&svm->vcpu); | 1914 | skip_emulated_instruction(&svm->vcpu); |
| 1825 | 1915 | ||
| 1826 | svm->vcpu.arch.hflags |= HF_GIF_MASK; | 1916 | enable_gif(svm); |
| 1827 | 1917 | ||
| 1828 | return 1; | 1918 | return 1; |
| 1829 | } | 1919 | } |
| @@ -1836,7 +1926,7 @@ static int clgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
| 1836 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | 1926 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; |
| 1837 | skip_emulated_instruction(&svm->vcpu); | 1927 | skip_emulated_instruction(&svm->vcpu); |
| 1838 | 1928 | ||
| 1839 | svm->vcpu.arch.hflags &= ~HF_GIF_MASK; | 1929 | disable_gif(svm); |
| 1840 | 1930 | ||
| 1841 | /* After a CLGI no interrupts should come */ | 1931 | /* After a CLGI no interrupts should come */ |
| 1842 | svm_clear_vintr(svm); | 1932 | svm_clear_vintr(svm); |
| @@ -1845,6 +1935,19 @@ static int clgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
| 1845 | return 1; | 1935 | return 1; |
| 1846 | } | 1936 | } |
| 1847 | 1937 | ||
| 1938 | static int invlpga_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | ||
| 1939 | { | ||
| 1940 | struct kvm_vcpu *vcpu = &svm->vcpu; | ||
| 1941 | nsvm_printk("INVLPGA\n"); | ||
| 1942 | |||
| 1943 | /* Let's treat INVLPGA the same as INVLPG (can be optimized!) */ | ||
| 1944 | kvm_mmu_invlpg(vcpu, vcpu->arch.regs[VCPU_REGS_RAX]); | ||
| 1945 | |||
| 1946 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 3; | ||
| 1947 | skip_emulated_instruction(&svm->vcpu); | ||
| 1948 | return 1; | ||
| 1949 | } | ||
| 1950 | |||
| 1848 | static int invalid_op_interception(struct vcpu_svm *svm, | 1951 | static int invalid_op_interception(struct vcpu_svm *svm, |
| 1849 | struct kvm_run *kvm_run) | 1952 | struct kvm_run *kvm_run) |
| 1850 | { | 1953 | { |
| @@ -1953,7 +2056,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) | |||
| 1953 | struct vcpu_svm *svm = to_svm(vcpu); | 2056 | struct vcpu_svm *svm = to_svm(vcpu); |
| 1954 | 2057 | ||
| 1955 | switch (ecx) { | 2058 | switch (ecx) { |
| 1956 | case MSR_IA32_TIME_STAMP_COUNTER: { | 2059 | case MSR_IA32_TSC: { |
| 1957 | u64 tsc; | 2060 | u64 tsc; |
| 1958 | 2061 | ||
| 1959 | rdtscll(tsc); | 2062 | rdtscll(tsc); |
| @@ -1981,10 +2084,10 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) | |||
| 1981 | *data = svm->vmcb->save.sysenter_cs; | 2084 | *data = svm->vmcb->save.sysenter_cs; |
| 1982 | break; | 2085 | break; |
| 1983 | case MSR_IA32_SYSENTER_EIP: | 2086 | case MSR_IA32_SYSENTER_EIP: |
| 1984 | *data = svm->vmcb->save.sysenter_eip; | 2087 | *data = svm->sysenter_eip; |
| 1985 | break; | 2088 | break; |
| 1986 | case MSR_IA32_SYSENTER_ESP: | 2089 | case MSR_IA32_SYSENTER_ESP: |
| 1987 | *data = svm->vmcb->save.sysenter_esp; | 2090 | *data = svm->sysenter_esp; |
| 1988 | break; | 2091 | break; |
| 1989 | /* Nobody will change the following 5 values in the VMCB so | 2092 | /* Nobody will change the following 5 values in the VMCB so |
| 1990 | we can safely return them on rdmsr. They will always be 0 | 2093 | we can safely return them on rdmsr. They will always be 0 |
| @@ -2005,7 +2108,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) | |||
| 2005 | *data = svm->vmcb->save.last_excp_to; | 2108 | *data = svm->vmcb->save.last_excp_to; |
| 2006 | break; | 2109 | break; |
| 2007 | case MSR_VM_HSAVE_PA: | 2110 | case MSR_VM_HSAVE_PA: |
| 2008 | *data = svm->hsave_msr; | 2111 | *data = svm->nested.hsave_msr; |
| 2009 | break; | 2112 | break; |
| 2010 | case MSR_VM_CR: | 2113 | case MSR_VM_CR: |
| 2011 | *data = 0; | 2114 | *data = 0; |
| @@ -2027,8 +2130,7 @@ static int rdmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
| 2027 | if (svm_get_msr(&svm->vcpu, ecx, &data)) | 2130 | if (svm_get_msr(&svm->vcpu, ecx, &data)) |
| 2028 | kvm_inject_gp(&svm->vcpu, 0); | 2131 | kvm_inject_gp(&svm->vcpu, 0); |
| 2029 | else { | 2132 | else { |
| 2030 | KVMTRACE_3D(MSR_READ, &svm->vcpu, ecx, (u32)data, | 2133 | trace_kvm_msr_read(ecx, data); |
| 2031 | (u32)(data >> 32), handler); | ||
| 2032 | 2134 | ||
| 2033 | svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff; | 2135 | svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff; |
| 2034 | svm->vcpu.arch.regs[VCPU_REGS_RDX] = data >> 32; | 2136 | svm->vcpu.arch.regs[VCPU_REGS_RDX] = data >> 32; |
| @@ -2043,7 +2145,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) | |||
| 2043 | struct vcpu_svm *svm = to_svm(vcpu); | 2145 | struct vcpu_svm *svm = to_svm(vcpu); |
| 2044 | 2146 | ||
| 2045 | switch (ecx) { | 2147 | switch (ecx) { |
| 2046 | case MSR_IA32_TIME_STAMP_COUNTER: { | 2148 | case MSR_IA32_TSC: { |
| 2047 | u64 tsc; | 2149 | u64 tsc; |
| 2048 | 2150 | ||
| 2049 | rdtscll(tsc); | 2151 | rdtscll(tsc); |
| @@ -2071,9 +2173,11 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) | |||
| 2071 | svm->vmcb->save.sysenter_cs = data; | 2173 | svm->vmcb->save.sysenter_cs = data; |
| 2072 | break; | 2174 | break; |
| 2073 | case MSR_IA32_SYSENTER_EIP: | 2175 | case MSR_IA32_SYSENTER_EIP: |
| 2176 | svm->sysenter_eip = data; | ||
| 2074 | svm->vmcb->save.sysenter_eip = data; | 2177 | svm->vmcb->save.sysenter_eip = data; |
| 2075 | break; | 2178 | break; |
| 2076 | case MSR_IA32_SYSENTER_ESP: | 2179 | case MSR_IA32_SYSENTER_ESP: |
| 2180 | svm->sysenter_esp = data; | ||
| 2077 | svm->vmcb->save.sysenter_esp = data; | 2181 | svm->vmcb->save.sysenter_esp = data; |
| 2078 | break; | 2182 | break; |
| 2079 | case MSR_IA32_DEBUGCTLMSR: | 2183 | case MSR_IA32_DEBUGCTLMSR: |
| @@ -2091,24 +2195,12 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) | |||
| 2091 | else | 2195 | else |
| 2092 | svm_disable_lbrv(svm); | 2196 | svm_disable_lbrv(svm); |
| 2093 | break; | 2197 | break; |
| 2094 | case MSR_K7_EVNTSEL0: | ||
| 2095 | case MSR_K7_EVNTSEL1: | ||
| 2096 | case MSR_K7_EVNTSEL2: | ||
| 2097 | case MSR_K7_EVNTSEL3: | ||
| 2098 | case MSR_K7_PERFCTR0: | ||
| 2099 | case MSR_K7_PERFCTR1: | ||
| 2100 | case MSR_K7_PERFCTR2: | ||
| 2101 | case MSR_K7_PERFCTR3: | ||
| 2102 | /* | ||
| 2103 | * Just discard all writes to the performance counters; this | ||
| 2104 | * should keep both older linux and windows 64-bit guests | ||
| 2105 | * happy | ||
| 2106 | */ | ||
| 2107 | pr_unimpl(vcpu, "unimplemented perfctr wrmsr: 0x%x data 0x%llx\n", ecx, data); | ||
| 2108 | |||
| 2109 | break; | ||
| 2110 | case MSR_VM_HSAVE_PA: | 2198 | case MSR_VM_HSAVE_PA: |
| 2111 | svm->hsave_msr = data; | 2199 | svm->nested.hsave_msr = data; |
| 2200 | break; | ||
| 2201 | case MSR_VM_CR: | ||
| 2202 | case MSR_VM_IGNNE: | ||
| 2203 | pr_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data); | ||
| 2112 | break; | 2204 | break; |
| 2113 | default: | 2205 | default: |
| 2114 | return kvm_set_msr_common(vcpu, ecx, data); | 2206 | return kvm_set_msr_common(vcpu, ecx, data); |
| @@ -2122,8 +2214,7 @@ static int wrmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
| 2122 | u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u) | 2214 | u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u) |
| 2123 | | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32); | 2215 | | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32); |
| 2124 | 2216 | ||
| 2125 | KVMTRACE_3D(MSR_WRITE, &svm->vcpu, ecx, (u32)data, (u32)(data >> 32), | 2217 | trace_kvm_msr_write(ecx, data); |
| 2126 | handler); | ||
| 2127 | 2218 | ||
| 2128 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 2; | 2219 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 2; |
| 2129 | if (svm_set_msr(&svm->vcpu, ecx, data)) | 2220 | if (svm_set_msr(&svm->vcpu, ecx, data)) |
| @@ -2144,8 +2235,6 @@ static int msr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | |||
| 2144 | static int interrupt_window_interception(struct vcpu_svm *svm, | 2235 | static int interrupt_window_interception(struct vcpu_svm *svm, |
| 2145 | struct kvm_run *kvm_run) | 2236 | struct kvm_run *kvm_run) |
| 2146 | { | 2237 | { |
| 2147 | KVMTRACE_0D(PEND_INTR, &svm->vcpu, handler); | ||
| 2148 | |||
| 2149 | svm_clear_vintr(svm); | 2238 | svm_clear_vintr(svm); |
| 2150 | svm->vmcb->control.int_ctl &= ~V_IRQ_MASK; | 2239 | svm->vmcb->control.int_ctl &= ~V_IRQ_MASK; |
| 2151 | /* | 2240 | /* |
| @@ -2201,7 +2290,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm, | |||
| 2201 | [SVM_EXIT_INVD] = emulate_on_interception, | 2290 | [SVM_EXIT_INVD] = emulate_on_interception, |
| 2202 | [SVM_EXIT_HLT] = halt_interception, | 2291 | [SVM_EXIT_HLT] = halt_interception, |
| 2203 | [SVM_EXIT_INVLPG] = invlpg_interception, | 2292 | [SVM_EXIT_INVLPG] = invlpg_interception, |
| 2204 | [SVM_EXIT_INVLPGA] = invalid_op_interception, | 2293 | [SVM_EXIT_INVLPGA] = invlpga_interception, |
| 2205 | [SVM_EXIT_IOIO] = io_interception, | 2294 | [SVM_EXIT_IOIO] = io_interception, |
| 2206 | [SVM_EXIT_MSR] = msr_interception, | 2295 | [SVM_EXIT_MSR] = msr_interception, |
| 2207 | [SVM_EXIT_TASK_SWITCH] = task_switch_interception, | 2296 | [SVM_EXIT_TASK_SWITCH] = task_switch_interception, |
| @@ -2224,20 +2313,26 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
| 2224 | struct vcpu_svm *svm = to_svm(vcpu); | 2313 | struct vcpu_svm *svm = to_svm(vcpu); |
| 2225 | u32 exit_code = svm->vmcb->control.exit_code; | 2314 | u32 exit_code = svm->vmcb->control.exit_code; |
| 2226 | 2315 | ||
| 2227 | KVMTRACE_3D(VMEXIT, vcpu, exit_code, (u32)svm->vmcb->save.rip, | 2316 | trace_kvm_exit(exit_code, svm->vmcb->save.rip); |
| 2228 | (u32)((u64)svm->vmcb->save.rip >> 32), entryexit); | ||
| 2229 | 2317 | ||
| 2230 | if (is_nested(svm)) { | 2318 | if (is_nested(svm)) { |
| 2319 | int vmexit; | ||
| 2320 | |||
| 2231 | nsvm_printk("nested handle_exit: 0x%x | 0x%lx | 0x%lx | 0x%lx\n", | 2321 | nsvm_printk("nested handle_exit: 0x%x | 0x%lx | 0x%lx | 0x%lx\n", |
| 2232 | exit_code, svm->vmcb->control.exit_info_1, | 2322 | exit_code, svm->vmcb->control.exit_info_1, |
| 2233 | svm->vmcb->control.exit_info_2, svm->vmcb->save.rip); | 2323 | svm->vmcb->control.exit_info_2, svm->vmcb->save.rip); |
| 2234 | if (nested_svm_exit_handled(svm, true)) { | 2324 | |
| 2235 | nested_svm_vmexit(svm); | 2325 | vmexit = nested_svm_exit_special(svm); |
| 2236 | nsvm_printk("-> #VMEXIT\n"); | 2326 | |
| 2327 | if (vmexit == NESTED_EXIT_CONTINUE) | ||
| 2328 | vmexit = nested_svm_exit_handled(svm); | ||
| 2329 | |||
| 2330 | if (vmexit == NESTED_EXIT_DONE) | ||
| 2237 | return 1; | 2331 | return 1; |
| 2238 | } | ||
| 2239 | } | 2332 | } |
| 2240 | 2333 | ||
| 2334 | svm_complete_interrupts(svm); | ||
| 2335 | |||
| 2241 | if (npt_enabled) { | 2336 | if (npt_enabled) { |
| 2242 | int mmu_reload = 0; | 2337 | int mmu_reload = 0; |
| 2243 | if ((vcpu->arch.cr0 ^ svm->vmcb->save.cr0) & X86_CR0_PG) { | 2338 | if ((vcpu->arch.cr0 ^ svm->vmcb->save.cr0) & X86_CR0_PG) { |
| @@ -2246,12 +2341,6 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
| 2246 | } | 2341 | } |
| 2247 | vcpu->arch.cr0 = svm->vmcb->save.cr0; | 2342 | vcpu->arch.cr0 = svm->vmcb->save.cr0; |
| 2248 | vcpu->arch.cr3 = svm->vmcb->save.cr3; | 2343 | vcpu->arch.cr3 = svm->vmcb->save.cr3; |
| 2249 | if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { | ||
| 2250 | if (!load_pdptrs(vcpu, vcpu->arch.cr3)) { | ||
| 2251 | kvm_inject_gp(vcpu, 0); | ||
| 2252 | return 1; | ||
| 2253 | } | ||
| 2254 | } | ||
| 2255 | if (mmu_reload) { | 2344 | if (mmu_reload) { |
| 2256 | kvm_mmu_reset_context(vcpu); | 2345 | kvm_mmu_reset_context(vcpu); |
| 2257 | kvm_mmu_load(vcpu); | 2346 | kvm_mmu_load(vcpu); |
| @@ -2319,7 +2408,7 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq) | |||
| 2319 | { | 2408 | { |
| 2320 | struct vmcb_control_area *control; | 2409 | struct vmcb_control_area *control; |
| 2321 | 2410 | ||
| 2322 | KVMTRACE_1D(INJ_VIRQ, &svm->vcpu, (u32)irq, handler); | 2411 | trace_kvm_inj_virq(irq); |
| 2323 | 2412 | ||
| 2324 | ++svm->vcpu.stat.irq_injections; | 2413 | ++svm->vcpu.stat.irq_injections; |
| 2325 | control = &svm->vmcb->control; | 2414 | control = &svm->vmcb->control; |
| @@ -2329,21 +2418,14 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq) | |||
| 2329 | ((/*control->int_vector >> 4*/ 0xf) << V_INTR_PRIO_SHIFT); | 2418 | ((/*control->int_vector >> 4*/ 0xf) << V_INTR_PRIO_SHIFT); |
| 2330 | } | 2419 | } |
| 2331 | 2420 | ||
| 2332 | static void svm_queue_irq(struct kvm_vcpu *vcpu, unsigned nr) | ||
| 2333 | { | ||
| 2334 | struct vcpu_svm *svm = to_svm(vcpu); | ||
| 2335 | |||
| 2336 | svm->vmcb->control.event_inj = nr | | ||
| 2337 | SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR; | ||
| 2338 | } | ||
| 2339 | |||
| 2340 | static void svm_set_irq(struct kvm_vcpu *vcpu) | 2421 | static void svm_set_irq(struct kvm_vcpu *vcpu) |
| 2341 | { | 2422 | { |
| 2342 | struct vcpu_svm *svm = to_svm(vcpu); | 2423 | struct vcpu_svm *svm = to_svm(vcpu); |
| 2343 | 2424 | ||
| 2344 | nested_svm_intr(svm); | 2425 | BUG_ON(!(gif_set(svm))); |
| 2345 | 2426 | ||
| 2346 | svm_queue_irq(vcpu, vcpu->arch.interrupt.nr); | 2427 | svm->vmcb->control.event_inj = vcpu->arch.interrupt.nr | |
| 2428 | SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR; | ||
| 2347 | } | 2429 | } |
| 2348 | 2430 | ||
| 2349 | static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) | 2431 | static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) |
| @@ -2371,13 +2453,25 @@ static int svm_interrupt_allowed(struct kvm_vcpu *vcpu) | |||
| 2371 | struct vmcb *vmcb = svm->vmcb; | 2453 | struct vmcb *vmcb = svm->vmcb; |
| 2372 | return (vmcb->save.rflags & X86_EFLAGS_IF) && | 2454 | return (vmcb->save.rflags & X86_EFLAGS_IF) && |
| 2373 | !(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) && | 2455 | !(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) && |
| 2374 | (svm->vcpu.arch.hflags & HF_GIF_MASK); | 2456 | gif_set(svm) && |
| 2457 | !(is_nested(svm) && (svm->vcpu.arch.hflags & HF_VINTR_MASK)); | ||
| 2375 | } | 2458 | } |
| 2376 | 2459 | ||
| 2377 | static void enable_irq_window(struct kvm_vcpu *vcpu) | 2460 | static void enable_irq_window(struct kvm_vcpu *vcpu) |
| 2378 | { | 2461 | { |
| 2379 | svm_set_vintr(to_svm(vcpu)); | 2462 | struct vcpu_svm *svm = to_svm(vcpu); |
| 2380 | svm_inject_irq(to_svm(vcpu), 0x0); | 2463 | nsvm_printk("Trying to open IRQ window\n"); |
| 2464 | |||
| 2465 | nested_svm_intr(svm); | ||
| 2466 | |||
| 2467 | /* In case GIF=0 we can't rely on the CPU to tell us when | ||
| 2468 | * GIF becomes 1, because that's a separate STGI/VMRUN intercept. | ||
| 2469 | * The next time we get that intercept, this function will be | ||
| 2470 | * called again though and we'll get the vintr intercept. */ | ||
| 2471 | if (gif_set(svm)) { | ||
| 2472 | svm_set_vintr(svm); | ||
| 2473 | svm_inject_irq(svm, 0x0); | ||
| 2474 | } | ||
| 2381 | } | 2475 | } |
| 2382 | 2476 | ||
| 2383 | static void enable_nmi_window(struct kvm_vcpu *vcpu) | 2477 | static void enable_nmi_window(struct kvm_vcpu *vcpu) |
| @@ -2456,6 +2550,8 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) | |||
| 2456 | case SVM_EXITINTINFO_TYPE_EXEPT: | 2550 | case SVM_EXITINTINFO_TYPE_EXEPT: |
| 2457 | /* In case of software exception do not reinject an exception | 2551 | /* In case of software exception do not reinject an exception |
| 2458 | vector, but re-execute and instruction instead */ | 2552 | vector, but re-execute and instruction instead */ |
| 2553 | if (is_nested(svm)) | ||
| 2554 | break; | ||
| 2459 | if (kvm_exception_is_soft(vector)) | 2555 | if (kvm_exception_is_soft(vector)) |
| 2460 | break; | 2556 | break; |
| 2461 | if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) { | 2557 | if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) { |
| @@ -2498,9 +2594,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 2498 | fs_selector = kvm_read_fs(); | 2594 | fs_selector = kvm_read_fs(); |
| 2499 | gs_selector = kvm_read_gs(); | 2595 | gs_selector = kvm_read_gs(); |
| 2500 | ldt_selector = kvm_read_ldt(); | 2596 | ldt_selector = kvm_read_ldt(); |
| 2501 | svm->host_cr2 = kvm_read_cr2(); | 2597 | svm->vmcb->save.cr2 = vcpu->arch.cr2; |
| 2502 | if (!is_nested(svm)) | ||
| 2503 | svm->vmcb->save.cr2 = vcpu->arch.cr2; | ||
| 2504 | /* required for live migration with NPT */ | 2598 | /* required for live migration with NPT */ |
| 2505 | if (npt_enabled) | 2599 | if (npt_enabled) |
| 2506 | svm->vmcb->save.cr3 = vcpu->arch.cr3; | 2600 | svm->vmcb->save.cr3 = vcpu->arch.cr3; |
| @@ -2585,8 +2679,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 2585 | vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; | 2679 | vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; |
| 2586 | vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip; | 2680 | vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip; |
| 2587 | 2681 | ||
| 2588 | kvm_write_cr2(svm->host_cr2); | ||
| 2589 | |||
| 2590 | kvm_load_fs(fs_selector); | 2682 | kvm_load_fs(fs_selector); |
| 2591 | kvm_load_gs(gs_selector); | 2683 | kvm_load_gs(gs_selector); |
| 2592 | kvm_load_ldt(ldt_selector); | 2684 | kvm_load_ldt(ldt_selector); |
| @@ -2602,7 +2694,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 2602 | 2694 | ||
| 2603 | svm->next_rip = 0; | 2695 | svm->next_rip = 0; |
| 2604 | 2696 | ||
| 2605 | svm_complete_interrupts(svm); | 2697 | if (npt_enabled) { |
| 2698 | vcpu->arch.regs_avail &= ~(1 << VCPU_EXREG_PDPTR); | ||
| 2699 | vcpu->arch.regs_dirty &= ~(1 << VCPU_EXREG_PDPTR); | ||
| 2700 | } | ||
| 2606 | } | 2701 | } |
| 2607 | 2702 | ||
| 2608 | #undef R | 2703 | #undef R |
| @@ -2673,6 +2768,64 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio) | |||
| 2673 | return 0; | 2768 | return 0; |
| 2674 | } | 2769 | } |
| 2675 | 2770 | ||
| 2771 | static const struct trace_print_flags svm_exit_reasons_str[] = { | ||
| 2772 | { SVM_EXIT_READ_CR0, "read_cr0" }, | ||
| 2773 | { SVM_EXIT_READ_CR3, "read_cr3" }, | ||
| 2774 | { SVM_EXIT_READ_CR4, "read_cr4" }, | ||
| 2775 | { SVM_EXIT_READ_CR8, "read_cr8" }, | ||
| 2776 | { SVM_EXIT_WRITE_CR0, "write_cr0" }, | ||
| 2777 | { SVM_EXIT_WRITE_CR3, "write_cr3" }, | ||
| 2778 | { SVM_EXIT_WRITE_CR4, "write_cr4" }, | ||
| 2779 | { SVM_EXIT_WRITE_CR8, "write_cr8" }, | ||
| 2780 | { SVM_EXIT_READ_DR0, "read_dr0" }, | ||
| 2781 | { SVM_EXIT_READ_DR1, "read_dr1" }, | ||
| 2782 | { SVM_EXIT_READ_DR2, "read_dr2" }, | ||
| 2783 | { SVM_EXIT_READ_DR3, "read_dr3" }, | ||
| 2784 | { SVM_EXIT_WRITE_DR0, "write_dr0" }, | ||
| 2785 | { SVM_EXIT_WRITE_DR1, "write_dr1" }, | ||
| 2786 | { SVM_EXIT_WRITE_DR2, "write_dr2" }, | ||
| 2787 | { SVM_EXIT_WRITE_DR3, "write_dr3" }, | ||
| 2788 | { SVM_EXIT_WRITE_DR5, "write_dr5" }, | ||
| 2789 | { SVM_EXIT_WRITE_DR7, "write_dr7" }, | ||
| 2790 | { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, | ||
| 2791 | { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, | ||
| 2792 | { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, | ||
| 2793 | { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, | ||
| 2794 | { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, | ||
| 2795 | { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, | ||
| 2796 | { SVM_EXIT_INTR, "interrupt" }, | ||
| 2797 | { SVM_EXIT_NMI, "nmi" }, | ||
| 2798 | { SVM_EXIT_SMI, "smi" }, | ||
| 2799 | { SVM_EXIT_INIT, "init" }, | ||
| 2800 | { SVM_EXIT_VINTR, "vintr" }, | ||
| 2801 | { SVM_EXIT_CPUID, "cpuid" }, | ||
| 2802 | { SVM_EXIT_INVD, "invd" }, | ||
| 2803 | { SVM_EXIT_HLT, "hlt" }, | ||
| 2804 | { SVM_EXIT_INVLPG, "invlpg" }, | ||
| 2805 | { SVM_EXIT_INVLPGA, "invlpga" }, | ||
| 2806 | { SVM_EXIT_IOIO, "io" }, | ||
| 2807 | { SVM_EXIT_MSR, "msr" }, | ||
| 2808 | { SVM_EXIT_TASK_SWITCH, "task_switch" }, | ||
| 2809 | { SVM_EXIT_SHUTDOWN, "shutdown" }, | ||
| 2810 | { SVM_EXIT_VMRUN, "vmrun" }, | ||
| 2811 | { SVM_EXIT_VMMCALL, "hypercall" }, | ||
| 2812 | { SVM_EXIT_VMLOAD, "vmload" }, | ||
| 2813 | { SVM_EXIT_VMSAVE, "vmsave" }, | ||
| 2814 | { SVM_EXIT_STGI, "stgi" }, | ||
| 2815 | { SVM_EXIT_CLGI, "clgi" }, | ||
| 2816 | { SVM_EXIT_SKINIT, "skinit" }, | ||
| 2817 | { SVM_EXIT_WBINVD, "wbinvd" }, | ||
| 2818 | { SVM_EXIT_MONITOR, "monitor" }, | ||
| 2819 | { SVM_EXIT_MWAIT, "mwait" }, | ||
| 2820 | { SVM_EXIT_NPF, "npf" }, | ||
| 2821 | { -1, NULL } | ||
| 2822 | }; | ||
| 2823 | |||
| 2824 | static bool svm_gb_page_enable(void) | ||
| 2825 | { | ||
| 2826 | return true; | ||
| 2827 | } | ||
| 2828 | |||
| 2676 | static struct kvm_x86_ops svm_x86_ops = { | 2829 | static struct kvm_x86_ops svm_x86_ops = { |
| 2677 | .cpu_has_kvm_support = has_svm, | 2830 | .cpu_has_kvm_support = has_svm, |
| 2678 | .disabled_by_bios = is_disabled, | 2831 | .disabled_by_bios = is_disabled, |
| @@ -2710,6 +2863,7 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
| 2710 | .set_gdt = svm_set_gdt, | 2863 | .set_gdt = svm_set_gdt, |
| 2711 | .get_dr = svm_get_dr, | 2864 | .get_dr = svm_get_dr, |
| 2712 | .set_dr = svm_set_dr, | 2865 | .set_dr = svm_set_dr, |
| 2866 | .cache_reg = svm_cache_reg, | ||
| 2713 | .get_rflags = svm_get_rflags, | 2867 | .get_rflags = svm_get_rflags, |
| 2714 | .set_rflags = svm_set_rflags, | 2868 | .set_rflags = svm_set_rflags, |
| 2715 | 2869 | ||
| @@ -2733,6 +2887,9 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
| 2733 | .set_tss_addr = svm_set_tss_addr, | 2887 | .set_tss_addr = svm_set_tss_addr, |
| 2734 | .get_tdp_level = get_npt_level, | 2888 | .get_tdp_level = get_npt_level, |
| 2735 | .get_mt_mask = svm_get_mt_mask, | 2889 | .get_mt_mask = svm_get_mt_mask, |
| 2890 | |||
| 2891 | .exit_reasons_str = svm_exit_reasons_str, | ||
| 2892 | .gb_page_enable = svm_gb_page_enable, | ||
| 2736 | }; | 2893 | }; |
| 2737 | 2894 | ||
| 2738 | static int __init svm_init(void) | 2895 | static int __init svm_init(void) |
diff --git a/arch/x86/kvm/timer.c b/arch/x86/kvm/timer.c index 86dbac072d0c..eea40439066c 100644 --- a/arch/x86/kvm/timer.c +++ b/arch/x86/kvm/timer.c | |||
| @@ -9,12 +9,16 @@ static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer) | |||
| 9 | int restart_timer = 0; | 9 | int restart_timer = 0; |
| 10 | wait_queue_head_t *q = &vcpu->wq; | 10 | wait_queue_head_t *q = &vcpu->wq; |
| 11 | 11 | ||
| 12 | /* FIXME: this code should not know anything about vcpus */ | 12 | /* |
| 13 | if (!atomic_inc_and_test(&ktimer->pending)) | 13 | * There is a race window between reading and incrementing, but we do |
| 14 | * not care about potentially loosing timer events in the !reinject | ||
| 15 | * case anyway. | ||
| 16 | */ | ||
| 17 | if (ktimer->reinject || !atomic_read(&ktimer->pending)) { | ||
| 18 | atomic_inc(&ktimer->pending); | ||
| 19 | /* FIXME: this code should not know anything about vcpus */ | ||
| 14 | set_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests); | 20 | set_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests); |
| 15 | 21 | } | |
| 16 | if (!ktimer->reinject) | ||
| 17 | atomic_set(&ktimer->pending, 1); | ||
| 18 | 22 | ||
| 19 | if (waitqueue_active(q)) | 23 | if (waitqueue_active(q)) |
| 20 | wake_up_interruptible(q); | 24 | wake_up_interruptible(q); |
| @@ -33,7 +37,7 @@ enum hrtimer_restart kvm_timer_fn(struct hrtimer *data) | |||
| 33 | struct kvm_vcpu *vcpu; | 37 | struct kvm_vcpu *vcpu; |
| 34 | struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer); | 38 | struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer); |
| 35 | 39 | ||
| 36 | vcpu = ktimer->kvm->vcpus[ktimer->vcpu_id]; | 40 | vcpu = ktimer->vcpu; |
| 37 | if (!vcpu) | 41 | if (!vcpu) |
| 38 | return HRTIMER_NORESTART; | 42 | return HRTIMER_NORESTART; |
| 39 | 43 | ||
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h new file mode 100644 index 000000000000..0d480e77eacf --- /dev/null +++ b/arch/x86/kvm/trace.h | |||
| @@ -0,0 +1,355 @@ | |||
| 1 | #if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ) | ||
| 2 | #define _TRACE_KVM_H | ||
| 3 | |||
| 4 | #include <linux/tracepoint.h> | ||
| 5 | |||
| 6 | #undef TRACE_SYSTEM | ||
| 7 | #define TRACE_SYSTEM kvm | ||
| 8 | #define TRACE_INCLUDE_PATH arch/x86/kvm | ||
| 9 | #define TRACE_INCLUDE_FILE trace | ||
| 10 | |||
| 11 | /* | ||
| 12 | * Tracepoint for guest mode entry. | ||
| 13 | */ | ||
| 14 | TRACE_EVENT(kvm_entry, | ||
| 15 | TP_PROTO(unsigned int vcpu_id), | ||
| 16 | TP_ARGS(vcpu_id), | ||
| 17 | |||
| 18 | TP_STRUCT__entry( | ||
| 19 | __field( unsigned int, vcpu_id ) | ||
| 20 | ), | ||
| 21 | |||
| 22 | TP_fast_assign( | ||
| 23 | __entry->vcpu_id = vcpu_id; | ||
| 24 | ), | ||
| 25 | |||
| 26 | TP_printk("vcpu %u", __entry->vcpu_id) | ||
| 27 | ); | ||
| 28 | |||
| 29 | /* | ||
| 30 | * Tracepoint for hypercall. | ||
| 31 | */ | ||
| 32 | TRACE_EVENT(kvm_hypercall, | ||
| 33 | TP_PROTO(unsigned long nr, unsigned long a0, unsigned long a1, | ||
| 34 | unsigned long a2, unsigned long a3), | ||
| 35 | TP_ARGS(nr, a0, a1, a2, a3), | ||
| 36 | |||
| 37 | TP_STRUCT__entry( | ||
| 38 | __field( unsigned long, nr ) | ||
| 39 | __field( unsigned long, a0 ) | ||
| 40 | __field( unsigned long, a1 ) | ||
| 41 | __field( unsigned long, a2 ) | ||
| 42 | __field( unsigned long, a3 ) | ||
| 43 | ), | ||
| 44 | |||
| 45 | TP_fast_assign( | ||
| 46 | __entry->nr = nr; | ||
| 47 | __entry->a0 = a0; | ||
| 48 | __entry->a1 = a1; | ||
| 49 | __entry->a2 = a2; | ||
| 50 | __entry->a3 = a3; | ||
| 51 | ), | ||
| 52 | |||
| 53 | TP_printk("nr 0x%lx a0 0x%lx a1 0x%lx a2 0x%lx a3 0x%lx", | ||
| 54 | __entry->nr, __entry->a0, __entry->a1, __entry->a2, | ||
| 55 | __entry->a3) | ||
| 56 | ); | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Tracepoint for PIO. | ||
| 60 | */ | ||
| 61 | TRACE_EVENT(kvm_pio, | ||
| 62 | TP_PROTO(unsigned int rw, unsigned int port, unsigned int size, | ||
| 63 | unsigned int count), | ||
| 64 | TP_ARGS(rw, port, size, count), | ||
| 65 | |||
| 66 | TP_STRUCT__entry( | ||
| 67 | __field( unsigned int, rw ) | ||
| 68 | __field( unsigned int, port ) | ||
| 69 | __field( unsigned int, size ) | ||
| 70 | __field( unsigned int, count ) | ||
| 71 | ), | ||
| 72 | |||
| 73 | TP_fast_assign( | ||
| 74 | __entry->rw = rw; | ||
| 75 | __entry->port = port; | ||
| 76 | __entry->size = size; | ||
| 77 | __entry->count = count; | ||
| 78 | ), | ||
| 79 | |||
| 80 | TP_printk("pio_%s at 0x%x size %d count %d", | ||
| 81 | __entry->rw ? "write" : "read", | ||
| 82 | __entry->port, __entry->size, __entry->count) | ||
| 83 | ); | ||
| 84 | |||
| 85 | /* | ||
| 86 | * Tracepoint for cpuid. | ||
| 87 | */ | ||
| 88 | TRACE_EVENT(kvm_cpuid, | ||
| 89 | TP_PROTO(unsigned int function, unsigned long rax, unsigned long rbx, | ||
| 90 | unsigned long rcx, unsigned long rdx), | ||
| 91 | TP_ARGS(function, rax, rbx, rcx, rdx), | ||
| 92 | |||
| 93 | TP_STRUCT__entry( | ||
| 94 | __field( unsigned int, function ) | ||
| 95 | __field( unsigned long, rax ) | ||
| 96 | __field( unsigned long, rbx ) | ||
| 97 | __field( unsigned long, rcx ) | ||
| 98 | __field( unsigned long, rdx ) | ||
| 99 | ), | ||
| 100 | |||
| 101 | TP_fast_assign( | ||
| 102 | __entry->function = function; | ||
| 103 | __entry->rax = rax; | ||
| 104 | __entry->rbx = rbx; | ||
| 105 | __entry->rcx = rcx; | ||
| 106 | __entry->rdx = rdx; | ||
| 107 | ), | ||
| 108 | |||
| 109 | TP_printk("func %x rax %lx rbx %lx rcx %lx rdx %lx", | ||
| 110 | __entry->function, __entry->rax, | ||
| 111 | __entry->rbx, __entry->rcx, __entry->rdx) | ||
| 112 | ); | ||
| 113 | |||
| 114 | #define AREG(x) { APIC_##x, "APIC_" #x } | ||
| 115 | |||
| 116 | #define kvm_trace_symbol_apic \ | ||
| 117 | AREG(ID), AREG(LVR), AREG(TASKPRI), AREG(ARBPRI), AREG(PROCPRI), \ | ||
| 118 | AREG(EOI), AREG(RRR), AREG(LDR), AREG(DFR), AREG(SPIV), AREG(ISR), \ | ||
| 119 | AREG(TMR), AREG(IRR), AREG(ESR), AREG(ICR), AREG(ICR2), AREG(LVTT), \ | ||
| 120 | AREG(LVTTHMR), AREG(LVTPC), AREG(LVT0), AREG(LVT1), AREG(LVTERR), \ | ||
| 121 | AREG(TMICT), AREG(TMCCT), AREG(TDCR), AREG(SELF_IPI), AREG(EFEAT), \ | ||
| 122 | AREG(ECTRL) | ||
| 123 | /* | ||
| 124 | * Tracepoint for apic access. | ||
| 125 | */ | ||
| 126 | TRACE_EVENT(kvm_apic, | ||
| 127 | TP_PROTO(unsigned int rw, unsigned int reg, unsigned int val), | ||
| 128 | TP_ARGS(rw, reg, val), | ||
| 129 | |||
| 130 | TP_STRUCT__entry( | ||
| 131 | __field( unsigned int, rw ) | ||
| 132 | __field( unsigned int, reg ) | ||
| 133 | __field( unsigned int, val ) | ||
| 134 | ), | ||
| 135 | |||
| 136 | TP_fast_assign( | ||
| 137 | __entry->rw = rw; | ||
| 138 | __entry->reg = reg; | ||
| 139 | __entry->val = val; | ||
| 140 | ), | ||
| 141 | |||
| 142 | TP_printk("apic_%s %s = 0x%x", | ||
| 143 | __entry->rw ? "write" : "read", | ||
| 144 | __print_symbolic(__entry->reg, kvm_trace_symbol_apic), | ||
| 145 | __entry->val) | ||
| 146 | ); | ||
| 147 | |||
| 148 | #define trace_kvm_apic_read(reg, val) trace_kvm_apic(0, reg, val) | ||
| 149 | #define trace_kvm_apic_write(reg, val) trace_kvm_apic(1, reg, val) | ||
| 150 | |||
| 151 | /* | ||
| 152 | * Tracepoint for kvm guest exit: | ||
| 153 | */ | ||
| 154 | TRACE_EVENT(kvm_exit, | ||
| 155 | TP_PROTO(unsigned int exit_reason, unsigned long guest_rip), | ||
| 156 | TP_ARGS(exit_reason, guest_rip), | ||
| 157 | |||
| 158 | TP_STRUCT__entry( | ||
| 159 | __field( unsigned int, exit_reason ) | ||
| 160 | __field( unsigned long, guest_rip ) | ||
| 161 | ), | ||
| 162 | |||
| 163 | TP_fast_assign( | ||
| 164 | __entry->exit_reason = exit_reason; | ||
| 165 | __entry->guest_rip = guest_rip; | ||
| 166 | ), | ||
| 167 | |||
| 168 | TP_printk("reason %s rip 0x%lx", | ||
| 169 | ftrace_print_symbols_seq(p, __entry->exit_reason, | ||
| 170 | kvm_x86_ops->exit_reasons_str), | ||
| 171 | __entry->guest_rip) | ||
| 172 | ); | ||
| 173 | |||
| 174 | /* | ||
| 175 | * Tracepoint for kvm interrupt injection: | ||
| 176 | */ | ||
| 177 | TRACE_EVENT(kvm_inj_virq, | ||
| 178 | TP_PROTO(unsigned int irq), | ||
| 179 | TP_ARGS(irq), | ||
| 180 | |||
| 181 | TP_STRUCT__entry( | ||
| 182 | __field( unsigned int, irq ) | ||
| 183 | ), | ||
| 184 | |||
| 185 | TP_fast_assign( | ||
| 186 | __entry->irq = irq; | ||
| 187 | ), | ||
| 188 | |||
| 189 | TP_printk("irq %u", __entry->irq) | ||
| 190 | ); | ||
| 191 | |||
| 192 | /* | ||
| 193 | * Tracepoint for page fault. | ||
| 194 | */ | ||
| 195 | TRACE_EVENT(kvm_page_fault, | ||
| 196 | TP_PROTO(unsigned long fault_address, unsigned int error_code), | ||
| 197 | TP_ARGS(fault_address, error_code), | ||
| 198 | |||
| 199 | TP_STRUCT__entry( | ||
| 200 | __field( unsigned long, fault_address ) | ||
| 201 | __field( unsigned int, error_code ) | ||
| 202 | ), | ||
| 203 | |||
| 204 | TP_fast_assign( | ||
| 205 | __entry->fault_address = fault_address; | ||
| 206 | __entry->error_code = error_code; | ||
| 207 | ), | ||
| 208 | |||
| 209 | TP_printk("address %lx error_code %x", | ||
| 210 | __entry->fault_address, __entry->error_code) | ||
| 211 | ); | ||
| 212 | |||
| 213 | /* | ||
| 214 | * Tracepoint for guest MSR access. | ||
| 215 | */ | ||
| 216 | TRACE_EVENT(kvm_msr, | ||
| 217 | TP_PROTO(unsigned int rw, unsigned int ecx, unsigned long data), | ||
| 218 | TP_ARGS(rw, ecx, data), | ||
| 219 | |||
| 220 | TP_STRUCT__entry( | ||
| 221 | __field( unsigned int, rw ) | ||
| 222 | __field( unsigned int, ecx ) | ||
| 223 | __field( unsigned long, data ) | ||
| 224 | ), | ||
| 225 | |||
| 226 | TP_fast_assign( | ||
| 227 | __entry->rw = rw; | ||
| 228 | __entry->ecx = ecx; | ||
| 229 | __entry->data = data; | ||
| 230 | ), | ||
| 231 | |||
| 232 | TP_printk("msr_%s %x = 0x%lx", | ||
| 233 | __entry->rw ? "write" : "read", | ||
| 234 | __entry->ecx, __entry->data) | ||
| 235 | ); | ||
| 236 | |||
| 237 | #define trace_kvm_msr_read(ecx, data) trace_kvm_msr(0, ecx, data) | ||
| 238 | #define trace_kvm_msr_write(ecx, data) trace_kvm_msr(1, ecx, data) | ||
| 239 | |||
| 240 | /* | ||
| 241 | * Tracepoint for guest CR access. | ||
| 242 | */ | ||
| 243 | TRACE_EVENT(kvm_cr, | ||
| 244 | TP_PROTO(unsigned int rw, unsigned int cr, unsigned long val), | ||
| 245 | TP_ARGS(rw, cr, val), | ||
| 246 | |||
| 247 | TP_STRUCT__entry( | ||
| 248 | __field( unsigned int, rw ) | ||
| 249 | __field( unsigned int, cr ) | ||
| 250 | __field( unsigned long, val ) | ||
| 251 | ), | ||
| 252 | |||
| 253 | TP_fast_assign( | ||
| 254 | __entry->rw = rw; | ||
| 255 | __entry->cr = cr; | ||
| 256 | __entry->val = val; | ||
| 257 | ), | ||
| 258 | |||
| 259 | TP_printk("cr_%s %x = 0x%lx", | ||
| 260 | __entry->rw ? "write" : "read", | ||
| 261 | __entry->cr, __entry->val) | ||
| 262 | ); | ||
| 263 | |||
| 264 | #define trace_kvm_cr_read(cr, val) trace_kvm_cr(0, cr, val) | ||
| 265 | #define trace_kvm_cr_write(cr, val) trace_kvm_cr(1, cr, val) | ||
| 266 | |||
| 267 | TRACE_EVENT(kvm_pic_set_irq, | ||
| 268 | TP_PROTO(__u8 chip, __u8 pin, __u8 elcr, __u8 imr, bool coalesced), | ||
| 269 | TP_ARGS(chip, pin, elcr, imr, coalesced), | ||
| 270 | |||
| 271 | TP_STRUCT__entry( | ||
| 272 | __field( __u8, chip ) | ||
| 273 | __field( __u8, pin ) | ||
| 274 | __field( __u8, elcr ) | ||
| 275 | __field( __u8, imr ) | ||
| 276 | __field( bool, coalesced ) | ||
| 277 | ), | ||
| 278 | |||
| 279 | TP_fast_assign( | ||
| 280 | __entry->chip = chip; | ||
| 281 | __entry->pin = pin; | ||
| 282 | __entry->elcr = elcr; | ||
| 283 | __entry->imr = imr; | ||
| 284 | __entry->coalesced = coalesced; | ||
| 285 | ), | ||
| 286 | |||
| 287 | TP_printk("chip %u pin %u (%s%s)%s", | ||
| 288 | __entry->chip, __entry->pin, | ||
| 289 | (__entry->elcr & (1 << __entry->pin)) ? "level":"edge", | ||
| 290 | (__entry->imr & (1 << __entry->pin)) ? "|masked":"", | ||
| 291 | __entry->coalesced ? " (coalesced)" : "") | ||
| 292 | ); | ||
| 293 | |||
| 294 | #define kvm_apic_dst_shorthand \ | ||
| 295 | {0x0, "dst"}, \ | ||
| 296 | {0x1, "self"}, \ | ||
| 297 | {0x2, "all"}, \ | ||
| 298 | {0x3, "all-but-self"} | ||
| 299 | |||
| 300 | TRACE_EVENT(kvm_apic_ipi, | ||
| 301 | TP_PROTO(__u32 icr_low, __u32 dest_id), | ||
| 302 | TP_ARGS(icr_low, dest_id), | ||
| 303 | |||
| 304 | TP_STRUCT__entry( | ||
| 305 | __field( __u32, icr_low ) | ||
| 306 | __field( __u32, dest_id ) | ||
| 307 | ), | ||
| 308 | |||
| 309 | TP_fast_assign( | ||
| 310 | __entry->icr_low = icr_low; | ||
| 311 | __entry->dest_id = dest_id; | ||
| 312 | ), | ||
| 313 | |||
| 314 | TP_printk("dst %x vec %u (%s|%s|%s|%s|%s)", | ||
| 315 | __entry->dest_id, (u8)__entry->icr_low, | ||
| 316 | __print_symbolic((__entry->icr_low >> 8 & 0x7), | ||
| 317 | kvm_deliver_mode), | ||
| 318 | (__entry->icr_low & (1<<11)) ? "logical" : "physical", | ||
| 319 | (__entry->icr_low & (1<<14)) ? "assert" : "de-assert", | ||
| 320 | (__entry->icr_low & (1<<15)) ? "level" : "edge", | ||
| 321 | __print_symbolic((__entry->icr_low >> 18 & 0x3), | ||
| 322 | kvm_apic_dst_shorthand)) | ||
| 323 | ); | ||
| 324 | |||
| 325 | TRACE_EVENT(kvm_apic_accept_irq, | ||
| 326 | TP_PROTO(__u32 apicid, __u16 dm, __u8 tm, __u8 vec, bool coalesced), | ||
| 327 | TP_ARGS(apicid, dm, tm, vec, coalesced), | ||
| 328 | |||
| 329 | TP_STRUCT__entry( | ||
| 330 | __field( __u32, apicid ) | ||
| 331 | __field( __u16, dm ) | ||
| 332 | __field( __u8, tm ) | ||
| 333 | __field( __u8, vec ) | ||
| 334 | __field( bool, coalesced ) | ||
| 335 | ), | ||
| 336 | |||
| 337 | TP_fast_assign( | ||
| 338 | __entry->apicid = apicid; | ||
| 339 | __entry->dm = dm; | ||
| 340 | __entry->tm = tm; | ||
| 341 | __entry->vec = vec; | ||
| 342 | __entry->coalesced = coalesced; | ||
| 343 | ), | ||
| 344 | |||
| 345 | TP_printk("apicid %x vec %u (%s|%s)%s", | ||
| 346 | __entry->apicid, __entry->vec, | ||
| 347 | __print_symbolic((__entry->dm >> 8 & 0x7), kvm_deliver_mode), | ||
| 348 | __entry->tm ? "level" : "edge", | ||
| 349 | __entry->coalesced ? " (coalesced)" : "") | ||
| 350 | ); | ||
| 351 | |||
| 352 | #endif /* _TRACE_KVM_H */ | ||
| 353 | |||
| 354 | /* This part must be outside protection */ | ||
| 355 | #include <trace/define_trace.h> | ||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 29f912927a58..f3812014bd0b 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/highmem.h> | 25 | #include <linux/highmem.h> |
| 26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
| 27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
| 28 | #include <linux/ftrace_event.h> | ||
| 28 | #include "kvm_cache_regs.h" | 29 | #include "kvm_cache_regs.h" |
| 29 | #include "x86.h" | 30 | #include "x86.h" |
| 30 | 31 | ||
| @@ -34,6 +35,8 @@ | |||
| 34 | #include <asm/virtext.h> | 35 | #include <asm/virtext.h> |
| 35 | #include <asm/mce.h> | 36 | #include <asm/mce.h> |
| 36 | 37 | ||
| 38 | #include "trace.h" | ||
| 39 | |||
| 37 | #define __ex(x) __kvm_handle_fault_on_reboot(x) | 40 | #define __ex(x) __kvm_handle_fault_on_reboot(x) |
| 38 | 41 | ||
| 39 | MODULE_AUTHOR("Qumranet"); | 42 | MODULE_AUTHOR("Qumranet"); |
| @@ -51,6 +54,10 @@ module_param_named(flexpriority, flexpriority_enabled, bool, S_IRUGO); | |||
| 51 | static int __read_mostly enable_ept = 1; | 54 | static int __read_mostly enable_ept = 1; |
| 52 | module_param_named(ept, enable_ept, bool, S_IRUGO); | 55 | module_param_named(ept, enable_ept, bool, S_IRUGO); |
| 53 | 56 | ||
| 57 | static int __read_mostly enable_unrestricted_guest = 1; | ||
| 58 | module_param_named(unrestricted_guest, | ||
| 59 | enable_unrestricted_guest, bool, S_IRUGO); | ||
| 60 | |||
| 54 | static int __read_mostly emulate_invalid_guest_state = 0; | 61 | static int __read_mostly emulate_invalid_guest_state = 0; |
| 55 | module_param(emulate_invalid_guest_state, bool, S_IRUGO); | 62 | module_param(emulate_invalid_guest_state, bool, S_IRUGO); |
| 56 | 63 | ||
| @@ -84,6 +91,14 @@ struct vcpu_vmx { | |||
| 84 | int guest_efer_loaded; | 91 | int guest_efer_loaded; |
| 85 | } host_state; | 92 | } host_state; |
| 86 | struct { | 93 | struct { |
| 94 | int vm86_active; | ||
| 95 | u8 save_iopl; | ||
| 96 | struct kvm_save_segment { | ||
| 97 | u16 selector; | ||
| 98 | unsigned long base; | ||
| 99 | u32 limit; | ||
| 100 | u32 ar; | ||
| 101 | } tr, es, ds, fs, gs; | ||
| 87 | struct { | 102 | struct { |
| 88 | bool pending; | 103 | bool pending; |
| 89 | u8 vector; | 104 | u8 vector; |
| @@ -161,6 +176,8 @@ static struct kvm_vmx_segment_field { | |||
| 161 | VMX_SEGMENT_FIELD(LDTR), | 176 | VMX_SEGMENT_FIELD(LDTR), |
| 162 | }; | 177 | }; |
| 163 | 178 | ||
| 179 | static void ept_save_pdptrs(struct kvm_vcpu *vcpu); | ||
| 180 | |||
| 164 | /* | 181 | /* |
| 165 | * Keep MSR_K6_STAR at the end, as setup_msrs() will try to optimize it | 182 | * Keep MSR_K6_STAR at the end, as setup_msrs() will try to optimize it |
| 166 | * away by decrementing the array size. | 183 | * away by decrementing the array size. |
| @@ -256,6 +273,26 @@ static inline bool cpu_has_vmx_flexpriority(void) | |||
| 256 | cpu_has_vmx_virtualize_apic_accesses(); | 273 | cpu_has_vmx_virtualize_apic_accesses(); |
| 257 | } | 274 | } |
| 258 | 275 | ||
| 276 | static inline bool cpu_has_vmx_ept_execute_only(void) | ||
| 277 | { | ||
| 278 | return !!(vmx_capability.ept & VMX_EPT_EXECUTE_ONLY_BIT); | ||
| 279 | } | ||
| 280 | |||
| 281 | static inline bool cpu_has_vmx_eptp_uncacheable(void) | ||
| 282 | { | ||
| 283 | return !!(vmx_capability.ept & VMX_EPTP_UC_BIT); | ||
| 284 | } | ||
| 285 | |||
| 286 | static inline bool cpu_has_vmx_eptp_writeback(void) | ||
| 287 | { | ||
| 288 | return !!(vmx_capability.ept & VMX_EPTP_WB_BIT); | ||
| 289 | } | ||
| 290 | |||
| 291 | static inline bool cpu_has_vmx_ept_2m_page(void) | ||
| 292 | { | ||
| 293 | return !!(vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT); | ||
| 294 | } | ||
| 295 | |||
| 259 | static inline int cpu_has_vmx_invept_individual_addr(void) | 296 | static inline int cpu_has_vmx_invept_individual_addr(void) |
| 260 | { | 297 | { |
| 261 | return !!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT); | 298 | return !!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT); |
| @@ -277,6 +314,12 @@ static inline int cpu_has_vmx_ept(void) | |||
| 277 | SECONDARY_EXEC_ENABLE_EPT; | 314 | SECONDARY_EXEC_ENABLE_EPT; |
| 278 | } | 315 | } |
| 279 | 316 | ||
| 317 | static inline int cpu_has_vmx_unrestricted_guest(void) | ||
| 318 | { | ||
| 319 | return vmcs_config.cpu_based_2nd_exec_ctrl & | ||
| 320 | SECONDARY_EXEC_UNRESTRICTED_GUEST; | ||
| 321 | } | ||
| 322 | |||
| 280 | static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm) | 323 | static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm) |
| 281 | { | 324 | { |
| 282 | return flexpriority_enabled && | 325 | return flexpriority_enabled && |
| @@ -497,14 +540,16 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu) | |||
| 497 | eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR); | 540 | eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR); |
| 498 | if (!vcpu->fpu_active) | 541 | if (!vcpu->fpu_active) |
| 499 | eb |= 1u << NM_VECTOR; | 542 | eb |= 1u << NM_VECTOR; |
| 543 | /* | ||
| 544 | * Unconditionally intercept #DB so we can maintain dr6 without | ||
| 545 | * reading it every exit. | ||
| 546 | */ | ||
| 547 | eb |= 1u << DB_VECTOR; | ||
| 500 | if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) { | 548 | if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) { |
| 501 | if (vcpu->guest_debug & | ||
| 502 | (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) | ||
| 503 | eb |= 1u << DB_VECTOR; | ||
| 504 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) | 549 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) |
| 505 | eb |= 1u << BP_VECTOR; | 550 | eb |= 1u << BP_VECTOR; |
| 506 | } | 551 | } |
| 507 | if (vcpu->arch.rmode.vm86_active) | 552 | if (to_vmx(vcpu)->rmode.vm86_active) |
| 508 | eb = ~0; | 553 | eb = ~0; |
| 509 | if (enable_ept) | 554 | if (enable_ept) |
| 510 | eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */ | 555 | eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */ |
| @@ -528,12 +573,15 @@ static void reload_tss(void) | |||
| 528 | static void load_transition_efer(struct vcpu_vmx *vmx) | 573 | static void load_transition_efer(struct vcpu_vmx *vmx) |
| 529 | { | 574 | { |
| 530 | int efer_offset = vmx->msr_offset_efer; | 575 | int efer_offset = vmx->msr_offset_efer; |
| 531 | u64 host_efer = vmx->host_msrs[efer_offset].data; | 576 | u64 host_efer; |
| 532 | u64 guest_efer = vmx->guest_msrs[efer_offset].data; | 577 | u64 guest_efer; |
| 533 | u64 ignore_bits; | 578 | u64 ignore_bits; |
| 534 | 579 | ||
| 535 | if (efer_offset < 0) | 580 | if (efer_offset < 0) |
| 536 | return; | 581 | return; |
| 582 | host_efer = vmx->host_msrs[efer_offset].data; | ||
| 583 | guest_efer = vmx->guest_msrs[efer_offset].data; | ||
| 584 | |||
| 537 | /* | 585 | /* |
| 538 | * NX is emulated; LMA and LME handled by hardware; SCE meaninless | 586 | * NX is emulated; LMA and LME handled by hardware; SCE meaninless |
| 539 | * outside long mode | 587 | * outside long mode |
| @@ -735,12 +783,17 @@ static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu) | |||
| 735 | 783 | ||
| 736 | static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) | 784 | static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) |
| 737 | { | 785 | { |
| 738 | return vmcs_readl(GUEST_RFLAGS); | 786 | unsigned long rflags; |
| 787 | |||
| 788 | rflags = vmcs_readl(GUEST_RFLAGS); | ||
| 789 | if (to_vmx(vcpu)->rmode.vm86_active) | ||
| 790 | rflags &= ~(unsigned long)(X86_EFLAGS_IOPL | X86_EFLAGS_VM); | ||
| 791 | return rflags; | ||
| 739 | } | 792 | } |
| 740 | 793 | ||
| 741 | static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) | 794 | static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) |
| 742 | { | 795 | { |
| 743 | if (vcpu->arch.rmode.vm86_active) | 796 | if (to_vmx(vcpu)->rmode.vm86_active) |
| 744 | rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; | 797 | rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; |
| 745 | vmcs_writel(GUEST_RFLAGS, rflags); | 798 | vmcs_writel(GUEST_RFLAGS, rflags); |
| 746 | } | 799 | } |
| @@ -797,12 +850,13 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, | |||
| 797 | intr_info |= INTR_INFO_DELIVER_CODE_MASK; | 850 | intr_info |= INTR_INFO_DELIVER_CODE_MASK; |
| 798 | } | 851 | } |
| 799 | 852 | ||
| 800 | if (vcpu->arch.rmode.vm86_active) { | 853 | if (vmx->rmode.vm86_active) { |
| 801 | vmx->rmode.irq.pending = true; | 854 | vmx->rmode.irq.pending = true; |
| 802 | vmx->rmode.irq.vector = nr; | 855 | vmx->rmode.irq.vector = nr; |
| 803 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); | 856 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); |
| 804 | if (nr == BP_VECTOR || nr == OF_VECTOR) | 857 | if (kvm_exception_is_soft(nr)) |
| 805 | vmx->rmode.irq.rip++; | 858 | vmx->rmode.irq.rip += |
| 859 | vmx->vcpu.arch.event_exit_inst_len; | ||
| 806 | intr_info |= INTR_TYPE_SOFT_INTR; | 860 | intr_info |= INTR_TYPE_SOFT_INTR; |
| 807 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); | 861 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); |
| 808 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); | 862 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); |
| @@ -940,7 +994,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) | |||
| 940 | case MSR_EFER: | 994 | case MSR_EFER: |
| 941 | return kvm_get_msr_common(vcpu, msr_index, pdata); | 995 | return kvm_get_msr_common(vcpu, msr_index, pdata); |
| 942 | #endif | 996 | #endif |
| 943 | case MSR_IA32_TIME_STAMP_COUNTER: | 997 | case MSR_IA32_TSC: |
| 944 | data = guest_read_tsc(); | 998 | data = guest_read_tsc(); |
| 945 | break; | 999 | break; |
| 946 | case MSR_IA32_SYSENTER_CS: | 1000 | case MSR_IA32_SYSENTER_CS: |
| @@ -953,9 +1007,9 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) | |||
| 953 | data = vmcs_readl(GUEST_SYSENTER_ESP); | 1007 | data = vmcs_readl(GUEST_SYSENTER_ESP); |
| 954 | break; | 1008 | break; |
| 955 | default: | 1009 | default: |
| 956 | vmx_load_host_state(to_vmx(vcpu)); | ||
| 957 | msr = find_msr_entry(to_vmx(vcpu), msr_index); | 1010 | msr = find_msr_entry(to_vmx(vcpu), msr_index); |
| 958 | if (msr) { | 1011 | if (msr) { |
| 1012 | vmx_load_host_state(to_vmx(vcpu)); | ||
| 959 | data = msr->data; | 1013 | data = msr->data; |
| 960 | break; | 1014 | break; |
| 961 | } | 1015 | } |
| @@ -1000,22 +1054,10 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) | |||
| 1000 | case MSR_IA32_SYSENTER_ESP: | 1054 | case MSR_IA32_SYSENTER_ESP: |
| 1001 | vmcs_writel(GUEST_SYSENTER_ESP, data); | 1055 | vmcs_writel(GUEST_SYSENTER_ESP, data); |
| 1002 | break; | 1056 | break; |
| 1003 | case MSR_IA32_TIME_STAMP_COUNTER: | 1057 | case MSR_IA32_TSC: |
| 1004 | rdtscll(host_tsc); | 1058 | rdtscll(host_tsc); |
| 1005 | guest_write_tsc(data, host_tsc); | 1059 | guest_write_tsc(data, host_tsc); |
| 1006 | break; | 1060 | break; |
| 1007 | case MSR_P6_PERFCTR0: | ||
| 1008 | case MSR_P6_PERFCTR1: | ||
| 1009 | case MSR_P6_EVNTSEL0: | ||
| 1010 | case MSR_P6_EVNTSEL1: | ||
| 1011 | /* | ||
| 1012 | * Just discard all writes to the performance counters; this | ||
| 1013 | * should keep both older linux and windows 64-bit guests | ||
| 1014 | * happy | ||
| 1015 | */ | ||
| 1016 | pr_unimpl(vcpu, "unimplemented perfctr wrmsr: 0x%x data 0x%llx\n", msr_index, data); | ||
| 1017 | |||
| 1018 | break; | ||
| 1019 | case MSR_IA32_CR_PAT: | 1061 | case MSR_IA32_CR_PAT: |
| 1020 | if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) { | 1062 | if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) { |
| 1021 | vmcs_write64(GUEST_IA32_PAT, data); | 1063 | vmcs_write64(GUEST_IA32_PAT, data); |
| @@ -1024,9 +1066,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) | |||
| 1024 | } | 1066 | } |
| 1025 | /* Otherwise falls through to kvm_set_msr_common */ | 1067 | /* Otherwise falls through to kvm_set_msr_common */ |
| 1026 | default: | 1068 | default: |
| 1027 | vmx_load_host_state(vmx); | ||
| 1028 | msr = find_msr_entry(vmx, msr_index); | 1069 | msr = find_msr_entry(vmx, msr_index); |
| 1029 | if (msr) { | 1070 | if (msr) { |
| 1071 | vmx_load_host_state(vmx); | ||
| 1030 | msr->data = data; | 1072 | msr->data = data; |
| 1031 | break; | 1073 | break; |
| 1032 | } | 1074 | } |
| @@ -1046,6 +1088,10 @@ static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) | |||
| 1046 | case VCPU_REGS_RIP: | 1088 | case VCPU_REGS_RIP: |
| 1047 | vcpu->arch.regs[VCPU_REGS_RIP] = vmcs_readl(GUEST_RIP); | 1089 | vcpu->arch.regs[VCPU_REGS_RIP] = vmcs_readl(GUEST_RIP); |
| 1048 | break; | 1090 | break; |
| 1091 | case VCPU_EXREG_PDPTR: | ||
| 1092 | if (enable_ept) | ||
| 1093 | ept_save_pdptrs(vcpu); | ||
| 1094 | break; | ||
| 1049 | default: | 1095 | default: |
| 1050 | break; | 1096 | break; |
| 1051 | } | 1097 | } |
| @@ -1203,7 +1249,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | |||
| 1203 | opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | | 1249 | opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | |
| 1204 | SECONDARY_EXEC_WBINVD_EXITING | | 1250 | SECONDARY_EXEC_WBINVD_EXITING | |
| 1205 | SECONDARY_EXEC_ENABLE_VPID | | 1251 | SECONDARY_EXEC_ENABLE_VPID | |
| 1206 | SECONDARY_EXEC_ENABLE_EPT; | 1252 | SECONDARY_EXEC_ENABLE_EPT | |
| 1253 | SECONDARY_EXEC_UNRESTRICTED_GUEST; | ||
| 1207 | if (adjust_vmx_controls(min2, opt2, | 1254 | if (adjust_vmx_controls(min2, opt2, |
| 1208 | MSR_IA32_VMX_PROCBASED_CTLS2, | 1255 | MSR_IA32_VMX_PROCBASED_CTLS2, |
| 1209 | &_cpu_based_2nd_exec_control) < 0) | 1256 | &_cpu_based_2nd_exec_control) < 0) |
| @@ -1217,12 +1264,9 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | |||
| 1217 | if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) { | 1264 | if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) { |
| 1218 | /* CR3 accesses and invlpg don't need to cause VM Exits when EPT | 1265 | /* CR3 accesses and invlpg don't need to cause VM Exits when EPT |
| 1219 | enabled */ | 1266 | enabled */ |
| 1220 | min &= ~(CPU_BASED_CR3_LOAD_EXITING | | 1267 | _cpu_based_exec_control &= ~(CPU_BASED_CR3_LOAD_EXITING | |
| 1221 | CPU_BASED_CR3_STORE_EXITING | | 1268 | CPU_BASED_CR3_STORE_EXITING | |
| 1222 | CPU_BASED_INVLPG_EXITING); | 1269 | CPU_BASED_INVLPG_EXITING); |
| 1223 | if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS, | ||
| 1224 | &_cpu_based_exec_control) < 0) | ||
| 1225 | return -EIO; | ||
| 1226 | rdmsr(MSR_IA32_VMX_EPT_VPID_CAP, | 1270 | rdmsr(MSR_IA32_VMX_EPT_VPID_CAP, |
| 1227 | vmx_capability.ept, vmx_capability.vpid); | 1271 | vmx_capability.ept, vmx_capability.vpid); |
| 1228 | } | 1272 | } |
| @@ -1333,8 +1377,13 @@ static __init int hardware_setup(void) | |||
| 1333 | if (!cpu_has_vmx_vpid()) | 1377 | if (!cpu_has_vmx_vpid()) |
| 1334 | enable_vpid = 0; | 1378 | enable_vpid = 0; |
| 1335 | 1379 | ||
| 1336 | if (!cpu_has_vmx_ept()) | 1380 | if (!cpu_has_vmx_ept()) { |
| 1337 | enable_ept = 0; | 1381 | enable_ept = 0; |
| 1382 | enable_unrestricted_guest = 0; | ||
| 1383 | } | ||
| 1384 | |||
| 1385 | if (!cpu_has_vmx_unrestricted_guest()) | ||
| 1386 | enable_unrestricted_guest = 0; | ||
| 1338 | 1387 | ||
| 1339 | if (!cpu_has_vmx_flexpriority()) | 1388 | if (!cpu_has_vmx_flexpriority()) |
| 1340 | flexpriority_enabled = 0; | 1389 | flexpriority_enabled = 0; |
| @@ -1342,6 +1391,9 @@ static __init int hardware_setup(void) | |||
| 1342 | if (!cpu_has_vmx_tpr_shadow()) | 1391 | if (!cpu_has_vmx_tpr_shadow()) |
| 1343 | kvm_x86_ops->update_cr8_intercept = NULL; | 1392 | kvm_x86_ops->update_cr8_intercept = NULL; |
| 1344 | 1393 | ||
| 1394 | if (enable_ept && !cpu_has_vmx_ept_2m_page()) | ||
| 1395 | kvm_disable_largepages(); | ||
| 1396 | |||
| 1345 | return alloc_kvm_area(); | 1397 | return alloc_kvm_area(); |
| 1346 | } | 1398 | } |
| 1347 | 1399 | ||
| @@ -1372,15 +1424,15 @@ static void enter_pmode(struct kvm_vcpu *vcpu) | |||
| 1372 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 1424 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 1373 | 1425 | ||
| 1374 | vmx->emulation_required = 1; | 1426 | vmx->emulation_required = 1; |
| 1375 | vcpu->arch.rmode.vm86_active = 0; | 1427 | vmx->rmode.vm86_active = 0; |
| 1376 | 1428 | ||
| 1377 | vmcs_writel(GUEST_TR_BASE, vcpu->arch.rmode.tr.base); | 1429 | vmcs_writel(GUEST_TR_BASE, vmx->rmode.tr.base); |
| 1378 | vmcs_write32(GUEST_TR_LIMIT, vcpu->arch.rmode.tr.limit); | 1430 | vmcs_write32(GUEST_TR_LIMIT, vmx->rmode.tr.limit); |
| 1379 | vmcs_write32(GUEST_TR_AR_BYTES, vcpu->arch.rmode.tr.ar); | 1431 | vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar); |
| 1380 | 1432 | ||
| 1381 | flags = vmcs_readl(GUEST_RFLAGS); | 1433 | flags = vmcs_readl(GUEST_RFLAGS); |
| 1382 | flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM); | 1434 | flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM); |
| 1383 | flags |= (vcpu->arch.rmode.save_iopl << IOPL_SHIFT); | 1435 | flags |= (vmx->rmode.save_iopl << IOPL_SHIFT); |
| 1384 | vmcs_writel(GUEST_RFLAGS, flags); | 1436 | vmcs_writel(GUEST_RFLAGS, flags); |
| 1385 | 1437 | ||
| 1386 | vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) | | 1438 | vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) | |
| @@ -1391,10 +1443,10 @@ static void enter_pmode(struct kvm_vcpu *vcpu) | |||
| 1391 | if (emulate_invalid_guest_state) | 1443 | if (emulate_invalid_guest_state) |
| 1392 | return; | 1444 | return; |
| 1393 | 1445 | ||
| 1394 | fix_pmode_dataseg(VCPU_SREG_ES, &vcpu->arch.rmode.es); | 1446 | fix_pmode_dataseg(VCPU_SREG_ES, &vmx->rmode.es); |
| 1395 | fix_pmode_dataseg(VCPU_SREG_DS, &vcpu->arch.rmode.ds); | 1447 | fix_pmode_dataseg(VCPU_SREG_DS, &vmx->rmode.ds); |
| 1396 | fix_pmode_dataseg(VCPU_SREG_GS, &vcpu->arch.rmode.gs); | 1448 | fix_pmode_dataseg(VCPU_SREG_GS, &vmx->rmode.gs); |
| 1397 | fix_pmode_dataseg(VCPU_SREG_FS, &vcpu->arch.rmode.fs); | 1449 | fix_pmode_dataseg(VCPU_SREG_FS, &vmx->rmode.fs); |
| 1398 | 1450 | ||
| 1399 | vmcs_write16(GUEST_SS_SELECTOR, 0); | 1451 | vmcs_write16(GUEST_SS_SELECTOR, 0); |
| 1400 | vmcs_write32(GUEST_SS_AR_BYTES, 0x93); | 1452 | vmcs_write32(GUEST_SS_AR_BYTES, 0x93); |
| @@ -1433,20 +1485,23 @@ static void enter_rmode(struct kvm_vcpu *vcpu) | |||
| 1433 | unsigned long flags; | 1485 | unsigned long flags; |
| 1434 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 1486 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 1435 | 1487 | ||
| 1488 | if (enable_unrestricted_guest) | ||
| 1489 | return; | ||
| 1490 | |||
| 1436 | vmx->emulation_required = 1; | 1491 | vmx->emulation_required = 1; |
| 1437 | vcpu->arch.rmode.vm86_active = 1; | 1492 | vmx->rmode.vm86_active = 1; |
| 1438 | 1493 | ||
| 1439 | vcpu->arch.rmode.tr.base = vmcs_readl(GUEST_TR_BASE); | 1494 | vmx->rmode.tr.base = vmcs_readl(GUEST_TR_BASE); |
| 1440 | vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm)); | 1495 | vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm)); |
| 1441 | 1496 | ||
| 1442 | vcpu->arch.rmode.tr.limit = vmcs_read32(GUEST_TR_LIMIT); | 1497 | vmx->rmode.tr.limit = vmcs_read32(GUEST_TR_LIMIT); |
| 1443 | vmcs_write32(GUEST_TR_LIMIT, RMODE_TSS_SIZE - 1); | 1498 | vmcs_write32(GUEST_TR_LIMIT, RMODE_TSS_SIZE - 1); |
| 1444 | 1499 | ||
| 1445 | vcpu->arch.rmode.tr.ar = vmcs_read32(GUEST_TR_AR_BYTES); | 1500 | vmx->rmode.tr.ar = vmcs_read32(GUEST_TR_AR_BYTES); |
| 1446 | vmcs_write32(GUEST_TR_AR_BYTES, 0x008b); | 1501 | vmcs_write32(GUEST_TR_AR_BYTES, 0x008b); |
| 1447 | 1502 | ||
| 1448 | flags = vmcs_readl(GUEST_RFLAGS); | 1503 | flags = vmcs_readl(GUEST_RFLAGS); |
| 1449 | vcpu->arch.rmode.save_iopl | 1504 | vmx->rmode.save_iopl |
| 1450 | = (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; | 1505 | = (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; |
| 1451 | 1506 | ||
| 1452 | flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; | 1507 | flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM; |
| @@ -1468,10 +1523,10 @@ static void enter_rmode(struct kvm_vcpu *vcpu) | |||
| 1468 | vmcs_writel(GUEST_CS_BASE, 0xf0000); | 1523 | vmcs_writel(GUEST_CS_BASE, 0xf0000); |
| 1469 | vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4); | 1524 | vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4); |
| 1470 | 1525 | ||
| 1471 | fix_rmode_seg(VCPU_SREG_ES, &vcpu->arch.rmode.es); | 1526 | fix_rmode_seg(VCPU_SREG_ES, &vmx->rmode.es); |
| 1472 | fix_rmode_seg(VCPU_SREG_DS, &vcpu->arch.rmode.ds); | 1527 | fix_rmode_seg(VCPU_SREG_DS, &vmx->rmode.ds); |
| 1473 | fix_rmode_seg(VCPU_SREG_GS, &vcpu->arch.rmode.gs); | 1528 | fix_rmode_seg(VCPU_SREG_GS, &vmx->rmode.gs); |
| 1474 | fix_rmode_seg(VCPU_SREG_FS, &vcpu->arch.rmode.fs); | 1529 | fix_rmode_seg(VCPU_SREG_FS, &vmx->rmode.fs); |
| 1475 | 1530 | ||
| 1476 | continue_rmode: | 1531 | continue_rmode: |
| 1477 | kvm_mmu_reset_context(vcpu); | 1532 | kvm_mmu_reset_context(vcpu); |
| @@ -1545,11 +1600,11 @@ static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) | |||
| 1545 | 1600 | ||
| 1546 | static void ept_load_pdptrs(struct kvm_vcpu *vcpu) | 1601 | static void ept_load_pdptrs(struct kvm_vcpu *vcpu) |
| 1547 | { | 1602 | { |
| 1603 | if (!test_bit(VCPU_EXREG_PDPTR, | ||
| 1604 | (unsigned long *)&vcpu->arch.regs_dirty)) | ||
| 1605 | return; | ||
| 1606 | |||
| 1548 | if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { | 1607 | if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { |
| 1549 | if (!load_pdptrs(vcpu, vcpu->arch.cr3)) { | ||
| 1550 | printk(KERN_ERR "EPT: Fail to load pdptrs!\n"); | ||
| 1551 | return; | ||
| 1552 | } | ||
| 1553 | vmcs_write64(GUEST_PDPTR0, vcpu->arch.pdptrs[0]); | 1608 | vmcs_write64(GUEST_PDPTR0, vcpu->arch.pdptrs[0]); |
| 1554 | vmcs_write64(GUEST_PDPTR1, vcpu->arch.pdptrs[1]); | 1609 | vmcs_write64(GUEST_PDPTR1, vcpu->arch.pdptrs[1]); |
| 1555 | vmcs_write64(GUEST_PDPTR2, vcpu->arch.pdptrs[2]); | 1610 | vmcs_write64(GUEST_PDPTR2, vcpu->arch.pdptrs[2]); |
| @@ -1557,6 +1612,21 @@ static void ept_load_pdptrs(struct kvm_vcpu *vcpu) | |||
| 1557 | } | 1612 | } |
| 1558 | } | 1613 | } |
| 1559 | 1614 | ||
| 1615 | static void ept_save_pdptrs(struct kvm_vcpu *vcpu) | ||
| 1616 | { | ||
| 1617 | if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) { | ||
| 1618 | vcpu->arch.pdptrs[0] = vmcs_read64(GUEST_PDPTR0); | ||
| 1619 | vcpu->arch.pdptrs[1] = vmcs_read64(GUEST_PDPTR1); | ||
| 1620 | vcpu->arch.pdptrs[2] = vmcs_read64(GUEST_PDPTR2); | ||
| 1621 | vcpu->arch.pdptrs[3] = vmcs_read64(GUEST_PDPTR3); | ||
| 1622 | } | ||
| 1623 | |||
| 1624 | __set_bit(VCPU_EXREG_PDPTR, | ||
| 1625 | (unsigned long *)&vcpu->arch.regs_avail); | ||
| 1626 | __set_bit(VCPU_EXREG_PDPTR, | ||
| 1627 | (unsigned long *)&vcpu->arch.regs_dirty); | ||
| 1628 | } | ||
| 1629 | |||
| 1560 | static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); | 1630 | static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); |
| 1561 | 1631 | ||
| 1562 | static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, | 1632 | static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, |
| @@ -1571,8 +1641,6 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, | |||
| 1571 | CPU_BASED_CR3_STORE_EXITING)); | 1641 | CPU_BASED_CR3_STORE_EXITING)); |
| 1572 | vcpu->arch.cr0 = cr0; | 1642 | vcpu->arch.cr0 = cr0; |
| 1573 | vmx_set_cr4(vcpu, vcpu->arch.cr4); | 1643 | vmx_set_cr4(vcpu, vcpu->arch.cr4); |
| 1574 | *hw_cr0 |= X86_CR0_PE | X86_CR0_PG; | ||
| 1575 | *hw_cr0 &= ~X86_CR0_WP; | ||
| 1576 | } else if (!is_paging(vcpu)) { | 1644 | } else if (!is_paging(vcpu)) { |
| 1577 | /* From nonpaging to paging */ | 1645 | /* From nonpaging to paging */ |
| 1578 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, | 1646 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, |
| @@ -1581,9 +1649,10 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, | |||
| 1581 | CPU_BASED_CR3_STORE_EXITING)); | 1649 | CPU_BASED_CR3_STORE_EXITING)); |
| 1582 | vcpu->arch.cr0 = cr0; | 1650 | vcpu->arch.cr0 = cr0; |
| 1583 | vmx_set_cr4(vcpu, vcpu->arch.cr4); | 1651 | vmx_set_cr4(vcpu, vcpu->arch.cr4); |
| 1584 | if (!(vcpu->arch.cr0 & X86_CR0_WP)) | ||
| 1585 | *hw_cr0 &= ~X86_CR0_WP; | ||
| 1586 | } | 1652 | } |
| 1653 | |||
| 1654 | if (!(cr0 & X86_CR0_WP)) | ||
| 1655 | *hw_cr0 &= ~X86_CR0_WP; | ||
| 1587 | } | 1656 | } |
| 1588 | 1657 | ||
| 1589 | static void ept_update_paging_mode_cr4(unsigned long *hw_cr4, | 1658 | static void ept_update_paging_mode_cr4(unsigned long *hw_cr4, |
| @@ -1598,15 +1667,21 @@ static void ept_update_paging_mode_cr4(unsigned long *hw_cr4, | |||
| 1598 | 1667 | ||
| 1599 | static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | 1668 | static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) |
| 1600 | { | 1669 | { |
| 1601 | unsigned long hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK) | | 1670 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 1602 | KVM_VM_CR0_ALWAYS_ON; | 1671 | unsigned long hw_cr0; |
| 1672 | |||
| 1673 | if (enable_unrestricted_guest) | ||
| 1674 | hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST) | ||
| 1675 | | KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST; | ||
| 1676 | else | ||
| 1677 | hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON; | ||
| 1603 | 1678 | ||
| 1604 | vmx_fpu_deactivate(vcpu); | 1679 | vmx_fpu_deactivate(vcpu); |
| 1605 | 1680 | ||
| 1606 | if (vcpu->arch.rmode.vm86_active && (cr0 & X86_CR0_PE)) | 1681 | if (vmx->rmode.vm86_active && (cr0 & X86_CR0_PE)) |
| 1607 | enter_pmode(vcpu); | 1682 | enter_pmode(vcpu); |
| 1608 | 1683 | ||
| 1609 | if (!vcpu->arch.rmode.vm86_active && !(cr0 & X86_CR0_PE)) | 1684 | if (!vmx->rmode.vm86_active && !(cr0 & X86_CR0_PE)) |
| 1610 | enter_rmode(vcpu); | 1685 | enter_rmode(vcpu); |
| 1611 | 1686 | ||
| 1612 | #ifdef CONFIG_X86_64 | 1687 | #ifdef CONFIG_X86_64 |
| @@ -1650,10 +1725,8 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
| 1650 | if (enable_ept) { | 1725 | if (enable_ept) { |
| 1651 | eptp = construct_eptp(cr3); | 1726 | eptp = construct_eptp(cr3); |
| 1652 | vmcs_write64(EPT_POINTER, eptp); | 1727 | vmcs_write64(EPT_POINTER, eptp); |
| 1653 | ept_sync_context(eptp); | ||
| 1654 | ept_load_pdptrs(vcpu); | ||
| 1655 | guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 : | 1728 | guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 : |
| 1656 | VMX_EPT_IDENTITY_PAGETABLE_ADDR; | 1729 | vcpu->kvm->arch.ept_identity_map_addr; |
| 1657 | } | 1730 | } |
| 1658 | 1731 | ||
| 1659 | vmx_flush_tlb(vcpu); | 1732 | vmx_flush_tlb(vcpu); |
| @@ -1664,7 +1737,7 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
| 1664 | 1737 | ||
| 1665 | static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | 1738 | static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) |
| 1666 | { | 1739 | { |
| 1667 | unsigned long hw_cr4 = cr4 | (vcpu->arch.rmode.vm86_active ? | 1740 | unsigned long hw_cr4 = cr4 | (to_vmx(vcpu)->rmode.vm86_active ? |
| 1668 | KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON); | 1741 | KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON); |
| 1669 | 1742 | ||
| 1670 | vcpu->arch.cr4 = cr4; | 1743 | vcpu->arch.cr4 = cr4; |
| @@ -1707,16 +1780,13 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu, | |||
| 1707 | 1780 | ||
| 1708 | static int vmx_get_cpl(struct kvm_vcpu *vcpu) | 1781 | static int vmx_get_cpl(struct kvm_vcpu *vcpu) |
| 1709 | { | 1782 | { |
| 1710 | struct kvm_segment kvm_seg; | ||
| 1711 | |||
| 1712 | if (!(vcpu->arch.cr0 & X86_CR0_PE)) /* if real mode */ | 1783 | if (!(vcpu->arch.cr0 & X86_CR0_PE)) /* if real mode */ |
| 1713 | return 0; | 1784 | return 0; |
| 1714 | 1785 | ||
| 1715 | if (vmx_get_rflags(vcpu) & X86_EFLAGS_VM) /* if virtual 8086 */ | 1786 | if (vmx_get_rflags(vcpu) & X86_EFLAGS_VM) /* if virtual 8086 */ |
| 1716 | return 3; | 1787 | return 3; |
| 1717 | 1788 | ||
| 1718 | vmx_get_segment(vcpu, &kvm_seg, VCPU_SREG_CS); | 1789 | return vmcs_read16(GUEST_CS_SELECTOR) & 3; |
| 1719 | return kvm_seg.selector & 3; | ||
| 1720 | } | 1790 | } |
| 1721 | 1791 | ||
| 1722 | static u32 vmx_segment_access_rights(struct kvm_segment *var) | 1792 | static u32 vmx_segment_access_rights(struct kvm_segment *var) |
| @@ -1744,20 +1814,21 @@ static u32 vmx_segment_access_rights(struct kvm_segment *var) | |||
| 1744 | static void vmx_set_segment(struct kvm_vcpu *vcpu, | 1814 | static void vmx_set_segment(struct kvm_vcpu *vcpu, |
| 1745 | struct kvm_segment *var, int seg) | 1815 | struct kvm_segment *var, int seg) |
| 1746 | { | 1816 | { |
| 1817 | struct vcpu_vmx *vmx = to_vmx(vcpu); | ||
| 1747 | struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; | 1818 | struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; |
| 1748 | u32 ar; | 1819 | u32 ar; |
| 1749 | 1820 | ||
| 1750 | if (vcpu->arch.rmode.vm86_active && seg == VCPU_SREG_TR) { | 1821 | if (vmx->rmode.vm86_active && seg == VCPU_SREG_TR) { |
| 1751 | vcpu->arch.rmode.tr.selector = var->selector; | 1822 | vmx->rmode.tr.selector = var->selector; |
| 1752 | vcpu->arch.rmode.tr.base = var->base; | 1823 | vmx->rmode.tr.base = var->base; |
| 1753 | vcpu->arch.rmode.tr.limit = var->limit; | 1824 | vmx->rmode.tr.limit = var->limit; |
| 1754 | vcpu->arch.rmode.tr.ar = vmx_segment_access_rights(var); | 1825 | vmx->rmode.tr.ar = vmx_segment_access_rights(var); |
| 1755 | return; | 1826 | return; |
| 1756 | } | 1827 | } |
| 1757 | vmcs_writel(sf->base, var->base); | 1828 | vmcs_writel(sf->base, var->base); |
| 1758 | vmcs_write32(sf->limit, var->limit); | 1829 | vmcs_write32(sf->limit, var->limit); |
| 1759 | vmcs_write16(sf->selector, var->selector); | 1830 | vmcs_write16(sf->selector, var->selector); |
| 1760 | if (vcpu->arch.rmode.vm86_active && var->s) { | 1831 | if (vmx->rmode.vm86_active && var->s) { |
| 1761 | /* | 1832 | /* |
| 1762 | * Hack real-mode segments into vm86 compatibility. | 1833 | * Hack real-mode segments into vm86 compatibility. |
| 1763 | */ | 1834 | */ |
| @@ -1766,6 +1837,21 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu, | |||
| 1766 | ar = 0xf3; | 1837 | ar = 0xf3; |
| 1767 | } else | 1838 | } else |
| 1768 | ar = vmx_segment_access_rights(var); | 1839 | ar = vmx_segment_access_rights(var); |
| 1840 | |||
| 1841 | /* | ||
| 1842 | * Fix the "Accessed" bit in AR field of segment registers for older | ||
| 1843 | * qemu binaries. | ||
| 1844 | * IA32 arch specifies that at the time of processor reset the | ||
| 1845 | * "Accessed" bit in the AR field of segment registers is 1. And qemu | ||
| 1846 | * is setting it to 0 in the usedland code. This causes invalid guest | ||
| 1847 | * state vmexit when "unrestricted guest" mode is turned on. | ||
| 1848 | * Fix for this setup issue in cpu_reset is being pushed in the qemu | ||
| 1849 | * tree. Newer qemu binaries with that qemu fix would not need this | ||
| 1850 | * kvm hack. | ||
| 1851 | */ | ||
| 1852 | if (enable_unrestricted_guest && (seg != VCPU_SREG_LDTR)) | ||
| 1853 | ar |= 0x1; /* Accessed */ | ||
| 1854 | |||
| 1769 | vmcs_write32(sf->ar_bytes, ar); | 1855 | vmcs_write32(sf->ar_bytes, ar); |
| 1770 | } | 1856 | } |
| 1771 | 1857 | ||
| @@ -2040,7 +2126,7 @@ static int init_rmode_identity_map(struct kvm *kvm) | |||
| 2040 | if (likely(kvm->arch.ept_identity_pagetable_done)) | 2126 | if (likely(kvm->arch.ept_identity_pagetable_done)) |
| 2041 | return 1; | 2127 | return 1; |
| 2042 | ret = 0; | 2128 | ret = 0; |
| 2043 | identity_map_pfn = VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT; | 2129 | identity_map_pfn = kvm->arch.ept_identity_map_addr >> PAGE_SHIFT; |
| 2044 | r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE); | 2130 | r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE); |
| 2045 | if (r < 0) | 2131 | if (r < 0) |
| 2046 | goto out; | 2132 | goto out; |
| @@ -2062,11 +2148,19 @@ out: | |||
| 2062 | static void seg_setup(int seg) | 2148 | static void seg_setup(int seg) |
| 2063 | { | 2149 | { |
| 2064 | struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; | 2150 | struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; |
| 2151 | unsigned int ar; | ||
| 2065 | 2152 | ||
| 2066 | vmcs_write16(sf->selector, 0); | 2153 | vmcs_write16(sf->selector, 0); |
| 2067 | vmcs_writel(sf->base, 0); | 2154 | vmcs_writel(sf->base, 0); |
| 2068 | vmcs_write32(sf->limit, 0xffff); | 2155 | vmcs_write32(sf->limit, 0xffff); |
| 2069 | vmcs_write32(sf->ar_bytes, 0xf3); | 2156 | if (enable_unrestricted_guest) { |
| 2157 | ar = 0x93; | ||
| 2158 | if (seg == VCPU_SREG_CS) | ||
| 2159 | ar |= 0x08; /* code segment */ | ||
| 2160 | } else | ||
| 2161 | ar = 0xf3; | ||
| 2162 | |||
| 2163 | vmcs_write32(sf->ar_bytes, ar); | ||
| 2070 | } | 2164 | } |
| 2071 | 2165 | ||
| 2072 | static int alloc_apic_access_page(struct kvm *kvm) | 2166 | static int alloc_apic_access_page(struct kvm *kvm) |
| @@ -2101,14 +2195,15 @@ static int alloc_identity_pagetable(struct kvm *kvm) | |||
| 2101 | goto out; | 2195 | goto out; |
| 2102 | kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT; | 2196 | kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT; |
| 2103 | kvm_userspace_mem.flags = 0; | 2197 | kvm_userspace_mem.flags = 0; |
| 2104 | kvm_userspace_mem.guest_phys_addr = VMX_EPT_IDENTITY_PAGETABLE_ADDR; | 2198 | kvm_userspace_mem.guest_phys_addr = |
| 2199 | kvm->arch.ept_identity_map_addr; | ||
| 2105 | kvm_userspace_mem.memory_size = PAGE_SIZE; | 2200 | kvm_userspace_mem.memory_size = PAGE_SIZE; |
| 2106 | r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0); | 2201 | r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0); |
| 2107 | if (r) | 2202 | if (r) |
| 2108 | goto out; | 2203 | goto out; |
| 2109 | 2204 | ||
| 2110 | kvm->arch.ept_identity_pagetable = gfn_to_page(kvm, | 2205 | kvm->arch.ept_identity_pagetable = gfn_to_page(kvm, |
| 2111 | VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT); | 2206 | kvm->arch.ept_identity_map_addr >> PAGE_SHIFT); |
| 2112 | out: | 2207 | out: |
| 2113 | up_write(&kvm->slots_lock); | 2208 | up_write(&kvm->slots_lock); |
| 2114 | return r; | 2209 | return r; |
| @@ -2209,6 +2304,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) | |||
| 2209 | exec_control &= ~SECONDARY_EXEC_ENABLE_VPID; | 2304 | exec_control &= ~SECONDARY_EXEC_ENABLE_VPID; |
| 2210 | if (!enable_ept) | 2305 | if (!enable_ept) |
| 2211 | exec_control &= ~SECONDARY_EXEC_ENABLE_EPT; | 2306 | exec_control &= ~SECONDARY_EXEC_ENABLE_EPT; |
| 2307 | if (!enable_unrestricted_guest) | ||
| 2308 | exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST; | ||
| 2212 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control); | 2309 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control); |
| 2213 | } | 2310 | } |
| 2214 | 2311 | ||
| @@ -2326,14 +2423,14 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu) | |||
| 2326 | goto out; | 2423 | goto out; |
| 2327 | } | 2424 | } |
| 2328 | 2425 | ||
| 2329 | vmx->vcpu.arch.rmode.vm86_active = 0; | 2426 | vmx->rmode.vm86_active = 0; |
| 2330 | 2427 | ||
| 2331 | vmx->soft_vnmi_blocked = 0; | 2428 | vmx->soft_vnmi_blocked = 0; |
| 2332 | 2429 | ||
| 2333 | vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val(); | 2430 | vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val(); |
| 2334 | kvm_set_cr8(&vmx->vcpu, 0); | 2431 | kvm_set_cr8(&vmx->vcpu, 0); |
| 2335 | msr = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; | 2432 | msr = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; |
| 2336 | if (vmx->vcpu.vcpu_id == 0) | 2433 | if (kvm_vcpu_is_bsp(&vmx->vcpu)) |
| 2337 | msr |= MSR_IA32_APICBASE_BSP; | 2434 | msr |= MSR_IA32_APICBASE_BSP; |
| 2338 | kvm_set_apic_base(&vmx->vcpu, msr); | 2435 | kvm_set_apic_base(&vmx->vcpu, msr); |
| 2339 | 2436 | ||
| @@ -2344,7 +2441,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu) | |||
| 2344 | * GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode | 2441 | * GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode |
| 2345 | * insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4. Sigh. | 2442 | * insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4. Sigh. |
| 2346 | */ | 2443 | */ |
| 2347 | if (vmx->vcpu.vcpu_id == 0) { | 2444 | if (kvm_vcpu_is_bsp(&vmx->vcpu)) { |
| 2348 | vmcs_write16(GUEST_CS_SELECTOR, 0xf000); | 2445 | vmcs_write16(GUEST_CS_SELECTOR, 0xf000); |
| 2349 | vmcs_writel(GUEST_CS_BASE, 0x000f0000); | 2446 | vmcs_writel(GUEST_CS_BASE, 0x000f0000); |
| 2350 | } else { | 2447 | } else { |
| @@ -2373,7 +2470,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu) | |||
| 2373 | vmcs_writel(GUEST_SYSENTER_EIP, 0); | 2470 | vmcs_writel(GUEST_SYSENTER_EIP, 0); |
| 2374 | 2471 | ||
| 2375 | vmcs_writel(GUEST_RFLAGS, 0x02); | 2472 | vmcs_writel(GUEST_RFLAGS, 0x02); |
| 2376 | if (vmx->vcpu.vcpu_id == 0) | 2473 | if (kvm_vcpu_is_bsp(&vmx->vcpu)) |
| 2377 | kvm_rip_write(vcpu, 0xfff0); | 2474 | kvm_rip_write(vcpu, 0xfff0); |
| 2378 | else | 2475 | else |
| 2379 | kvm_rip_write(vcpu, 0); | 2476 | kvm_rip_write(vcpu, 0); |
| @@ -2461,13 +2558,16 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu) | |||
| 2461 | uint32_t intr; | 2558 | uint32_t intr; |
| 2462 | int irq = vcpu->arch.interrupt.nr; | 2559 | int irq = vcpu->arch.interrupt.nr; |
| 2463 | 2560 | ||
| 2464 | KVMTRACE_1D(INJ_VIRQ, vcpu, (u32)irq, handler); | 2561 | trace_kvm_inj_virq(irq); |
| 2465 | 2562 | ||
| 2466 | ++vcpu->stat.irq_injections; | 2563 | ++vcpu->stat.irq_injections; |
| 2467 | if (vcpu->arch.rmode.vm86_active) { | 2564 | if (vmx->rmode.vm86_active) { |
| 2468 | vmx->rmode.irq.pending = true; | 2565 | vmx->rmode.irq.pending = true; |
| 2469 | vmx->rmode.irq.vector = irq; | 2566 | vmx->rmode.irq.vector = irq; |
| 2470 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); | 2567 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); |
| 2568 | if (vcpu->arch.interrupt.soft) | ||
| 2569 | vmx->rmode.irq.rip += | ||
| 2570 | vmx->vcpu.arch.event_exit_inst_len; | ||
| 2471 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, | 2571 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, |
| 2472 | irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK); | 2572 | irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK); |
| 2473 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); | 2573 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); |
| @@ -2502,7 +2602,7 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu) | |||
| 2502 | } | 2602 | } |
| 2503 | 2603 | ||
| 2504 | ++vcpu->stat.nmi_injections; | 2604 | ++vcpu->stat.nmi_injections; |
| 2505 | if (vcpu->arch.rmode.vm86_active) { | 2605 | if (vmx->rmode.vm86_active) { |
| 2506 | vmx->rmode.irq.pending = true; | 2606 | vmx->rmode.irq.pending = true; |
| 2507 | vmx->rmode.irq.vector = NMI_VECTOR; | 2607 | vmx->rmode.irq.vector = NMI_VECTOR; |
| 2508 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); | 2608 | vmx->rmode.irq.rip = kvm_rip_read(vcpu); |
| @@ -2659,14 +2759,14 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 2659 | if (enable_ept) | 2759 | if (enable_ept) |
| 2660 | BUG(); | 2760 | BUG(); |
| 2661 | cr2 = vmcs_readl(EXIT_QUALIFICATION); | 2761 | cr2 = vmcs_readl(EXIT_QUALIFICATION); |
| 2662 | KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2, | 2762 | trace_kvm_page_fault(cr2, error_code); |
| 2663 | (u32)((u64)cr2 >> 32), handler); | 2763 | |
| 2664 | if (kvm_event_needs_reinjection(vcpu)) | 2764 | if (kvm_event_needs_reinjection(vcpu)) |
| 2665 | kvm_mmu_unprotect_page_virt(vcpu, cr2); | 2765 | kvm_mmu_unprotect_page_virt(vcpu, cr2); |
| 2666 | return kvm_mmu_page_fault(vcpu, cr2, error_code); | 2766 | return kvm_mmu_page_fault(vcpu, cr2, error_code); |
| 2667 | } | 2767 | } |
| 2668 | 2768 | ||
| 2669 | if (vcpu->arch.rmode.vm86_active && | 2769 | if (vmx->rmode.vm86_active && |
| 2670 | handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK, | 2770 | handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK, |
| 2671 | error_code)) { | 2771 | error_code)) { |
| 2672 | if (vcpu->arch.halt_request) { | 2772 | if (vcpu->arch.halt_request) { |
| @@ -2707,7 +2807,6 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu, | |||
| 2707 | struct kvm_run *kvm_run) | 2807 | struct kvm_run *kvm_run) |
| 2708 | { | 2808 | { |
| 2709 | ++vcpu->stat.irq_exits; | 2809 | ++vcpu->stat.irq_exits; |
| 2710 | KVMTRACE_1D(INTR, vcpu, vmcs_read32(VM_EXIT_INTR_INFO), handler); | ||
| 2711 | return 1; | 2810 | return 1; |
| 2712 | } | 2811 | } |
| 2713 | 2812 | ||
| @@ -2755,7 +2854,7 @@ vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall) | |||
| 2755 | 2854 | ||
| 2756 | static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 2855 | static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) |
| 2757 | { | 2856 | { |
| 2758 | unsigned long exit_qualification; | 2857 | unsigned long exit_qualification, val; |
| 2759 | int cr; | 2858 | int cr; |
| 2760 | int reg; | 2859 | int reg; |
| 2761 | 2860 | ||
| @@ -2764,21 +2863,19 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 2764 | reg = (exit_qualification >> 8) & 15; | 2863 | reg = (exit_qualification >> 8) & 15; |
| 2765 | switch ((exit_qualification >> 4) & 3) { | 2864 | switch ((exit_qualification >> 4) & 3) { |
| 2766 | case 0: /* mov to cr */ | 2865 | case 0: /* mov to cr */ |
| 2767 | KVMTRACE_3D(CR_WRITE, vcpu, (u32)cr, | 2866 | val = kvm_register_read(vcpu, reg); |
| 2768 | (u32)kvm_register_read(vcpu, reg), | 2867 | trace_kvm_cr_write(cr, val); |
| 2769 | (u32)((u64)kvm_register_read(vcpu, reg) >> 32), | ||
| 2770 | handler); | ||
| 2771 | switch (cr) { | 2868 | switch (cr) { |
| 2772 | case 0: | 2869 | case 0: |
| 2773 | kvm_set_cr0(vcpu, kvm_register_read(vcpu, reg)); | 2870 | kvm_set_cr0(vcpu, val); |
| 2774 | skip_emulated_instruction(vcpu); | 2871 | skip_emulated_instruction(vcpu); |
| 2775 | return 1; | 2872 | return 1; |
| 2776 | case 3: | 2873 | case 3: |
| 2777 | kvm_set_cr3(vcpu, kvm_register_read(vcpu, reg)); | 2874 | kvm_set_cr3(vcpu, val); |
| 2778 | skip_emulated_instruction(vcpu); | 2875 | skip_emulated_instruction(vcpu); |
| 2779 | return 1; | 2876 | return 1; |
| 2780 | case 4: | 2877 | case 4: |
| 2781 | kvm_set_cr4(vcpu, kvm_register_read(vcpu, reg)); | 2878 | kvm_set_cr4(vcpu, val); |
| 2782 | skip_emulated_instruction(vcpu); | 2879 | skip_emulated_instruction(vcpu); |
| 2783 | return 1; | 2880 | return 1; |
| 2784 | case 8: { | 2881 | case 8: { |
| @@ -2800,23 +2897,19 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 2800 | vcpu->arch.cr0 &= ~X86_CR0_TS; | 2897 | vcpu->arch.cr0 &= ~X86_CR0_TS; |
| 2801 | vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0); | 2898 | vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0); |
| 2802 | vmx_fpu_activate(vcpu); | 2899 | vmx_fpu_activate(vcpu); |
| 2803 | KVMTRACE_0D(CLTS, vcpu, handler); | ||
| 2804 | skip_emulated_instruction(vcpu); | 2900 | skip_emulated_instruction(vcpu); |
| 2805 | return 1; | 2901 | return 1; |
| 2806 | case 1: /*mov from cr*/ | 2902 | case 1: /*mov from cr*/ |
| 2807 | switch (cr) { | 2903 | switch (cr) { |
| 2808 | case 3: | 2904 | case 3: |
| 2809 | kvm_register_write(vcpu, reg, vcpu->arch.cr3); | 2905 | kvm_register_write(vcpu, reg, vcpu->arch.cr3); |
| 2810 | KVMTRACE_3D(CR_READ, vcpu, (u32)cr, | 2906 | trace_kvm_cr_read(cr, vcpu->arch.cr3); |
| 2811 | (u32)kvm_register_read(vcpu, reg), | ||
| 2812 | (u32)((u64)kvm_register_read(vcpu, reg) >> 32), | ||
| 2813 | handler); | ||
| 2814 | skip_emulated_instruction(vcpu); | 2907 | skip_emulated_instruction(vcpu); |
| 2815 | return 1; | 2908 | return 1; |
| 2816 | case 8: | 2909 | case 8: |
| 2817 | kvm_register_write(vcpu, reg, kvm_get_cr8(vcpu)); | 2910 | val = kvm_get_cr8(vcpu); |
| 2818 | KVMTRACE_2D(CR_READ, vcpu, (u32)cr, | 2911 | kvm_register_write(vcpu, reg, val); |
| 2819 | (u32)kvm_register_read(vcpu, reg), handler); | 2912 | trace_kvm_cr_read(cr, val); |
| 2820 | skip_emulated_instruction(vcpu); | 2913 | skip_emulated_instruction(vcpu); |
| 2821 | return 1; | 2914 | return 1; |
| 2822 | } | 2915 | } |
| @@ -2841,6 +2934,8 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 2841 | unsigned long val; | 2934 | unsigned long val; |
| 2842 | int dr, reg; | 2935 | int dr, reg; |
| 2843 | 2936 | ||
| 2937 | if (!kvm_require_cpl(vcpu, 0)) | ||
| 2938 | return 1; | ||
| 2844 | dr = vmcs_readl(GUEST_DR7); | 2939 | dr = vmcs_readl(GUEST_DR7); |
| 2845 | if (dr & DR7_GD) { | 2940 | if (dr & DR7_GD) { |
| 2846 | /* | 2941 | /* |
| @@ -2884,7 +2979,6 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 2884 | val = 0; | 2979 | val = 0; |
| 2885 | } | 2980 | } |
| 2886 | kvm_register_write(vcpu, reg, val); | 2981 | kvm_register_write(vcpu, reg, val); |
| 2887 | KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler); | ||
| 2888 | } else { | 2982 | } else { |
| 2889 | val = vcpu->arch.regs[reg]; | 2983 | val = vcpu->arch.regs[reg]; |
| 2890 | switch (dr) { | 2984 | switch (dr) { |
| @@ -2917,7 +3011,6 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 2917 | } | 3011 | } |
| 2918 | break; | 3012 | break; |
| 2919 | } | 3013 | } |
| 2920 | KVMTRACE_2D(DR_WRITE, vcpu, (u32)dr, (u32)val, handler); | ||
| 2921 | } | 3014 | } |
| 2922 | skip_emulated_instruction(vcpu); | 3015 | skip_emulated_instruction(vcpu); |
| 2923 | return 1; | 3016 | return 1; |
| @@ -2939,8 +3032,7 @@ static int handle_rdmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 2939 | return 1; | 3032 | return 1; |
| 2940 | } | 3033 | } |
| 2941 | 3034 | ||
| 2942 | KVMTRACE_3D(MSR_READ, vcpu, ecx, (u32)data, (u32)(data >> 32), | 3035 | trace_kvm_msr_read(ecx, data); |
| 2943 | handler); | ||
| 2944 | 3036 | ||
| 2945 | /* FIXME: handling of bits 32:63 of rax, rdx */ | 3037 | /* FIXME: handling of bits 32:63 of rax, rdx */ |
| 2946 | vcpu->arch.regs[VCPU_REGS_RAX] = data & -1u; | 3038 | vcpu->arch.regs[VCPU_REGS_RAX] = data & -1u; |
| @@ -2955,8 +3047,7 @@ static int handle_wrmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 2955 | u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u) | 3047 | u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u) |
| 2956 | | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32); | 3048 | | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32); |
| 2957 | 3049 | ||
| 2958 | KVMTRACE_3D(MSR_WRITE, vcpu, ecx, (u32)data, (u32)(data >> 32), | 3050 | trace_kvm_msr_write(ecx, data); |
| 2959 | handler); | ||
| 2960 | 3051 | ||
| 2961 | if (vmx_set_msr(vcpu, ecx, data) != 0) { | 3052 | if (vmx_set_msr(vcpu, ecx, data) != 0) { |
| 2962 | kvm_inject_gp(vcpu, 0); | 3053 | kvm_inject_gp(vcpu, 0); |
| @@ -2983,7 +3074,6 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu, | |||
| 2983 | cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING; | 3074 | cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING; |
| 2984 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); | 3075 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); |
| 2985 | 3076 | ||
| 2986 | KVMTRACE_0D(PEND_INTR, vcpu, handler); | ||
| 2987 | ++vcpu->stat.irq_window_exits; | 3077 | ++vcpu->stat.irq_window_exits; |
| 2988 | 3078 | ||
| 2989 | /* | 3079 | /* |
| @@ -3049,7 +3139,7 @@ static int handle_apic_access(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 3049 | printk(KERN_ERR | 3139 | printk(KERN_ERR |
| 3050 | "Fail to handle apic access vmexit! Offset is 0x%lx\n", | 3140 | "Fail to handle apic access vmexit! Offset is 0x%lx\n", |
| 3051 | offset); | 3141 | offset); |
| 3052 | return -ENOTSUPP; | 3142 | return -ENOEXEC; |
| 3053 | } | 3143 | } |
| 3054 | return 1; | 3144 | return 1; |
| 3055 | } | 3145 | } |
| @@ -3118,7 +3208,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 3118 | 3208 | ||
| 3119 | if (exit_qualification & (1 << 6)) { | 3209 | if (exit_qualification & (1 << 6)) { |
| 3120 | printk(KERN_ERR "EPT: GPA exceeds GAW!\n"); | 3210 | printk(KERN_ERR "EPT: GPA exceeds GAW!\n"); |
| 3121 | return -ENOTSUPP; | 3211 | return -EINVAL; |
| 3122 | } | 3212 | } |
| 3123 | 3213 | ||
| 3124 | gla_validity = (exit_qualification >> 7) & 0x3; | 3214 | gla_validity = (exit_qualification >> 7) & 0x3; |
| @@ -3130,14 +3220,98 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 3130 | printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n", | 3220 | printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n", |
| 3131 | (long unsigned int)exit_qualification); | 3221 | (long unsigned int)exit_qualification); |
| 3132 | kvm_run->exit_reason = KVM_EXIT_UNKNOWN; | 3222 | kvm_run->exit_reason = KVM_EXIT_UNKNOWN; |
| 3133 | kvm_run->hw.hardware_exit_reason = 0; | 3223 | kvm_run->hw.hardware_exit_reason = EXIT_REASON_EPT_VIOLATION; |
| 3134 | return -ENOTSUPP; | 3224 | return 0; |
| 3135 | } | 3225 | } |
| 3136 | 3226 | ||
| 3137 | gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS); | 3227 | gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS); |
| 3228 | trace_kvm_page_fault(gpa, exit_qualification); | ||
| 3138 | return kvm_mmu_page_fault(vcpu, gpa & PAGE_MASK, 0); | 3229 | return kvm_mmu_page_fault(vcpu, gpa & PAGE_MASK, 0); |
| 3139 | } | 3230 | } |
| 3140 | 3231 | ||
| 3232 | static u64 ept_rsvd_mask(u64 spte, int level) | ||
| 3233 | { | ||
| 3234 | int i; | ||
| 3235 | u64 mask = 0; | ||
| 3236 | |||
| 3237 | for (i = 51; i > boot_cpu_data.x86_phys_bits; i--) | ||
| 3238 | mask |= (1ULL << i); | ||
| 3239 | |||
| 3240 | if (level > 2) | ||
| 3241 | /* bits 7:3 reserved */ | ||
| 3242 | mask |= 0xf8; | ||
| 3243 | else if (level == 2) { | ||
| 3244 | if (spte & (1ULL << 7)) | ||
| 3245 | /* 2MB ref, bits 20:12 reserved */ | ||
| 3246 | mask |= 0x1ff000; | ||
| 3247 | else | ||
| 3248 | /* bits 6:3 reserved */ | ||
| 3249 | mask |= 0x78; | ||
| 3250 | } | ||
| 3251 | |||
| 3252 | return mask; | ||
| 3253 | } | ||
| 3254 | |||
| 3255 | static void ept_misconfig_inspect_spte(struct kvm_vcpu *vcpu, u64 spte, | ||
| 3256 | int level) | ||
| 3257 | { | ||
| 3258 | printk(KERN_ERR "%s: spte 0x%llx level %d\n", __func__, spte, level); | ||
| 3259 | |||
| 3260 | /* 010b (write-only) */ | ||
| 3261 | WARN_ON((spte & 0x7) == 0x2); | ||
| 3262 | |||
| 3263 | /* 110b (write/execute) */ | ||
| 3264 | WARN_ON((spte & 0x7) == 0x6); | ||
| 3265 | |||
| 3266 | /* 100b (execute-only) and value not supported by logical processor */ | ||
| 3267 | if (!cpu_has_vmx_ept_execute_only()) | ||
| 3268 | WARN_ON((spte & 0x7) == 0x4); | ||
| 3269 | |||
| 3270 | /* not 000b */ | ||
| 3271 | if ((spte & 0x7)) { | ||
| 3272 | u64 rsvd_bits = spte & ept_rsvd_mask(spte, level); | ||
| 3273 | |||
| 3274 | if (rsvd_bits != 0) { | ||
| 3275 | printk(KERN_ERR "%s: rsvd_bits = 0x%llx\n", | ||
| 3276 | __func__, rsvd_bits); | ||
| 3277 | WARN_ON(1); | ||
| 3278 | } | ||
| 3279 | |||
| 3280 | if (level == 1 || (level == 2 && (spte & (1ULL << 7)))) { | ||
| 3281 | u64 ept_mem_type = (spte & 0x38) >> 3; | ||
| 3282 | |||
| 3283 | if (ept_mem_type == 2 || ept_mem_type == 3 || | ||
| 3284 | ept_mem_type == 7) { | ||
| 3285 | printk(KERN_ERR "%s: ept_mem_type=0x%llx\n", | ||
| 3286 | __func__, ept_mem_type); | ||
| 3287 | WARN_ON(1); | ||
| 3288 | } | ||
| 3289 | } | ||
| 3290 | } | ||
| 3291 | } | ||
| 3292 | |||
| 3293 | static int handle_ept_misconfig(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
| 3294 | { | ||
| 3295 | u64 sptes[4]; | ||
| 3296 | int nr_sptes, i; | ||
| 3297 | gpa_t gpa; | ||
| 3298 | |||
| 3299 | gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS); | ||
| 3300 | |||
| 3301 | printk(KERN_ERR "EPT: Misconfiguration.\n"); | ||
| 3302 | printk(KERN_ERR "EPT: GPA: 0x%llx\n", gpa); | ||
| 3303 | |||
| 3304 | nr_sptes = kvm_mmu_get_spte_hierarchy(vcpu, gpa, sptes); | ||
| 3305 | |||
| 3306 | for (i = PT64_ROOT_LEVEL; i > PT64_ROOT_LEVEL - nr_sptes; --i) | ||
| 3307 | ept_misconfig_inspect_spte(vcpu, sptes[i-1], i); | ||
| 3308 | |||
| 3309 | kvm_run->exit_reason = KVM_EXIT_UNKNOWN; | ||
| 3310 | kvm_run->hw.hardware_exit_reason = EXIT_REASON_EPT_MISCONFIG; | ||
| 3311 | |||
| 3312 | return 0; | ||
| 3313 | } | ||
| 3314 | |||
| 3141 | static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 3315 | static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) |
| 3142 | { | 3316 | { |
| 3143 | u32 cpu_based_vm_exec_control; | 3317 | u32 cpu_based_vm_exec_control; |
| @@ -3217,8 +3391,9 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu, | |||
| 3217 | [EXIT_REASON_APIC_ACCESS] = handle_apic_access, | 3391 | [EXIT_REASON_APIC_ACCESS] = handle_apic_access, |
| 3218 | [EXIT_REASON_WBINVD] = handle_wbinvd, | 3392 | [EXIT_REASON_WBINVD] = handle_wbinvd, |
| 3219 | [EXIT_REASON_TASK_SWITCH] = handle_task_switch, | 3393 | [EXIT_REASON_TASK_SWITCH] = handle_task_switch, |
| 3220 | [EXIT_REASON_EPT_VIOLATION] = handle_ept_violation, | ||
| 3221 | [EXIT_REASON_MCE_DURING_VMENTRY] = handle_machine_check, | 3394 | [EXIT_REASON_MCE_DURING_VMENTRY] = handle_machine_check, |
| 3395 | [EXIT_REASON_EPT_VIOLATION] = handle_ept_violation, | ||
| 3396 | [EXIT_REASON_EPT_MISCONFIG] = handle_ept_misconfig, | ||
| 3222 | }; | 3397 | }; |
| 3223 | 3398 | ||
| 3224 | static const int kvm_vmx_max_exit_handlers = | 3399 | static const int kvm_vmx_max_exit_handlers = |
| @@ -3234,8 +3409,7 @@ static int vmx_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
| 3234 | u32 exit_reason = vmx->exit_reason; | 3409 | u32 exit_reason = vmx->exit_reason; |
| 3235 | u32 vectoring_info = vmx->idt_vectoring_info; | 3410 | u32 vectoring_info = vmx->idt_vectoring_info; |
| 3236 | 3411 | ||
| 3237 | KVMTRACE_3D(VMEXIT, vcpu, exit_reason, (u32)kvm_rip_read(vcpu), | 3412 | trace_kvm_exit(exit_reason, kvm_rip_read(vcpu)); |
| 3238 | (u32)((u64)kvm_rip_read(vcpu) >> 32), entryexit); | ||
| 3239 | 3413 | ||
| 3240 | /* If we need to emulate an MMIO from handle_invalid_guest_state | 3414 | /* If we need to emulate an MMIO from handle_invalid_guest_state |
| 3241 | * we just return 0 */ | 3415 | * we just return 0 */ |
| @@ -3247,10 +3421,8 @@ static int vmx_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
| 3247 | 3421 | ||
| 3248 | /* Access CR3 don't cause VMExit in paging mode, so we need | 3422 | /* Access CR3 don't cause VMExit in paging mode, so we need |
| 3249 | * to sync with guest real CR3. */ | 3423 | * to sync with guest real CR3. */ |
| 3250 | if (enable_ept && is_paging(vcpu)) { | 3424 | if (enable_ept && is_paging(vcpu)) |
| 3251 | vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); | 3425 | vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); |
| 3252 | ept_load_pdptrs(vcpu); | ||
| 3253 | } | ||
| 3254 | 3426 | ||
| 3255 | if (unlikely(vmx->fail)) { | 3427 | if (unlikely(vmx->fail)) { |
| 3256 | kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; | 3428 | kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; |
| @@ -3326,10 +3498,8 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx) | |||
| 3326 | 3498 | ||
| 3327 | /* We need to handle NMIs before interrupts are enabled */ | 3499 | /* We need to handle NMIs before interrupts are enabled */ |
| 3328 | if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR && | 3500 | if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR && |
| 3329 | (exit_intr_info & INTR_INFO_VALID_MASK)) { | 3501 | (exit_intr_info & INTR_INFO_VALID_MASK)) |
| 3330 | KVMTRACE_0D(NMI, &vmx->vcpu, handler); | ||
| 3331 | asm("int $2"); | 3502 | asm("int $2"); |
| 3332 | } | ||
| 3333 | 3503 | ||
| 3334 | idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK; | 3504 | idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK; |
| 3335 | 3505 | ||
| @@ -3434,6 +3604,10 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 3434 | { | 3604 | { |
| 3435 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 3605 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 3436 | 3606 | ||
| 3607 | if (enable_ept && is_paging(vcpu)) { | ||
| 3608 | vmcs_writel(GUEST_CR3, vcpu->arch.cr3); | ||
| 3609 | ept_load_pdptrs(vcpu); | ||
| 3610 | } | ||
| 3437 | /* Record the guest's net vcpu time for enforced NMI injections. */ | 3611 | /* Record the guest's net vcpu time for enforced NMI injections. */ |
| 3438 | if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked)) | 3612 | if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked)) |
| 3439 | vmx->entry_time = ktime_get(); | 3613 | vmx->entry_time = ktime_get(); |
| @@ -3449,12 +3623,21 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 3449 | if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty)) | 3623 | if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty)) |
| 3450 | vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]); | 3624 | vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]); |
| 3451 | 3625 | ||
| 3626 | /* When single-stepping over STI and MOV SS, we must clear the | ||
| 3627 | * corresponding interruptibility bits in the guest state. Otherwise | ||
| 3628 | * vmentry fails as it then expects bit 14 (BS) in pending debug | ||
| 3629 | * exceptions being set, but that's not correct for the guest debugging | ||
| 3630 | * case. */ | ||
| 3631 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) | ||
| 3632 | vmx_set_interrupt_shadow(vcpu, 0); | ||
| 3633 | |||
| 3452 | /* | 3634 | /* |
| 3453 | * Loading guest fpu may have cleared host cr0.ts | 3635 | * Loading guest fpu may have cleared host cr0.ts |
| 3454 | */ | 3636 | */ |
| 3455 | vmcs_writel(HOST_CR0, read_cr0()); | 3637 | vmcs_writel(HOST_CR0, read_cr0()); |
| 3456 | 3638 | ||
| 3457 | set_debugreg(vcpu->arch.dr6, 6); | 3639 | if (vcpu->arch.switch_db_regs) |
| 3640 | set_debugreg(vcpu->arch.dr6, 6); | ||
| 3458 | 3641 | ||
| 3459 | asm( | 3642 | asm( |
| 3460 | /* Store host registers */ | 3643 | /* Store host registers */ |
| @@ -3465,11 +3648,16 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 3465 | "mov %%"R"sp, %c[host_rsp](%0) \n\t" | 3648 | "mov %%"R"sp, %c[host_rsp](%0) \n\t" |
| 3466 | __ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t" | 3649 | __ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t" |
| 3467 | "1: \n\t" | 3650 | "1: \n\t" |
| 3651 | /* Reload cr2 if changed */ | ||
| 3652 | "mov %c[cr2](%0), %%"R"ax \n\t" | ||
| 3653 | "mov %%cr2, %%"R"dx \n\t" | ||
| 3654 | "cmp %%"R"ax, %%"R"dx \n\t" | ||
| 3655 | "je 2f \n\t" | ||
| 3656 | "mov %%"R"ax, %%cr2 \n\t" | ||
| 3657 | "2: \n\t" | ||
| 3468 | /* Check if vmlaunch of vmresume is needed */ | 3658 | /* Check if vmlaunch of vmresume is needed */ |
| 3469 | "cmpl $0, %c[launched](%0) \n\t" | 3659 | "cmpl $0, %c[launched](%0) \n\t" |
| 3470 | /* Load guest registers. Don't clobber flags. */ | 3660 | /* Load guest registers. Don't clobber flags. */ |
| 3471 | "mov %c[cr2](%0), %%"R"ax \n\t" | ||
| 3472 | "mov %%"R"ax, %%cr2 \n\t" | ||
| 3473 | "mov %c[rax](%0), %%"R"ax \n\t" | 3661 | "mov %c[rax](%0), %%"R"ax \n\t" |
| 3474 | "mov %c[rbx](%0), %%"R"bx \n\t" | 3662 | "mov %c[rbx](%0), %%"R"bx \n\t" |
| 3475 | "mov %c[rdx](%0), %%"R"dx \n\t" | 3663 | "mov %c[rdx](%0), %%"R"dx \n\t" |
| @@ -3547,10 +3735,12 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 3547 | #endif | 3735 | #endif |
| 3548 | ); | 3736 | ); |
| 3549 | 3737 | ||
| 3550 | vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)); | 3738 | vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) |
| 3739 | | (1 << VCPU_EXREG_PDPTR)); | ||
| 3551 | vcpu->arch.regs_dirty = 0; | 3740 | vcpu->arch.regs_dirty = 0; |
| 3552 | 3741 | ||
| 3553 | get_debugreg(vcpu->arch.dr6, 6); | 3742 | if (vcpu->arch.switch_db_regs) |
| 3743 | get_debugreg(vcpu->arch.dr6, 6); | ||
| 3554 | 3744 | ||
| 3555 | vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); | 3745 | vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); |
| 3556 | if (vmx->rmode.irq.pending) | 3746 | if (vmx->rmode.irq.pending) |
| @@ -3633,9 +3823,13 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) | |||
| 3633 | if (alloc_apic_access_page(kvm) != 0) | 3823 | if (alloc_apic_access_page(kvm) != 0) |
| 3634 | goto free_vmcs; | 3824 | goto free_vmcs; |
| 3635 | 3825 | ||
| 3636 | if (enable_ept) | 3826 | if (enable_ept) { |
| 3827 | if (!kvm->arch.ept_identity_map_addr) | ||
| 3828 | kvm->arch.ept_identity_map_addr = | ||
| 3829 | VMX_EPT_IDENTITY_PAGETABLE_ADDR; | ||
| 3637 | if (alloc_identity_pagetable(kvm) != 0) | 3830 | if (alloc_identity_pagetable(kvm) != 0) |
| 3638 | goto free_vmcs; | 3831 | goto free_vmcs; |
| 3832 | } | ||
| 3639 | 3833 | ||
| 3640 | return &vmx->vcpu; | 3834 | return &vmx->vcpu; |
| 3641 | 3835 | ||
| @@ -3699,6 +3893,34 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio) | |||
| 3699 | return ret; | 3893 | return ret; |
| 3700 | } | 3894 | } |
| 3701 | 3895 | ||
| 3896 | static const struct trace_print_flags vmx_exit_reasons_str[] = { | ||
| 3897 | { EXIT_REASON_EXCEPTION_NMI, "exception" }, | ||
| 3898 | { EXIT_REASON_EXTERNAL_INTERRUPT, "ext_irq" }, | ||
| 3899 | { EXIT_REASON_TRIPLE_FAULT, "triple_fault" }, | ||
| 3900 | { EXIT_REASON_NMI_WINDOW, "nmi_window" }, | ||
| 3901 | { EXIT_REASON_IO_INSTRUCTION, "io_instruction" }, | ||
| 3902 | { EXIT_REASON_CR_ACCESS, "cr_access" }, | ||
| 3903 | { EXIT_REASON_DR_ACCESS, "dr_access" }, | ||
| 3904 | { EXIT_REASON_CPUID, "cpuid" }, | ||
| 3905 | { EXIT_REASON_MSR_READ, "rdmsr" }, | ||
| 3906 | { EXIT_REASON_MSR_WRITE, "wrmsr" }, | ||
| 3907 | { EXIT_REASON_PENDING_INTERRUPT, "interrupt_window" }, | ||
| 3908 | { EXIT_REASON_HLT, "halt" }, | ||
| 3909 | { EXIT_REASON_INVLPG, "invlpg" }, | ||
| 3910 | { EXIT_REASON_VMCALL, "hypercall" }, | ||
| 3911 | { EXIT_REASON_TPR_BELOW_THRESHOLD, "tpr_below_thres" }, | ||
| 3912 | { EXIT_REASON_APIC_ACCESS, "apic_access" }, | ||
| 3913 | { EXIT_REASON_WBINVD, "wbinvd" }, | ||
| 3914 | { EXIT_REASON_TASK_SWITCH, "task_switch" }, | ||
| 3915 | { EXIT_REASON_EPT_VIOLATION, "ept_violation" }, | ||
| 3916 | { -1, NULL } | ||
| 3917 | }; | ||
| 3918 | |||
| 3919 | static bool vmx_gb_page_enable(void) | ||
| 3920 | { | ||
| 3921 | return false; | ||
| 3922 | } | ||
| 3923 | |||
| 3702 | static struct kvm_x86_ops vmx_x86_ops = { | 3924 | static struct kvm_x86_ops vmx_x86_ops = { |
| 3703 | .cpu_has_kvm_support = cpu_has_kvm_support, | 3925 | .cpu_has_kvm_support = cpu_has_kvm_support, |
| 3704 | .disabled_by_bios = vmx_disabled_by_bios, | 3926 | .disabled_by_bios = vmx_disabled_by_bios, |
| @@ -3758,6 +3980,9 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
| 3758 | .set_tss_addr = vmx_set_tss_addr, | 3980 | .set_tss_addr = vmx_set_tss_addr, |
| 3759 | .get_tdp_level = get_ept_level, | 3981 | .get_tdp_level = get_ept_level, |
| 3760 | .get_mt_mask = vmx_get_mt_mask, | 3982 | .get_mt_mask = vmx_get_mt_mask, |
| 3983 | |||
| 3984 | .exit_reasons_str = vmx_exit_reasons_str, | ||
| 3985 | .gb_page_enable = vmx_gb_page_enable, | ||
| 3761 | }; | 3986 | }; |
| 3762 | 3987 | ||
| 3763 | static int __init vmx_init(void) | 3988 | static int __init vmx_init(void) |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 3d4529011828..be451ee44249 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -37,11 +37,16 @@ | |||
| 37 | #include <linux/iommu.h> | 37 | #include <linux/iommu.h> |
| 38 | #include <linux/intel-iommu.h> | 38 | #include <linux/intel-iommu.h> |
| 39 | #include <linux/cpufreq.h> | 39 | #include <linux/cpufreq.h> |
| 40 | #include <trace/events/kvm.h> | ||
| 41 | #undef TRACE_INCLUDE_FILE | ||
| 42 | #define CREATE_TRACE_POINTS | ||
| 43 | #include "trace.h" | ||
| 40 | 44 | ||
| 41 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
| 42 | #include <asm/msr.h> | 46 | #include <asm/msr.h> |
| 43 | #include <asm/desc.h> | 47 | #include <asm/desc.h> |
| 44 | #include <asm/mtrr.h> | 48 | #include <asm/mtrr.h> |
| 49 | #include <asm/mce.h> | ||
| 45 | 50 | ||
| 46 | #define MAX_IO_MSRS 256 | 51 | #define MAX_IO_MSRS 256 |
| 47 | #define CR0_RESERVED_BITS \ | 52 | #define CR0_RESERVED_BITS \ |
| @@ -55,6 +60,10 @@ | |||
| 55 | | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE)) | 60 | | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE)) |
| 56 | 61 | ||
| 57 | #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) | 62 | #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) |
| 63 | |||
| 64 | #define KVM_MAX_MCE_BANKS 32 | ||
| 65 | #define KVM_MCE_CAP_SUPPORTED MCG_CTL_P | ||
| 66 | |||
| 58 | /* EFER defaults: | 67 | /* EFER defaults: |
| 59 | * - enable syscall per default because its emulated by KVM | 68 | * - enable syscall per default because its emulated by KVM |
| 60 | * - enable LME and LMA per default on 64 bit KVM | 69 | * - enable LME and LMA per default on 64 bit KVM |
| @@ -68,14 +77,16 @@ static u64 __read_mostly efer_reserved_bits = 0xfffffffffffffffeULL; | |||
| 68 | #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM | 77 | #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM |
| 69 | #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU | 78 | #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU |
| 70 | 79 | ||
| 80 | static void update_cr8_intercept(struct kvm_vcpu *vcpu); | ||
| 71 | static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, | 81 | static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, |
| 72 | struct kvm_cpuid_entry2 __user *entries); | 82 | struct kvm_cpuid_entry2 __user *entries); |
| 73 | struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, | ||
| 74 | u32 function, u32 index); | ||
| 75 | 83 | ||
| 76 | struct kvm_x86_ops *kvm_x86_ops; | 84 | struct kvm_x86_ops *kvm_x86_ops; |
| 77 | EXPORT_SYMBOL_GPL(kvm_x86_ops); | 85 | EXPORT_SYMBOL_GPL(kvm_x86_ops); |
| 78 | 86 | ||
| 87 | int ignore_msrs = 0; | ||
| 88 | module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR); | ||
| 89 | |||
| 79 | struct kvm_stats_debugfs_item debugfs_entries[] = { | 90 | struct kvm_stats_debugfs_item debugfs_entries[] = { |
| 80 | { "pf_fixed", VCPU_STAT(pf_fixed) }, | 91 | { "pf_fixed", VCPU_STAT(pf_fixed) }, |
| 81 | { "pf_guest", VCPU_STAT(pf_guest) }, | 92 | { "pf_guest", VCPU_STAT(pf_guest) }, |
| @@ -122,18 +133,16 @@ unsigned long segment_base(u16 selector) | |||
| 122 | if (selector == 0) | 133 | if (selector == 0) |
| 123 | return 0; | 134 | return 0; |
| 124 | 135 | ||
| 125 | asm("sgdt %0" : "=m"(gdt)); | 136 | kvm_get_gdt(&gdt); |
| 126 | table_base = gdt.base; | 137 | table_base = gdt.base; |
| 127 | 138 | ||
| 128 | if (selector & 4) { /* from ldt */ | 139 | if (selector & 4) { /* from ldt */ |
| 129 | u16 ldt_selector; | 140 | u16 ldt_selector = kvm_read_ldt(); |
| 130 | 141 | ||
| 131 | asm("sldt %0" : "=g"(ldt_selector)); | ||
| 132 | table_base = segment_base(ldt_selector); | 142 | table_base = segment_base(ldt_selector); |
| 133 | } | 143 | } |
| 134 | d = (struct desc_struct *)(table_base + (selector & ~7)); | 144 | d = (struct desc_struct *)(table_base + (selector & ~7)); |
| 135 | v = d->base0 | ((unsigned long)d->base1 << 16) | | 145 | v = get_desc_base(d); |
| 136 | ((unsigned long)d->base2 << 24); | ||
| 137 | #ifdef CONFIG_X86_64 | 146 | #ifdef CONFIG_X86_64 |
| 138 | if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11)) | 147 | if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11)) |
| 139 | v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32; | 148 | v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32; |
| @@ -176,16 +185,22 @@ void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr, | |||
| 176 | ++vcpu->stat.pf_guest; | 185 | ++vcpu->stat.pf_guest; |
| 177 | 186 | ||
| 178 | if (vcpu->arch.exception.pending) { | 187 | if (vcpu->arch.exception.pending) { |
| 179 | if (vcpu->arch.exception.nr == PF_VECTOR) { | 188 | switch(vcpu->arch.exception.nr) { |
| 180 | printk(KERN_DEBUG "kvm: inject_page_fault:" | 189 | case DF_VECTOR: |
| 181 | " double fault 0x%lx\n", addr); | ||
| 182 | vcpu->arch.exception.nr = DF_VECTOR; | ||
| 183 | vcpu->arch.exception.error_code = 0; | ||
| 184 | } else if (vcpu->arch.exception.nr == DF_VECTOR) { | ||
| 185 | /* triple fault -> shutdown */ | 190 | /* triple fault -> shutdown */ |
| 186 | set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests); | 191 | set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests); |
| 192 | return; | ||
| 193 | case PF_VECTOR: | ||
| 194 | vcpu->arch.exception.nr = DF_VECTOR; | ||
| 195 | vcpu->arch.exception.error_code = 0; | ||
| 196 | return; | ||
| 197 | default: | ||
| 198 | /* replace previous exception with a new one in a hope | ||
| 199 | that instruction re-execution will regenerate lost | ||
| 200 | exception */ | ||
| 201 | vcpu->arch.exception.pending = false; | ||
| 202 | break; | ||
| 187 | } | 203 | } |
| 188 | return; | ||
| 189 | } | 204 | } |
| 190 | vcpu->arch.cr2 = addr; | 205 | vcpu->arch.cr2 = addr; |
| 191 | kvm_queue_exception_e(vcpu, PF_VECTOR, error_code); | 206 | kvm_queue_exception_e(vcpu, PF_VECTOR, error_code); |
| @@ -207,12 +222,18 @@ void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code) | |||
| 207 | } | 222 | } |
| 208 | EXPORT_SYMBOL_GPL(kvm_queue_exception_e); | 223 | EXPORT_SYMBOL_GPL(kvm_queue_exception_e); |
| 209 | 224 | ||
| 210 | static void __queue_exception(struct kvm_vcpu *vcpu) | 225 | /* |
| 226 | * Checks if cpl <= required_cpl; if true, return true. Otherwise queue | ||
| 227 | * a #GP and return false. | ||
| 228 | */ | ||
| 229 | bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl) | ||
| 211 | { | 230 | { |
| 212 | kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr, | 231 | if (kvm_x86_ops->get_cpl(vcpu) <= required_cpl) |
| 213 | vcpu->arch.exception.has_error_code, | 232 | return true; |
| 214 | vcpu->arch.exception.error_code); | 233 | kvm_queue_exception_e(vcpu, GP_VECTOR, 0); |
| 234 | return false; | ||
| 215 | } | 235 | } |
| 236 | EXPORT_SYMBOL_GPL(kvm_require_cpl); | ||
| 216 | 237 | ||
| 217 | /* | 238 | /* |
| 218 | * Load the pae pdptrs. Return true is they are all valid. | 239 | * Load the pae pdptrs. Return true is they are all valid. |
| @@ -232,7 +253,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
| 232 | goto out; | 253 | goto out; |
| 233 | } | 254 | } |
| 234 | for (i = 0; i < ARRAY_SIZE(pdpte); ++i) { | 255 | for (i = 0; i < ARRAY_SIZE(pdpte); ++i) { |
| 235 | if (is_present_pte(pdpte[i]) && | 256 | if (is_present_gpte(pdpte[i]) && |
| 236 | (pdpte[i] & vcpu->arch.mmu.rsvd_bits_mask[0][2])) { | 257 | (pdpte[i] & vcpu->arch.mmu.rsvd_bits_mask[0][2])) { |
| 237 | ret = 0; | 258 | ret = 0; |
| 238 | goto out; | 259 | goto out; |
| @@ -241,6 +262,10 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
| 241 | ret = 1; | 262 | ret = 1; |
| 242 | 263 | ||
| 243 | memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs)); | 264 | memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs)); |
| 265 | __set_bit(VCPU_EXREG_PDPTR, | ||
| 266 | (unsigned long *)&vcpu->arch.regs_avail); | ||
| 267 | __set_bit(VCPU_EXREG_PDPTR, | ||
| 268 | (unsigned long *)&vcpu->arch.regs_dirty); | ||
| 244 | out: | 269 | out: |
| 245 | 270 | ||
| 246 | return ret; | 271 | return ret; |
| @@ -256,6 +281,10 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu) | |||
| 256 | if (is_long_mode(vcpu) || !is_pae(vcpu)) | 281 | if (is_long_mode(vcpu) || !is_pae(vcpu)) |
| 257 | return false; | 282 | return false; |
| 258 | 283 | ||
| 284 | if (!test_bit(VCPU_EXREG_PDPTR, | ||
| 285 | (unsigned long *)&vcpu->arch.regs_avail)) | ||
| 286 | return true; | ||
| 287 | |||
| 259 | r = kvm_read_guest(vcpu->kvm, vcpu->arch.cr3 & ~31u, pdpte, sizeof(pdpte)); | 288 | r = kvm_read_guest(vcpu->kvm, vcpu->arch.cr3 & ~31u, pdpte, sizeof(pdpte)); |
| 260 | if (r < 0) | 289 | if (r < 0) |
| 261 | goto out; | 290 | goto out; |
| @@ -328,9 +357,6 @@ EXPORT_SYMBOL_GPL(kvm_set_cr0); | |||
| 328 | void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw) | 357 | void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw) |
| 329 | { | 358 | { |
| 330 | kvm_set_cr0(vcpu, (vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f)); | 359 | kvm_set_cr0(vcpu, (vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f)); |
| 331 | KVMTRACE_1D(LMSW, vcpu, | ||
| 332 | (u32)((vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f)), | ||
| 333 | handler); | ||
| 334 | } | 360 | } |
| 335 | EXPORT_SYMBOL_GPL(kvm_lmsw); | 361 | EXPORT_SYMBOL_GPL(kvm_lmsw); |
| 336 | 362 | ||
| @@ -466,7 +492,7 @@ static u32 msrs_to_save[] = { | |||
| 466 | #ifdef CONFIG_X86_64 | 492 | #ifdef CONFIG_X86_64 |
| 467 | MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, | 493 | MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, |
| 468 | #endif | 494 | #endif |
| 469 | MSR_IA32_TIME_STAMP_COUNTER, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, | 495 | MSR_IA32_TSC, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, |
| 470 | MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA | 496 | MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA |
| 471 | }; | 497 | }; |
| 472 | 498 | ||
| @@ -644,8 +670,7 @@ static void kvm_write_guest_time(struct kvm_vcpu *v) | |||
| 644 | 670 | ||
| 645 | /* Keep irq disabled to prevent changes to the clock */ | 671 | /* Keep irq disabled to prevent changes to the clock */ |
| 646 | local_irq_save(flags); | 672 | local_irq_save(flags); |
| 647 | kvm_get_msr(v, MSR_IA32_TIME_STAMP_COUNTER, | 673 | kvm_get_msr(v, MSR_IA32_TSC, &vcpu->hv_clock.tsc_timestamp); |
| 648 | &vcpu->hv_clock.tsc_timestamp); | ||
| 649 | ktime_get_ts(&ts); | 674 | ktime_get_ts(&ts); |
| 650 | local_irq_restore(flags); | 675 | local_irq_restore(flags); |
| 651 | 676 | ||
| @@ -778,23 +803,60 @@ static int set_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 data) | |||
| 778 | return 0; | 803 | return 0; |
| 779 | } | 804 | } |
| 780 | 805 | ||
| 806 | static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data) | ||
| 807 | { | ||
| 808 | u64 mcg_cap = vcpu->arch.mcg_cap; | ||
| 809 | unsigned bank_num = mcg_cap & 0xff; | ||
| 810 | |||
| 811 | switch (msr) { | ||
| 812 | case MSR_IA32_MCG_STATUS: | ||
| 813 | vcpu->arch.mcg_status = data; | ||
| 814 | break; | ||
| 815 | case MSR_IA32_MCG_CTL: | ||
| 816 | if (!(mcg_cap & MCG_CTL_P)) | ||
| 817 | return 1; | ||
| 818 | if (data != 0 && data != ~(u64)0) | ||
| 819 | return -1; | ||
| 820 | vcpu->arch.mcg_ctl = data; | ||
| 821 | break; | ||
| 822 | default: | ||
| 823 | if (msr >= MSR_IA32_MC0_CTL && | ||
| 824 | msr < MSR_IA32_MC0_CTL + 4 * bank_num) { | ||
| 825 | u32 offset = msr - MSR_IA32_MC0_CTL; | ||
| 826 | /* only 0 or all 1s can be written to IA32_MCi_CTL */ | ||
| 827 | if ((offset & 0x3) == 0 && | ||
| 828 | data != 0 && data != ~(u64)0) | ||
| 829 | return -1; | ||
| 830 | vcpu->arch.mce_banks[offset] = data; | ||
| 831 | break; | ||
| 832 | } | ||
| 833 | return 1; | ||
| 834 | } | ||
| 835 | return 0; | ||
| 836 | } | ||
| 837 | |||
| 781 | int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) | 838 | int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) |
| 782 | { | 839 | { |
| 783 | switch (msr) { | 840 | switch (msr) { |
| 784 | case MSR_EFER: | 841 | case MSR_EFER: |
| 785 | set_efer(vcpu, data); | 842 | set_efer(vcpu, data); |
| 786 | break; | 843 | break; |
| 787 | case MSR_IA32_MC0_STATUS: | 844 | case MSR_K7_HWCR: |
| 788 | pr_unimpl(vcpu, "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n", | 845 | data &= ~(u64)0x40; /* ignore flush filter disable */ |
| 789 | __func__, data); | 846 | if (data != 0) { |
| 847 | pr_unimpl(vcpu, "unimplemented HWCR wrmsr: 0x%llx\n", | ||
| 848 | data); | ||
| 849 | return 1; | ||
| 850 | } | ||
| 790 | break; | 851 | break; |
| 791 | case MSR_IA32_MCG_STATUS: | 852 | case MSR_FAM10H_MMIO_CONF_BASE: |
| 792 | pr_unimpl(vcpu, "%s: MSR_IA32_MCG_STATUS 0x%llx, nop\n", | 853 | if (data != 0) { |
| 793 | __func__, data); | 854 | pr_unimpl(vcpu, "unimplemented MMIO_CONF_BASE wrmsr: " |
| 855 | "0x%llx\n", data); | ||
| 856 | return 1; | ||
| 857 | } | ||
| 794 | break; | 858 | break; |
| 795 | case MSR_IA32_MCG_CTL: | 859 | case MSR_AMD64_NB_CFG: |
| 796 | pr_unimpl(vcpu, "%s: MSR_IA32_MCG_CTL 0x%llx, nop\n", | ||
| 797 | __func__, data); | ||
| 798 | break; | 860 | break; |
| 799 | case MSR_IA32_DEBUGCTLMSR: | 861 | case MSR_IA32_DEBUGCTLMSR: |
| 800 | if (!data) { | 862 | if (!data) { |
| @@ -811,12 +873,15 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) | |||
| 811 | case MSR_IA32_UCODE_REV: | 873 | case MSR_IA32_UCODE_REV: |
| 812 | case MSR_IA32_UCODE_WRITE: | 874 | case MSR_IA32_UCODE_WRITE: |
| 813 | case MSR_VM_HSAVE_PA: | 875 | case MSR_VM_HSAVE_PA: |
| 876 | case MSR_AMD64_PATCH_LOADER: | ||
| 814 | break; | 877 | break; |
| 815 | case 0x200 ... 0x2ff: | 878 | case 0x200 ... 0x2ff: |
| 816 | return set_msr_mtrr(vcpu, msr, data); | 879 | return set_msr_mtrr(vcpu, msr, data); |
| 817 | case MSR_IA32_APICBASE: | 880 | case MSR_IA32_APICBASE: |
| 818 | kvm_set_apic_base(vcpu, data); | 881 | kvm_set_apic_base(vcpu, data); |
| 819 | break; | 882 | break; |
| 883 | case APIC_BASE_MSR ... APIC_BASE_MSR + 0x3ff: | ||
| 884 | return kvm_x2apic_msr_write(vcpu, msr, data); | ||
| 820 | case MSR_IA32_MISC_ENABLE: | 885 | case MSR_IA32_MISC_ENABLE: |
| 821 | vcpu->arch.ia32_misc_enable_msr = data; | 886 | vcpu->arch.ia32_misc_enable_msr = data; |
| 822 | break; | 887 | break; |
| @@ -850,9 +915,50 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) | |||
| 850 | kvm_request_guest_time_update(vcpu); | 915 | kvm_request_guest_time_update(vcpu); |
| 851 | break; | 916 | break; |
| 852 | } | 917 | } |
| 918 | case MSR_IA32_MCG_CTL: | ||
| 919 | case MSR_IA32_MCG_STATUS: | ||
| 920 | case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1: | ||
| 921 | return set_msr_mce(vcpu, msr, data); | ||
| 922 | |||
| 923 | /* Performance counters are not protected by a CPUID bit, | ||
| 924 | * so we should check all of them in the generic path for the sake of | ||
| 925 | * cross vendor migration. | ||
| 926 | * Writing a zero into the event select MSRs disables them, | ||
| 927 | * which we perfectly emulate ;-). Any other value should be at least | ||
| 928 | * reported, some guests depend on them. | ||
| 929 | */ | ||
| 930 | case MSR_P6_EVNTSEL0: | ||
| 931 | case MSR_P6_EVNTSEL1: | ||
| 932 | case MSR_K7_EVNTSEL0: | ||
| 933 | case MSR_K7_EVNTSEL1: | ||
| 934 | case MSR_K7_EVNTSEL2: | ||
| 935 | case MSR_K7_EVNTSEL3: | ||
| 936 | if (data != 0) | ||
| 937 | pr_unimpl(vcpu, "unimplemented perfctr wrmsr: " | ||
| 938 | "0x%x data 0x%llx\n", msr, data); | ||
| 939 | break; | ||
| 940 | /* at least RHEL 4 unconditionally writes to the perfctr registers, | ||
| 941 | * so we ignore writes to make it happy. | ||
| 942 | */ | ||
| 943 | case MSR_P6_PERFCTR0: | ||
| 944 | case MSR_P6_PERFCTR1: | ||
| 945 | case MSR_K7_PERFCTR0: | ||
| 946 | case MSR_K7_PERFCTR1: | ||
| 947 | case MSR_K7_PERFCTR2: | ||
| 948 | case MSR_K7_PERFCTR3: | ||
| 949 | pr_unimpl(vcpu, "unimplemented perfctr wrmsr: " | ||
| 950 | "0x%x data 0x%llx\n", msr, data); | ||
| 951 | break; | ||
| 853 | default: | 952 | default: |
| 854 | pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", msr, data); | 953 | if (!ignore_msrs) { |
| 855 | return 1; | 954 | pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", |
| 955 | msr, data); | ||
| 956 | return 1; | ||
| 957 | } else { | ||
| 958 | pr_unimpl(vcpu, "ignored wrmsr: 0x%x data %llx\n", | ||
| 959 | msr, data); | ||
| 960 | break; | ||
| 961 | } | ||
| 856 | } | 962 | } |
| 857 | return 0; | 963 | return 0; |
| 858 | } | 964 | } |
| @@ -905,26 +1011,47 @@ static int get_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | |||
| 905 | return 0; | 1011 | return 0; |
| 906 | } | 1012 | } |
| 907 | 1013 | ||
| 908 | int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | 1014 | static int get_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) |
| 909 | { | 1015 | { |
| 910 | u64 data; | 1016 | u64 data; |
| 1017 | u64 mcg_cap = vcpu->arch.mcg_cap; | ||
| 1018 | unsigned bank_num = mcg_cap & 0xff; | ||
| 911 | 1019 | ||
| 912 | switch (msr) { | 1020 | switch (msr) { |
| 913 | case 0xc0010010: /* SYSCFG */ | ||
| 914 | case 0xc0010015: /* HWCR */ | ||
| 915 | case MSR_IA32_PLATFORM_ID: | ||
| 916 | case MSR_IA32_P5_MC_ADDR: | 1021 | case MSR_IA32_P5_MC_ADDR: |
| 917 | case MSR_IA32_P5_MC_TYPE: | 1022 | case MSR_IA32_P5_MC_TYPE: |
| 918 | case MSR_IA32_MC0_CTL: | 1023 | data = 0; |
| 919 | case MSR_IA32_MCG_STATUS: | 1024 | break; |
| 920 | case MSR_IA32_MCG_CAP: | 1025 | case MSR_IA32_MCG_CAP: |
| 1026 | data = vcpu->arch.mcg_cap; | ||
| 1027 | break; | ||
| 921 | case MSR_IA32_MCG_CTL: | 1028 | case MSR_IA32_MCG_CTL: |
| 922 | case MSR_IA32_MC0_MISC: | 1029 | if (!(mcg_cap & MCG_CTL_P)) |
| 923 | case MSR_IA32_MC0_MISC+4: | 1030 | return 1; |
| 924 | case MSR_IA32_MC0_MISC+8: | 1031 | data = vcpu->arch.mcg_ctl; |
| 925 | case MSR_IA32_MC0_MISC+12: | 1032 | break; |
| 926 | case MSR_IA32_MC0_MISC+16: | 1033 | case MSR_IA32_MCG_STATUS: |
| 927 | case MSR_IA32_MC0_MISC+20: | 1034 | data = vcpu->arch.mcg_status; |
| 1035 | break; | ||
| 1036 | default: | ||
| 1037 | if (msr >= MSR_IA32_MC0_CTL && | ||
| 1038 | msr < MSR_IA32_MC0_CTL + 4 * bank_num) { | ||
| 1039 | u32 offset = msr - MSR_IA32_MC0_CTL; | ||
| 1040 | data = vcpu->arch.mce_banks[offset]; | ||
| 1041 | break; | ||
| 1042 | } | ||
| 1043 | return 1; | ||
| 1044 | } | ||
| 1045 | *pdata = data; | ||
| 1046 | return 0; | ||
| 1047 | } | ||
| 1048 | |||
| 1049 | int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | ||
| 1050 | { | ||
| 1051 | u64 data; | ||
| 1052 | |||
| 1053 | switch (msr) { | ||
| 1054 | case MSR_IA32_PLATFORM_ID: | ||
| 928 | case MSR_IA32_UCODE_REV: | 1055 | case MSR_IA32_UCODE_REV: |
| 929 | case MSR_IA32_EBL_CR_POWERON: | 1056 | case MSR_IA32_EBL_CR_POWERON: |
| 930 | case MSR_IA32_DEBUGCTLMSR: | 1057 | case MSR_IA32_DEBUGCTLMSR: |
| @@ -932,10 +1059,18 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | |||
| 932 | case MSR_IA32_LASTBRANCHTOIP: | 1059 | case MSR_IA32_LASTBRANCHTOIP: |
| 933 | case MSR_IA32_LASTINTFROMIP: | 1060 | case MSR_IA32_LASTINTFROMIP: |
| 934 | case MSR_IA32_LASTINTTOIP: | 1061 | case MSR_IA32_LASTINTTOIP: |
| 1062 | case MSR_K8_SYSCFG: | ||
| 1063 | case MSR_K7_HWCR: | ||
| 935 | case MSR_VM_HSAVE_PA: | 1064 | case MSR_VM_HSAVE_PA: |
| 1065 | case MSR_P6_PERFCTR0: | ||
| 1066 | case MSR_P6_PERFCTR1: | ||
| 936 | case MSR_P6_EVNTSEL0: | 1067 | case MSR_P6_EVNTSEL0: |
| 937 | case MSR_P6_EVNTSEL1: | 1068 | case MSR_P6_EVNTSEL1: |
| 938 | case MSR_K7_EVNTSEL0: | 1069 | case MSR_K7_EVNTSEL0: |
| 1070 | case MSR_K7_PERFCTR0: | ||
| 1071 | case MSR_K8_INT_PENDING_MSG: | ||
| 1072 | case MSR_AMD64_NB_CFG: | ||
| 1073 | case MSR_FAM10H_MMIO_CONF_BASE: | ||
| 939 | data = 0; | 1074 | data = 0; |
| 940 | break; | 1075 | break; |
| 941 | case MSR_MTRRcap: | 1076 | case MSR_MTRRcap: |
| @@ -949,6 +1084,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | |||
| 949 | case MSR_IA32_APICBASE: | 1084 | case MSR_IA32_APICBASE: |
| 950 | data = kvm_get_apic_base(vcpu); | 1085 | data = kvm_get_apic_base(vcpu); |
| 951 | break; | 1086 | break; |
| 1087 | case APIC_BASE_MSR ... APIC_BASE_MSR + 0x3ff: | ||
| 1088 | return kvm_x2apic_msr_read(vcpu, msr, pdata); | ||
| 1089 | break; | ||
| 952 | case MSR_IA32_MISC_ENABLE: | 1090 | case MSR_IA32_MISC_ENABLE: |
| 953 | data = vcpu->arch.ia32_misc_enable_msr; | 1091 | data = vcpu->arch.ia32_misc_enable_msr; |
| 954 | break; | 1092 | break; |
| @@ -967,9 +1105,22 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | |||
| 967 | case MSR_KVM_SYSTEM_TIME: | 1105 | case MSR_KVM_SYSTEM_TIME: |
| 968 | data = vcpu->arch.time; | 1106 | data = vcpu->arch.time; |
| 969 | break; | 1107 | break; |
| 1108 | case MSR_IA32_P5_MC_ADDR: | ||
| 1109 | case MSR_IA32_P5_MC_TYPE: | ||
| 1110 | case MSR_IA32_MCG_CAP: | ||
| 1111 | case MSR_IA32_MCG_CTL: | ||
| 1112 | case MSR_IA32_MCG_STATUS: | ||
| 1113 | case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1: | ||
| 1114 | return get_msr_mce(vcpu, msr, pdata); | ||
| 970 | default: | 1115 | default: |
| 971 | pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr); | 1116 | if (!ignore_msrs) { |
| 972 | return 1; | 1117 | pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr); |
| 1118 | return 1; | ||
| 1119 | } else { | ||
| 1120 | pr_unimpl(vcpu, "ignored rdmsr: 0x%x\n", msr); | ||
| 1121 | data = 0; | ||
| 1122 | } | ||
| 1123 | break; | ||
| 973 | } | 1124 | } |
| 974 | *pdata = data; | 1125 | *pdata = data; |
| 975 | return 0; | 1126 | return 0; |
| @@ -1068,6 +1219,11 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
| 1068 | case KVM_CAP_REINJECT_CONTROL: | 1219 | case KVM_CAP_REINJECT_CONTROL: |
| 1069 | case KVM_CAP_IRQ_INJECT_STATUS: | 1220 | case KVM_CAP_IRQ_INJECT_STATUS: |
| 1070 | case KVM_CAP_ASSIGN_DEV_IRQ: | 1221 | case KVM_CAP_ASSIGN_DEV_IRQ: |
| 1222 | case KVM_CAP_IRQFD: | ||
| 1223 | case KVM_CAP_IOEVENTFD: | ||
| 1224 | case KVM_CAP_PIT2: | ||
| 1225 | case KVM_CAP_PIT_STATE2: | ||
| 1226 | case KVM_CAP_SET_IDENTITY_MAP_ADDR: | ||
| 1071 | r = 1; | 1227 | r = 1; |
| 1072 | break; | 1228 | break; |
| 1073 | case KVM_CAP_COALESCED_MMIO: | 1229 | case KVM_CAP_COALESCED_MMIO: |
| @@ -1088,6 +1244,9 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
| 1088 | case KVM_CAP_IOMMU: | 1244 | case KVM_CAP_IOMMU: |
| 1089 | r = iommu_found(); | 1245 | r = iommu_found(); |
| 1090 | break; | 1246 | break; |
| 1247 | case KVM_CAP_MCE: | ||
| 1248 | r = KVM_MAX_MCE_BANKS; | ||
| 1249 | break; | ||
| 1091 | default: | 1250 | default: |
| 1092 | r = 0; | 1251 | r = 0; |
| 1093 | break; | 1252 | break; |
| @@ -1147,6 +1306,16 @@ long kvm_arch_dev_ioctl(struct file *filp, | |||
| 1147 | r = 0; | 1306 | r = 0; |
| 1148 | break; | 1307 | break; |
| 1149 | } | 1308 | } |
| 1309 | case KVM_X86_GET_MCE_CAP_SUPPORTED: { | ||
| 1310 | u64 mce_cap; | ||
| 1311 | |||
| 1312 | mce_cap = KVM_MCE_CAP_SUPPORTED; | ||
| 1313 | r = -EFAULT; | ||
| 1314 | if (copy_to_user(argp, &mce_cap, sizeof mce_cap)) | ||
| 1315 | goto out; | ||
| 1316 | r = 0; | ||
| 1317 | break; | ||
| 1318 | } | ||
| 1150 | default: | 1319 | default: |
| 1151 | r = -EINVAL; | 1320 | r = -EINVAL; |
| 1152 | } | 1321 | } |
| @@ -1227,6 +1396,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, | |||
| 1227 | vcpu->arch.cpuid_nent = cpuid->nent; | 1396 | vcpu->arch.cpuid_nent = cpuid->nent; |
| 1228 | cpuid_fix_nx_cap(vcpu); | 1397 | cpuid_fix_nx_cap(vcpu); |
| 1229 | r = 0; | 1398 | r = 0; |
| 1399 | kvm_apic_set_version(vcpu); | ||
| 1230 | 1400 | ||
| 1231 | out_free: | 1401 | out_free: |
| 1232 | vfree(cpuid_entries); | 1402 | vfree(cpuid_entries); |
| @@ -1248,6 +1418,7 @@ static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu, | |||
| 1248 | cpuid->nent * sizeof(struct kvm_cpuid_entry2))) | 1418 | cpuid->nent * sizeof(struct kvm_cpuid_entry2))) |
| 1249 | goto out; | 1419 | goto out; |
| 1250 | vcpu->arch.cpuid_nent = cpuid->nent; | 1420 | vcpu->arch.cpuid_nent = cpuid->nent; |
| 1421 | kvm_apic_set_version(vcpu); | ||
| 1251 | return 0; | 1422 | return 0; |
| 1252 | 1423 | ||
| 1253 | out: | 1424 | out: |
| @@ -1290,6 +1461,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
| 1290 | u32 index, int *nent, int maxnent) | 1461 | u32 index, int *nent, int maxnent) |
| 1291 | { | 1462 | { |
| 1292 | unsigned f_nx = is_efer_nx() ? F(NX) : 0; | 1463 | unsigned f_nx = is_efer_nx() ? F(NX) : 0; |
| 1464 | unsigned f_gbpages = kvm_x86_ops->gb_page_enable() ? F(GBPAGES) : 0; | ||
| 1293 | #ifdef CONFIG_X86_64 | 1465 | #ifdef CONFIG_X86_64 |
| 1294 | unsigned f_lm = F(LM); | 1466 | unsigned f_lm = F(LM); |
| 1295 | #else | 1467 | #else |
| @@ -1314,7 +1486,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
| 1314 | F(MTRR) | F(PGE) | F(MCA) | F(CMOV) | | 1486 | F(MTRR) | F(PGE) | F(MCA) | F(CMOV) | |
| 1315 | F(PAT) | F(PSE36) | 0 /* Reserved */ | | 1487 | F(PAT) | F(PSE36) | 0 /* Reserved */ | |
| 1316 | f_nx | 0 /* Reserved */ | F(MMXEXT) | F(MMX) | | 1488 | f_nx | 0 /* Reserved */ | F(MMXEXT) | F(MMX) | |
| 1317 | F(FXSR) | F(FXSR_OPT) | 0 /* GBPAGES */ | 0 /* RDTSCP */ | | 1489 | F(FXSR) | F(FXSR_OPT) | f_gbpages | 0 /* RDTSCP */ | |
| 1318 | 0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW); | 1490 | 0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW); |
| 1319 | /* cpuid 1.ecx */ | 1491 | /* cpuid 1.ecx */ |
| 1320 | const u32 kvm_supported_word4_x86_features = | 1492 | const u32 kvm_supported_word4_x86_features = |
| @@ -1323,7 +1495,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
| 1323 | 0 /* TM2 */ | F(SSSE3) | 0 /* CNXT-ID */ | 0 /* Reserved */ | | 1495 | 0 /* TM2 */ | F(SSSE3) | 0 /* CNXT-ID */ | 0 /* Reserved */ | |
| 1324 | 0 /* Reserved */ | F(CX16) | 0 /* xTPR Update, PDCM */ | | 1496 | 0 /* Reserved */ | F(CX16) | 0 /* xTPR Update, PDCM */ | |
| 1325 | 0 /* Reserved, DCA */ | F(XMM4_1) | | 1497 | 0 /* Reserved, DCA */ | F(XMM4_1) | |
| 1326 | F(XMM4_2) | 0 /* x2APIC */ | F(MOVBE) | F(POPCNT) | | 1498 | F(XMM4_2) | F(X2APIC) | F(MOVBE) | F(POPCNT) | |
| 1327 | 0 /* Reserved, XSAVE, OSXSAVE */; | 1499 | 0 /* Reserved, XSAVE, OSXSAVE */; |
| 1328 | /* cpuid 0x80000001.ecx */ | 1500 | /* cpuid 0x80000001.ecx */ |
| 1329 | const u32 kvm_supported_word6_x86_features = | 1501 | const u32 kvm_supported_word6_x86_features = |
| @@ -1344,6 +1516,9 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
| 1344 | case 1: | 1516 | case 1: |
| 1345 | entry->edx &= kvm_supported_word0_x86_features; | 1517 | entry->edx &= kvm_supported_word0_x86_features; |
| 1346 | entry->ecx &= kvm_supported_word4_x86_features; | 1518 | entry->ecx &= kvm_supported_word4_x86_features; |
| 1519 | /* we support x2apic emulation even if host does not support | ||
| 1520 | * it since we emulate x2apic in software */ | ||
| 1521 | entry->ecx |= F(X2APIC); | ||
| 1347 | break; | 1522 | break; |
| 1348 | /* function 2 entries are STATEFUL. That is, repeated cpuid commands | 1523 | /* function 2 entries are STATEFUL. That is, repeated cpuid commands |
| 1349 | * may return different values. This forces us to get_cpu() before | 1524 | * may return different values. This forces us to get_cpu() before |
| @@ -1435,6 +1610,10 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, | |||
| 1435 | for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func) | 1610 | for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func) |
| 1436 | do_cpuid_ent(&cpuid_entries[nent], func, 0, | 1611 | do_cpuid_ent(&cpuid_entries[nent], func, 0, |
| 1437 | &nent, cpuid->nent); | 1612 | &nent, cpuid->nent); |
| 1613 | r = -E2BIG; | ||
| 1614 | if (nent >= cpuid->nent) | ||
| 1615 | goto out_free; | ||
| 1616 | |||
| 1438 | r = -EFAULT; | 1617 | r = -EFAULT; |
| 1439 | if (copy_to_user(entries, cpuid_entries, | 1618 | if (copy_to_user(entries, cpuid_entries, |
| 1440 | nent * sizeof(struct kvm_cpuid_entry2))) | 1619 | nent * sizeof(struct kvm_cpuid_entry2))) |
| @@ -1464,6 +1643,7 @@ static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu, | |||
| 1464 | vcpu_load(vcpu); | 1643 | vcpu_load(vcpu); |
| 1465 | memcpy(vcpu->arch.apic->regs, s->regs, sizeof *s); | 1644 | memcpy(vcpu->arch.apic->regs, s->regs, sizeof *s); |
| 1466 | kvm_apic_post_state_restore(vcpu); | 1645 | kvm_apic_post_state_restore(vcpu); |
| 1646 | update_cr8_intercept(vcpu); | ||
| 1467 | vcpu_put(vcpu); | 1647 | vcpu_put(vcpu); |
| 1468 | 1648 | ||
| 1469 | return 0; | 1649 | return 0; |
| @@ -1503,6 +1683,80 @@ static int vcpu_ioctl_tpr_access_reporting(struct kvm_vcpu *vcpu, | |||
| 1503 | return 0; | 1683 | return 0; |
| 1504 | } | 1684 | } |
| 1505 | 1685 | ||
| 1686 | static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu, | ||
| 1687 | u64 mcg_cap) | ||
| 1688 | { | ||
| 1689 | int r; | ||
| 1690 | unsigned bank_num = mcg_cap & 0xff, bank; | ||
| 1691 | |||
| 1692 | r = -EINVAL; | ||
| 1693 | if (!bank_num) | ||
| 1694 | goto out; | ||
| 1695 | if (mcg_cap & ~(KVM_MCE_CAP_SUPPORTED | 0xff | 0xff0000)) | ||
| 1696 | goto out; | ||
| 1697 | r = 0; | ||
| 1698 | vcpu->arch.mcg_cap = mcg_cap; | ||
| 1699 | /* Init IA32_MCG_CTL to all 1s */ | ||
| 1700 | if (mcg_cap & MCG_CTL_P) | ||
| 1701 | vcpu->arch.mcg_ctl = ~(u64)0; | ||
| 1702 | /* Init IA32_MCi_CTL to all 1s */ | ||
| 1703 | for (bank = 0; bank < bank_num; bank++) | ||
| 1704 | vcpu->arch.mce_banks[bank*4] = ~(u64)0; | ||
| 1705 | out: | ||
| 1706 | return r; | ||
| 1707 | } | ||
| 1708 | |||
| 1709 | static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu *vcpu, | ||
| 1710 | struct kvm_x86_mce *mce) | ||
| 1711 | { | ||
| 1712 | u64 mcg_cap = vcpu->arch.mcg_cap; | ||
| 1713 | unsigned bank_num = mcg_cap & 0xff; | ||
| 1714 | u64 *banks = vcpu->arch.mce_banks; | ||
| 1715 | |||
| 1716 | if (mce->bank >= bank_num || !(mce->status & MCI_STATUS_VAL)) | ||
| 1717 | return -EINVAL; | ||
| 1718 | /* | ||
| 1719 | * if IA32_MCG_CTL is not all 1s, the uncorrected error | ||
| 1720 | * reporting is disabled | ||
| 1721 | */ | ||
| 1722 | if ((mce->status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) && | ||
| 1723 | vcpu->arch.mcg_ctl != ~(u64)0) | ||
| 1724 | return 0; | ||
| 1725 | banks += 4 * mce->bank; | ||
| 1726 | /* | ||
| 1727 | * if IA32_MCi_CTL is not all 1s, the uncorrected error | ||
| 1728 | * reporting is disabled for the bank | ||
| 1729 | */ | ||
| 1730 | if ((mce->status & MCI_STATUS_UC) && banks[0] != ~(u64)0) | ||
| 1731 | return 0; | ||
| 1732 | if (mce->status & MCI_STATUS_UC) { | ||
| 1733 | if ((vcpu->arch.mcg_status & MCG_STATUS_MCIP) || | ||
| 1734 | !(vcpu->arch.cr4 & X86_CR4_MCE)) { | ||
| 1735 | printk(KERN_DEBUG "kvm: set_mce: " | ||
| 1736 | "injects mce exception while " | ||
| 1737 | "previous one is in progress!\n"); | ||
| 1738 | set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests); | ||
| 1739 | return 0; | ||
| 1740 | } | ||
| 1741 | if (banks[1] & MCI_STATUS_VAL) | ||
| 1742 | mce->status |= MCI_STATUS_OVER; | ||
| 1743 | banks[2] = mce->addr; | ||
| 1744 | banks[3] = mce->misc; | ||
| 1745 | vcpu->arch.mcg_status = mce->mcg_status; | ||
| 1746 | banks[1] = mce->status; | ||
| 1747 | kvm_queue_exception(vcpu, MC_VECTOR); | ||
| 1748 | } else if (!(banks[1] & MCI_STATUS_VAL) | ||
| 1749 | || !(banks[1] & MCI_STATUS_UC)) { | ||
| 1750 | if (banks[1] & MCI_STATUS_VAL) | ||
| 1751 | mce->status |= MCI_STATUS_OVER; | ||
| 1752 | banks[2] = mce->addr; | ||
| 1753 | banks[3] = mce->misc; | ||
| 1754 | banks[1] = mce->status; | ||
| 1755 | } else | ||
| 1756 | banks[1] |= MCI_STATUS_OVER; | ||
| 1757 | return 0; | ||
| 1758 | } | ||
| 1759 | |||
| 1506 | long kvm_arch_vcpu_ioctl(struct file *filp, | 1760 | long kvm_arch_vcpu_ioctl(struct file *filp, |
| 1507 | unsigned int ioctl, unsigned long arg) | 1761 | unsigned int ioctl, unsigned long arg) |
| 1508 | { | 1762 | { |
| @@ -1636,6 +1890,24 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
| 1636 | kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr); | 1890 | kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr); |
| 1637 | break; | 1891 | break; |
| 1638 | } | 1892 | } |
| 1893 | case KVM_X86_SETUP_MCE: { | ||
| 1894 | u64 mcg_cap; | ||
| 1895 | |||
| 1896 | r = -EFAULT; | ||
| 1897 | if (copy_from_user(&mcg_cap, argp, sizeof mcg_cap)) | ||
| 1898 | goto out; | ||
| 1899 | r = kvm_vcpu_ioctl_x86_setup_mce(vcpu, mcg_cap); | ||
| 1900 | break; | ||
| 1901 | } | ||
| 1902 | case KVM_X86_SET_MCE: { | ||
| 1903 | struct kvm_x86_mce mce; | ||
| 1904 | |||
| 1905 | r = -EFAULT; | ||
| 1906 | if (copy_from_user(&mce, argp, sizeof mce)) | ||
| 1907 | goto out; | ||
| 1908 | r = kvm_vcpu_ioctl_x86_set_mce(vcpu, &mce); | ||
| 1909 | break; | ||
| 1910 | } | ||
| 1639 | default: | 1911 | default: |
| 1640 | r = -EINVAL; | 1912 | r = -EINVAL; |
| 1641 | } | 1913 | } |
| @@ -1654,6 +1926,13 @@ static int kvm_vm_ioctl_set_tss_addr(struct kvm *kvm, unsigned long addr) | |||
| 1654 | return ret; | 1926 | return ret; |
| 1655 | } | 1927 | } |
| 1656 | 1928 | ||
| 1929 | static int kvm_vm_ioctl_set_identity_map_addr(struct kvm *kvm, | ||
| 1930 | u64 ident_addr) | ||
| 1931 | { | ||
| 1932 | kvm->arch.ept_identity_map_addr = ident_addr; | ||
| 1933 | return 0; | ||
| 1934 | } | ||
| 1935 | |||
| 1657 | static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm, | 1936 | static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm, |
| 1658 | u32 kvm_nr_mmu_pages) | 1937 | u32 kvm_nr_mmu_pages) |
| 1659 | { | 1938 | { |
| @@ -1775,19 +2054,25 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip) | |||
| 1775 | r = 0; | 2054 | r = 0; |
| 1776 | switch (chip->chip_id) { | 2055 | switch (chip->chip_id) { |
| 1777 | case KVM_IRQCHIP_PIC_MASTER: | 2056 | case KVM_IRQCHIP_PIC_MASTER: |
| 2057 | spin_lock(&pic_irqchip(kvm)->lock); | ||
| 1778 | memcpy(&pic_irqchip(kvm)->pics[0], | 2058 | memcpy(&pic_irqchip(kvm)->pics[0], |
| 1779 | &chip->chip.pic, | 2059 | &chip->chip.pic, |
| 1780 | sizeof(struct kvm_pic_state)); | 2060 | sizeof(struct kvm_pic_state)); |
| 2061 | spin_unlock(&pic_irqchip(kvm)->lock); | ||
| 1781 | break; | 2062 | break; |
| 1782 | case KVM_IRQCHIP_PIC_SLAVE: | 2063 | case KVM_IRQCHIP_PIC_SLAVE: |
| 2064 | spin_lock(&pic_irqchip(kvm)->lock); | ||
| 1783 | memcpy(&pic_irqchip(kvm)->pics[1], | 2065 | memcpy(&pic_irqchip(kvm)->pics[1], |
| 1784 | &chip->chip.pic, | 2066 | &chip->chip.pic, |
| 1785 | sizeof(struct kvm_pic_state)); | 2067 | sizeof(struct kvm_pic_state)); |
| 2068 | spin_unlock(&pic_irqchip(kvm)->lock); | ||
| 1786 | break; | 2069 | break; |
| 1787 | case KVM_IRQCHIP_IOAPIC: | 2070 | case KVM_IRQCHIP_IOAPIC: |
| 2071 | mutex_lock(&kvm->irq_lock); | ||
| 1788 | memcpy(ioapic_irqchip(kvm), | 2072 | memcpy(ioapic_irqchip(kvm), |
| 1789 | &chip->chip.ioapic, | 2073 | &chip->chip.ioapic, |
| 1790 | sizeof(struct kvm_ioapic_state)); | 2074 | sizeof(struct kvm_ioapic_state)); |
| 2075 | mutex_unlock(&kvm->irq_lock); | ||
| 1791 | break; | 2076 | break; |
| 1792 | default: | 2077 | default: |
| 1793 | r = -EINVAL; | 2078 | r = -EINVAL; |
| @@ -1801,7 +2086,9 @@ static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps) | |||
| 1801 | { | 2086 | { |
| 1802 | int r = 0; | 2087 | int r = 0; |
| 1803 | 2088 | ||
| 2089 | mutex_lock(&kvm->arch.vpit->pit_state.lock); | ||
| 1804 | memcpy(ps, &kvm->arch.vpit->pit_state, sizeof(struct kvm_pit_state)); | 2090 | memcpy(ps, &kvm->arch.vpit->pit_state, sizeof(struct kvm_pit_state)); |
| 2091 | mutex_unlock(&kvm->arch.vpit->pit_state.lock); | ||
| 1805 | return r; | 2092 | return r; |
| 1806 | } | 2093 | } |
| 1807 | 2094 | ||
| @@ -1809,8 +2096,39 @@ static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps) | |||
| 1809 | { | 2096 | { |
| 1810 | int r = 0; | 2097 | int r = 0; |
| 1811 | 2098 | ||
| 2099 | mutex_lock(&kvm->arch.vpit->pit_state.lock); | ||
| 1812 | memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state)); | 2100 | memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state)); |
| 1813 | kvm_pit_load_count(kvm, 0, ps->channels[0].count); | 2101 | kvm_pit_load_count(kvm, 0, ps->channels[0].count, 0); |
| 2102 | mutex_unlock(&kvm->arch.vpit->pit_state.lock); | ||
| 2103 | return r; | ||
| 2104 | } | ||
| 2105 | |||
| 2106 | static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) | ||
| 2107 | { | ||
| 2108 | int r = 0; | ||
| 2109 | |||
| 2110 | mutex_lock(&kvm->arch.vpit->pit_state.lock); | ||
| 2111 | memcpy(ps->channels, &kvm->arch.vpit->pit_state.channels, | ||
| 2112 | sizeof(ps->channels)); | ||
| 2113 | ps->flags = kvm->arch.vpit->pit_state.flags; | ||
| 2114 | mutex_unlock(&kvm->arch.vpit->pit_state.lock); | ||
| 2115 | return r; | ||
| 2116 | } | ||
| 2117 | |||
| 2118 | static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) | ||
| 2119 | { | ||
| 2120 | int r = 0, start = 0; | ||
| 2121 | u32 prev_legacy, cur_legacy; | ||
| 2122 | mutex_lock(&kvm->arch.vpit->pit_state.lock); | ||
| 2123 | prev_legacy = kvm->arch.vpit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY; | ||
| 2124 | cur_legacy = ps->flags & KVM_PIT_FLAGS_HPET_LEGACY; | ||
| 2125 | if (!prev_legacy && cur_legacy) | ||
| 2126 | start = 1; | ||
| 2127 | memcpy(&kvm->arch.vpit->pit_state.channels, &ps->channels, | ||
| 2128 | sizeof(kvm->arch.vpit->pit_state.channels)); | ||
| 2129 | kvm->arch.vpit->pit_state.flags = ps->flags; | ||
| 2130 | kvm_pit_load_count(kvm, 0, kvm->arch.vpit->pit_state.channels[0].count, start); | ||
| 2131 | mutex_unlock(&kvm->arch.vpit->pit_state.lock); | ||
| 1814 | return r; | 2132 | return r; |
| 1815 | } | 2133 | } |
| 1816 | 2134 | ||
| @@ -1819,7 +2137,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm, | |||
| 1819 | { | 2137 | { |
| 1820 | if (!kvm->arch.vpit) | 2138 | if (!kvm->arch.vpit) |
| 1821 | return -ENXIO; | 2139 | return -ENXIO; |
| 2140 | mutex_lock(&kvm->arch.vpit->pit_state.lock); | ||
| 1822 | kvm->arch.vpit->pit_state.pit_timer.reinject = control->pit_reinject; | 2141 | kvm->arch.vpit->pit_state.pit_timer.reinject = control->pit_reinject; |
| 2142 | mutex_unlock(&kvm->arch.vpit->pit_state.lock); | ||
| 1823 | return 0; | 2143 | return 0; |
| 1824 | } | 2144 | } |
| 1825 | 2145 | ||
| @@ -1845,7 +2165,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, | |||
| 1845 | spin_lock(&kvm->mmu_lock); | 2165 | spin_lock(&kvm->mmu_lock); |
| 1846 | kvm_mmu_slot_remove_write_access(kvm, log->slot); | 2166 | kvm_mmu_slot_remove_write_access(kvm, log->slot); |
| 1847 | spin_unlock(&kvm->mmu_lock); | 2167 | spin_unlock(&kvm->mmu_lock); |
| 1848 | kvm_flush_remote_tlbs(kvm); | ||
| 1849 | memslot = &kvm->memslots[log->slot]; | 2168 | memslot = &kvm->memslots[log->slot]; |
| 1850 | n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; | 2169 | n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; |
| 1851 | memset(memslot->dirty_bitmap, 0, n); | 2170 | memset(memslot->dirty_bitmap, 0, n); |
| @@ -1869,7 +2188,9 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
| 1869 | */ | 2188 | */ |
| 1870 | union { | 2189 | union { |
| 1871 | struct kvm_pit_state ps; | 2190 | struct kvm_pit_state ps; |
| 2191 | struct kvm_pit_state2 ps2; | ||
| 1872 | struct kvm_memory_alias alias; | 2192 | struct kvm_memory_alias alias; |
| 2193 | struct kvm_pit_config pit_config; | ||
| 1873 | } u; | 2194 | } u; |
| 1874 | 2195 | ||
| 1875 | switch (ioctl) { | 2196 | switch (ioctl) { |
| @@ -1878,6 +2199,17 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
| 1878 | if (r < 0) | 2199 | if (r < 0) |
| 1879 | goto out; | 2200 | goto out; |
| 1880 | break; | 2201 | break; |
| 2202 | case KVM_SET_IDENTITY_MAP_ADDR: { | ||
| 2203 | u64 ident_addr; | ||
| 2204 | |||
| 2205 | r = -EFAULT; | ||
| 2206 | if (copy_from_user(&ident_addr, argp, sizeof ident_addr)) | ||
| 2207 | goto out; | ||
| 2208 | r = kvm_vm_ioctl_set_identity_map_addr(kvm, ident_addr); | ||
| 2209 | if (r < 0) | ||
| 2210 | goto out; | ||
| 2211 | break; | ||
| 2212 | } | ||
| 1881 | case KVM_SET_MEMORY_REGION: { | 2213 | case KVM_SET_MEMORY_REGION: { |
| 1882 | struct kvm_memory_region kvm_mem; | 2214 | struct kvm_memory_region kvm_mem; |
| 1883 | struct kvm_userspace_memory_region kvm_userspace_mem; | 2215 | struct kvm_userspace_memory_region kvm_userspace_mem; |
| @@ -1930,16 +2262,24 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
| 1930 | } | 2262 | } |
| 1931 | break; | 2263 | break; |
| 1932 | case KVM_CREATE_PIT: | 2264 | case KVM_CREATE_PIT: |
| 1933 | mutex_lock(&kvm->lock); | 2265 | u.pit_config.flags = KVM_PIT_SPEAKER_DUMMY; |
| 2266 | goto create_pit; | ||
| 2267 | case KVM_CREATE_PIT2: | ||
| 2268 | r = -EFAULT; | ||
| 2269 | if (copy_from_user(&u.pit_config, argp, | ||
| 2270 | sizeof(struct kvm_pit_config))) | ||
| 2271 | goto out; | ||
| 2272 | create_pit: | ||
| 2273 | down_write(&kvm->slots_lock); | ||
| 1934 | r = -EEXIST; | 2274 | r = -EEXIST; |
| 1935 | if (kvm->arch.vpit) | 2275 | if (kvm->arch.vpit) |
| 1936 | goto create_pit_unlock; | 2276 | goto create_pit_unlock; |
| 1937 | r = -ENOMEM; | 2277 | r = -ENOMEM; |
| 1938 | kvm->arch.vpit = kvm_create_pit(kvm); | 2278 | kvm->arch.vpit = kvm_create_pit(kvm, u.pit_config.flags); |
| 1939 | if (kvm->arch.vpit) | 2279 | if (kvm->arch.vpit) |
| 1940 | r = 0; | 2280 | r = 0; |
| 1941 | create_pit_unlock: | 2281 | create_pit_unlock: |
| 1942 | mutex_unlock(&kvm->lock); | 2282 | up_write(&kvm->slots_lock); |
| 1943 | break; | 2283 | break; |
| 1944 | case KVM_IRQ_LINE_STATUS: | 2284 | case KVM_IRQ_LINE_STATUS: |
| 1945 | case KVM_IRQ_LINE: { | 2285 | case KVM_IRQ_LINE: { |
| @@ -1950,10 +2290,10 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
| 1950 | goto out; | 2290 | goto out; |
| 1951 | if (irqchip_in_kernel(kvm)) { | 2291 | if (irqchip_in_kernel(kvm)) { |
| 1952 | __s32 status; | 2292 | __s32 status; |
| 1953 | mutex_lock(&kvm->lock); | 2293 | mutex_lock(&kvm->irq_lock); |
| 1954 | status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, | 2294 | status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, |
| 1955 | irq_event.irq, irq_event.level); | 2295 | irq_event.irq, irq_event.level); |
| 1956 | mutex_unlock(&kvm->lock); | 2296 | mutex_unlock(&kvm->irq_lock); |
| 1957 | if (ioctl == KVM_IRQ_LINE_STATUS) { | 2297 | if (ioctl == KVM_IRQ_LINE_STATUS) { |
| 1958 | irq_event.status = status; | 2298 | irq_event.status = status; |
| 1959 | if (copy_to_user(argp, &irq_event, | 2299 | if (copy_to_user(argp, &irq_event, |
| @@ -2042,6 +2382,32 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
| 2042 | r = 0; | 2382 | r = 0; |
| 2043 | break; | 2383 | break; |
| 2044 | } | 2384 | } |
| 2385 | case KVM_GET_PIT2: { | ||
| 2386 | r = -ENXIO; | ||
| 2387 | if (!kvm->arch.vpit) | ||
| 2388 | goto out; | ||
| 2389 | r = kvm_vm_ioctl_get_pit2(kvm, &u.ps2); | ||
| 2390 | if (r) | ||
| 2391 | goto out; | ||
| 2392 | r = -EFAULT; | ||
| 2393 | if (copy_to_user(argp, &u.ps2, sizeof(u.ps2))) | ||
| 2394 | goto out; | ||
| 2395 | r = 0; | ||
| 2396 | break; | ||
| 2397 | } | ||
| 2398 | case KVM_SET_PIT2: { | ||
| 2399 | r = -EFAULT; | ||
| 2400 | if (copy_from_user(&u.ps2, argp, sizeof(u.ps2))) | ||
| 2401 | goto out; | ||
| 2402 | r = -ENXIO; | ||
| 2403 | if (!kvm->arch.vpit) | ||
| 2404 | goto out; | ||
| 2405 | r = kvm_vm_ioctl_set_pit2(kvm, &u.ps2); | ||
| 2406 | if (r) | ||
| 2407 | goto out; | ||
| 2408 | r = 0; | ||
| 2409 | break; | ||
| 2410 | } | ||
| 2045 | case KVM_REINJECT_CONTROL: { | 2411 | case KVM_REINJECT_CONTROL: { |
| 2046 | struct kvm_reinject_control control; | 2412 | struct kvm_reinject_control control; |
| 2047 | r = -EFAULT; | 2413 | r = -EFAULT; |
| @@ -2075,35 +2441,23 @@ static void kvm_init_msr_list(void) | |||
| 2075 | num_msrs_to_save = j; | 2441 | num_msrs_to_save = j; |
| 2076 | } | 2442 | } |
| 2077 | 2443 | ||
| 2078 | /* | 2444 | static int vcpu_mmio_write(struct kvm_vcpu *vcpu, gpa_t addr, int len, |
| 2079 | * Only apic need an MMIO device hook, so shortcut now.. | 2445 | const void *v) |
| 2080 | */ | ||
| 2081 | static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu, | ||
| 2082 | gpa_t addr, int len, | ||
| 2083 | int is_write) | ||
| 2084 | { | 2446 | { |
| 2085 | struct kvm_io_device *dev; | 2447 | if (vcpu->arch.apic && |
| 2448 | !kvm_iodevice_write(&vcpu->arch.apic->dev, addr, len, v)) | ||
| 2449 | return 0; | ||
| 2086 | 2450 | ||
| 2087 | if (vcpu->arch.apic) { | 2451 | return kvm_io_bus_write(&vcpu->kvm->mmio_bus, addr, len, v); |
| 2088 | dev = &vcpu->arch.apic->dev; | ||
| 2089 | if (dev->in_range(dev, addr, len, is_write)) | ||
| 2090 | return dev; | ||
| 2091 | } | ||
| 2092 | return NULL; | ||
| 2093 | } | 2452 | } |
| 2094 | 2453 | ||
| 2095 | 2454 | static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v) | |
| 2096 | static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu, | ||
| 2097 | gpa_t addr, int len, | ||
| 2098 | int is_write) | ||
| 2099 | { | 2455 | { |
| 2100 | struct kvm_io_device *dev; | 2456 | if (vcpu->arch.apic && |
| 2457 | !kvm_iodevice_read(&vcpu->arch.apic->dev, addr, len, v)) | ||
| 2458 | return 0; | ||
| 2101 | 2459 | ||
| 2102 | dev = vcpu_find_pervcpu_dev(vcpu, addr, len, is_write); | 2460 | return kvm_io_bus_read(&vcpu->kvm->mmio_bus, addr, len, v); |
| 2103 | if (dev == NULL) | ||
| 2104 | dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len, | ||
| 2105 | is_write); | ||
| 2106 | return dev; | ||
| 2107 | } | 2461 | } |
| 2108 | 2462 | ||
| 2109 | static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes, | 2463 | static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes, |
| @@ -2172,11 +2526,12 @@ static int emulator_read_emulated(unsigned long addr, | |||
| 2172 | unsigned int bytes, | 2526 | unsigned int bytes, |
| 2173 | struct kvm_vcpu *vcpu) | 2527 | struct kvm_vcpu *vcpu) |
| 2174 | { | 2528 | { |
| 2175 | struct kvm_io_device *mmio_dev; | ||
| 2176 | gpa_t gpa; | 2529 | gpa_t gpa; |
| 2177 | 2530 | ||
| 2178 | if (vcpu->mmio_read_completed) { | 2531 | if (vcpu->mmio_read_completed) { |
| 2179 | memcpy(val, vcpu->mmio_data, bytes); | 2532 | memcpy(val, vcpu->mmio_data, bytes); |
| 2533 | trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes, | ||
| 2534 | vcpu->mmio_phys_addr, *(u64 *)val); | ||
| 2180 | vcpu->mmio_read_completed = 0; | 2535 | vcpu->mmio_read_completed = 0; |
| 2181 | return X86EMUL_CONTINUE; | 2536 | return X86EMUL_CONTINUE; |
| 2182 | } | 2537 | } |
| @@ -2197,14 +2552,12 @@ mmio: | |||
| 2197 | /* | 2552 | /* |
| 2198 | * Is this MMIO handled locally? | 2553 | * Is this MMIO handled locally? |
| 2199 | */ | 2554 | */ |
| 2200 | mutex_lock(&vcpu->kvm->lock); | 2555 | if (!vcpu_mmio_read(vcpu, gpa, bytes, val)) { |
| 2201 | mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 0); | 2556 | trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes, gpa, *(u64 *)val); |
| 2202 | if (mmio_dev) { | ||
| 2203 | kvm_iodevice_read(mmio_dev, gpa, bytes, val); | ||
| 2204 | mutex_unlock(&vcpu->kvm->lock); | ||
| 2205 | return X86EMUL_CONTINUE; | 2557 | return X86EMUL_CONTINUE; |
| 2206 | } | 2558 | } |
| 2207 | mutex_unlock(&vcpu->kvm->lock); | 2559 | |
| 2560 | trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, 0); | ||
| 2208 | 2561 | ||
| 2209 | vcpu->mmio_needed = 1; | 2562 | vcpu->mmio_needed = 1; |
| 2210 | vcpu->mmio_phys_addr = gpa; | 2563 | vcpu->mmio_phys_addr = gpa; |
| @@ -2231,7 +2584,6 @@ static int emulator_write_emulated_onepage(unsigned long addr, | |||
| 2231 | unsigned int bytes, | 2584 | unsigned int bytes, |
| 2232 | struct kvm_vcpu *vcpu) | 2585 | struct kvm_vcpu *vcpu) |
| 2233 | { | 2586 | { |
| 2234 | struct kvm_io_device *mmio_dev; | ||
| 2235 | gpa_t gpa; | 2587 | gpa_t gpa; |
| 2236 | 2588 | ||
| 2237 | gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); | 2589 | gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); |
| @@ -2249,17 +2601,12 @@ static int emulator_write_emulated_onepage(unsigned long addr, | |||
| 2249 | return X86EMUL_CONTINUE; | 2601 | return X86EMUL_CONTINUE; |
| 2250 | 2602 | ||
| 2251 | mmio: | 2603 | mmio: |
| 2604 | trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, *(u64 *)val); | ||
| 2252 | /* | 2605 | /* |
| 2253 | * Is this MMIO handled locally? | 2606 | * Is this MMIO handled locally? |
| 2254 | */ | 2607 | */ |
| 2255 | mutex_lock(&vcpu->kvm->lock); | 2608 | if (!vcpu_mmio_write(vcpu, gpa, bytes, val)) |
| 2256 | mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 1); | ||
| 2257 | if (mmio_dev) { | ||
| 2258 | kvm_iodevice_write(mmio_dev, gpa, bytes, val); | ||
| 2259 | mutex_unlock(&vcpu->kvm->lock); | ||
| 2260 | return X86EMUL_CONTINUE; | 2609 | return X86EMUL_CONTINUE; |
| 2261 | } | ||
| 2262 | mutex_unlock(&vcpu->kvm->lock); | ||
| 2263 | 2610 | ||
| 2264 | vcpu->mmio_needed = 1; | 2611 | vcpu->mmio_needed = 1; |
| 2265 | vcpu->mmio_phys_addr = gpa; | 2612 | vcpu->mmio_phys_addr = gpa; |
| @@ -2297,12 +2644,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr, | |||
| 2297 | unsigned int bytes, | 2644 | unsigned int bytes, |
| 2298 | struct kvm_vcpu *vcpu) | 2645 | struct kvm_vcpu *vcpu) |
| 2299 | { | 2646 | { |
| 2300 | static int reported; | 2647 | printk_once(KERN_WARNING "kvm: emulating exchange as write\n"); |
| 2301 | |||
| 2302 | if (!reported) { | ||
| 2303 | reported = 1; | ||
| 2304 | printk(KERN_WARNING "kvm: emulating exchange as write\n"); | ||
| 2305 | } | ||
| 2306 | #ifndef CONFIG_X86_64 | 2648 | #ifndef CONFIG_X86_64 |
| 2307 | /* guests cmpxchg8b have to be emulated atomically */ | 2649 | /* guests cmpxchg8b have to be emulated atomically */ |
| 2308 | if (bytes == 8) { | 2650 | if (bytes == 8) { |
| @@ -2348,7 +2690,6 @@ int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address) | |||
| 2348 | 2690 | ||
| 2349 | int emulate_clts(struct kvm_vcpu *vcpu) | 2691 | int emulate_clts(struct kvm_vcpu *vcpu) |
| 2350 | { | 2692 | { |
| 2351 | KVMTRACE_0D(CLTS, vcpu, handler); | ||
| 2352 | kvm_x86_ops->set_cr0(vcpu, vcpu->arch.cr0 & ~X86_CR0_TS); | 2693 | kvm_x86_ops->set_cr0(vcpu, vcpu->arch.cr0 & ~X86_CR0_TS); |
| 2353 | return X86EMUL_CONTINUE; | 2694 | return X86EMUL_CONTINUE; |
| 2354 | } | 2695 | } |
| @@ -2425,7 +2766,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
| 2425 | kvm_clear_exception_queue(vcpu); | 2766 | kvm_clear_exception_queue(vcpu); |
| 2426 | vcpu->arch.mmio_fault_cr2 = cr2; | 2767 | vcpu->arch.mmio_fault_cr2 = cr2; |
| 2427 | /* | 2768 | /* |
| 2428 | * TODO: fix x86_emulate.c to use guest_read/write_register | 2769 | * TODO: fix emulate.c to use guest_read/write_register |
| 2429 | * instead of direct ->regs accesses, can save hundred cycles | 2770 | * instead of direct ->regs accesses, can save hundred cycles |
| 2430 | * on Intel for instructions that don't read/change RSP, for | 2771 | * on Intel for instructions that don't read/change RSP, for |
| 2431 | * for example. | 2772 | * for example. |
| @@ -2449,14 +2790,33 @@ int emulate_instruction(struct kvm_vcpu *vcpu, | |||
| 2449 | 2790 | ||
| 2450 | r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); | 2791 | r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops); |
| 2451 | 2792 | ||
| 2452 | /* Reject the instructions other than VMCALL/VMMCALL when | 2793 | /* Only allow emulation of specific instructions on #UD |
| 2453 | * try to emulate invalid opcode */ | 2794 | * (namely VMMCALL, sysenter, sysexit, syscall)*/ |
| 2454 | c = &vcpu->arch.emulate_ctxt.decode; | 2795 | c = &vcpu->arch.emulate_ctxt.decode; |
| 2455 | if ((emulation_type & EMULTYPE_TRAP_UD) && | 2796 | if (emulation_type & EMULTYPE_TRAP_UD) { |
| 2456 | (!(c->twobyte && c->b == 0x01 && | 2797 | if (!c->twobyte) |
| 2457 | (c->modrm_reg == 0 || c->modrm_reg == 3) && | 2798 | return EMULATE_FAIL; |
| 2458 | c->modrm_mod == 3 && c->modrm_rm == 1))) | 2799 | switch (c->b) { |
| 2459 | return EMULATE_FAIL; | 2800 | case 0x01: /* VMMCALL */ |
| 2801 | if (c->modrm_mod != 3 || c->modrm_rm != 1) | ||
| 2802 | return EMULATE_FAIL; | ||
| 2803 | break; | ||
| 2804 | case 0x34: /* sysenter */ | ||
| 2805 | case 0x35: /* sysexit */ | ||
| 2806 | if (c->modrm_mod != 0 || c->modrm_rm != 0) | ||
| 2807 | return EMULATE_FAIL; | ||
| 2808 | break; | ||
| 2809 | case 0x05: /* syscall */ | ||
| 2810 | if (c->modrm_mod != 0 || c->modrm_rm != 0) | ||
| 2811 | return EMULATE_FAIL; | ||
| 2812 | break; | ||
| 2813 | default: | ||
| 2814 | return EMULATE_FAIL; | ||
| 2815 | } | ||
| 2816 | |||
| 2817 | if (!(c->modrm_reg == 0 || c->modrm_reg == 3)) | ||
| 2818 | return EMULATE_FAIL; | ||
| 2819 | } | ||
| 2460 | 2820 | ||
| 2461 | ++vcpu->stat.insn_emulation; | 2821 | ++vcpu->stat.insn_emulation; |
| 2462 | if (r) { | 2822 | if (r) { |
| @@ -2576,52 +2936,40 @@ int complete_pio(struct kvm_vcpu *vcpu) | |||
| 2576 | return 0; | 2936 | return 0; |
| 2577 | } | 2937 | } |
| 2578 | 2938 | ||
| 2579 | static void kernel_pio(struct kvm_io_device *pio_dev, | 2939 | static int kernel_pio(struct kvm_vcpu *vcpu, void *pd) |
| 2580 | struct kvm_vcpu *vcpu, | ||
| 2581 | void *pd) | ||
| 2582 | { | 2940 | { |
| 2583 | /* TODO: String I/O for in kernel device */ | 2941 | /* TODO: String I/O for in kernel device */ |
| 2942 | int r; | ||
| 2584 | 2943 | ||
| 2585 | mutex_lock(&vcpu->kvm->lock); | ||
| 2586 | if (vcpu->arch.pio.in) | 2944 | if (vcpu->arch.pio.in) |
| 2587 | kvm_iodevice_read(pio_dev, vcpu->arch.pio.port, | 2945 | r = kvm_io_bus_read(&vcpu->kvm->pio_bus, vcpu->arch.pio.port, |
| 2588 | vcpu->arch.pio.size, | 2946 | vcpu->arch.pio.size, pd); |
| 2589 | pd); | ||
| 2590 | else | 2947 | else |
| 2591 | kvm_iodevice_write(pio_dev, vcpu->arch.pio.port, | 2948 | r = kvm_io_bus_write(&vcpu->kvm->pio_bus, vcpu->arch.pio.port, |
| 2592 | vcpu->arch.pio.size, | 2949 | vcpu->arch.pio.size, pd); |
| 2593 | pd); | 2950 | return r; |
| 2594 | mutex_unlock(&vcpu->kvm->lock); | ||
| 2595 | } | 2951 | } |
| 2596 | 2952 | ||
| 2597 | static void pio_string_write(struct kvm_io_device *pio_dev, | 2953 | static int pio_string_write(struct kvm_vcpu *vcpu) |
| 2598 | struct kvm_vcpu *vcpu) | ||
| 2599 | { | 2954 | { |
| 2600 | struct kvm_pio_request *io = &vcpu->arch.pio; | 2955 | struct kvm_pio_request *io = &vcpu->arch.pio; |
| 2601 | void *pd = vcpu->arch.pio_data; | 2956 | void *pd = vcpu->arch.pio_data; |
| 2602 | int i; | 2957 | int i, r = 0; |
| 2603 | 2958 | ||
| 2604 | mutex_lock(&vcpu->kvm->lock); | ||
| 2605 | for (i = 0; i < io->cur_count; i++) { | 2959 | for (i = 0; i < io->cur_count; i++) { |
| 2606 | kvm_iodevice_write(pio_dev, io->port, | 2960 | if (kvm_io_bus_write(&vcpu->kvm->pio_bus, |
| 2607 | io->size, | 2961 | io->port, io->size, pd)) { |
| 2608 | pd); | 2962 | r = -EOPNOTSUPP; |
| 2963 | break; | ||
| 2964 | } | ||
| 2609 | pd += io->size; | 2965 | pd += io->size; |
| 2610 | } | 2966 | } |
| 2611 | mutex_unlock(&vcpu->kvm->lock); | 2967 | return r; |
| 2612 | } | ||
| 2613 | |||
| 2614 | static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu, | ||
| 2615 | gpa_t addr, int len, | ||
| 2616 | int is_write) | ||
| 2617 | { | ||
| 2618 | return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr, len, is_write); | ||
| 2619 | } | 2968 | } |
| 2620 | 2969 | ||
| 2621 | int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, | 2970 | int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, |
| 2622 | int size, unsigned port) | 2971 | int size, unsigned port) |
| 2623 | { | 2972 | { |
| 2624 | struct kvm_io_device *pio_dev; | ||
| 2625 | unsigned long val; | 2973 | unsigned long val; |
| 2626 | 2974 | ||
| 2627 | vcpu->run->exit_reason = KVM_EXIT_IO; | 2975 | vcpu->run->exit_reason = KVM_EXIT_IO; |
| @@ -2635,19 +2983,13 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, | |||
| 2635 | vcpu->arch.pio.down = 0; | 2983 | vcpu->arch.pio.down = 0; |
| 2636 | vcpu->arch.pio.rep = 0; | 2984 | vcpu->arch.pio.rep = 0; |
| 2637 | 2985 | ||
| 2638 | if (vcpu->run->io.direction == KVM_EXIT_IO_IN) | 2986 | trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port, |
| 2639 | KVMTRACE_2D(IO_READ, vcpu, vcpu->run->io.port, (u32)size, | 2987 | size, 1); |
| 2640 | handler); | ||
| 2641 | else | ||
| 2642 | KVMTRACE_2D(IO_WRITE, vcpu, vcpu->run->io.port, (u32)size, | ||
| 2643 | handler); | ||
| 2644 | 2988 | ||
| 2645 | val = kvm_register_read(vcpu, VCPU_REGS_RAX); | 2989 | val = kvm_register_read(vcpu, VCPU_REGS_RAX); |
| 2646 | memcpy(vcpu->arch.pio_data, &val, 4); | 2990 | memcpy(vcpu->arch.pio_data, &val, 4); |
| 2647 | 2991 | ||
| 2648 | pio_dev = vcpu_find_pio_dev(vcpu, port, size, !in); | 2992 | if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { |
| 2649 | if (pio_dev) { | ||
| 2650 | kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data); | ||
| 2651 | complete_pio(vcpu); | 2993 | complete_pio(vcpu); |
| 2652 | return 1; | 2994 | return 1; |
| 2653 | } | 2995 | } |
| @@ -2661,7 +3003,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, | |||
| 2661 | { | 3003 | { |
| 2662 | unsigned now, in_page; | 3004 | unsigned now, in_page; |
| 2663 | int ret = 0; | 3005 | int ret = 0; |
| 2664 | struct kvm_io_device *pio_dev; | ||
| 2665 | 3006 | ||
| 2666 | vcpu->run->exit_reason = KVM_EXIT_IO; | 3007 | vcpu->run->exit_reason = KVM_EXIT_IO; |
| 2667 | vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; | 3008 | vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; |
| @@ -2674,12 +3015,8 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, | |||
| 2674 | vcpu->arch.pio.down = down; | 3015 | vcpu->arch.pio.down = down; |
| 2675 | vcpu->arch.pio.rep = rep; | 3016 | vcpu->arch.pio.rep = rep; |
| 2676 | 3017 | ||
| 2677 | if (vcpu->run->io.direction == KVM_EXIT_IO_IN) | 3018 | trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port, |
| 2678 | KVMTRACE_2D(IO_READ, vcpu, vcpu->run->io.port, (u32)size, | 3019 | size, count); |
| 2679 | handler); | ||
| 2680 | else | ||
| 2681 | KVMTRACE_2D(IO_WRITE, vcpu, vcpu->run->io.port, (u32)size, | ||
| 2682 | handler); | ||
| 2683 | 3020 | ||
| 2684 | if (!count) { | 3021 | if (!count) { |
| 2685 | kvm_x86_ops->skip_emulated_instruction(vcpu); | 3022 | kvm_x86_ops->skip_emulated_instruction(vcpu); |
| @@ -2709,9 +3046,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, | |||
| 2709 | 3046 | ||
| 2710 | vcpu->arch.pio.guest_gva = address; | 3047 | vcpu->arch.pio.guest_gva = address; |
| 2711 | 3048 | ||
| 2712 | pio_dev = vcpu_find_pio_dev(vcpu, port, | ||
| 2713 | vcpu->arch.pio.cur_count, | ||
| 2714 | !vcpu->arch.pio.in); | ||
| 2715 | if (!vcpu->arch.pio.in) { | 3049 | if (!vcpu->arch.pio.in) { |
| 2716 | /* string PIO write */ | 3050 | /* string PIO write */ |
| 2717 | ret = pio_copy_data(vcpu); | 3051 | ret = pio_copy_data(vcpu); |
| @@ -2719,16 +3053,13 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, | |||
| 2719 | kvm_inject_gp(vcpu, 0); | 3053 | kvm_inject_gp(vcpu, 0); |
| 2720 | return 1; | 3054 | return 1; |
| 2721 | } | 3055 | } |
| 2722 | if (ret == 0 && pio_dev) { | 3056 | if (ret == 0 && !pio_string_write(vcpu)) { |
| 2723 | pio_string_write(pio_dev, vcpu); | ||
| 2724 | complete_pio(vcpu); | 3057 | complete_pio(vcpu); |
| 2725 | if (vcpu->arch.pio.count == 0) | 3058 | if (vcpu->arch.pio.count == 0) |
| 2726 | ret = 1; | 3059 | ret = 1; |
| 2727 | } | 3060 | } |
| 2728 | } else if (pio_dev) | 3061 | } |
| 2729 | pr_unimpl(vcpu, "no string pio read support yet, " | 3062 | /* no string PIO read support yet */ |
| 2730 | "port %x size %d count %ld\n", | ||
| 2731 | port, size, count); | ||
| 2732 | 3063 | ||
| 2733 | return ret; | 3064 | return ret; |
| 2734 | } | 3065 | } |
| @@ -2761,10 +3092,7 @@ static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long va | |||
| 2761 | 3092 | ||
| 2762 | spin_lock(&kvm_lock); | 3093 | spin_lock(&kvm_lock); |
| 2763 | list_for_each_entry(kvm, &vm_list, vm_list) { | 3094 | list_for_each_entry(kvm, &vm_list, vm_list) { |
| 2764 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | 3095 | kvm_for_each_vcpu(i, vcpu, kvm) { |
| 2765 | vcpu = kvm->vcpus[i]; | ||
| 2766 | if (!vcpu) | ||
| 2767 | continue; | ||
| 2768 | if (vcpu->cpu != freq->cpu) | 3096 | if (vcpu->cpu != freq->cpu) |
| 2769 | continue; | 3097 | continue; |
| 2770 | if (!kvm_request_guest_time_update(vcpu)) | 3098 | if (!kvm_request_guest_time_update(vcpu)) |
| @@ -2857,7 +3185,6 @@ void kvm_arch_exit(void) | |||
| 2857 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) | 3185 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) |
| 2858 | { | 3186 | { |
| 2859 | ++vcpu->stat.halt_exits; | 3187 | ++vcpu->stat.halt_exits; |
| 2860 | KVMTRACE_0D(HLT, vcpu, handler); | ||
| 2861 | if (irqchip_in_kernel(vcpu->kvm)) { | 3188 | if (irqchip_in_kernel(vcpu->kvm)) { |
| 2862 | vcpu->arch.mp_state = KVM_MP_STATE_HALTED; | 3189 | vcpu->arch.mp_state = KVM_MP_STATE_HALTED; |
| 2863 | return 1; | 3190 | return 1; |
| @@ -2888,7 +3215,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) | |||
| 2888 | a2 = kvm_register_read(vcpu, VCPU_REGS_RDX); | 3215 | a2 = kvm_register_read(vcpu, VCPU_REGS_RDX); |
| 2889 | a3 = kvm_register_read(vcpu, VCPU_REGS_RSI); | 3216 | a3 = kvm_register_read(vcpu, VCPU_REGS_RSI); |
| 2890 | 3217 | ||
| 2891 | KVMTRACE_1D(VMMCALL, vcpu, (u32)nr, handler); | 3218 | trace_kvm_hypercall(nr, a0, a1, a2, a3); |
| 2892 | 3219 | ||
| 2893 | if (!is_long_mode(vcpu)) { | 3220 | if (!is_long_mode(vcpu)) { |
| 2894 | nr &= 0xFFFFFFFF; | 3221 | nr &= 0xFFFFFFFF; |
| @@ -2898,6 +3225,11 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) | |||
| 2898 | a3 &= 0xFFFFFFFF; | 3225 | a3 &= 0xFFFFFFFF; |
| 2899 | } | 3226 | } |
| 2900 | 3227 | ||
| 3228 | if (kvm_x86_ops->get_cpl(vcpu) != 0) { | ||
| 3229 | ret = -KVM_EPERM; | ||
| 3230 | goto out; | ||
| 3231 | } | ||
| 3232 | |||
| 2901 | switch (nr) { | 3233 | switch (nr) { |
| 2902 | case KVM_HC_VAPIC_POLL_IRQ: | 3234 | case KVM_HC_VAPIC_POLL_IRQ: |
| 2903 | ret = 0; | 3235 | ret = 0; |
| @@ -2909,6 +3241,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) | |||
| 2909 | ret = -KVM_ENOSYS; | 3241 | ret = -KVM_ENOSYS; |
| 2910 | break; | 3242 | break; |
| 2911 | } | 3243 | } |
| 3244 | out: | ||
| 2912 | kvm_register_write(vcpu, VCPU_REGS_RAX, ret); | 3245 | kvm_register_write(vcpu, VCPU_REGS_RAX, ret); |
| 2913 | ++vcpu->stat.hypercalls; | 3246 | ++vcpu->stat.hypercalls; |
| 2914 | return r; | 3247 | return r; |
| @@ -2988,8 +3321,6 @@ unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr) | |||
| 2988 | vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); | 3321 | vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr); |
| 2989 | return 0; | 3322 | return 0; |
| 2990 | } | 3323 | } |
| 2991 | KVMTRACE_3D(CR_READ, vcpu, (u32)cr, (u32)value, | ||
| 2992 | (u32)((u64)value >> 32), handler); | ||
| 2993 | 3324 | ||
| 2994 | return value; | 3325 | return value; |
| 2995 | } | 3326 | } |
| @@ -2997,9 +3328,6 @@ unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr) | |||
| 2997 | void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val, | 3328 | void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val, |
| 2998 | unsigned long *rflags) | 3329 | unsigned long *rflags) |
| 2999 | { | 3330 | { |
| 3000 | KVMTRACE_3D(CR_WRITE, vcpu, (u32)cr, (u32)val, | ||
| 3001 | (u32)((u64)val >> 32), handler); | ||
| 3002 | |||
| 3003 | switch (cr) { | 3331 | switch (cr) { |
| 3004 | case 0: | 3332 | case 0: |
| 3005 | kvm_set_cr0(vcpu, mk_cr_64(vcpu->arch.cr0, val)); | 3333 | kvm_set_cr0(vcpu, mk_cr_64(vcpu->arch.cr0, val)); |
| @@ -3109,11 +3437,11 @@ void kvm_emulate_cpuid(struct kvm_vcpu *vcpu) | |||
| 3109 | kvm_register_write(vcpu, VCPU_REGS_RDX, best->edx); | 3437 | kvm_register_write(vcpu, VCPU_REGS_RDX, best->edx); |
| 3110 | } | 3438 | } |
| 3111 | kvm_x86_ops->skip_emulated_instruction(vcpu); | 3439 | kvm_x86_ops->skip_emulated_instruction(vcpu); |
| 3112 | KVMTRACE_5D(CPUID, vcpu, function, | 3440 | trace_kvm_cpuid(function, |
| 3113 | (u32)kvm_register_read(vcpu, VCPU_REGS_RAX), | 3441 | kvm_register_read(vcpu, VCPU_REGS_RAX), |
| 3114 | (u32)kvm_register_read(vcpu, VCPU_REGS_RBX), | 3442 | kvm_register_read(vcpu, VCPU_REGS_RBX), |
| 3115 | (u32)kvm_register_read(vcpu, VCPU_REGS_RCX), | 3443 | kvm_register_read(vcpu, VCPU_REGS_RCX), |
| 3116 | (u32)kvm_register_read(vcpu, VCPU_REGS_RDX), handler); | 3444 | kvm_register_read(vcpu, VCPU_REGS_RDX)); |
| 3117 | } | 3445 | } |
| 3118 | EXPORT_SYMBOL_GPL(kvm_emulate_cpuid); | 3446 | EXPORT_SYMBOL_GPL(kvm_emulate_cpuid); |
| 3119 | 3447 | ||
| @@ -3179,6 +3507,9 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu) | |||
| 3179 | if (!kvm_x86_ops->update_cr8_intercept) | 3507 | if (!kvm_x86_ops->update_cr8_intercept) |
| 3180 | return; | 3508 | return; |
| 3181 | 3509 | ||
| 3510 | if (!vcpu->arch.apic) | ||
| 3511 | return; | ||
| 3512 | |||
| 3182 | if (!vcpu->arch.apic->vapic_addr) | 3513 | if (!vcpu->arch.apic->vapic_addr) |
| 3183 | max_irr = kvm_lapic_find_highest_irr(vcpu); | 3514 | max_irr = kvm_lapic_find_highest_irr(vcpu); |
| 3184 | else | 3515 | else |
| @@ -3192,12 +3523,16 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu) | |||
| 3192 | kvm_x86_ops->update_cr8_intercept(vcpu, tpr, max_irr); | 3523 | kvm_x86_ops->update_cr8_intercept(vcpu, tpr, max_irr); |
| 3193 | } | 3524 | } |
| 3194 | 3525 | ||
| 3195 | static void inject_pending_irq(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 3526 | static void inject_pending_event(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) |
| 3196 | { | 3527 | { |
| 3197 | if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) | ||
| 3198 | kvm_x86_ops->set_interrupt_shadow(vcpu, 0); | ||
| 3199 | |||
| 3200 | /* try to reinject previous events if any */ | 3528 | /* try to reinject previous events if any */ |
| 3529 | if (vcpu->arch.exception.pending) { | ||
| 3530 | kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr, | ||
| 3531 | vcpu->arch.exception.has_error_code, | ||
| 3532 | vcpu->arch.exception.error_code); | ||
| 3533 | return; | ||
| 3534 | } | ||
| 3535 | |||
| 3201 | if (vcpu->arch.nmi_injected) { | 3536 | if (vcpu->arch.nmi_injected) { |
| 3202 | kvm_x86_ops->set_nmi(vcpu); | 3537 | kvm_x86_ops->set_nmi(vcpu); |
| 3203 | return; | 3538 | return; |
| @@ -3271,16 +3606,14 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 3271 | smp_mb__after_clear_bit(); | 3606 | smp_mb__after_clear_bit(); |
| 3272 | 3607 | ||
| 3273 | if (vcpu->requests || need_resched() || signal_pending(current)) { | 3608 | if (vcpu->requests || need_resched() || signal_pending(current)) { |
| 3609 | set_bit(KVM_REQ_KICK, &vcpu->requests); | ||
| 3274 | local_irq_enable(); | 3610 | local_irq_enable(); |
| 3275 | preempt_enable(); | 3611 | preempt_enable(); |
| 3276 | r = 1; | 3612 | r = 1; |
| 3277 | goto out; | 3613 | goto out; |
| 3278 | } | 3614 | } |
| 3279 | 3615 | ||
| 3280 | if (vcpu->arch.exception.pending) | 3616 | inject_pending_event(vcpu, kvm_run); |
| 3281 | __queue_exception(vcpu); | ||
| 3282 | else | ||
| 3283 | inject_pending_irq(vcpu, kvm_run); | ||
| 3284 | 3617 | ||
| 3285 | /* enable NMI/IRQ window open exits if needed */ | 3618 | /* enable NMI/IRQ window open exits if needed */ |
| 3286 | if (vcpu->arch.nmi_pending) | 3619 | if (vcpu->arch.nmi_pending) |
| @@ -3297,14 +3630,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 3297 | 3630 | ||
| 3298 | kvm_guest_enter(); | 3631 | kvm_guest_enter(); |
| 3299 | 3632 | ||
| 3300 | get_debugreg(vcpu->arch.host_dr6, 6); | ||
| 3301 | get_debugreg(vcpu->arch.host_dr7, 7); | ||
| 3302 | if (unlikely(vcpu->arch.switch_db_regs)) { | 3633 | if (unlikely(vcpu->arch.switch_db_regs)) { |
| 3303 | get_debugreg(vcpu->arch.host_db[0], 0); | ||
| 3304 | get_debugreg(vcpu->arch.host_db[1], 1); | ||
| 3305 | get_debugreg(vcpu->arch.host_db[2], 2); | ||
| 3306 | get_debugreg(vcpu->arch.host_db[3], 3); | ||
| 3307 | |||
| 3308 | set_debugreg(0, 7); | 3634 | set_debugreg(0, 7); |
| 3309 | set_debugreg(vcpu->arch.eff_db[0], 0); | 3635 | set_debugreg(vcpu->arch.eff_db[0], 0); |
| 3310 | set_debugreg(vcpu->arch.eff_db[1], 1); | 3636 | set_debugreg(vcpu->arch.eff_db[1], 1); |
| @@ -3312,18 +3638,17 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 3312 | set_debugreg(vcpu->arch.eff_db[3], 3); | 3638 | set_debugreg(vcpu->arch.eff_db[3], 3); |
| 3313 | } | 3639 | } |
| 3314 | 3640 | ||
| 3315 | KVMTRACE_0D(VMENTRY, vcpu, entryexit); | 3641 | trace_kvm_entry(vcpu->vcpu_id); |
| 3316 | kvm_x86_ops->run(vcpu, kvm_run); | 3642 | kvm_x86_ops->run(vcpu, kvm_run); |
| 3317 | 3643 | ||
| 3318 | if (unlikely(vcpu->arch.switch_db_regs)) { | 3644 | if (unlikely(vcpu->arch.switch_db_regs || test_thread_flag(TIF_DEBUG))) { |
| 3319 | set_debugreg(0, 7); | 3645 | set_debugreg(current->thread.debugreg0, 0); |
| 3320 | set_debugreg(vcpu->arch.host_db[0], 0); | 3646 | set_debugreg(current->thread.debugreg1, 1); |
| 3321 | set_debugreg(vcpu->arch.host_db[1], 1); | 3647 | set_debugreg(current->thread.debugreg2, 2); |
| 3322 | set_debugreg(vcpu->arch.host_db[2], 2); | 3648 | set_debugreg(current->thread.debugreg3, 3); |
| 3323 | set_debugreg(vcpu->arch.host_db[3], 3); | 3649 | set_debugreg(current->thread.debugreg6, 6); |
| 3650 | set_debugreg(current->thread.debugreg7, 7); | ||
| 3324 | } | 3651 | } |
| 3325 | set_debugreg(vcpu->arch.host_dr6, 6); | ||
| 3326 | set_debugreg(vcpu->arch.host_dr7, 7); | ||
| 3327 | 3652 | ||
| 3328 | set_bit(KVM_REQ_KICK, &vcpu->requests); | 3653 | set_bit(KVM_REQ_KICK, &vcpu->requests); |
| 3329 | local_irq_enable(); | 3654 | local_irq_enable(); |
| @@ -3653,11 +3978,8 @@ static void kvm_set_segment(struct kvm_vcpu *vcpu, | |||
| 3653 | static void seg_desct_to_kvm_desct(struct desc_struct *seg_desc, u16 selector, | 3978 | static void seg_desct_to_kvm_desct(struct desc_struct *seg_desc, u16 selector, |
| 3654 | struct kvm_segment *kvm_desct) | 3979 | struct kvm_segment *kvm_desct) |
| 3655 | { | 3980 | { |
| 3656 | kvm_desct->base = seg_desc->base0; | 3981 | kvm_desct->base = get_desc_base(seg_desc); |
| 3657 | kvm_desct->base |= seg_desc->base1 << 16; | 3982 | kvm_desct->limit = get_desc_limit(seg_desc); |
| 3658 | kvm_desct->base |= seg_desc->base2 << 24; | ||
| 3659 | kvm_desct->limit = seg_desc->limit0; | ||
| 3660 | kvm_desct->limit |= seg_desc->limit << 16; | ||
| 3661 | if (seg_desc->g) { | 3983 | if (seg_desc->g) { |
| 3662 | kvm_desct->limit <<= 12; | 3984 | kvm_desct->limit <<= 12; |
| 3663 | kvm_desct->limit |= 0xfff; | 3985 | kvm_desct->limit |= 0xfff; |
| @@ -3701,7 +4023,6 @@ static void get_segment_descriptor_dtable(struct kvm_vcpu *vcpu, | |||
| 3701 | static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | 4023 | static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, |
| 3702 | struct desc_struct *seg_desc) | 4024 | struct desc_struct *seg_desc) |
| 3703 | { | 4025 | { |
| 3704 | gpa_t gpa; | ||
| 3705 | struct descriptor_table dtable; | 4026 | struct descriptor_table dtable; |
| 3706 | u16 index = selector >> 3; | 4027 | u16 index = selector >> 3; |
| 3707 | 4028 | ||
| @@ -3711,16 +4032,13 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | |||
| 3711 | kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc); | 4032 | kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc); |
| 3712 | return 1; | 4033 | return 1; |
| 3713 | } | 4034 | } |
| 3714 | gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base); | 4035 | return kvm_read_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu); |
| 3715 | gpa += index * 8; | ||
| 3716 | return kvm_read_guest(vcpu->kvm, gpa, seg_desc, 8); | ||
| 3717 | } | 4036 | } |
| 3718 | 4037 | ||
| 3719 | /* allowed just for 8 bytes segments */ | 4038 | /* allowed just for 8 bytes segments */ |
| 3720 | static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | 4039 | static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, |
| 3721 | struct desc_struct *seg_desc) | 4040 | struct desc_struct *seg_desc) |
| 3722 | { | 4041 | { |
| 3723 | gpa_t gpa; | ||
| 3724 | struct descriptor_table dtable; | 4042 | struct descriptor_table dtable; |
| 3725 | u16 index = selector >> 3; | 4043 | u16 index = selector >> 3; |
| 3726 | 4044 | ||
| @@ -3728,19 +4046,13 @@ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | |||
| 3728 | 4046 | ||
| 3729 | if (dtable.limit < index * 8 + 7) | 4047 | if (dtable.limit < index * 8 + 7) |
| 3730 | return 1; | 4048 | return 1; |
| 3731 | gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base); | 4049 | return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu); |
| 3732 | gpa += index * 8; | ||
| 3733 | return kvm_write_guest(vcpu->kvm, gpa, seg_desc, 8); | ||
| 3734 | } | 4050 | } |
| 3735 | 4051 | ||
| 3736 | static u32 get_tss_base_addr(struct kvm_vcpu *vcpu, | 4052 | static u32 get_tss_base_addr(struct kvm_vcpu *vcpu, |
| 3737 | struct desc_struct *seg_desc) | 4053 | struct desc_struct *seg_desc) |
| 3738 | { | 4054 | { |
| 3739 | u32 base_addr; | 4055 | u32 base_addr = get_desc_base(seg_desc); |
| 3740 | |||
| 3741 | base_addr = seg_desc->base0; | ||
| 3742 | base_addr |= (seg_desc->base1 << 16); | ||
| 3743 | base_addr |= (seg_desc->base2 << 24); | ||
| 3744 | 4056 | ||
| 3745 | return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr); | 4057 | return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr); |
| 3746 | } | 4058 | } |
| @@ -3785,12 +4097,19 @@ static int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int se | |||
| 3785 | return 0; | 4097 | return 0; |
| 3786 | } | 4098 | } |
| 3787 | 4099 | ||
| 4100 | static int is_vm86_segment(struct kvm_vcpu *vcpu, int seg) | ||
| 4101 | { | ||
| 4102 | return (seg != VCPU_SREG_LDTR) && | ||
| 4103 | (seg != VCPU_SREG_TR) && | ||
| 4104 | (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_VM); | ||
| 4105 | } | ||
| 4106 | |||
| 3788 | int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, | 4107 | int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector, |
| 3789 | int type_bits, int seg) | 4108 | int type_bits, int seg) |
| 3790 | { | 4109 | { |
| 3791 | struct kvm_segment kvm_seg; | 4110 | struct kvm_segment kvm_seg; |
| 3792 | 4111 | ||
| 3793 | if (!(vcpu->arch.cr0 & X86_CR0_PE)) | 4112 | if (is_vm86_segment(vcpu, seg) || !(vcpu->arch.cr0 & X86_CR0_PE)) |
| 3794 | return kvm_load_realmode_segment(vcpu, selector, seg); | 4113 | return kvm_load_realmode_segment(vcpu, selector, seg); |
| 3795 | if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg)) | 4114 | if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg)) |
| 3796 | return 1; | 4115 | return 1; |
| @@ -4029,7 +4348,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason) | |||
| 4029 | } | 4348 | } |
| 4030 | } | 4349 | } |
| 4031 | 4350 | ||
| 4032 | if (!nseg_desc.p || (nseg_desc.limit0 | nseg_desc.limit << 16) < 0x67) { | 4351 | if (!nseg_desc.p || get_desc_limit(&nseg_desc) < 0x67) { |
| 4033 | kvm_queue_exception_e(vcpu, TS_VECTOR, tss_selector & 0xfffc); | 4352 | kvm_queue_exception_e(vcpu, TS_VECTOR, tss_selector & 0xfffc); |
| 4034 | return 1; | 4353 | return 1; |
| 4035 | } | 4354 | } |
| @@ -4099,13 +4418,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
| 4099 | 4418 | ||
| 4100 | vcpu->arch.cr2 = sregs->cr2; | 4419 | vcpu->arch.cr2 = sregs->cr2; |
| 4101 | mmu_reset_needed |= vcpu->arch.cr3 != sregs->cr3; | 4420 | mmu_reset_needed |= vcpu->arch.cr3 != sregs->cr3; |
| 4102 | 4421 | vcpu->arch.cr3 = sregs->cr3; | |
| 4103 | down_read(&vcpu->kvm->slots_lock); | ||
| 4104 | if (gfn_to_memslot(vcpu->kvm, sregs->cr3 >> PAGE_SHIFT)) | ||
| 4105 | vcpu->arch.cr3 = sregs->cr3; | ||
| 4106 | else | ||
| 4107 | set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests); | ||
| 4108 | up_read(&vcpu->kvm->slots_lock); | ||
| 4109 | 4422 | ||
| 4110 | kvm_set_cr8(vcpu, sregs->cr8); | 4423 | kvm_set_cr8(vcpu, sregs->cr8); |
| 4111 | 4424 | ||
| @@ -4147,8 +4460,10 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
| 4147 | kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR); | 4460 | kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR); |
| 4148 | kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); | 4461 | kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); |
| 4149 | 4462 | ||
| 4463 | update_cr8_intercept(vcpu); | ||
| 4464 | |||
| 4150 | /* Older userspace won't unhalt the vcpu on reset. */ | 4465 | /* Older userspace won't unhalt the vcpu on reset. */ |
| 4151 | if (vcpu->vcpu_id == 0 && kvm_rip_read(vcpu) == 0xfff0 && | 4466 | if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 && |
| 4152 | sregs->cs.selector == 0xf000 && sregs->cs.base == 0xffff0000 && | 4467 | sregs->cs.selector == 0xf000 && sregs->cs.base == 0xffff0000 && |
| 4153 | !(vcpu->arch.cr0 & X86_CR0_PE)) | 4468 | !(vcpu->arch.cr0 & X86_CR0_PE)) |
| 4154 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; | 4469 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; |
| @@ -4419,7 +4734,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
| 4419 | kvm = vcpu->kvm; | 4734 | kvm = vcpu->kvm; |
| 4420 | 4735 | ||
| 4421 | vcpu->arch.mmu.root_hpa = INVALID_PAGE; | 4736 | vcpu->arch.mmu.root_hpa = INVALID_PAGE; |
| 4422 | if (!irqchip_in_kernel(kvm) || vcpu->vcpu_id == 0) | 4737 | if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_bsp(vcpu)) |
| 4423 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; | 4738 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; |
| 4424 | else | 4739 | else |
| 4425 | vcpu->arch.mp_state = KVM_MP_STATE_UNINITIALIZED; | 4740 | vcpu->arch.mp_state = KVM_MP_STATE_UNINITIALIZED; |
| @@ -4441,6 +4756,14 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
| 4441 | goto fail_mmu_destroy; | 4756 | goto fail_mmu_destroy; |
| 4442 | } | 4757 | } |
| 4443 | 4758 | ||
| 4759 | vcpu->arch.mce_banks = kzalloc(KVM_MAX_MCE_BANKS * sizeof(u64) * 4, | ||
| 4760 | GFP_KERNEL); | ||
| 4761 | if (!vcpu->arch.mce_banks) { | ||
| 4762 | r = -ENOMEM; | ||
| 4763 | goto fail_mmu_destroy; | ||
| 4764 | } | ||
| 4765 | vcpu->arch.mcg_cap = KVM_MAX_MCE_BANKS; | ||
| 4766 | |||
| 4444 | return 0; | 4767 | return 0; |
| 4445 | 4768 | ||
| 4446 | fail_mmu_destroy: | 4769 | fail_mmu_destroy: |
| @@ -4488,20 +4811,22 @@ static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu) | |||
| 4488 | static void kvm_free_vcpus(struct kvm *kvm) | 4811 | static void kvm_free_vcpus(struct kvm *kvm) |
| 4489 | { | 4812 | { |
| 4490 | unsigned int i; | 4813 | unsigned int i; |
| 4814 | struct kvm_vcpu *vcpu; | ||
| 4491 | 4815 | ||
| 4492 | /* | 4816 | /* |
| 4493 | * Unpin any mmu pages first. | 4817 | * Unpin any mmu pages first. |
| 4494 | */ | 4818 | */ |
| 4495 | for (i = 0; i < KVM_MAX_VCPUS; ++i) | 4819 | kvm_for_each_vcpu(i, vcpu, kvm) |
| 4496 | if (kvm->vcpus[i]) | 4820 | kvm_unload_vcpu_mmu(vcpu); |
| 4497 | kvm_unload_vcpu_mmu(kvm->vcpus[i]); | 4821 | kvm_for_each_vcpu(i, vcpu, kvm) |
| 4498 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | 4822 | kvm_arch_vcpu_free(vcpu); |
| 4499 | if (kvm->vcpus[i]) { | 4823 | |
| 4500 | kvm_arch_vcpu_free(kvm->vcpus[i]); | 4824 | mutex_lock(&kvm->lock); |
| 4501 | kvm->vcpus[i] = NULL; | 4825 | for (i = 0; i < atomic_read(&kvm->online_vcpus); i++) |
| 4502 | } | 4826 | kvm->vcpus[i] = NULL; |
| 4503 | } | ||
| 4504 | 4827 | ||
| 4828 | atomic_set(&kvm->online_vcpus, 0); | ||
| 4829 | mutex_unlock(&kvm->lock); | ||
| 4505 | } | 4830 | } |
| 4506 | 4831 | ||
| 4507 | void kvm_arch_sync_events(struct kvm *kvm) | 4832 | void kvm_arch_sync_events(struct kvm *kvm) |
| @@ -4578,7 +4903,6 @@ int kvm_arch_set_memory_region(struct kvm *kvm, | |||
| 4578 | 4903 | ||
| 4579 | kvm_mmu_slot_remove_write_access(kvm, mem->slot); | 4904 | kvm_mmu_slot_remove_write_access(kvm, mem->slot); |
| 4580 | spin_unlock(&kvm->mmu_lock); | 4905 | spin_unlock(&kvm->mmu_lock); |
| 4581 | kvm_flush_remote_tlbs(kvm); | ||
| 4582 | 4906 | ||
| 4583 | return 0; | 4907 | return 0; |
| 4584 | } | 4908 | } |
| @@ -4592,8 +4916,10 @@ void kvm_arch_flush_shadow(struct kvm *kvm) | |||
| 4592 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) | 4916 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) |
| 4593 | { | 4917 | { |
| 4594 | return vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE | 4918 | return vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE |
| 4595 | || vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED | 4919 | || vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED |
| 4596 | || vcpu->arch.nmi_pending; | 4920 | || vcpu->arch.nmi_pending || |
| 4921 | (kvm_arch_interrupt_allowed(vcpu) && | ||
| 4922 | kvm_cpu_has_interrupt(vcpu)); | ||
| 4597 | } | 4923 | } |
| 4598 | 4924 | ||
| 4599 | void kvm_vcpu_kick(struct kvm_vcpu *vcpu) | 4925 | void kvm_vcpu_kick(struct kvm_vcpu *vcpu) |
| @@ -4617,3 +4943,9 @@ int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu) | |||
| 4617 | { | 4943 | { |
| 4618 | return kvm_x86_ops->interrupt_allowed(vcpu); | 4944 | return kvm_x86_ops->interrupt_allowed(vcpu); |
| 4619 | } | 4945 | } |
| 4946 | |||
| 4947 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit); | ||
| 4948 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq); | ||
| 4949 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault); | ||
| 4950 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_msr); | ||
| 4951 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_cr); | ||
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 4c8e10af78e8..5eadea585d2a 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h | |||
| @@ -31,4 +31,8 @@ static inline bool kvm_exception_is_soft(unsigned int nr) | |||
| 31 | { | 31 | { |
| 32 | return (nr == BP_VECTOR) || (nr == OF_VECTOR); | 32 | return (nr == BP_VECTOR) || (nr == OF_VECTOR); |
| 33 | } | 33 | } |
| 34 | |||
| 35 | struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu, | ||
| 36 | u32 function, u32 index); | ||
| 37 | |||
| 34 | #endif | 38 | #endif |
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 07c31899c9c2..9e609206fac9 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile | |||
| @@ -9,6 +9,8 @@ lib-y += thunk_$(BITS).o | |||
| 9 | lib-y += usercopy_$(BITS).o getuser.o putuser.o | 9 | lib-y += usercopy_$(BITS).o getuser.o putuser.o |
| 10 | lib-y += memcpy_$(BITS).o | 10 | lib-y += memcpy_$(BITS).o |
| 11 | 11 | ||
| 12 | obj-y += msr-reg.o msr-reg-export.o | ||
| 13 | |||
| 12 | ifeq ($(CONFIG_X86_32),y) | 14 | ifeq ($(CONFIG_X86_32),y) |
| 13 | obj-y += atomic64_32.o | 15 | obj-y += atomic64_32.o |
| 14 | lib-y += checksum_32.o | 16 | lib-y += checksum_32.o |
diff --git a/arch/x86/lib/msr-reg-export.c b/arch/x86/lib/msr-reg-export.c new file mode 100644 index 000000000000..a311cc59b65d --- /dev/null +++ b/arch/x86/lib/msr-reg-export.c | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | #include <linux/module.h> | ||
| 2 | #include <asm/msr.h> | ||
| 3 | |||
| 4 | EXPORT_SYMBOL(native_rdmsr_safe_regs); | ||
| 5 | EXPORT_SYMBOL(native_wrmsr_safe_regs); | ||
diff --git a/arch/x86/lib/msr-reg.S b/arch/x86/lib/msr-reg.S new file mode 100644 index 000000000000..69fa10623f21 --- /dev/null +++ b/arch/x86/lib/msr-reg.S | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | #include <linux/linkage.h> | ||
| 2 | #include <linux/errno.h> | ||
| 3 | #include <asm/dwarf2.h> | ||
| 4 | #include <asm/asm.h> | ||
| 5 | #include <asm/msr.h> | ||
| 6 | |||
| 7 | #ifdef CONFIG_X86_64 | ||
| 8 | /* | ||
| 9 | * int native_{rdmsr,wrmsr}_safe_regs(u32 gprs[8]); | ||
| 10 | * | ||
| 11 | * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi] | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | .macro op_safe_regs op | ||
| 15 | ENTRY(native_\op\()_safe_regs) | ||
| 16 | CFI_STARTPROC | ||
| 17 | pushq_cfi %rbx | ||
| 18 | pushq_cfi %rbp | ||
| 19 | movq %rdi, %r10 /* Save pointer */ | ||
| 20 | xorl %r11d, %r11d /* Return value */ | ||
| 21 | movl (%rdi), %eax | ||
| 22 | movl 4(%rdi), %ecx | ||
| 23 | movl 8(%rdi), %edx | ||
| 24 | movl 12(%rdi), %ebx | ||
| 25 | movl 20(%rdi), %ebp | ||
| 26 | movl 24(%rdi), %esi | ||
| 27 | movl 28(%rdi), %edi | ||
| 28 | CFI_REMEMBER_STATE | ||
| 29 | 1: \op | ||
| 30 | 2: movl %eax, (%r10) | ||
| 31 | movl %r11d, %eax /* Return value */ | ||
| 32 | movl %ecx, 4(%r10) | ||
| 33 | movl %edx, 8(%r10) | ||
| 34 | movl %ebx, 12(%r10) | ||
| 35 | movl %ebp, 20(%r10) | ||
| 36 | movl %esi, 24(%r10) | ||
| 37 | movl %edi, 28(%r10) | ||
| 38 | popq_cfi %rbp | ||
| 39 | popq_cfi %rbx | ||
| 40 | ret | ||
| 41 | 3: | ||
| 42 | CFI_RESTORE_STATE | ||
| 43 | movl $-EIO, %r11d | ||
| 44 | jmp 2b | ||
| 45 | |||
| 46 | _ASM_EXTABLE(1b, 3b) | ||
| 47 | CFI_ENDPROC | ||
| 48 | ENDPROC(native_\op\()_safe_regs) | ||
| 49 | .endm | ||
| 50 | |||
| 51 | #else /* X86_32 */ | ||
| 52 | |||
| 53 | .macro op_safe_regs op | ||
| 54 | ENTRY(native_\op\()_safe_regs) | ||
| 55 | CFI_STARTPROC | ||
| 56 | pushl_cfi %ebx | ||
| 57 | pushl_cfi %ebp | ||
| 58 | pushl_cfi %esi | ||
| 59 | pushl_cfi %edi | ||
| 60 | pushl_cfi $0 /* Return value */ | ||
| 61 | pushl_cfi %eax | ||
| 62 | movl 4(%eax), %ecx | ||
| 63 | movl 8(%eax), %edx | ||
| 64 | movl 12(%eax), %ebx | ||
| 65 | movl 20(%eax), %ebp | ||
| 66 | movl 24(%eax), %esi | ||
| 67 | movl 28(%eax), %edi | ||
| 68 | movl (%eax), %eax | ||
| 69 | CFI_REMEMBER_STATE | ||
| 70 | 1: \op | ||
| 71 | 2: pushl_cfi %eax | ||
| 72 | movl 4(%esp), %eax | ||
| 73 | popl_cfi (%eax) | ||
| 74 | addl $4, %esp | ||
| 75 | CFI_ADJUST_CFA_OFFSET -4 | ||
| 76 | movl %ecx, 4(%eax) | ||
| 77 | movl %edx, 8(%eax) | ||
| 78 | movl %ebx, 12(%eax) | ||
| 79 | movl %ebp, 20(%eax) | ||
| 80 | movl %esi, 24(%eax) | ||
| 81 | movl %edi, 28(%eax) | ||
| 82 | popl_cfi %eax | ||
| 83 | popl_cfi %edi | ||
| 84 | popl_cfi %esi | ||
| 85 | popl_cfi %ebp | ||
| 86 | popl_cfi %ebx | ||
| 87 | ret | ||
| 88 | 3: | ||
| 89 | CFI_RESTORE_STATE | ||
| 90 | movl $-EIO, 4(%esp) | ||
| 91 | jmp 2b | ||
| 92 | |||
| 93 | _ASM_EXTABLE(1b, 3b) | ||
| 94 | CFI_ENDPROC | ||
| 95 | ENDPROC(native_\op\()_safe_regs) | ||
| 96 | .endm | ||
| 97 | |||
| 98 | #endif | ||
| 99 | |||
| 100 | op_safe_regs rdmsr | ||
| 101 | op_safe_regs wrmsr | ||
| 102 | |||
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c index caa24aca8115..33a1e3ca22d8 100644 --- a/arch/x86/lib/msr.c +++ b/arch/x86/lib/msr.c | |||
| @@ -175,3 +175,52 @@ int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) | |||
| 175 | return err ? err : rv.err; | 175 | return err ? err : rv.err; |
| 176 | } | 176 | } |
| 177 | EXPORT_SYMBOL(wrmsr_safe_on_cpu); | 177 | EXPORT_SYMBOL(wrmsr_safe_on_cpu); |
| 178 | |||
| 179 | /* | ||
| 180 | * These variants are significantly slower, but allows control over | ||
| 181 | * the entire 32-bit GPR set. | ||
| 182 | */ | ||
| 183 | struct msr_regs_info { | ||
| 184 | u32 *regs; | ||
| 185 | int err; | ||
| 186 | }; | ||
| 187 | |||
| 188 | static void __rdmsr_safe_regs_on_cpu(void *info) | ||
| 189 | { | ||
| 190 | struct msr_regs_info *rv = info; | ||
| 191 | |||
| 192 | rv->err = rdmsr_safe_regs(rv->regs); | ||
| 193 | } | ||
| 194 | |||
| 195 | static void __wrmsr_safe_regs_on_cpu(void *info) | ||
| 196 | { | ||
| 197 | struct msr_regs_info *rv = info; | ||
| 198 | |||
| 199 | rv->err = wrmsr_safe_regs(rv->regs); | ||
| 200 | } | ||
| 201 | |||
| 202 | int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs) | ||
| 203 | { | ||
| 204 | int err; | ||
| 205 | struct msr_regs_info rv; | ||
| 206 | |||
| 207 | rv.regs = regs; | ||
| 208 | rv.err = -EIO; | ||
| 209 | err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1); | ||
| 210 | |||
| 211 | return err ? err : rv.err; | ||
| 212 | } | ||
| 213 | EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu); | ||
| 214 | |||
| 215 | int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs) | ||
| 216 | { | ||
| 217 | int err; | ||
| 218 | struct msr_regs_info rv; | ||
| 219 | |||
| 220 | rv.regs = regs; | ||
| 221 | rv.err = -EIO; | ||
| 222 | err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1); | ||
| 223 | |||
| 224 | return err ? err : rv.err; | ||
| 225 | } | ||
| 226 | EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu); | ||
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index eefdeee8a871..9b5a9f59a478 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile | |||
| @@ -1,5 +1,9 @@ | |||
| 1 | obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ | 1 | obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ |
| 2 | pat.o pgtable.o gup.o | 2 | pat.o pgtable.o physaddr.o gup.o |
| 3 | |||
| 4 | # Make sure __phys_addr has no stackprotector | ||
| 5 | nostackp := $(call cc-option, -fno-stack-protector) | ||
| 6 | CFLAGS_physaddr.o := $(nostackp) | ||
| 3 | 7 | ||
| 4 | obj-$(CONFIG_SMP) += tlb.o | 8 | obj-$(CONFIG_SMP) += tlb.o |
| 5 | 9 | ||
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index bfae139182ff..775a020990a5 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
| @@ -285,26 +285,25 @@ check_v8086_mode(struct pt_regs *regs, unsigned long address, | |||
| 285 | tsk->thread.screen_bitmap |= 1 << bit; | 285 | tsk->thread.screen_bitmap |= 1 << bit; |
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | static void dump_pagetable(unsigned long address) | 288 | static bool low_pfn(unsigned long pfn) |
| 289 | { | 289 | { |
| 290 | __typeof__(pte_val(__pte(0))) page; | 290 | return pfn < max_low_pfn; |
| 291 | } | ||
| 291 | 292 | ||
| 292 | page = read_cr3(); | 293 | static void dump_pagetable(unsigned long address) |
| 293 | page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT]; | 294 | { |
| 295 | pgd_t *base = __va(read_cr3()); | ||
| 296 | pgd_t *pgd = &base[pgd_index(address)]; | ||
| 297 | pmd_t *pmd; | ||
| 298 | pte_t *pte; | ||
| 294 | 299 | ||
| 295 | #ifdef CONFIG_X86_PAE | 300 | #ifdef CONFIG_X86_PAE |
| 296 | printk("*pdpt = %016Lx ", page); | 301 | printk("*pdpt = %016Lx ", pgd_val(*pgd)); |
| 297 | if ((page >> PAGE_SHIFT) < max_low_pfn | 302 | if (!low_pfn(pgd_val(*pgd) >> PAGE_SHIFT) || !pgd_present(*pgd)) |
| 298 | && page & _PAGE_PRESENT) { | 303 | goto out; |
| 299 | page &= PAGE_MASK; | ||
| 300 | page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT) | ||
| 301 | & (PTRS_PER_PMD - 1)]; | ||
| 302 | printk(KERN_CONT "*pde = %016Lx ", page); | ||
| 303 | page &= ~_PAGE_NX; | ||
| 304 | } | ||
| 305 | #else | ||
| 306 | printk("*pde = %08lx ", page); | ||
| 307 | #endif | 304 | #endif |
| 305 | pmd = pmd_offset(pud_offset(pgd, address), address); | ||
| 306 | printk(KERN_CONT "*pde = %0*Lx ", sizeof(*pmd) * 2, (u64)pmd_val(*pmd)); | ||
| 308 | 307 | ||
| 309 | /* | 308 | /* |
| 310 | * We must not directly access the pte in the highpte | 309 | * We must not directly access the pte in the highpte |
| @@ -312,16 +311,12 @@ static void dump_pagetable(unsigned long address) | |||
| 312 | * And let's rather not kmap-atomic the pte, just in case | 311 | * And let's rather not kmap-atomic the pte, just in case |
| 313 | * it's allocated already: | 312 | * it's allocated already: |
| 314 | */ | 313 | */ |
| 315 | if ((page >> PAGE_SHIFT) < max_low_pfn | 314 | if (!low_pfn(pmd_pfn(*pmd)) || !pmd_present(*pmd) || pmd_large(*pmd)) |
| 316 | && (page & _PAGE_PRESENT) | 315 | goto out; |
| 317 | && !(page & _PAGE_PSE)) { | ||
| 318 | |||
| 319 | page &= PAGE_MASK; | ||
| 320 | page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT) | ||
| 321 | & (PTRS_PER_PTE - 1)]; | ||
| 322 | printk("*pte = %0*Lx ", sizeof(page)*2, (u64)page); | ||
| 323 | } | ||
| 324 | 316 | ||
| 317 | pte = pte_offset_kernel(pmd, address); | ||
| 318 | printk("*pte = %0*Lx ", sizeof(*pte) * 2, (u64)pte_val(*pte)); | ||
| 319 | out: | ||
| 325 | printk("\n"); | 320 | printk("\n"); |
| 326 | } | 321 | } |
| 327 | 322 | ||
| @@ -450,16 +445,12 @@ static int bad_address(void *p) | |||
| 450 | 445 | ||
| 451 | static void dump_pagetable(unsigned long address) | 446 | static void dump_pagetable(unsigned long address) |
| 452 | { | 447 | { |
| 453 | pgd_t *pgd; | 448 | pgd_t *base = __va(read_cr3() & PHYSICAL_PAGE_MASK); |
| 449 | pgd_t *pgd = base + pgd_index(address); | ||
| 454 | pud_t *pud; | 450 | pud_t *pud; |
| 455 | pmd_t *pmd; | 451 | pmd_t *pmd; |
| 456 | pte_t *pte; | 452 | pte_t *pte; |
| 457 | 453 | ||
| 458 | pgd = (pgd_t *)read_cr3(); | ||
| 459 | |||
| 460 | pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK); | ||
| 461 | |||
| 462 | pgd += pgd_index(address); | ||
| 463 | if (bad_address(pgd)) | 454 | if (bad_address(pgd)) |
| 464 | goto bad; | 455 | goto bad; |
| 465 | 456 | ||
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c index 2112ed55e7ea..63a6ba66cbe0 100644 --- a/arch/x86/mm/highmem_32.c +++ b/arch/x86/mm/highmem_32.c | |||
| @@ -24,7 +24,7 @@ void kunmap(struct page *page) | |||
| 24 | * no global lock is needed and because the kmap code must perform a global TLB | 24 | * no global lock is needed and because the kmap code must perform a global TLB |
| 25 | * invalidation when the kmap pool wraps. | 25 | * invalidation when the kmap pool wraps. |
| 26 | * | 26 | * |
| 27 | * However when holding an atomic kmap is is not legal to sleep, so atomic | 27 | * However when holding an atomic kmap it is not legal to sleep, so atomic |
| 28 | * kmaps are appropriate for short, tight code paths only. | 28 | * kmaps are appropriate for short, tight code paths only. |
| 29 | */ | 29 | */ |
| 30 | void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | 30 | void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) |
| @@ -104,6 +104,7 @@ EXPORT_SYMBOL(kunmap); | |||
| 104 | EXPORT_SYMBOL(kmap_atomic); | 104 | EXPORT_SYMBOL(kmap_atomic); |
| 105 | EXPORT_SYMBOL(kunmap_atomic); | 105 | EXPORT_SYMBOL(kunmap_atomic); |
| 106 | EXPORT_SYMBOL(kmap_atomic_prot); | 106 | EXPORT_SYMBOL(kmap_atomic_prot); |
| 107 | EXPORT_SYMBOL(kmap_atomic_to_page); | ||
| 107 | 108 | ||
| 108 | void __init set_highmem_pages_init(void) | 109 | void __init set_highmem_pages_init(void) |
| 109 | { | 110 | { |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 6176fe8f29e0..ea56b8cbb6a6 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
| @@ -796,7 +796,7 @@ int __init reserve_bootmem_generic(unsigned long phys, unsigned long len, | |||
| 796 | return ret; | 796 | return ret; |
| 797 | 797 | ||
| 798 | #else | 798 | #else |
| 799 | reserve_bootmem(phys, len, BOOTMEM_DEFAULT); | 799 | reserve_bootmem(phys, len, flags); |
| 800 | #endif | 800 | #endif |
| 801 | 801 | ||
| 802 | if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) { | 802 | if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) { |
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 8a450930834f..04e1ad60c63a 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
| @@ -22,77 +22,7 @@ | |||
| 22 | #include <asm/pgalloc.h> | 22 | #include <asm/pgalloc.h> |
| 23 | #include <asm/pat.h> | 23 | #include <asm/pat.h> |
| 24 | 24 | ||
| 25 | static inline int phys_addr_valid(resource_size_t addr) | 25 | #include "physaddr.h" |
| 26 | { | ||
| 27 | #ifdef CONFIG_PHYS_ADDR_T_64BIT | ||
| 28 | return !(addr >> boot_cpu_data.x86_phys_bits); | ||
| 29 | #else | ||
| 30 | return 1; | ||
| 31 | #endif | ||
| 32 | } | ||
| 33 | |||
| 34 | #ifdef CONFIG_X86_64 | ||
| 35 | |||
| 36 | unsigned long __phys_addr(unsigned long x) | ||
| 37 | { | ||
| 38 | if (x >= __START_KERNEL_map) { | ||
| 39 | x -= __START_KERNEL_map; | ||
| 40 | VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE); | ||
| 41 | x += phys_base; | ||
| 42 | } else { | ||
| 43 | VIRTUAL_BUG_ON(x < PAGE_OFFSET); | ||
| 44 | x -= PAGE_OFFSET; | ||
| 45 | VIRTUAL_BUG_ON(!phys_addr_valid(x)); | ||
| 46 | } | ||
| 47 | return x; | ||
| 48 | } | ||
| 49 | EXPORT_SYMBOL(__phys_addr); | ||
| 50 | |||
| 51 | bool __virt_addr_valid(unsigned long x) | ||
| 52 | { | ||
| 53 | if (x >= __START_KERNEL_map) { | ||
| 54 | x -= __START_KERNEL_map; | ||
| 55 | if (x >= KERNEL_IMAGE_SIZE) | ||
| 56 | return false; | ||
| 57 | x += phys_base; | ||
| 58 | } else { | ||
| 59 | if (x < PAGE_OFFSET) | ||
| 60 | return false; | ||
| 61 | x -= PAGE_OFFSET; | ||
| 62 | if (!phys_addr_valid(x)) | ||
| 63 | return false; | ||
| 64 | } | ||
| 65 | |||
| 66 | return pfn_valid(x >> PAGE_SHIFT); | ||
| 67 | } | ||
| 68 | EXPORT_SYMBOL(__virt_addr_valid); | ||
| 69 | |||
| 70 | #else | ||
| 71 | |||
| 72 | #ifdef CONFIG_DEBUG_VIRTUAL | ||
| 73 | unsigned long __phys_addr(unsigned long x) | ||
| 74 | { | ||
| 75 | /* VMALLOC_* aren't constants */ | ||
| 76 | VIRTUAL_BUG_ON(x < PAGE_OFFSET); | ||
| 77 | VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x)); | ||
| 78 | return x - PAGE_OFFSET; | ||
| 79 | } | ||
| 80 | EXPORT_SYMBOL(__phys_addr); | ||
| 81 | #endif | ||
| 82 | |||
| 83 | bool __virt_addr_valid(unsigned long x) | ||
| 84 | { | ||
| 85 | if (x < PAGE_OFFSET) | ||
| 86 | return false; | ||
| 87 | if (__vmalloc_start_set && is_vmalloc_addr((void *) x)) | ||
| 88 | return false; | ||
| 89 | if (x >= FIXADDR_START) | ||
| 90 | return false; | ||
| 91 | return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT); | ||
| 92 | } | ||
| 93 | EXPORT_SYMBOL(__virt_addr_valid); | ||
| 94 | |||
| 95 | #endif | ||
| 96 | 26 | ||
| 97 | int page_is_ram(unsigned long pagenr) | 27 | int page_is_ram(unsigned long pagenr) |
| 98 | { | 28 | { |
diff --git a/arch/x86/mm/kmemcheck/kmemcheck.c b/arch/x86/mm/kmemcheck/kmemcheck.c index 2c55ed098654..528bf954eb74 100644 --- a/arch/x86/mm/kmemcheck/kmemcheck.c +++ b/arch/x86/mm/kmemcheck/kmemcheck.c | |||
| @@ -331,6 +331,20 @@ static void kmemcheck_read_strict(struct pt_regs *regs, | |||
| 331 | kmemcheck_shadow_set(shadow, size); | 331 | kmemcheck_shadow_set(shadow, size); |
| 332 | } | 332 | } |
| 333 | 333 | ||
| 334 | bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size) | ||
| 335 | { | ||
| 336 | enum kmemcheck_shadow status; | ||
| 337 | void *shadow; | ||
| 338 | |||
| 339 | shadow = kmemcheck_shadow_lookup(addr); | ||
| 340 | if (!shadow) | ||
| 341 | return true; | ||
| 342 | |||
| 343 | status = kmemcheck_shadow_test(shadow, size); | ||
| 344 | |||
| 345 | return status == KMEMCHECK_SHADOW_INITIALIZED; | ||
| 346 | } | ||
| 347 | |||
| 334 | /* Access may cross page boundary */ | 348 | /* Access may cross page boundary */ |
| 335 | static void kmemcheck_read(struct pt_regs *regs, | 349 | static void kmemcheck_read(struct pt_regs *regs, |
| 336 | unsigned long addr, unsigned int size) | 350 | unsigned long addr, unsigned int size) |
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index e6718bb28065..b2f7d3e59b86 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
| @@ -623,7 +623,8 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot, | |||
| 623 | return ret; | 623 | return ret; |
| 624 | 624 | ||
| 625 | if (flags != want_flags) { | 625 | if (flags != want_flags) { |
| 626 | if (strict_prot || !is_new_memtype_allowed(want_flags, flags)) { | 626 | if (strict_prot || |
| 627 | !is_new_memtype_allowed(paddr, size, want_flags, flags)) { | ||
| 627 | free_memtype(paddr, paddr + size); | 628 | free_memtype(paddr, paddr + size); |
| 628 | printk(KERN_ERR "%s:%d map pfn expected mapping type %s" | 629 | printk(KERN_ERR "%s:%d map pfn expected mapping type %s" |
| 629 | " for %Lx-%Lx, got %s\n", | 630 | " for %Lx-%Lx, got %s\n", |
| @@ -826,7 +827,7 @@ static int memtype_seq_show(struct seq_file *seq, void *v) | |||
| 826 | return 0; | 827 | return 0; |
| 827 | } | 828 | } |
| 828 | 829 | ||
| 829 | static struct seq_operations memtype_seq_ops = { | 830 | static const struct seq_operations memtype_seq_ops = { |
| 830 | .start = memtype_seq_start, | 831 | .start = memtype_seq_start, |
| 831 | .next = memtype_seq_next, | 832 | .next = memtype_seq_next, |
| 832 | .stop = memtype_seq_stop, | 833 | .stop = memtype_seq_stop, |
diff --git a/arch/x86/mm/physaddr.c b/arch/x86/mm/physaddr.c new file mode 100644 index 000000000000..d2e2735327b4 --- /dev/null +++ b/arch/x86/mm/physaddr.c | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | #include <linux/mmdebug.h> | ||
| 2 | #include <linux/module.h> | ||
| 3 | #include <linux/mm.h> | ||
| 4 | |||
| 5 | #include <asm/page.h> | ||
| 6 | |||
| 7 | #include "physaddr.h" | ||
| 8 | |||
| 9 | #ifdef CONFIG_X86_64 | ||
| 10 | |||
| 11 | unsigned long __phys_addr(unsigned long x) | ||
| 12 | { | ||
| 13 | if (x >= __START_KERNEL_map) { | ||
| 14 | x -= __START_KERNEL_map; | ||
| 15 | VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE); | ||
| 16 | x += phys_base; | ||
| 17 | } else { | ||
| 18 | VIRTUAL_BUG_ON(x < PAGE_OFFSET); | ||
| 19 | x -= PAGE_OFFSET; | ||
| 20 | VIRTUAL_BUG_ON(!phys_addr_valid(x)); | ||
| 21 | } | ||
| 22 | return x; | ||
| 23 | } | ||
| 24 | EXPORT_SYMBOL(__phys_addr); | ||
| 25 | |||
| 26 | bool __virt_addr_valid(unsigned long x) | ||
| 27 | { | ||
| 28 | if (x >= __START_KERNEL_map) { | ||
| 29 | x -= __START_KERNEL_map; | ||
| 30 | if (x >= KERNEL_IMAGE_SIZE) | ||
| 31 | return false; | ||
| 32 | x += phys_base; | ||
| 33 | } else { | ||
| 34 | if (x < PAGE_OFFSET) | ||
| 35 | return false; | ||
| 36 | x -= PAGE_OFFSET; | ||
| 37 | if (!phys_addr_valid(x)) | ||
| 38 | return false; | ||
| 39 | } | ||
| 40 | |||
| 41 | return pfn_valid(x >> PAGE_SHIFT); | ||
| 42 | } | ||
| 43 | EXPORT_SYMBOL(__virt_addr_valid); | ||
| 44 | |||
| 45 | #else | ||
| 46 | |||
| 47 | #ifdef CONFIG_DEBUG_VIRTUAL | ||
| 48 | unsigned long __phys_addr(unsigned long x) | ||
| 49 | { | ||
| 50 | /* VMALLOC_* aren't constants */ | ||
| 51 | VIRTUAL_BUG_ON(x < PAGE_OFFSET); | ||
| 52 | VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x)); | ||
| 53 | return x - PAGE_OFFSET; | ||
| 54 | } | ||
| 55 | EXPORT_SYMBOL(__phys_addr); | ||
| 56 | #endif | ||
| 57 | |||
| 58 | bool __virt_addr_valid(unsigned long x) | ||
| 59 | { | ||
| 60 | if (x < PAGE_OFFSET) | ||
| 61 | return false; | ||
| 62 | if (__vmalloc_start_set && is_vmalloc_addr((void *) x)) | ||
| 63 | return false; | ||
| 64 | if (x >= FIXADDR_START) | ||
| 65 | return false; | ||
| 66 | return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT); | ||
| 67 | } | ||
| 68 | EXPORT_SYMBOL(__virt_addr_valid); | ||
| 69 | |||
| 70 | #endif /* CONFIG_X86_64 */ | ||
diff --git a/arch/x86/mm/physaddr.h b/arch/x86/mm/physaddr.h new file mode 100644 index 000000000000..a3cd5a0c97b3 --- /dev/null +++ b/arch/x86/mm/physaddr.h | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | #include <asm/processor.h> | ||
| 2 | |||
| 3 | static inline int phys_addr_valid(resource_size_t addr) | ||
| 4 | { | ||
| 5 | #ifdef CONFIG_PHYS_ADDR_T_64BIT | ||
| 6 | return !(addr >> boot_cpu_data.x86_phys_bits); | ||
| 7 | #else | ||
| 8 | return 1; | ||
| 9 | #endif | ||
| 10 | } | ||
diff --git a/arch/x86/mm/srat_32.c b/arch/x86/mm/srat_32.c index 29a0e37114f8..6f8aa33031c7 100644 --- a/arch/x86/mm/srat_32.c +++ b/arch/x86/mm/srat_32.c | |||
| @@ -215,7 +215,7 @@ int __init get_memcfg_from_srat(void) | |||
| 215 | goto out_fail; | 215 | goto out_fail; |
| 216 | 216 | ||
| 217 | if (num_memory_chunks == 0) { | 217 | if (num_memory_chunks == 0) { |
| 218 | printk(KERN_WARNING | 218 | printk(KERN_DEBUG |
| 219 | "could not find any ACPI SRAT memory areas.\n"); | 219 | "could not find any ACPI SRAT memory areas.\n"); |
| 220 | goto out_fail; | 220 | goto out_fail; |
| 221 | } | 221 | } |
| @@ -277,7 +277,7 @@ int __init get_memcfg_from_srat(void) | |||
| 277 | } | 277 | } |
| 278 | return 1; | 278 | return 1; |
| 279 | out_fail: | 279 | out_fail: |
| 280 | printk(KERN_ERR "failed to get NUMA memory information from SRAT" | 280 | printk(KERN_DEBUG "failed to get NUMA memory information from SRAT" |
| 281 | " table\n"); | 281 | " table\n"); |
| 282 | return 0; | 282 | return 0; |
| 283 | } | 283 | } |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 89b9a5cd63da..cb88b1a0bd5f 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
| @@ -1,11 +1,14 @@ | |||
| 1 | /** | 1 | /** |
| 2 | * @file nmi_int.c | 2 | * @file nmi_int.c |
| 3 | * | 3 | * |
| 4 | * @remark Copyright 2002-2008 OProfile authors | 4 | * @remark Copyright 2002-2009 OProfile authors |
| 5 | * @remark Read the file COPYING | 5 | * @remark Read the file COPYING |
| 6 | * | 6 | * |
| 7 | * @author John Levon <levon@movementarian.org> | 7 | * @author John Levon <levon@movementarian.org> |
| 8 | * @author Robert Richter <robert.richter@amd.com> | 8 | * @author Robert Richter <robert.richter@amd.com> |
| 9 | * @author Barry Kasindorf <barry.kasindorf@amd.com> | ||
| 10 | * @author Jason Yeh <jason.yeh@amd.com> | ||
| 11 | * @author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> | ||
| 9 | */ | 12 | */ |
| 10 | 13 | ||
| 11 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| @@ -24,13 +27,35 @@ | |||
| 24 | #include "op_counter.h" | 27 | #include "op_counter.h" |
| 25 | #include "op_x86_model.h" | 28 | #include "op_x86_model.h" |
| 26 | 29 | ||
| 27 | static struct op_x86_model_spec const *model; | 30 | static struct op_x86_model_spec *model; |
| 28 | static DEFINE_PER_CPU(struct op_msrs, cpu_msrs); | 31 | static DEFINE_PER_CPU(struct op_msrs, cpu_msrs); |
| 29 | static DEFINE_PER_CPU(unsigned long, saved_lvtpc); | 32 | static DEFINE_PER_CPU(unsigned long, saved_lvtpc); |
| 30 | 33 | ||
| 31 | /* 0 == registered but off, 1 == registered and on */ | 34 | /* 0 == registered but off, 1 == registered and on */ |
| 32 | static int nmi_enabled = 0; | 35 | static int nmi_enabled = 0; |
| 33 | 36 | ||
| 37 | struct op_counter_config counter_config[OP_MAX_COUNTER]; | ||
| 38 | |||
| 39 | /* common functions */ | ||
| 40 | |||
| 41 | u64 op_x86_get_ctrl(struct op_x86_model_spec const *model, | ||
| 42 | struct op_counter_config *counter_config) | ||
| 43 | { | ||
| 44 | u64 val = 0; | ||
| 45 | u16 event = (u16)counter_config->event; | ||
| 46 | |||
| 47 | val |= ARCH_PERFMON_EVENTSEL_INT; | ||
| 48 | val |= counter_config->user ? ARCH_PERFMON_EVENTSEL_USR : 0; | ||
| 49 | val |= counter_config->kernel ? ARCH_PERFMON_EVENTSEL_OS : 0; | ||
| 50 | val |= (counter_config->unit_mask & 0xFF) << 8; | ||
| 51 | event &= model->event_mask ? model->event_mask : 0xFF; | ||
| 52 | val |= event & 0xFF; | ||
| 53 | val |= (event & 0x0F00) << 24; | ||
| 54 | |||
| 55 | return val; | ||
| 56 | } | ||
| 57 | |||
| 58 | |||
| 34 | static int profile_exceptions_notify(struct notifier_block *self, | 59 | static int profile_exceptions_notify(struct notifier_block *self, |
| 35 | unsigned long val, void *data) | 60 | unsigned long val, void *data) |
| 36 | { | 61 | { |
| @@ -52,36 +77,214 @@ static int profile_exceptions_notify(struct notifier_block *self, | |||
| 52 | 77 | ||
| 53 | static void nmi_cpu_save_registers(struct op_msrs *msrs) | 78 | static void nmi_cpu_save_registers(struct op_msrs *msrs) |
| 54 | { | 79 | { |
| 55 | unsigned int const nr_ctrs = model->num_counters; | ||
| 56 | unsigned int const nr_ctrls = model->num_controls; | ||
| 57 | struct op_msr *counters = msrs->counters; | 80 | struct op_msr *counters = msrs->counters; |
| 58 | struct op_msr *controls = msrs->controls; | 81 | struct op_msr *controls = msrs->controls; |
| 59 | unsigned int i; | 82 | unsigned int i; |
| 60 | 83 | ||
| 61 | for (i = 0; i < nr_ctrs; ++i) { | 84 | for (i = 0; i < model->num_counters; ++i) { |
| 62 | if (counters[i].addr) { | 85 | if (counters[i].addr) |
| 63 | rdmsr(counters[i].addr, | 86 | rdmsrl(counters[i].addr, counters[i].saved); |
| 64 | counters[i].saved.low, | 87 | } |
| 65 | counters[i].saved.high); | 88 | |
| 66 | } | 89 | for (i = 0; i < model->num_controls; ++i) { |
| 90 | if (controls[i].addr) | ||
| 91 | rdmsrl(controls[i].addr, controls[i].saved); | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | static void nmi_cpu_start(void *dummy) | ||
| 96 | { | ||
| 97 | struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs); | ||
| 98 | model->start(msrs); | ||
| 99 | } | ||
| 100 | |||
| 101 | static int nmi_start(void) | ||
| 102 | { | ||
| 103 | on_each_cpu(nmi_cpu_start, NULL, 1); | ||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | static void nmi_cpu_stop(void *dummy) | ||
| 108 | { | ||
| 109 | struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs); | ||
| 110 | model->stop(msrs); | ||
| 111 | } | ||
| 112 | |||
| 113 | static void nmi_stop(void) | ||
| 114 | { | ||
| 115 | on_each_cpu(nmi_cpu_stop, NULL, 1); | ||
| 116 | } | ||
| 117 | |||
| 118 | #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX | ||
| 119 | |||
| 120 | static DEFINE_PER_CPU(int, switch_index); | ||
| 121 | |||
| 122 | static inline int has_mux(void) | ||
| 123 | { | ||
| 124 | return !!model->switch_ctrl; | ||
| 125 | } | ||
| 126 | |||
| 127 | inline int op_x86_phys_to_virt(int phys) | ||
| 128 | { | ||
| 129 | return __get_cpu_var(switch_index) + phys; | ||
| 130 | } | ||
| 131 | |||
| 132 | inline int op_x86_virt_to_phys(int virt) | ||
| 133 | { | ||
| 134 | return virt % model->num_counters; | ||
| 135 | } | ||
| 136 | |||
| 137 | static void nmi_shutdown_mux(void) | ||
| 138 | { | ||
| 139 | int i; | ||
| 140 | |||
| 141 | if (!has_mux()) | ||
| 142 | return; | ||
| 143 | |||
| 144 | for_each_possible_cpu(i) { | ||
| 145 | kfree(per_cpu(cpu_msrs, i).multiplex); | ||
| 146 | per_cpu(cpu_msrs, i).multiplex = NULL; | ||
| 147 | per_cpu(switch_index, i) = 0; | ||
| 67 | } | 148 | } |
| 149 | } | ||
| 150 | |||
| 151 | static int nmi_setup_mux(void) | ||
| 152 | { | ||
| 153 | size_t multiplex_size = | ||
| 154 | sizeof(struct op_msr) * model->num_virt_counters; | ||
| 155 | int i; | ||
| 156 | |||
| 157 | if (!has_mux()) | ||
| 158 | return 1; | ||
| 159 | |||
| 160 | for_each_possible_cpu(i) { | ||
| 161 | per_cpu(cpu_msrs, i).multiplex = | ||
| 162 | kmalloc(multiplex_size, GFP_KERNEL); | ||
| 163 | if (!per_cpu(cpu_msrs, i).multiplex) | ||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | return 1; | ||
| 168 | } | ||
| 169 | |||
| 170 | static void nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) | ||
| 171 | { | ||
| 172 | int i; | ||
| 173 | struct op_msr *multiplex = msrs->multiplex; | ||
| 174 | |||
| 175 | if (!has_mux()) | ||
| 176 | return; | ||
| 68 | 177 | ||
| 69 | for (i = 0; i < nr_ctrls; ++i) { | 178 | for (i = 0; i < model->num_virt_counters; ++i) { |
| 70 | if (controls[i].addr) { | 179 | if (counter_config[i].enabled) { |
| 71 | rdmsr(controls[i].addr, | 180 | multiplex[i].saved = -(u64)counter_config[i].count; |
| 72 | controls[i].saved.low, | 181 | } else { |
| 73 | controls[i].saved.high); | 182 | multiplex[i].addr = 0; |
| 183 | multiplex[i].saved = 0; | ||
| 74 | } | 184 | } |
| 75 | } | 185 | } |
| 186 | |||
| 187 | per_cpu(switch_index, cpu) = 0; | ||
| 188 | } | ||
| 189 | |||
| 190 | static void nmi_cpu_save_mpx_registers(struct op_msrs *msrs) | ||
| 191 | { | ||
| 192 | struct op_msr *multiplex = msrs->multiplex; | ||
| 193 | int i; | ||
| 194 | |||
| 195 | for (i = 0; i < model->num_counters; ++i) { | ||
| 196 | int virt = op_x86_phys_to_virt(i); | ||
| 197 | if (multiplex[virt].addr) | ||
| 198 | rdmsrl(multiplex[virt].addr, multiplex[virt].saved); | ||
| 199 | } | ||
| 200 | } | ||
| 201 | |||
| 202 | static void nmi_cpu_restore_mpx_registers(struct op_msrs *msrs) | ||
| 203 | { | ||
| 204 | struct op_msr *multiplex = msrs->multiplex; | ||
| 205 | int i; | ||
| 206 | |||
| 207 | for (i = 0; i < model->num_counters; ++i) { | ||
| 208 | int virt = op_x86_phys_to_virt(i); | ||
| 209 | if (multiplex[virt].addr) | ||
| 210 | wrmsrl(multiplex[virt].addr, multiplex[virt].saved); | ||
| 211 | } | ||
| 76 | } | 212 | } |
| 77 | 213 | ||
| 78 | static void nmi_save_registers(void *dummy) | 214 | static void nmi_cpu_switch(void *dummy) |
| 79 | { | 215 | { |
| 80 | int cpu = smp_processor_id(); | 216 | int cpu = smp_processor_id(); |
| 217 | int si = per_cpu(switch_index, cpu); | ||
| 81 | struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); | 218 | struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); |
| 82 | nmi_cpu_save_registers(msrs); | 219 | |
| 220 | nmi_cpu_stop(NULL); | ||
| 221 | nmi_cpu_save_mpx_registers(msrs); | ||
| 222 | |||
| 223 | /* move to next set */ | ||
| 224 | si += model->num_counters; | ||
| 225 | if ((si > model->num_virt_counters) || (counter_config[si].count == 0)) | ||
| 226 | per_cpu(switch_index, cpu) = 0; | ||
| 227 | else | ||
| 228 | per_cpu(switch_index, cpu) = si; | ||
| 229 | |||
| 230 | model->switch_ctrl(model, msrs); | ||
| 231 | nmi_cpu_restore_mpx_registers(msrs); | ||
| 232 | |||
| 233 | nmi_cpu_start(NULL); | ||
| 234 | } | ||
| 235 | |||
| 236 | |||
| 237 | /* | ||
| 238 | * Quick check to see if multiplexing is necessary. | ||
| 239 | * The check should be sufficient since counters are used | ||
| 240 | * in ordre. | ||
| 241 | */ | ||
| 242 | static int nmi_multiplex_on(void) | ||
| 243 | { | ||
| 244 | return counter_config[model->num_counters].count ? 0 : -EINVAL; | ||
| 245 | } | ||
| 246 | |||
| 247 | static int nmi_switch_event(void) | ||
| 248 | { | ||
| 249 | if (!has_mux()) | ||
| 250 | return -ENOSYS; /* not implemented */ | ||
| 251 | if (nmi_multiplex_on() < 0) | ||
| 252 | return -EINVAL; /* not necessary */ | ||
| 253 | |||
| 254 | on_each_cpu(nmi_cpu_switch, NULL, 1); | ||
| 255 | |||
| 256 | return 0; | ||
| 257 | } | ||
| 258 | |||
| 259 | static inline void mux_init(struct oprofile_operations *ops) | ||
| 260 | { | ||
| 261 | if (has_mux()) | ||
| 262 | ops->switch_events = nmi_switch_event; | ||
| 263 | } | ||
| 264 | |||
| 265 | static void mux_clone(int cpu) | ||
| 266 | { | ||
| 267 | if (!has_mux()) | ||
| 268 | return; | ||
| 269 | |||
| 270 | memcpy(per_cpu(cpu_msrs, cpu).multiplex, | ||
| 271 | per_cpu(cpu_msrs, 0).multiplex, | ||
| 272 | sizeof(struct op_msr) * model->num_virt_counters); | ||
| 83 | } | 273 | } |
| 84 | 274 | ||
| 275 | #else | ||
| 276 | |||
| 277 | inline int op_x86_phys_to_virt(int phys) { return phys; } | ||
| 278 | inline int op_x86_virt_to_phys(int virt) { return virt; } | ||
| 279 | static inline void nmi_shutdown_mux(void) { } | ||
| 280 | static inline int nmi_setup_mux(void) { return 1; } | ||
| 281 | static inline void | ||
| 282 | nmi_cpu_setup_mux(int cpu, struct op_msrs const * const msrs) { } | ||
| 283 | static inline void mux_init(struct oprofile_operations *ops) { } | ||
| 284 | static void mux_clone(int cpu) { } | ||
| 285 | |||
| 286 | #endif | ||
| 287 | |||
| 85 | static void free_msrs(void) | 288 | static void free_msrs(void) |
| 86 | { | 289 | { |
| 87 | int i; | 290 | int i; |
| @@ -95,38 +298,32 @@ static void free_msrs(void) | |||
| 95 | 298 | ||
| 96 | static int allocate_msrs(void) | 299 | static int allocate_msrs(void) |
| 97 | { | 300 | { |
| 98 | int success = 1; | ||
| 99 | size_t controls_size = sizeof(struct op_msr) * model->num_controls; | 301 | size_t controls_size = sizeof(struct op_msr) * model->num_controls; |
| 100 | size_t counters_size = sizeof(struct op_msr) * model->num_counters; | 302 | size_t counters_size = sizeof(struct op_msr) * model->num_counters; |
| 101 | 303 | ||
| 102 | int i; | 304 | int i; |
| 103 | for_each_possible_cpu(i) { | 305 | for_each_possible_cpu(i) { |
| 104 | per_cpu(cpu_msrs, i).counters = kmalloc(counters_size, | 306 | per_cpu(cpu_msrs, i).counters = kmalloc(counters_size, |
| 105 | GFP_KERNEL); | 307 | GFP_KERNEL); |
| 106 | if (!per_cpu(cpu_msrs, i).counters) { | 308 | if (!per_cpu(cpu_msrs, i).counters) |
| 107 | success = 0; | 309 | return 0; |
| 108 | break; | ||
| 109 | } | ||
| 110 | per_cpu(cpu_msrs, i).controls = kmalloc(controls_size, | 310 | per_cpu(cpu_msrs, i).controls = kmalloc(controls_size, |
| 111 | GFP_KERNEL); | 311 | GFP_KERNEL); |
| 112 | if (!per_cpu(cpu_msrs, i).controls) { | 312 | if (!per_cpu(cpu_msrs, i).controls) |
| 113 | success = 0; | 313 | return 0; |
| 114 | break; | ||
| 115 | } | ||
| 116 | } | 314 | } |
| 117 | 315 | ||
| 118 | if (!success) | 316 | return 1; |
| 119 | free_msrs(); | ||
| 120 | |||
| 121 | return success; | ||
| 122 | } | 317 | } |
| 123 | 318 | ||
| 124 | static void nmi_cpu_setup(void *dummy) | 319 | static void nmi_cpu_setup(void *dummy) |
| 125 | { | 320 | { |
| 126 | int cpu = smp_processor_id(); | 321 | int cpu = smp_processor_id(); |
| 127 | struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); | 322 | struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); |
| 323 | nmi_cpu_save_registers(msrs); | ||
| 128 | spin_lock(&oprofilefs_lock); | 324 | spin_lock(&oprofilefs_lock); |
| 129 | model->setup_ctrs(msrs); | 325 | model->setup_ctrs(model, msrs); |
| 326 | nmi_cpu_setup_mux(cpu, msrs); | ||
| 130 | spin_unlock(&oprofilefs_lock); | 327 | spin_unlock(&oprofilefs_lock); |
| 131 | per_cpu(saved_lvtpc, cpu) = apic_read(APIC_LVTPC); | 328 | per_cpu(saved_lvtpc, cpu) = apic_read(APIC_LVTPC); |
| 132 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 329 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
| @@ -144,11 +341,15 @@ static int nmi_setup(void) | |||
| 144 | int cpu; | 341 | int cpu; |
| 145 | 342 | ||
| 146 | if (!allocate_msrs()) | 343 | if (!allocate_msrs()) |
| 147 | return -ENOMEM; | 344 | err = -ENOMEM; |
| 345 | else if (!nmi_setup_mux()) | ||
| 346 | err = -ENOMEM; | ||
| 347 | else | ||
| 348 | err = register_die_notifier(&profile_exceptions_nb); | ||
| 148 | 349 | ||
| 149 | err = register_die_notifier(&profile_exceptions_nb); | ||
| 150 | if (err) { | 350 | if (err) { |
| 151 | free_msrs(); | 351 | free_msrs(); |
| 352 | nmi_shutdown_mux(); | ||
| 152 | return err; | 353 | return err; |
| 153 | } | 354 | } |
| 154 | 355 | ||
| @@ -159,45 +360,38 @@ static int nmi_setup(void) | |||
| 159 | /* Assume saved/restored counters are the same on all CPUs */ | 360 | /* Assume saved/restored counters are the same on all CPUs */ |
| 160 | model->fill_in_addresses(&per_cpu(cpu_msrs, 0)); | 361 | model->fill_in_addresses(&per_cpu(cpu_msrs, 0)); |
| 161 | for_each_possible_cpu(cpu) { | 362 | for_each_possible_cpu(cpu) { |
| 162 | if (cpu != 0) { | 363 | if (!cpu) |
| 163 | memcpy(per_cpu(cpu_msrs, cpu).counters, | 364 | continue; |
| 164 | per_cpu(cpu_msrs, 0).counters, | 365 | |
| 165 | sizeof(struct op_msr) * model->num_counters); | 366 | memcpy(per_cpu(cpu_msrs, cpu).counters, |
| 166 | 367 | per_cpu(cpu_msrs, 0).counters, | |
| 167 | memcpy(per_cpu(cpu_msrs, cpu).controls, | 368 | sizeof(struct op_msr) * model->num_counters); |
| 168 | per_cpu(cpu_msrs, 0).controls, | 369 | |
| 169 | sizeof(struct op_msr) * model->num_controls); | 370 | memcpy(per_cpu(cpu_msrs, cpu).controls, |
| 170 | } | 371 | per_cpu(cpu_msrs, 0).controls, |
| 372 | sizeof(struct op_msr) * model->num_controls); | ||
| 171 | 373 | ||
| 374 | mux_clone(cpu); | ||
| 172 | } | 375 | } |
| 173 | on_each_cpu(nmi_save_registers, NULL, 1); | ||
| 174 | on_each_cpu(nmi_cpu_setup, NULL, 1); | 376 | on_each_cpu(nmi_cpu_setup, NULL, 1); |
| 175 | nmi_enabled = 1; | 377 | nmi_enabled = 1; |
| 176 | return 0; | 378 | return 0; |
| 177 | } | 379 | } |
| 178 | 380 | ||
| 179 | static void nmi_restore_registers(struct op_msrs *msrs) | 381 | static void nmi_cpu_restore_registers(struct op_msrs *msrs) |
| 180 | { | 382 | { |
| 181 | unsigned int const nr_ctrs = model->num_counters; | ||
| 182 | unsigned int const nr_ctrls = model->num_controls; | ||
| 183 | struct op_msr *counters = msrs->counters; | 383 | struct op_msr *counters = msrs->counters; |
| 184 | struct op_msr *controls = msrs->controls; | 384 | struct op_msr *controls = msrs->controls; |
| 185 | unsigned int i; | 385 | unsigned int i; |
| 186 | 386 | ||
| 187 | for (i = 0; i < nr_ctrls; ++i) { | 387 | for (i = 0; i < model->num_controls; ++i) { |
| 188 | if (controls[i].addr) { | 388 | if (controls[i].addr) |
| 189 | wrmsr(controls[i].addr, | 389 | wrmsrl(controls[i].addr, controls[i].saved); |
| 190 | controls[i].saved.low, | ||
| 191 | controls[i].saved.high); | ||
| 192 | } | ||
| 193 | } | 390 | } |
| 194 | 391 | ||
| 195 | for (i = 0; i < nr_ctrs; ++i) { | 392 | for (i = 0; i < model->num_counters; ++i) { |
| 196 | if (counters[i].addr) { | 393 | if (counters[i].addr) |
| 197 | wrmsr(counters[i].addr, | 394 | wrmsrl(counters[i].addr, counters[i].saved); |
| 198 | counters[i].saved.low, | ||
| 199 | counters[i].saved.high); | ||
| 200 | } | ||
| 201 | } | 395 | } |
| 202 | } | 396 | } |
| 203 | 397 | ||
| @@ -205,7 +399,7 @@ static void nmi_cpu_shutdown(void *dummy) | |||
| 205 | { | 399 | { |
| 206 | unsigned int v; | 400 | unsigned int v; |
| 207 | int cpu = smp_processor_id(); | 401 | int cpu = smp_processor_id(); |
| 208 | struct op_msrs *msrs = &__get_cpu_var(cpu_msrs); | 402 | struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); |
| 209 | 403 | ||
| 210 | /* restoring APIC_LVTPC can trigger an apic error because the delivery | 404 | /* restoring APIC_LVTPC can trigger an apic error because the delivery |
| 211 | * mode and vector nr combination can be illegal. That's by design: on | 405 | * mode and vector nr combination can be illegal. That's by design: on |
| @@ -216,7 +410,7 @@ static void nmi_cpu_shutdown(void *dummy) | |||
| 216 | apic_write(APIC_LVTERR, v | APIC_LVT_MASKED); | 410 | apic_write(APIC_LVTERR, v | APIC_LVT_MASKED); |
| 217 | apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu)); | 411 | apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu)); |
| 218 | apic_write(APIC_LVTERR, v); | 412 | apic_write(APIC_LVTERR, v); |
| 219 | nmi_restore_registers(msrs); | 413 | nmi_cpu_restore_registers(msrs); |
| 220 | } | 414 | } |
| 221 | 415 | ||
| 222 | static void nmi_shutdown(void) | 416 | static void nmi_shutdown(void) |
| @@ -226,42 +420,18 @@ static void nmi_shutdown(void) | |||
| 226 | nmi_enabled = 0; | 420 | nmi_enabled = 0; |
| 227 | on_each_cpu(nmi_cpu_shutdown, NULL, 1); | 421 | on_each_cpu(nmi_cpu_shutdown, NULL, 1); |
| 228 | unregister_die_notifier(&profile_exceptions_nb); | 422 | unregister_die_notifier(&profile_exceptions_nb); |
| 423 | nmi_shutdown_mux(); | ||
| 229 | msrs = &get_cpu_var(cpu_msrs); | 424 | msrs = &get_cpu_var(cpu_msrs); |
| 230 | model->shutdown(msrs); | 425 | model->shutdown(msrs); |
| 231 | free_msrs(); | 426 | free_msrs(); |
| 232 | put_cpu_var(cpu_msrs); | 427 | put_cpu_var(cpu_msrs); |
| 233 | } | 428 | } |
| 234 | 429 | ||
| 235 | static void nmi_cpu_start(void *dummy) | ||
| 236 | { | ||
| 237 | struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs); | ||
| 238 | model->start(msrs); | ||
| 239 | } | ||
| 240 | |||
| 241 | static int nmi_start(void) | ||
| 242 | { | ||
| 243 | on_each_cpu(nmi_cpu_start, NULL, 1); | ||
| 244 | return 0; | ||
| 245 | } | ||
| 246 | |||
| 247 | static void nmi_cpu_stop(void *dummy) | ||
| 248 | { | ||
| 249 | struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs); | ||
| 250 | model->stop(msrs); | ||
| 251 | } | ||
| 252 | |||
| 253 | static void nmi_stop(void) | ||
| 254 | { | ||
| 255 | on_each_cpu(nmi_cpu_stop, NULL, 1); | ||
| 256 | } | ||
| 257 | |||
| 258 | struct op_counter_config counter_config[OP_MAX_COUNTER]; | ||
| 259 | |||
| 260 | static int nmi_create_files(struct super_block *sb, struct dentry *root) | 430 | static int nmi_create_files(struct super_block *sb, struct dentry *root) |
| 261 | { | 431 | { |
| 262 | unsigned int i; | 432 | unsigned int i; |
| 263 | 433 | ||
| 264 | for (i = 0; i < model->num_counters; ++i) { | 434 | for (i = 0; i < model->num_virt_counters; ++i) { |
| 265 | struct dentry *dir; | 435 | struct dentry *dir; |
| 266 | char buf[4]; | 436 | char buf[4]; |
| 267 | 437 | ||
| @@ -270,7 +440,7 @@ static int nmi_create_files(struct super_block *sb, struct dentry *root) | |||
| 270 | * NOTE: assumes 1:1 mapping here (that counters are organized | 440 | * NOTE: assumes 1:1 mapping here (that counters are organized |
| 271 | * sequentially in their struct assignment). | 441 | * sequentially in their struct assignment). |
| 272 | */ | 442 | */ |
| 273 | if (unlikely(!avail_to_resrv_perfctr_nmi_bit(i))) | 443 | if (!avail_to_resrv_perfctr_nmi_bit(op_x86_virt_to_phys(i))) |
| 274 | continue; | 444 | continue; |
| 275 | 445 | ||
| 276 | snprintf(buf, sizeof(buf), "%d", i); | 446 | snprintf(buf, sizeof(buf), "%d", i); |
| @@ -402,6 +572,7 @@ module_param_call(cpu_type, force_cpu_type, NULL, NULL, 0); | |||
| 402 | static int __init ppro_init(char **cpu_type) | 572 | static int __init ppro_init(char **cpu_type) |
| 403 | { | 573 | { |
| 404 | __u8 cpu_model = boot_cpu_data.x86_model; | 574 | __u8 cpu_model = boot_cpu_data.x86_model; |
| 575 | struct op_x86_model_spec *spec = &op_ppro_spec; /* default */ | ||
| 405 | 576 | ||
| 406 | if (force_arch_perfmon && cpu_has_arch_perfmon) | 577 | if (force_arch_perfmon && cpu_has_arch_perfmon) |
| 407 | return 0; | 578 | return 0; |
| @@ -428,7 +599,7 @@ static int __init ppro_init(char **cpu_type) | |||
| 428 | *cpu_type = "i386/core_2"; | 599 | *cpu_type = "i386/core_2"; |
| 429 | break; | 600 | break; |
| 430 | case 26: | 601 | case 26: |
| 431 | arch_perfmon_setup_counters(); | 602 | spec = &op_arch_perfmon_spec; |
| 432 | *cpu_type = "i386/core_i7"; | 603 | *cpu_type = "i386/core_i7"; |
| 433 | break; | 604 | break; |
| 434 | case 28: | 605 | case 28: |
| @@ -439,17 +610,7 @@ static int __init ppro_init(char **cpu_type) | |||
| 439 | return 0; | 610 | return 0; |
| 440 | } | 611 | } |
| 441 | 612 | ||
| 442 | model = &op_ppro_spec; | 613 | model = spec; |
| 443 | return 1; | ||
| 444 | } | ||
| 445 | |||
| 446 | static int __init arch_perfmon_init(char **cpu_type) | ||
| 447 | { | ||
| 448 | if (!cpu_has_arch_perfmon) | ||
| 449 | return 0; | ||
| 450 | *cpu_type = "i386/arch_perfmon"; | ||
| 451 | model = &op_arch_perfmon_spec; | ||
| 452 | arch_perfmon_setup_counters(); | ||
| 453 | return 1; | 614 | return 1; |
| 454 | } | 615 | } |
| 455 | 616 | ||
| @@ -471,27 +632,26 @@ int __init op_nmi_init(struct oprofile_operations *ops) | |||
| 471 | /* Needs to be at least an Athlon (or hammer in 32bit mode) */ | 632 | /* Needs to be at least an Athlon (or hammer in 32bit mode) */ |
| 472 | 633 | ||
| 473 | switch (family) { | 634 | switch (family) { |
| 474 | default: | ||
| 475 | return -ENODEV; | ||
| 476 | case 6: | 635 | case 6: |
| 477 | model = &op_amd_spec; | ||
| 478 | cpu_type = "i386/athlon"; | 636 | cpu_type = "i386/athlon"; |
| 479 | break; | 637 | break; |
| 480 | case 0xf: | 638 | case 0xf: |
| 481 | model = &op_amd_spec; | 639 | /* |
| 482 | /* Actually it could be i386/hammer too, but give | 640 | * Actually it could be i386/hammer too, but |
| 483 | user space an consistent name. */ | 641 | * give user space an consistent name. |
| 642 | */ | ||
| 484 | cpu_type = "x86-64/hammer"; | 643 | cpu_type = "x86-64/hammer"; |
| 485 | break; | 644 | break; |
| 486 | case 0x10: | 645 | case 0x10: |
| 487 | model = &op_amd_spec; | ||
| 488 | cpu_type = "x86-64/family10"; | 646 | cpu_type = "x86-64/family10"; |
| 489 | break; | 647 | break; |
| 490 | case 0x11: | 648 | case 0x11: |
| 491 | model = &op_amd_spec; | ||
| 492 | cpu_type = "x86-64/family11h"; | 649 | cpu_type = "x86-64/family11h"; |
| 493 | break; | 650 | break; |
| 651 | default: | ||
| 652 | return -ENODEV; | ||
| 494 | } | 653 | } |
| 654 | model = &op_amd_spec; | ||
| 495 | break; | 655 | break; |
| 496 | 656 | ||
| 497 | case X86_VENDOR_INTEL: | 657 | case X86_VENDOR_INTEL: |
| @@ -510,8 +670,15 @@ int __init op_nmi_init(struct oprofile_operations *ops) | |||
| 510 | break; | 670 | break; |
| 511 | } | 671 | } |
| 512 | 672 | ||
| 513 | if (!cpu_type && !arch_perfmon_init(&cpu_type)) | 673 | if (cpu_type) |
| 674 | break; | ||
| 675 | |||
| 676 | if (!cpu_has_arch_perfmon) | ||
| 514 | return -ENODEV; | 677 | return -ENODEV; |
| 678 | |||
| 679 | /* use arch perfmon as fallback */ | ||
| 680 | cpu_type = "i386/arch_perfmon"; | ||
| 681 | model = &op_arch_perfmon_spec; | ||
| 515 | break; | 682 | break; |
| 516 | 683 | ||
| 517 | default: | 684 | default: |
| @@ -522,18 +689,23 @@ int __init op_nmi_init(struct oprofile_operations *ops) | |||
| 522 | register_cpu_notifier(&oprofile_cpu_nb); | 689 | register_cpu_notifier(&oprofile_cpu_nb); |
| 523 | #endif | 690 | #endif |
| 524 | /* default values, can be overwritten by model */ | 691 | /* default values, can be overwritten by model */ |
| 525 | ops->create_files = nmi_create_files; | 692 | ops->create_files = nmi_create_files; |
| 526 | ops->setup = nmi_setup; | 693 | ops->setup = nmi_setup; |
| 527 | ops->shutdown = nmi_shutdown; | 694 | ops->shutdown = nmi_shutdown; |
| 528 | ops->start = nmi_start; | 695 | ops->start = nmi_start; |
| 529 | ops->stop = nmi_stop; | 696 | ops->stop = nmi_stop; |
| 530 | ops->cpu_type = cpu_type; | 697 | ops->cpu_type = cpu_type; |
| 531 | 698 | ||
| 532 | if (model->init) | 699 | if (model->init) |
| 533 | ret = model->init(ops); | 700 | ret = model->init(ops); |
| 534 | if (ret) | 701 | if (ret) |
| 535 | return ret; | 702 | return ret; |
| 536 | 703 | ||
| 704 | if (!model->num_virt_counters) | ||
| 705 | model->num_virt_counters = model->num_counters; | ||
| 706 | |||
| 707 | mux_init(ops); | ||
| 708 | |||
| 537 | init_sysfs(); | 709 | init_sysfs(); |
| 538 | using_nmi = 1; | 710 | using_nmi = 1; |
| 539 | printk(KERN_INFO "oprofile: using NMI interrupt.\n"); | 711 | printk(KERN_INFO "oprofile: using NMI interrupt.\n"); |
diff --git a/arch/x86/oprofile/op_counter.h b/arch/x86/oprofile/op_counter.h index 91b6a116165e..e28398df0df2 100644 --- a/arch/x86/oprofile/op_counter.h +++ b/arch/x86/oprofile/op_counter.h | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #ifndef OP_COUNTER_H | 10 | #ifndef OP_COUNTER_H |
| 11 | #define OP_COUNTER_H | 11 | #define OP_COUNTER_H |
| 12 | 12 | ||
| 13 | #define OP_MAX_COUNTER 8 | 13 | #define OP_MAX_COUNTER 32 |
| 14 | 14 | ||
| 15 | /* Per-perfctr configuration as set via | 15 | /* Per-perfctr configuration as set via |
| 16 | * oprofilefs. | 16 | * oprofilefs. |
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 8fdf06e4edf9..39686c29f03a 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c | |||
| @@ -9,12 +9,15 @@ | |||
| 9 | * @author Philippe Elie | 9 | * @author Philippe Elie |
| 10 | * @author Graydon Hoare | 10 | * @author Graydon Hoare |
| 11 | * @author Robert Richter <robert.richter@amd.com> | 11 | * @author Robert Richter <robert.richter@amd.com> |
| 12 | * @author Barry Kasindorf | 12 | * @author Barry Kasindorf <barry.kasindorf@amd.com> |
| 13 | * @author Jason Yeh <jason.yeh@amd.com> | ||
| 14 | * @author Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> | ||
| 13 | */ | 15 | */ |
| 14 | 16 | ||
| 15 | #include <linux/oprofile.h> | 17 | #include <linux/oprofile.h> |
| 16 | #include <linux/device.h> | 18 | #include <linux/device.h> |
| 17 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
| 20 | #include <linux/percpu.h> | ||
| 18 | 21 | ||
| 19 | #include <asm/ptrace.h> | 22 | #include <asm/ptrace.h> |
| 20 | #include <asm/msr.h> | 23 | #include <asm/msr.h> |
| @@ -25,43 +28,36 @@ | |||
| 25 | 28 | ||
| 26 | #define NUM_COUNTERS 4 | 29 | #define NUM_COUNTERS 4 |
| 27 | #define NUM_CONTROLS 4 | 30 | #define NUM_CONTROLS 4 |
| 31 | #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX | ||
| 32 | #define NUM_VIRT_COUNTERS 32 | ||
| 33 | #define NUM_VIRT_CONTROLS 32 | ||
| 34 | #else | ||
| 35 | #define NUM_VIRT_COUNTERS NUM_COUNTERS | ||
| 36 | #define NUM_VIRT_CONTROLS NUM_CONTROLS | ||
| 37 | #endif | ||
| 38 | |||
| 39 | #define OP_EVENT_MASK 0x0FFF | ||
| 40 | #define OP_CTR_OVERFLOW (1ULL<<31) | ||
| 28 | 41 | ||
| 29 | #define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0) | 42 | #define MSR_AMD_EVENTSEL_RESERVED ((0xFFFFFCF0ULL<<32)|(1ULL<<21)) |
| 30 | #define CTR_READ(l, h, msrs, c) do {rdmsr(msrs->counters[(c)].addr, (l), (h)); } while (0) | 43 | |
| 31 | #define CTR_WRITE(l, msrs, c) do {wrmsr(msrs->counters[(c)].addr, -(unsigned int)(l), -1); } while (0) | 44 | static unsigned long reset_value[NUM_VIRT_COUNTERS]; |
| 32 | #define CTR_OVERFLOWED(n) (!((n) & (1U<<31))) | ||
| 33 | |||
| 34 | #define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0) | ||
| 35 | #define CTRL_READ(l, h, msrs, c) do {rdmsr(msrs->controls[(c)].addr, (l), (h)); } while (0) | ||
| 36 | #define CTRL_WRITE(l, h, msrs, c) do {wrmsr(msrs->controls[(c)].addr, (l), (h)); } while (0) | ||
| 37 | #define CTRL_SET_ACTIVE(n) (n |= (1<<22)) | ||
| 38 | #define CTRL_SET_INACTIVE(n) (n &= ~(1<<22)) | ||
| 39 | #define CTRL_CLEAR_LO(x) (x &= (1<<21)) | ||
| 40 | #define CTRL_CLEAR_HI(x) (x &= 0xfffffcf0) | ||
| 41 | #define CTRL_SET_ENABLE(val) (val |= 1<<20) | ||
| 42 | #define CTRL_SET_USR(val, u) (val |= ((u & 1) << 16)) | ||
| 43 | #define CTRL_SET_KERN(val, k) (val |= ((k & 1) << 17)) | ||
| 44 | #define CTRL_SET_UM(val, m) (val |= (m << 8)) | ||
| 45 | #define CTRL_SET_EVENT_LOW(val, e) (val |= (e & 0xff)) | ||
| 46 | #define CTRL_SET_EVENT_HIGH(val, e) (val |= ((e >> 8) & 0xf)) | ||
| 47 | #define CTRL_SET_HOST_ONLY(val, h) (val |= ((h & 1) << 9)) | ||
| 48 | #define CTRL_SET_GUEST_ONLY(val, h) (val |= ((h & 1) << 8)) | ||
| 49 | |||
| 50 | static unsigned long reset_value[NUM_COUNTERS]; | ||
| 51 | 45 | ||
| 52 | #ifdef CONFIG_OPROFILE_IBS | 46 | #ifdef CONFIG_OPROFILE_IBS |
| 53 | 47 | ||
| 54 | /* IbsFetchCtl bits/masks */ | 48 | /* IbsFetchCtl bits/masks */ |
| 55 | #define IBS_FETCH_HIGH_VALID_BIT (1UL << 17) /* bit 49 */ | 49 | #define IBS_FETCH_RAND_EN (1ULL<<57) |
| 56 | #define IBS_FETCH_HIGH_ENABLE (1UL << 16) /* bit 48 */ | 50 | #define IBS_FETCH_VAL (1ULL<<49) |
| 57 | #define IBS_FETCH_LOW_MAX_CNT_MASK 0x0000FFFFUL /* MaxCnt mask */ | 51 | #define IBS_FETCH_ENABLE (1ULL<<48) |
| 52 | #define IBS_FETCH_CNT_MASK 0xFFFF0000ULL | ||
| 58 | 53 | ||
| 59 | /*IbsOpCtl bits */ | 54 | /*IbsOpCtl bits */ |
| 60 | #define IBS_OP_LOW_VALID_BIT (1ULL<<18) /* bit 18 */ | 55 | #define IBS_OP_CNT_CTL (1ULL<<19) |
| 61 | #define IBS_OP_LOW_ENABLE (1ULL<<17) /* bit 17 */ | 56 | #define IBS_OP_VAL (1ULL<<18) |
| 57 | #define IBS_OP_ENABLE (1ULL<<17) | ||
| 62 | 58 | ||
| 63 | #define IBS_FETCH_SIZE 6 | 59 | #define IBS_FETCH_SIZE 6 |
| 64 | #define IBS_OP_SIZE 12 | 60 | #define IBS_OP_SIZE 12 |
| 65 | 61 | ||
| 66 | static int has_ibs; /* AMD Family10h and later */ | 62 | static int has_ibs; /* AMD Family10h and later */ |
| 67 | 63 | ||
| @@ -78,6 +74,45 @@ static struct op_ibs_config ibs_config; | |||
| 78 | 74 | ||
| 79 | #endif | 75 | #endif |
| 80 | 76 | ||
| 77 | #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX | ||
| 78 | |||
| 79 | static void op_mux_fill_in_addresses(struct op_msrs * const msrs) | ||
| 80 | { | ||
| 81 | int i; | ||
| 82 | |||
| 83 | for (i = 0; i < NUM_VIRT_COUNTERS; i++) { | ||
| 84 | int hw_counter = op_x86_virt_to_phys(i); | ||
| 85 | if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) | ||
| 86 | msrs->multiplex[i].addr = MSR_K7_PERFCTR0 + hw_counter; | ||
| 87 | else | ||
| 88 | msrs->multiplex[i].addr = 0; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | static void op_mux_switch_ctrl(struct op_x86_model_spec const *model, | ||
| 93 | struct op_msrs const * const msrs) | ||
| 94 | { | ||
| 95 | u64 val; | ||
| 96 | int i; | ||
| 97 | |||
| 98 | /* enable active counters */ | ||
| 99 | for (i = 0; i < NUM_COUNTERS; ++i) { | ||
| 100 | int virt = op_x86_phys_to_virt(i); | ||
| 101 | if (!counter_config[virt].enabled) | ||
| 102 | continue; | ||
| 103 | rdmsrl(msrs->controls[i].addr, val); | ||
| 104 | val &= model->reserved; | ||
| 105 | val |= op_x86_get_ctrl(model, &counter_config[virt]); | ||
| 106 | wrmsrl(msrs->controls[i].addr, val); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | #else | ||
| 111 | |||
| 112 | static inline void op_mux_fill_in_addresses(struct op_msrs * const msrs) { } | ||
| 113 | |||
| 114 | #endif | ||
| 115 | |||
| 81 | /* functions for op_amd_spec */ | 116 | /* functions for op_amd_spec */ |
| 82 | 117 | ||
| 83 | static void op_amd_fill_in_addresses(struct op_msrs * const msrs) | 118 | static void op_amd_fill_in_addresses(struct op_msrs * const msrs) |
| @@ -97,150 +132,174 @@ static void op_amd_fill_in_addresses(struct op_msrs * const msrs) | |||
| 97 | else | 132 | else |
| 98 | msrs->controls[i].addr = 0; | 133 | msrs->controls[i].addr = 0; |
| 99 | } | 134 | } |
| 100 | } | ||
| 101 | 135 | ||
| 136 | op_mux_fill_in_addresses(msrs); | ||
| 137 | } | ||
| 102 | 138 | ||
| 103 | static void op_amd_setup_ctrs(struct op_msrs const * const msrs) | 139 | static void op_amd_setup_ctrs(struct op_x86_model_spec const *model, |
| 140 | struct op_msrs const * const msrs) | ||
| 104 | { | 141 | { |
| 105 | unsigned int low, high; | 142 | u64 val; |
| 106 | int i; | 143 | int i; |
| 107 | 144 | ||
| 145 | /* setup reset_value */ | ||
| 146 | for (i = 0; i < NUM_VIRT_COUNTERS; ++i) { | ||
| 147 | if (counter_config[i].enabled) | ||
| 148 | reset_value[i] = counter_config[i].count; | ||
| 149 | else | ||
| 150 | reset_value[i] = 0; | ||
| 151 | } | ||
| 152 | |||
| 108 | /* clear all counters */ | 153 | /* clear all counters */ |
| 109 | for (i = 0 ; i < NUM_CONTROLS; ++i) { | 154 | for (i = 0; i < NUM_CONTROLS; ++i) { |
| 110 | if (unlikely(!CTRL_IS_RESERVED(msrs, i))) | 155 | if (unlikely(!msrs->controls[i].addr)) |
| 111 | continue; | 156 | continue; |
| 112 | CTRL_READ(low, high, msrs, i); | 157 | rdmsrl(msrs->controls[i].addr, val); |
| 113 | CTRL_CLEAR_LO(low); | 158 | val &= model->reserved; |
| 114 | CTRL_CLEAR_HI(high); | 159 | wrmsrl(msrs->controls[i].addr, val); |
| 115 | CTRL_WRITE(low, high, msrs, i); | ||
| 116 | } | 160 | } |
| 117 | 161 | ||
| 118 | /* avoid a false detection of ctr overflows in NMI handler */ | 162 | /* avoid a false detection of ctr overflows in NMI handler */ |
| 119 | for (i = 0; i < NUM_COUNTERS; ++i) { | 163 | for (i = 0; i < NUM_COUNTERS; ++i) { |
| 120 | if (unlikely(!CTR_IS_RESERVED(msrs, i))) | 164 | if (unlikely(!msrs->counters[i].addr)) |
| 121 | continue; | 165 | continue; |
| 122 | CTR_WRITE(1, msrs, i); | 166 | wrmsrl(msrs->counters[i].addr, -1LL); |
| 123 | } | 167 | } |
| 124 | 168 | ||
| 125 | /* enable active counters */ | 169 | /* enable active counters */ |
| 126 | for (i = 0; i < NUM_COUNTERS; ++i) { | 170 | for (i = 0; i < NUM_COUNTERS; ++i) { |
| 127 | if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs, i))) { | 171 | int virt = op_x86_phys_to_virt(i); |
| 128 | reset_value[i] = counter_config[i].count; | 172 | if (!counter_config[virt].enabled) |
| 173 | continue; | ||
| 174 | if (!msrs->counters[i].addr) | ||
| 175 | continue; | ||
| 129 | 176 | ||
| 130 | CTR_WRITE(counter_config[i].count, msrs, i); | 177 | /* setup counter registers */ |
| 131 | 178 | wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]); | |
| 132 | CTRL_READ(low, high, msrs, i); | 179 | |
| 133 | CTRL_CLEAR_LO(low); | 180 | /* setup control registers */ |
| 134 | CTRL_CLEAR_HI(high); | 181 | rdmsrl(msrs->controls[i].addr, val); |
| 135 | CTRL_SET_ENABLE(low); | 182 | val &= model->reserved; |
| 136 | CTRL_SET_USR(low, counter_config[i].user); | 183 | val |= op_x86_get_ctrl(model, &counter_config[virt]); |
| 137 | CTRL_SET_KERN(low, counter_config[i].kernel); | 184 | wrmsrl(msrs->controls[i].addr, val); |
| 138 | CTRL_SET_UM(low, counter_config[i].unit_mask); | ||
| 139 | CTRL_SET_EVENT_LOW(low, counter_config[i].event); | ||
| 140 | CTRL_SET_EVENT_HIGH(high, counter_config[i].event); | ||
| 141 | CTRL_SET_HOST_ONLY(high, 0); | ||
| 142 | CTRL_SET_GUEST_ONLY(high, 0); | ||
| 143 | |||
| 144 | CTRL_WRITE(low, high, msrs, i); | ||
| 145 | } else { | ||
| 146 | reset_value[i] = 0; | ||
| 147 | } | ||
| 148 | } | 185 | } |
| 149 | } | 186 | } |
| 150 | 187 | ||
| 151 | #ifdef CONFIG_OPROFILE_IBS | 188 | #ifdef CONFIG_OPROFILE_IBS |
| 152 | 189 | ||
| 153 | static inline int | 190 | static inline void |
| 154 | op_amd_handle_ibs(struct pt_regs * const regs, | 191 | op_amd_handle_ibs(struct pt_regs * const regs, |
| 155 | struct op_msrs const * const msrs) | 192 | struct op_msrs const * const msrs) |
| 156 | { | 193 | { |
| 157 | u32 low, high; | 194 | u64 val, ctl; |
| 158 | u64 msr; | ||
| 159 | struct op_entry entry; | 195 | struct op_entry entry; |
| 160 | 196 | ||
| 161 | if (!has_ibs) | 197 | if (!has_ibs) |
| 162 | return 1; | 198 | return; |
| 163 | 199 | ||
| 164 | if (ibs_config.fetch_enabled) { | 200 | if (ibs_config.fetch_enabled) { |
| 165 | rdmsr(MSR_AMD64_IBSFETCHCTL, low, high); | 201 | rdmsrl(MSR_AMD64_IBSFETCHCTL, ctl); |
| 166 | if (high & IBS_FETCH_HIGH_VALID_BIT) { | 202 | if (ctl & IBS_FETCH_VAL) { |
| 167 | rdmsrl(MSR_AMD64_IBSFETCHLINAD, msr); | 203 | rdmsrl(MSR_AMD64_IBSFETCHLINAD, val); |
| 168 | oprofile_write_reserve(&entry, regs, msr, | 204 | oprofile_write_reserve(&entry, regs, val, |
| 169 | IBS_FETCH_CODE, IBS_FETCH_SIZE); | 205 | IBS_FETCH_CODE, IBS_FETCH_SIZE); |
| 170 | oprofile_add_data(&entry, (u32)msr); | 206 | oprofile_add_data64(&entry, val); |
| 171 | oprofile_add_data(&entry, (u32)(msr >> 32)); | 207 | oprofile_add_data64(&entry, ctl); |
| 172 | oprofile_add_data(&entry, low); | 208 | rdmsrl(MSR_AMD64_IBSFETCHPHYSAD, val); |
| 173 | oprofile_add_data(&entry, high); | 209 | oprofile_add_data64(&entry, val); |
| 174 | rdmsrl(MSR_AMD64_IBSFETCHPHYSAD, msr); | ||
| 175 | oprofile_add_data(&entry, (u32)msr); | ||
| 176 | oprofile_add_data(&entry, (u32)(msr >> 32)); | ||
| 177 | oprofile_write_commit(&entry); | 210 | oprofile_write_commit(&entry); |
| 178 | 211 | ||
| 179 | /* reenable the IRQ */ | 212 | /* reenable the IRQ */ |
| 180 | high &= ~IBS_FETCH_HIGH_VALID_BIT; | 213 | ctl &= ~(IBS_FETCH_VAL | IBS_FETCH_CNT_MASK); |
| 181 | high |= IBS_FETCH_HIGH_ENABLE; | 214 | ctl |= IBS_FETCH_ENABLE; |
| 182 | low &= IBS_FETCH_LOW_MAX_CNT_MASK; | 215 | wrmsrl(MSR_AMD64_IBSFETCHCTL, ctl); |
| 183 | wrmsr(MSR_AMD64_IBSFETCHCTL, low, high); | ||
| 184 | } | 216 | } |
| 185 | } | 217 | } |
| 186 | 218 | ||
| 187 | if (ibs_config.op_enabled) { | 219 | if (ibs_config.op_enabled) { |
| 188 | rdmsr(MSR_AMD64_IBSOPCTL, low, high); | 220 | rdmsrl(MSR_AMD64_IBSOPCTL, ctl); |
| 189 | if (low & IBS_OP_LOW_VALID_BIT) { | 221 | if (ctl & IBS_OP_VAL) { |
| 190 | rdmsrl(MSR_AMD64_IBSOPRIP, msr); | 222 | rdmsrl(MSR_AMD64_IBSOPRIP, val); |
| 191 | oprofile_write_reserve(&entry, regs, msr, | 223 | oprofile_write_reserve(&entry, regs, val, |
| 192 | IBS_OP_CODE, IBS_OP_SIZE); | 224 | IBS_OP_CODE, IBS_OP_SIZE); |
| 193 | oprofile_add_data(&entry, (u32)msr); | 225 | oprofile_add_data64(&entry, val); |
| 194 | oprofile_add_data(&entry, (u32)(msr >> 32)); | 226 | rdmsrl(MSR_AMD64_IBSOPDATA, val); |
| 195 | rdmsrl(MSR_AMD64_IBSOPDATA, msr); | 227 | oprofile_add_data64(&entry, val); |
| 196 | oprofile_add_data(&entry, (u32)msr); | 228 | rdmsrl(MSR_AMD64_IBSOPDATA2, val); |
| 197 | oprofile_add_data(&entry, (u32)(msr >> 32)); | 229 | oprofile_add_data64(&entry, val); |
| 198 | rdmsrl(MSR_AMD64_IBSOPDATA2, msr); | 230 | rdmsrl(MSR_AMD64_IBSOPDATA3, val); |
| 199 | oprofile_add_data(&entry, (u32)msr); | 231 | oprofile_add_data64(&entry, val); |
| 200 | oprofile_add_data(&entry, (u32)(msr >> 32)); | 232 | rdmsrl(MSR_AMD64_IBSDCLINAD, val); |
| 201 | rdmsrl(MSR_AMD64_IBSOPDATA3, msr); | 233 | oprofile_add_data64(&entry, val); |
| 202 | oprofile_add_data(&entry, (u32)msr); | 234 | rdmsrl(MSR_AMD64_IBSDCPHYSAD, val); |
| 203 | oprofile_add_data(&entry, (u32)(msr >> 32)); | 235 | oprofile_add_data64(&entry, val); |
| 204 | rdmsrl(MSR_AMD64_IBSDCLINAD, msr); | ||
| 205 | oprofile_add_data(&entry, (u32)msr); | ||
| 206 | oprofile_add_data(&entry, (u32)(msr >> 32)); | ||
| 207 | rdmsrl(MSR_AMD64_IBSDCPHYSAD, msr); | ||
| 208 | oprofile_add_data(&entry, (u32)msr); | ||
| 209 | oprofile_add_data(&entry, (u32)(msr >> 32)); | ||
| 210 | oprofile_write_commit(&entry); | 236 | oprofile_write_commit(&entry); |
| 211 | 237 | ||
| 212 | /* reenable the IRQ */ | 238 | /* reenable the IRQ */ |
| 213 | high = 0; | 239 | ctl &= ~IBS_OP_VAL & 0xFFFFFFFF; |
| 214 | low &= ~IBS_OP_LOW_VALID_BIT; | 240 | ctl |= IBS_OP_ENABLE; |
| 215 | low |= IBS_OP_LOW_ENABLE; | 241 | wrmsrl(MSR_AMD64_IBSOPCTL, ctl); |
| 216 | wrmsr(MSR_AMD64_IBSOPCTL, low, high); | ||
| 217 | } | 242 | } |
| 218 | } | 243 | } |
| 244 | } | ||
| 219 | 245 | ||
| 220 | return 1; | 246 | static inline void op_amd_start_ibs(void) |
| 247 | { | ||
| 248 | u64 val; | ||
| 249 | if (has_ibs && ibs_config.fetch_enabled) { | ||
| 250 | val = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF; | ||
| 251 | val |= ibs_config.rand_en ? IBS_FETCH_RAND_EN : 0; | ||
| 252 | val |= IBS_FETCH_ENABLE; | ||
| 253 | wrmsrl(MSR_AMD64_IBSFETCHCTL, val); | ||
| 254 | } | ||
| 255 | |||
| 256 | if (has_ibs && ibs_config.op_enabled) { | ||
| 257 | val = (ibs_config.max_cnt_op >> 4) & 0xFFFF; | ||
| 258 | val |= ibs_config.dispatched_ops ? IBS_OP_CNT_CTL : 0; | ||
| 259 | val |= IBS_OP_ENABLE; | ||
| 260 | wrmsrl(MSR_AMD64_IBSOPCTL, val); | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | static void op_amd_stop_ibs(void) | ||
| 265 | { | ||
| 266 | if (has_ibs && ibs_config.fetch_enabled) | ||
| 267 | /* clear max count and enable */ | ||
| 268 | wrmsrl(MSR_AMD64_IBSFETCHCTL, 0); | ||
| 269 | |||
| 270 | if (has_ibs && ibs_config.op_enabled) | ||
| 271 | /* clear max count and enable */ | ||
| 272 | wrmsrl(MSR_AMD64_IBSOPCTL, 0); | ||
| 221 | } | 273 | } |
| 222 | 274 | ||
| 275 | #else | ||
| 276 | |||
| 277 | static inline void op_amd_handle_ibs(struct pt_regs * const regs, | ||
| 278 | struct op_msrs const * const msrs) { } | ||
| 279 | static inline void op_amd_start_ibs(void) { } | ||
| 280 | static inline void op_amd_stop_ibs(void) { } | ||
| 281 | |||
| 223 | #endif | 282 | #endif |
| 224 | 283 | ||
| 225 | static int op_amd_check_ctrs(struct pt_regs * const regs, | 284 | static int op_amd_check_ctrs(struct pt_regs * const regs, |
| 226 | struct op_msrs const * const msrs) | 285 | struct op_msrs const * const msrs) |
| 227 | { | 286 | { |
| 228 | unsigned int low, high; | 287 | u64 val; |
| 229 | int i; | 288 | int i; |
| 230 | 289 | ||
| 231 | for (i = 0 ; i < NUM_COUNTERS; ++i) { | 290 | for (i = 0; i < NUM_COUNTERS; ++i) { |
| 232 | if (!reset_value[i]) | 291 | int virt = op_x86_phys_to_virt(i); |
| 292 | if (!reset_value[virt]) | ||
| 233 | continue; | 293 | continue; |
| 234 | CTR_READ(low, high, msrs, i); | 294 | rdmsrl(msrs->counters[i].addr, val); |
| 235 | if (CTR_OVERFLOWED(low)) { | 295 | /* bit is clear if overflowed: */ |
| 236 | oprofile_add_sample(regs, i); | 296 | if (val & OP_CTR_OVERFLOW) |
| 237 | CTR_WRITE(reset_value[i], msrs, i); | 297 | continue; |
| 238 | } | 298 | oprofile_add_sample(regs, virt); |
| 299 | wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]); | ||
| 239 | } | 300 | } |
| 240 | 301 | ||
| 241 | #ifdef CONFIG_OPROFILE_IBS | ||
| 242 | op_amd_handle_ibs(regs, msrs); | 302 | op_amd_handle_ibs(regs, msrs); |
| 243 | #endif | ||
| 244 | 303 | ||
| 245 | /* See op_model_ppro.c */ | 304 | /* See op_model_ppro.c */ |
| 246 | return 1; | 305 | return 1; |
| @@ -248,79 +307,50 @@ static int op_amd_check_ctrs(struct pt_regs * const regs, | |||
| 248 | 307 | ||
| 249 | static void op_amd_start(struct op_msrs const * const msrs) | 308 | static void op_amd_start(struct op_msrs const * const msrs) |
| 250 | { | 309 | { |
| 251 | unsigned int low, high; | 310 | u64 val; |
| 252 | int i; | 311 | int i; |
| 253 | for (i = 0 ; i < NUM_COUNTERS ; ++i) { | ||
| 254 | if (reset_value[i]) { | ||
| 255 | CTRL_READ(low, high, msrs, i); | ||
| 256 | CTRL_SET_ACTIVE(low); | ||
| 257 | CTRL_WRITE(low, high, msrs, i); | ||
| 258 | } | ||
| 259 | } | ||
| 260 | 312 | ||
| 261 | #ifdef CONFIG_OPROFILE_IBS | 313 | for (i = 0; i < NUM_COUNTERS; ++i) { |
| 262 | if (has_ibs && ibs_config.fetch_enabled) { | 314 | if (!reset_value[op_x86_phys_to_virt(i)]) |
| 263 | low = (ibs_config.max_cnt_fetch >> 4) & 0xFFFF; | 315 | continue; |
| 264 | high = ((ibs_config.rand_en & 0x1) << 25) /* bit 57 */ | 316 | rdmsrl(msrs->controls[i].addr, val); |
| 265 | + IBS_FETCH_HIGH_ENABLE; | 317 | val |= ARCH_PERFMON_EVENTSEL0_ENABLE; |
| 266 | wrmsr(MSR_AMD64_IBSFETCHCTL, low, high); | 318 | wrmsrl(msrs->controls[i].addr, val); |
| 267 | } | 319 | } |
| 268 | 320 | ||
| 269 | if (has_ibs && ibs_config.op_enabled) { | 321 | op_amd_start_ibs(); |
| 270 | low = ((ibs_config.max_cnt_op >> 4) & 0xFFFF) | ||
| 271 | + ((ibs_config.dispatched_ops & 0x1) << 19) /* bit 19 */ | ||
| 272 | + IBS_OP_LOW_ENABLE; | ||
| 273 | high = 0; | ||
| 274 | wrmsr(MSR_AMD64_IBSOPCTL, low, high); | ||
| 275 | } | ||
| 276 | #endif | ||
| 277 | } | 322 | } |
| 278 | 323 | ||
| 279 | |||
| 280 | static void op_amd_stop(struct op_msrs const * const msrs) | 324 | static void op_amd_stop(struct op_msrs const * const msrs) |
| 281 | { | 325 | { |
| 282 | unsigned int low, high; | 326 | u64 val; |
| 283 | int i; | 327 | int i; |
| 284 | 328 | ||
| 285 | /* | 329 | /* |
| 286 | * Subtle: stop on all counters to avoid race with setting our | 330 | * Subtle: stop on all counters to avoid race with setting our |
| 287 | * pm callback | 331 | * pm callback |
| 288 | */ | 332 | */ |
| 289 | for (i = 0 ; i < NUM_COUNTERS ; ++i) { | 333 | for (i = 0; i < NUM_COUNTERS; ++i) { |
| 290 | if (!reset_value[i]) | 334 | if (!reset_value[op_x86_phys_to_virt(i)]) |
| 291 | continue; | 335 | continue; |
| 292 | CTRL_READ(low, high, msrs, i); | 336 | rdmsrl(msrs->controls[i].addr, val); |
| 293 | CTRL_SET_INACTIVE(low); | 337 | val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; |
| 294 | CTRL_WRITE(low, high, msrs, i); | 338 | wrmsrl(msrs->controls[i].addr, val); |
| 295 | } | ||
| 296 | |||
| 297 | #ifdef CONFIG_OPROFILE_IBS | ||
| 298 | if (has_ibs && ibs_config.fetch_enabled) { | ||
| 299 | /* clear max count and enable */ | ||
| 300 | low = 0; | ||
| 301 | high = 0; | ||
| 302 | wrmsr(MSR_AMD64_IBSFETCHCTL, low, high); | ||
| 303 | } | 339 | } |
| 304 | 340 | ||
| 305 | if (has_ibs && ibs_config.op_enabled) { | 341 | op_amd_stop_ibs(); |
| 306 | /* clear max count and enable */ | ||
| 307 | low = 0; | ||
| 308 | high = 0; | ||
| 309 | wrmsr(MSR_AMD64_IBSOPCTL, low, high); | ||
| 310 | } | ||
| 311 | #endif | ||
| 312 | } | 342 | } |
| 313 | 343 | ||
| 314 | static void op_amd_shutdown(struct op_msrs const * const msrs) | 344 | static void op_amd_shutdown(struct op_msrs const * const msrs) |
| 315 | { | 345 | { |
| 316 | int i; | 346 | int i; |
| 317 | 347 | ||
| 318 | for (i = 0 ; i < NUM_COUNTERS ; ++i) { | 348 | for (i = 0; i < NUM_COUNTERS; ++i) { |
| 319 | if (CTR_IS_RESERVED(msrs, i)) | 349 | if (msrs->counters[i].addr) |
| 320 | release_perfctr_nmi(MSR_K7_PERFCTR0 + i); | 350 | release_perfctr_nmi(MSR_K7_PERFCTR0 + i); |
| 321 | } | 351 | } |
| 322 | for (i = 0 ; i < NUM_CONTROLS ; ++i) { | 352 | for (i = 0; i < NUM_CONTROLS; ++i) { |
| 323 | if (CTRL_IS_RESERVED(msrs, i)) | 353 | if (msrs->controls[i].addr) |
| 324 | release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); | 354 | release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); |
| 325 | } | 355 | } |
| 326 | } | 356 | } |
| @@ -490,15 +520,21 @@ static void op_amd_exit(void) {} | |||
| 490 | 520 | ||
| 491 | #endif /* CONFIG_OPROFILE_IBS */ | 521 | #endif /* CONFIG_OPROFILE_IBS */ |
| 492 | 522 | ||
| 493 | struct op_x86_model_spec const op_amd_spec = { | 523 | struct op_x86_model_spec op_amd_spec = { |
| 494 | .init = op_amd_init, | ||
| 495 | .exit = op_amd_exit, | ||
| 496 | .num_counters = NUM_COUNTERS, | 524 | .num_counters = NUM_COUNTERS, |
| 497 | .num_controls = NUM_CONTROLS, | 525 | .num_controls = NUM_CONTROLS, |
| 526 | .num_virt_counters = NUM_VIRT_COUNTERS, | ||
| 527 | .reserved = MSR_AMD_EVENTSEL_RESERVED, | ||
| 528 | .event_mask = OP_EVENT_MASK, | ||
| 529 | .init = op_amd_init, | ||
| 530 | .exit = op_amd_exit, | ||
| 498 | .fill_in_addresses = &op_amd_fill_in_addresses, | 531 | .fill_in_addresses = &op_amd_fill_in_addresses, |
| 499 | .setup_ctrs = &op_amd_setup_ctrs, | 532 | .setup_ctrs = &op_amd_setup_ctrs, |
| 500 | .check_ctrs = &op_amd_check_ctrs, | 533 | .check_ctrs = &op_amd_check_ctrs, |
| 501 | .start = &op_amd_start, | 534 | .start = &op_amd_start, |
| 502 | .stop = &op_amd_stop, | 535 | .stop = &op_amd_stop, |
| 503 | .shutdown = &op_amd_shutdown | 536 | .shutdown = &op_amd_shutdown, |
| 537 | #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX | ||
| 538 | .switch_ctrl = &op_mux_switch_ctrl, | ||
| 539 | #endif | ||
| 504 | }; | 540 | }; |
diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c index 819b131fd752..ac6b354becdf 100644 --- a/arch/x86/oprofile/op_model_p4.c +++ b/arch/x86/oprofile/op_model_p4.c | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | #define NUM_CCCRS_HT2 9 | 32 | #define NUM_CCCRS_HT2 9 |
| 33 | #define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2) | 33 | #define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2) |
| 34 | 34 | ||
| 35 | #define OP_CTR_OVERFLOW (1ULL<<31) | ||
| 36 | |||
| 35 | static unsigned int num_counters = NUM_COUNTERS_NON_HT; | 37 | static unsigned int num_counters = NUM_COUNTERS_NON_HT; |
| 36 | static unsigned int num_controls = NUM_CONTROLS_NON_HT; | 38 | static unsigned int num_controls = NUM_CONTROLS_NON_HT; |
| 37 | 39 | ||
| @@ -350,8 +352,6 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = { | |||
| 350 | #define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1)) | 352 | #define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1)) |
| 351 | #define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x3f) << 25)) | 353 | #define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x3f) << 25)) |
| 352 | #define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9)) | 354 | #define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9)) |
| 353 | #define ESCR_READ(escr, high, ev, i) do {rdmsr(ev->bindings[(i)].escr_address, (escr), (high)); } while (0) | ||
| 354 | #define ESCR_WRITE(escr, high, ev, i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high)); } while (0) | ||
| 355 | 355 | ||
| 356 | #define CCCR_RESERVED_BITS 0x38030FFF | 356 | #define CCCR_RESERVED_BITS 0x38030FFF |
| 357 | #define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS) | 357 | #define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS) |
| @@ -361,17 +361,9 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = { | |||
| 361 | #define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27)) | 361 | #define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27)) |
| 362 | #define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12)) | 362 | #define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12)) |
| 363 | #define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12)) | 363 | #define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12)) |
| 364 | #define CCCR_READ(low, high, i) do {rdmsr(p4_counters[(i)].cccr_address, (low), (high)); } while (0) | ||
| 365 | #define CCCR_WRITE(low, high, i) do {wrmsr(p4_counters[(i)].cccr_address, (low), (high)); } while (0) | ||
| 366 | #define CCCR_OVF_P(cccr) ((cccr) & (1U<<31)) | 364 | #define CCCR_OVF_P(cccr) ((cccr) & (1U<<31)) |
| 367 | #define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31))) | 365 | #define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31))) |
| 368 | 366 | ||
| 369 | #define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0) | ||
| 370 | #define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0) | ||
| 371 | #define CTR_READ(l, h, i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h)); } while (0) | ||
| 372 | #define CTR_WRITE(l, i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1); } while (0) | ||
| 373 | #define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000)) | ||
| 374 | |||
| 375 | 367 | ||
| 376 | /* this assigns a "stagger" to the current CPU, which is used throughout | 368 | /* this assigns a "stagger" to the current CPU, which is used throughout |
| 377 | the code in this module as an extra array offset, to select the "even" | 369 | the code in this module as an extra array offset, to select the "even" |
| @@ -515,7 +507,7 @@ static void pmc_setup_one_p4_counter(unsigned int ctr) | |||
| 515 | if (ev->bindings[i].virt_counter & counter_bit) { | 507 | if (ev->bindings[i].virt_counter & counter_bit) { |
| 516 | 508 | ||
| 517 | /* modify ESCR */ | 509 | /* modify ESCR */ |
| 518 | ESCR_READ(escr, high, ev, i); | 510 | rdmsr(ev->bindings[i].escr_address, escr, high); |
| 519 | ESCR_CLEAR(escr); | 511 | ESCR_CLEAR(escr); |
| 520 | if (stag == 0) { | 512 | if (stag == 0) { |
| 521 | ESCR_SET_USR_0(escr, counter_config[ctr].user); | 513 | ESCR_SET_USR_0(escr, counter_config[ctr].user); |
| @@ -526,10 +518,11 @@ static void pmc_setup_one_p4_counter(unsigned int ctr) | |||
| 526 | } | 518 | } |
| 527 | ESCR_SET_EVENT_SELECT(escr, ev->event_select); | 519 | ESCR_SET_EVENT_SELECT(escr, ev->event_select); |
| 528 | ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask); | 520 | ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask); |
| 529 | ESCR_WRITE(escr, high, ev, i); | 521 | wrmsr(ev->bindings[i].escr_address, escr, high); |
| 530 | 522 | ||
| 531 | /* modify CCCR */ | 523 | /* modify CCCR */ |
| 532 | CCCR_READ(cccr, high, VIRT_CTR(stag, ctr)); | 524 | rdmsr(p4_counters[VIRT_CTR(stag, ctr)].cccr_address, |
| 525 | cccr, high); | ||
| 533 | CCCR_CLEAR(cccr); | 526 | CCCR_CLEAR(cccr); |
| 534 | CCCR_SET_REQUIRED_BITS(cccr); | 527 | CCCR_SET_REQUIRED_BITS(cccr); |
| 535 | CCCR_SET_ESCR_SELECT(cccr, ev->escr_select); | 528 | CCCR_SET_ESCR_SELECT(cccr, ev->escr_select); |
| @@ -537,7 +530,8 @@ static void pmc_setup_one_p4_counter(unsigned int ctr) | |||
| 537 | CCCR_SET_PMI_OVF_0(cccr); | 530 | CCCR_SET_PMI_OVF_0(cccr); |
| 538 | else | 531 | else |
| 539 | CCCR_SET_PMI_OVF_1(cccr); | 532 | CCCR_SET_PMI_OVF_1(cccr); |
| 540 | CCCR_WRITE(cccr, high, VIRT_CTR(stag, ctr)); | 533 | wrmsr(p4_counters[VIRT_CTR(stag, ctr)].cccr_address, |
| 534 | cccr, high); | ||
| 541 | return; | 535 | return; |
| 542 | } | 536 | } |
| 543 | } | 537 | } |
| @@ -548,7 +542,8 @@ static void pmc_setup_one_p4_counter(unsigned int ctr) | |||
| 548 | } | 542 | } |
| 549 | 543 | ||
| 550 | 544 | ||
| 551 | static void p4_setup_ctrs(struct op_msrs const * const msrs) | 545 | static void p4_setup_ctrs(struct op_x86_model_spec const *model, |
| 546 | struct op_msrs const * const msrs) | ||
| 552 | { | 547 | { |
| 553 | unsigned int i; | 548 | unsigned int i; |
| 554 | unsigned int low, high; | 549 | unsigned int low, high; |
| @@ -563,8 +558,8 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs) | |||
| 563 | } | 558 | } |
| 564 | 559 | ||
| 565 | /* clear the cccrs we will use */ | 560 | /* clear the cccrs we will use */ |
| 566 | for (i = 0 ; i < num_counters ; i++) { | 561 | for (i = 0; i < num_counters; i++) { |
| 567 | if (unlikely(!CTRL_IS_RESERVED(msrs, i))) | 562 | if (unlikely(!msrs->controls[i].addr)) |
| 568 | continue; | 563 | continue; |
| 569 | rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); | 564 | rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); |
| 570 | CCCR_CLEAR(low); | 565 | CCCR_CLEAR(low); |
| @@ -574,17 +569,18 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs) | |||
| 574 | 569 | ||
| 575 | /* clear all escrs (including those outside our concern) */ | 570 | /* clear all escrs (including those outside our concern) */ |
| 576 | for (i = num_counters; i < num_controls; i++) { | 571 | for (i = num_counters; i < num_controls; i++) { |
| 577 | if (unlikely(!CTRL_IS_RESERVED(msrs, i))) | 572 | if (unlikely(!msrs->controls[i].addr)) |
| 578 | continue; | 573 | continue; |
| 579 | wrmsr(msrs->controls[i].addr, 0, 0); | 574 | wrmsr(msrs->controls[i].addr, 0, 0); |
| 580 | } | 575 | } |
| 581 | 576 | ||
| 582 | /* setup all counters */ | 577 | /* setup all counters */ |
| 583 | for (i = 0 ; i < num_counters ; ++i) { | 578 | for (i = 0; i < num_counters; ++i) { |
| 584 | if ((counter_config[i].enabled) && (CTRL_IS_RESERVED(msrs, i))) { | 579 | if (counter_config[i].enabled && msrs->controls[i].addr) { |
| 585 | reset_value[i] = counter_config[i].count; | 580 | reset_value[i] = counter_config[i].count; |
| 586 | pmc_setup_one_p4_counter(i); | 581 | pmc_setup_one_p4_counter(i); |
| 587 | CTR_WRITE(counter_config[i].count, VIRT_CTR(stag, i)); | 582 | wrmsrl(p4_counters[VIRT_CTR(stag, i)].counter_address, |
| 583 | -(u64)counter_config[i].count); | ||
| 588 | } else { | 584 | } else { |
| 589 | reset_value[i] = 0; | 585 | reset_value[i] = 0; |
| 590 | } | 586 | } |
| @@ -624,14 +620,16 @@ static int p4_check_ctrs(struct pt_regs * const regs, | |||
| 624 | 620 | ||
| 625 | real = VIRT_CTR(stag, i); | 621 | real = VIRT_CTR(stag, i); |
| 626 | 622 | ||
| 627 | CCCR_READ(low, high, real); | 623 | rdmsr(p4_counters[real].cccr_address, low, high); |
| 628 | CTR_READ(ctr, high, real); | 624 | rdmsr(p4_counters[real].counter_address, ctr, high); |
| 629 | if (CCCR_OVF_P(low) || CTR_OVERFLOW_P(ctr)) { | 625 | if (CCCR_OVF_P(low) || !(ctr & OP_CTR_OVERFLOW)) { |
| 630 | oprofile_add_sample(regs, i); | 626 | oprofile_add_sample(regs, i); |
| 631 | CTR_WRITE(reset_value[i], real); | 627 | wrmsrl(p4_counters[real].counter_address, |
| 628 | -(u64)reset_value[i]); | ||
| 632 | CCCR_CLEAR_OVF(low); | 629 | CCCR_CLEAR_OVF(low); |
| 633 | CCCR_WRITE(low, high, real); | 630 | wrmsr(p4_counters[real].cccr_address, low, high); |
| 634 | CTR_WRITE(reset_value[i], real); | 631 | wrmsrl(p4_counters[real].counter_address, |
| 632 | -(u64)reset_value[i]); | ||
| 635 | } | 633 | } |
| 636 | } | 634 | } |
| 637 | 635 | ||
| @@ -653,9 +651,9 @@ static void p4_start(struct op_msrs const * const msrs) | |||
| 653 | for (i = 0; i < num_counters; ++i) { | 651 | for (i = 0; i < num_counters; ++i) { |
| 654 | if (!reset_value[i]) | 652 | if (!reset_value[i]) |
| 655 | continue; | 653 | continue; |
| 656 | CCCR_READ(low, high, VIRT_CTR(stag, i)); | 654 | rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); |
| 657 | CCCR_SET_ENABLE(low); | 655 | CCCR_SET_ENABLE(low); |
| 658 | CCCR_WRITE(low, high, VIRT_CTR(stag, i)); | 656 | wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); |
| 659 | } | 657 | } |
| 660 | } | 658 | } |
| 661 | 659 | ||
| @@ -670,9 +668,9 @@ static void p4_stop(struct op_msrs const * const msrs) | |||
| 670 | for (i = 0; i < num_counters; ++i) { | 668 | for (i = 0; i < num_counters; ++i) { |
| 671 | if (!reset_value[i]) | 669 | if (!reset_value[i]) |
| 672 | continue; | 670 | continue; |
| 673 | CCCR_READ(low, high, VIRT_CTR(stag, i)); | 671 | rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); |
| 674 | CCCR_SET_DISABLE(low); | 672 | CCCR_SET_DISABLE(low); |
| 675 | CCCR_WRITE(low, high, VIRT_CTR(stag, i)); | 673 | wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); |
| 676 | } | 674 | } |
| 677 | } | 675 | } |
| 678 | 676 | ||
| @@ -680,8 +678,8 @@ static void p4_shutdown(struct op_msrs const * const msrs) | |||
| 680 | { | 678 | { |
| 681 | int i; | 679 | int i; |
| 682 | 680 | ||
| 683 | for (i = 0 ; i < num_counters ; ++i) { | 681 | for (i = 0; i < num_counters; ++i) { |
| 684 | if (CTR_IS_RESERVED(msrs, i)) | 682 | if (msrs->counters[i].addr) |
| 685 | release_perfctr_nmi(msrs->counters[i].addr); | 683 | release_perfctr_nmi(msrs->counters[i].addr); |
| 686 | } | 684 | } |
| 687 | /* | 685 | /* |
| @@ -689,15 +687,15 @@ static void p4_shutdown(struct op_msrs const * const msrs) | |||
| 689 | * conjunction with the counter registers (hence the starting offset). | 687 | * conjunction with the counter registers (hence the starting offset). |
| 690 | * This saves a few bits. | 688 | * This saves a few bits. |
| 691 | */ | 689 | */ |
| 692 | for (i = num_counters ; i < num_controls ; ++i) { | 690 | for (i = num_counters; i < num_controls; ++i) { |
| 693 | if (CTRL_IS_RESERVED(msrs, i)) | 691 | if (msrs->controls[i].addr) |
| 694 | release_evntsel_nmi(msrs->controls[i].addr); | 692 | release_evntsel_nmi(msrs->controls[i].addr); |
| 695 | } | 693 | } |
| 696 | } | 694 | } |
| 697 | 695 | ||
| 698 | 696 | ||
| 699 | #ifdef CONFIG_SMP | 697 | #ifdef CONFIG_SMP |
| 700 | struct op_x86_model_spec const op_p4_ht2_spec = { | 698 | struct op_x86_model_spec op_p4_ht2_spec = { |
| 701 | .num_counters = NUM_COUNTERS_HT2, | 699 | .num_counters = NUM_COUNTERS_HT2, |
| 702 | .num_controls = NUM_CONTROLS_HT2, | 700 | .num_controls = NUM_CONTROLS_HT2, |
| 703 | .fill_in_addresses = &p4_fill_in_addresses, | 701 | .fill_in_addresses = &p4_fill_in_addresses, |
| @@ -709,7 +707,7 @@ struct op_x86_model_spec const op_p4_ht2_spec = { | |||
| 709 | }; | 707 | }; |
| 710 | #endif | 708 | #endif |
| 711 | 709 | ||
| 712 | struct op_x86_model_spec const op_p4_spec = { | 710 | struct op_x86_model_spec op_p4_spec = { |
| 713 | .num_counters = NUM_COUNTERS_NON_HT, | 711 | .num_counters = NUM_COUNTERS_NON_HT, |
| 714 | .num_controls = NUM_CONTROLS_NON_HT, | 712 | .num_controls = NUM_CONTROLS_NON_HT, |
| 715 | .fill_in_addresses = &p4_fill_in_addresses, | 713 | .fill_in_addresses = &p4_fill_in_addresses, |
diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c index 4da7230b3d17..4899215999de 100644 --- a/arch/x86/oprofile/op_model_ppro.c +++ b/arch/x86/oprofile/op_model_ppro.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | * @author Philippe Elie | 10 | * @author Philippe Elie |
| 11 | * @author Graydon Hoare | 11 | * @author Graydon Hoare |
| 12 | * @author Andi Kleen | 12 | * @author Andi Kleen |
| 13 | * @author Robert Richter <robert.richter@amd.com> | ||
| 13 | */ | 14 | */ |
| 14 | 15 | ||
| 15 | #include <linux/oprofile.h> | 16 | #include <linux/oprofile.h> |
| @@ -18,7 +19,6 @@ | |||
| 18 | #include <asm/msr.h> | 19 | #include <asm/msr.h> |
| 19 | #include <asm/apic.h> | 20 | #include <asm/apic.h> |
| 20 | #include <asm/nmi.h> | 21 | #include <asm/nmi.h> |
| 21 | #include <asm/perf_counter.h> | ||
| 22 | 22 | ||
| 23 | #include "op_x86_model.h" | 23 | #include "op_x86_model.h" |
| 24 | #include "op_counter.h" | 24 | #include "op_counter.h" |
| @@ -26,20 +26,7 @@ | |||
| 26 | static int num_counters = 2; | 26 | static int num_counters = 2; |
| 27 | static int counter_width = 32; | 27 | static int counter_width = 32; |
| 28 | 28 | ||
| 29 | #define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0) | 29 | #define MSR_PPRO_EVENTSEL_RESERVED ((0xFFFFFFFFULL<<32)|(1ULL<<21)) |
| 30 | #define CTR_OVERFLOWED(n) (!((n) & (1ULL<<(counter_width-1)))) | ||
| 31 | |||
| 32 | #define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0) | ||
| 33 | #define CTRL_READ(l, h, msrs, c) do {rdmsr((msrs->controls[(c)].addr), (l), (h)); } while (0) | ||
| 34 | #define CTRL_WRITE(l, h, msrs, c) do {wrmsr((msrs->controls[(c)].addr), (l), (h)); } while (0) | ||
| 35 | #define CTRL_SET_ACTIVE(n) (n |= (1<<22)) | ||
| 36 | #define CTRL_SET_INACTIVE(n) (n &= ~(1<<22)) | ||
| 37 | #define CTRL_CLEAR(x) (x &= (1<<21)) | ||
| 38 | #define CTRL_SET_ENABLE(val) (val |= 1<<20) | ||
| 39 | #define CTRL_SET_USR(val, u) (val |= ((u & 1) << 16)) | ||
| 40 | #define CTRL_SET_KERN(val, k) (val |= ((k & 1) << 17)) | ||
| 41 | #define CTRL_SET_UM(val, m) (val |= (m << 8)) | ||
| 42 | #define CTRL_SET_EVENT(val, e) (val |= e) | ||
| 43 | 30 | ||
| 44 | static u64 *reset_value; | 31 | static u64 *reset_value; |
| 45 | 32 | ||
| @@ -63,9 +50,10 @@ static void ppro_fill_in_addresses(struct op_msrs * const msrs) | |||
| 63 | } | 50 | } |
| 64 | 51 | ||
| 65 | 52 | ||
| 66 | static void ppro_setup_ctrs(struct op_msrs const * const msrs) | 53 | static void ppro_setup_ctrs(struct op_x86_model_spec const *model, |
| 54 | struct op_msrs const * const msrs) | ||
| 67 | { | 55 | { |
| 68 | unsigned int low, high; | 56 | u64 val; |
| 69 | int i; | 57 | int i; |
| 70 | 58 | ||
| 71 | if (!reset_value) { | 59 | if (!reset_value) { |
| @@ -93,36 +81,30 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs) | |||
| 93 | } | 81 | } |
| 94 | 82 | ||
| 95 | /* clear all counters */ | 83 | /* clear all counters */ |
| 96 | for (i = 0 ; i < num_counters; ++i) { | 84 | for (i = 0; i < num_counters; ++i) { |
| 97 | if (unlikely(!CTRL_IS_RESERVED(msrs, i))) | 85 | if (unlikely(!msrs->controls[i].addr)) |
| 98 | continue; | 86 | continue; |
| 99 | CTRL_READ(low, high, msrs, i); | 87 | rdmsrl(msrs->controls[i].addr, val); |
| 100 | CTRL_CLEAR(low); | 88 | val &= model->reserved; |
| 101 | CTRL_WRITE(low, high, msrs, i); | 89 | wrmsrl(msrs->controls[i].addr, val); |
| 102 | } | 90 | } |
| 103 | 91 | ||
| 104 | /* avoid a false detection of ctr overflows in NMI handler */ | 92 | /* avoid a false detection of ctr overflows in NMI handler */ |
| 105 | for (i = 0; i < num_counters; ++i) { | 93 | for (i = 0; i < num_counters; ++i) { |
| 106 | if (unlikely(!CTR_IS_RESERVED(msrs, i))) | 94 | if (unlikely(!msrs->counters[i].addr)) |
| 107 | continue; | 95 | continue; |
| 108 | wrmsrl(msrs->counters[i].addr, -1LL); | 96 | wrmsrl(msrs->counters[i].addr, -1LL); |
| 109 | } | 97 | } |
| 110 | 98 | ||
| 111 | /* enable active counters */ | 99 | /* enable active counters */ |
| 112 | for (i = 0; i < num_counters; ++i) { | 100 | for (i = 0; i < num_counters; ++i) { |
| 113 | if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs, i))) { | 101 | if (counter_config[i].enabled && msrs->counters[i].addr) { |
| 114 | reset_value[i] = counter_config[i].count; | 102 | reset_value[i] = counter_config[i].count; |
| 115 | |||
| 116 | wrmsrl(msrs->counters[i].addr, -reset_value[i]); | 103 | wrmsrl(msrs->counters[i].addr, -reset_value[i]); |
| 117 | 104 | rdmsrl(msrs->controls[i].addr, val); | |
| 118 | CTRL_READ(low, high, msrs, i); | 105 | val &= model->reserved; |
| 119 | CTRL_CLEAR(low); | 106 | val |= op_x86_get_ctrl(model, &counter_config[i]); |
| 120 | CTRL_SET_ENABLE(low); | 107 | wrmsrl(msrs->controls[i].addr, val); |
| 121 | CTRL_SET_USR(low, counter_config[i].user); | ||
| 122 | CTRL_SET_KERN(low, counter_config[i].kernel); | ||
| 123 | CTRL_SET_UM(low, counter_config[i].unit_mask); | ||
| 124 | CTRL_SET_EVENT(low, counter_config[i].event); | ||
| 125 | CTRL_WRITE(low, high, msrs, i); | ||
| 126 | } else { | 108 | } else { |
| 127 | reset_value[i] = 0; | 109 | reset_value[i] = 0; |
| 128 | } | 110 | } |
| @@ -143,14 +125,14 @@ static int ppro_check_ctrs(struct pt_regs * const regs, | |||
| 143 | if (unlikely(!reset_value)) | 125 | if (unlikely(!reset_value)) |
| 144 | goto out; | 126 | goto out; |
| 145 | 127 | ||
| 146 | for (i = 0 ; i < num_counters; ++i) { | 128 | for (i = 0; i < num_counters; ++i) { |
| 147 | if (!reset_value[i]) | 129 | if (!reset_value[i]) |
| 148 | continue; | 130 | continue; |
| 149 | rdmsrl(msrs->counters[i].addr, val); | 131 | rdmsrl(msrs->counters[i].addr, val); |
| 150 | if (CTR_OVERFLOWED(val)) { | 132 | if (val & (1ULL << (counter_width - 1))) |
| 151 | oprofile_add_sample(regs, i); | 133 | continue; |
| 152 | wrmsrl(msrs->counters[i].addr, -reset_value[i]); | 134 | oprofile_add_sample(regs, i); |
| 153 | } | 135 | wrmsrl(msrs->counters[i].addr, -reset_value[i]); |
| 154 | } | 136 | } |
| 155 | 137 | ||
| 156 | out: | 138 | out: |
| @@ -171,16 +153,16 @@ out: | |||
| 171 | 153 | ||
| 172 | static void ppro_start(struct op_msrs const * const msrs) | 154 | static void ppro_start(struct op_msrs const * const msrs) |
| 173 | { | 155 | { |
| 174 | unsigned int low, high; | 156 | u64 val; |
| 175 | int i; | 157 | int i; |
| 176 | 158 | ||
| 177 | if (!reset_value) | 159 | if (!reset_value) |
| 178 | return; | 160 | return; |
| 179 | for (i = 0; i < num_counters; ++i) { | 161 | for (i = 0; i < num_counters; ++i) { |
| 180 | if (reset_value[i]) { | 162 | if (reset_value[i]) { |
| 181 | CTRL_READ(low, high, msrs, i); | 163 | rdmsrl(msrs->controls[i].addr, val); |
| 182 | CTRL_SET_ACTIVE(low); | 164 | val |= ARCH_PERFMON_EVENTSEL0_ENABLE; |
| 183 | CTRL_WRITE(low, high, msrs, i); | 165 | wrmsrl(msrs->controls[i].addr, val); |
| 184 | } | 166 | } |
| 185 | } | 167 | } |
| 186 | } | 168 | } |
| @@ -188,7 +170,7 @@ static void ppro_start(struct op_msrs const * const msrs) | |||
| 188 | 170 | ||
| 189 | static void ppro_stop(struct op_msrs const * const msrs) | 171 | static void ppro_stop(struct op_msrs const * const msrs) |
| 190 | { | 172 | { |
| 191 | unsigned int low, high; | 173 | u64 val; |
| 192 | int i; | 174 | int i; |
| 193 | 175 | ||
| 194 | if (!reset_value) | 176 | if (!reset_value) |
| @@ -196,9 +178,9 @@ static void ppro_stop(struct op_msrs const * const msrs) | |||
| 196 | for (i = 0; i < num_counters; ++i) { | 178 | for (i = 0; i < num_counters; ++i) { |
| 197 | if (!reset_value[i]) | 179 | if (!reset_value[i]) |
| 198 | continue; | 180 | continue; |
| 199 | CTRL_READ(low, high, msrs, i); | 181 | rdmsrl(msrs->controls[i].addr, val); |
| 200 | CTRL_SET_INACTIVE(low); | 182 | val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; |
| 201 | CTRL_WRITE(low, high, msrs, i); | 183 | wrmsrl(msrs->controls[i].addr, val); |
| 202 | } | 184 | } |
| 203 | } | 185 | } |
| 204 | 186 | ||
| @@ -206,12 +188,12 @@ static void ppro_shutdown(struct op_msrs const * const msrs) | |||
| 206 | { | 188 | { |
| 207 | int i; | 189 | int i; |
| 208 | 190 | ||
| 209 | for (i = 0 ; i < num_counters ; ++i) { | 191 | for (i = 0; i < num_counters; ++i) { |
| 210 | if (CTR_IS_RESERVED(msrs, i)) | 192 | if (msrs->counters[i].addr) |
| 211 | release_perfctr_nmi(MSR_P6_PERFCTR0 + i); | 193 | release_perfctr_nmi(MSR_P6_PERFCTR0 + i); |
| 212 | } | 194 | } |
| 213 | for (i = 0 ; i < num_counters ; ++i) { | 195 | for (i = 0; i < num_counters; ++i) { |
| 214 | if (CTRL_IS_RESERVED(msrs, i)) | 196 | if (msrs->controls[i].addr) |
| 215 | release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); | 197 | release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); |
| 216 | } | 198 | } |
| 217 | if (reset_value) { | 199 | if (reset_value) { |
| @@ -222,8 +204,9 @@ static void ppro_shutdown(struct op_msrs const * const msrs) | |||
| 222 | 204 | ||
| 223 | 205 | ||
| 224 | struct op_x86_model_spec op_ppro_spec = { | 206 | struct op_x86_model_spec op_ppro_spec = { |
| 225 | .num_counters = 2, /* can be overriden */ | 207 | .num_counters = 2, |
| 226 | .num_controls = 2, /* dito */ | 208 | .num_controls = 2, |
| 209 | .reserved = MSR_PPRO_EVENTSEL_RESERVED, | ||
| 227 | .fill_in_addresses = &ppro_fill_in_addresses, | 210 | .fill_in_addresses = &ppro_fill_in_addresses, |
| 228 | .setup_ctrs = &ppro_setup_ctrs, | 211 | .setup_ctrs = &ppro_setup_ctrs, |
| 229 | .check_ctrs = &ppro_check_ctrs, | 212 | .check_ctrs = &ppro_check_ctrs, |
| @@ -241,7 +224,7 @@ struct op_x86_model_spec op_ppro_spec = { | |||
| 241 | * the specific CPU. | 224 | * the specific CPU. |
| 242 | */ | 225 | */ |
| 243 | 226 | ||
| 244 | void arch_perfmon_setup_counters(void) | 227 | static void arch_perfmon_setup_counters(void) |
| 245 | { | 228 | { |
| 246 | union cpuid10_eax eax; | 229 | union cpuid10_eax eax; |
| 247 | 230 | ||
| @@ -259,11 +242,17 @@ void arch_perfmon_setup_counters(void) | |||
| 259 | 242 | ||
| 260 | op_arch_perfmon_spec.num_counters = num_counters; | 243 | op_arch_perfmon_spec.num_counters = num_counters; |
| 261 | op_arch_perfmon_spec.num_controls = num_counters; | 244 | op_arch_perfmon_spec.num_controls = num_counters; |
| 262 | op_ppro_spec.num_counters = num_counters; | 245 | } |
| 263 | op_ppro_spec.num_controls = num_counters; | 246 | |
| 247 | static int arch_perfmon_init(struct oprofile_operations *ignore) | ||
| 248 | { | ||
| 249 | arch_perfmon_setup_counters(); | ||
| 250 | return 0; | ||
| 264 | } | 251 | } |
| 265 | 252 | ||
| 266 | struct op_x86_model_spec op_arch_perfmon_spec = { | 253 | struct op_x86_model_spec op_arch_perfmon_spec = { |
| 254 | .reserved = MSR_PPRO_EVENTSEL_RESERVED, | ||
| 255 | .init = &arch_perfmon_init, | ||
| 267 | /* num_counters/num_controls filled in at runtime */ | 256 | /* num_counters/num_controls filled in at runtime */ |
| 268 | .fill_in_addresses = &ppro_fill_in_addresses, | 257 | .fill_in_addresses = &ppro_fill_in_addresses, |
| 269 | /* user space does the cpuid check for available events */ | 258 | /* user space does the cpuid check for available events */ |
diff --git a/arch/x86/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h index 825e79064d64..b83776180c7f 100644 --- a/arch/x86/oprofile/op_x86_model.h +++ b/arch/x86/oprofile/op_x86_model.h | |||
| @@ -6,51 +6,66 @@ | |||
| 6 | * @remark Read the file COPYING | 6 | * @remark Read the file COPYING |
| 7 | * | 7 | * |
| 8 | * @author Graydon Hoare | 8 | * @author Graydon Hoare |
| 9 | * @author Robert Richter <robert.richter@amd.com> | ||
| 9 | */ | 10 | */ |
| 10 | 11 | ||
| 11 | #ifndef OP_X86_MODEL_H | 12 | #ifndef OP_X86_MODEL_H |
| 12 | #define OP_X86_MODEL_H | 13 | #define OP_X86_MODEL_H |
| 13 | 14 | ||
| 14 | struct op_saved_msr { | 15 | #include <asm/types.h> |
| 15 | unsigned int high; | 16 | #include <asm/perf_counter.h> |
| 16 | unsigned int low; | ||
| 17 | }; | ||
| 18 | 17 | ||
| 19 | struct op_msr { | 18 | struct op_msr { |
| 20 | unsigned long addr; | 19 | unsigned long addr; |
| 21 | struct op_saved_msr saved; | 20 | u64 saved; |
| 22 | }; | 21 | }; |
| 23 | 22 | ||
| 24 | struct op_msrs { | 23 | struct op_msrs { |
| 25 | struct op_msr *counters; | 24 | struct op_msr *counters; |
| 26 | struct op_msr *controls; | 25 | struct op_msr *controls; |
| 26 | struct op_msr *multiplex; | ||
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | struct pt_regs; | 29 | struct pt_regs; |
| 30 | 30 | ||
| 31 | struct oprofile_operations; | ||
| 32 | |||
| 31 | /* The model vtable abstracts the differences between | 33 | /* The model vtable abstracts the differences between |
| 32 | * various x86 CPU models' perfctr support. | 34 | * various x86 CPU models' perfctr support. |
| 33 | */ | 35 | */ |
| 34 | struct op_x86_model_spec { | 36 | struct op_x86_model_spec { |
| 35 | int (*init)(struct oprofile_operations *ops); | 37 | unsigned int num_counters; |
| 36 | void (*exit)(void); | 38 | unsigned int num_controls; |
| 37 | unsigned int num_counters; | 39 | unsigned int num_virt_counters; |
| 38 | unsigned int num_controls; | 40 | u64 reserved; |
| 39 | void (*fill_in_addresses)(struct op_msrs * const msrs); | 41 | u16 event_mask; |
| 40 | void (*setup_ctrs)(struct op_msrs const * const msrs); | 42 | int (*init)(struct oprofile_operations *ops); |
| 41 | int (*check_ctrs)(struct pt_regs * const regs, | 43 | void (*exit)(void); |
| 42 | struct op_msrs const * const msrs); | 44 | void (*fill_in_addresses)(struct op_msrs * const msrs); |
| 43 | void (*start)(struct op_msrs const * const msrs); | 45 | void (*setup_ctrs)(struct op_x86_model_spec const *model, |
| 44 | void (*stop)(struct op_msrs const * const msrs); | 46 | struct op_msrs const * const msrs); |
| 45 | void (*shutdown)(struct op_msrs const * const msrs); | 47 | int (*check_ctrs)(struct pt_regs * const regs, |
| 48 | struct op_msrs const * const msrs); | ||
| 49 | void (*start)(struct op_msrs const * const msrs); | ||
| 50 | void (*stop)(struct op_msrs const * const msrs); | ||
| 51 | void (*shutdown)(struct op_msrs const * const msrs); | ||
| 52 | #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX | ||
| 53 | void (*switch_ctrl)(struct op_x86_model_spec const *model, | ||
| 54 | struct op_msrs const * const msrs); | ||
| 55 | #endif | ||
| 46 | }; | 56 | }; |
| 47 | 57 | ||
| 58 | struct op_counter_config; | ||
| 59 | |||
| 60 | extern u64 op_x86_get_ctrl(struct op_x86_model_spec const *model, | ||
| 61 | struct op_counter_config *counter_config); | ||
| 62 | extern int op_x86_phys_to_virt(int phys); | ||
| 63 | extern int op_x86_virt_to_phys(int virt); | ||
| 64 | |||
| 48 | extern struct op_x86_model_spec op_ppro_spec; | 65 | extern struct op_x86_model_spec op_ppro_spec; |
| 49 | extern struct op_x86_model_spec const op_p4_spec; | 66 | extern struct op_x86_model_spec op_p4_spec; |
| 50 | extern struct op_x86_model_spec const op_p4_ht2_spec; | 67 | extern struct op_x86_model_spec op_p4_ht2_spec; |
| 51 | extern struct op_x86_model_spec const op_amd_spec; | 68 | extern struct op_x86_model_spec op_amd_spec; |
| 52 | extern struct op_x86_model_spec op_arch_perfmon_spec; | 69 | extern struct op_x86_model_spec op_arch_perfmon_spec; |
| 53 | 70 | ||
| 54 | extern void arch_perfmon_setup_counters(void); | ||
| 55 | |||
| 56 | #endif /* OP_X86_MODEL_H */ | 71 | #endif /* OP_X86_MODEL_H */ |
diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c index bd13c3e4c6db..347d882b3bb3 100644 --- a/arch/x86/pci/direct.c +++ b/arch/x86/pci/direct.c | |||
| @@ -192,13 +192,14 @@ struct pci_raw_ops pci_direct_conf2 = { | |||
| 192 | static int __init pci_sanity_check(struct pci_raw_ops *o) | 192 | static int __init pci_sanity_check(struct pci_raw_ops *o) |
| 193 | { | 193 | { |
| 194 | u32 x = 0; | 194 | u32 x = 0; |
| 195 | int devfn; | 195 | int year, devfn; |
| 196 | 196 | ||
| 197 | if (pci_probe & PCI_NO_CHECKS) | 197 | if (pci_probe & PCI_NO_CHECKS) |
| 198 | return 1; | 198 | return 1; |
| 199 | /* Assume Type 1 works for newer systems. | 199 | /* Assume Type 1 works for newer systems. |
| 200 | This handles machines that don't have anything on PCI Bus 0. */ | 200 | This handles machines that don't have anything on PCI Bus 0. */ |
| 201 | if (dmi_get_year(DMI_BIOS_DATE) >= 2001) | 201 | dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL); |
| 202 | if (year >= 2001) | ||
| 202 | return 1; | 203 | return 1; |
| 203 | 204 | ||
| 204 | for (devfn = 0; devfn < 0x100; devfn++) { | 205 | for (devfn = 0; devfn < 0x100; devfn++) { |
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index 172438f86a02..3bb4fc21f4f2 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile | |||
| @@ -5,6 +5,11 @@ CFLAGS_REMOVE_time.o = -pg | |||
| 5 | CFLAGS_REMOVE_irq.o = -pg | 5 | CFLAGS_REMOVE_irq.o = -pg |
| 6 | endif | 6 | endif |
| 7 | 7 | ||
| 8 | # Make sure early boot has no stackprotector | ||
| 9 | nostackp := $(call cc-option, -fno-stack-protector) | ||
| 10 | CFLAGS_enlighten.o := $(nostackp) | ||
| 11 | CFLAGS_mmu.o := $(nostackp) | ||
| 12 | |||
| 8 | obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ | 13 | obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ |
| 9 | time.o xen-asm.o xen-asm_$(BITS).o \ | 14 | time.o xen-asm.o xen-asm_$(BITS).o \ |
| 10 | grant-table.o suspend.o | 15 | grant-table.o suspend.o |
| @@ -12,3 +17,4 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ | |||
| 12 | obj-$(CONFIG_SMP) += smp.o | 17 | obj-$(CONFIG_SMP) += smp.o |
| 13 | obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o | 18 | obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o |
| 14 | obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o | 19 | obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o |
| 20 | |||
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 0a1700a2be9c..0dd0c2c6cae0 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
| @@ -51,6 +51,7 @@ | |||
| 51 | #include <asm/pgtable.h> | 51 | #include <asm/pgtable.h> |
| 52 | #include <asm/tlbflush.h> | 52 | #include <asm/tlbflush.h> |
| 53 | #include <asm/reboot.h> | 53 | #include <asm/reboot.h> |
| 54 | #include <asm/stackprotector.h> | ||
| 54 | 55 | ||
| 55 | #include "xen-ops.h" | 56 | #include "xen-ops.h" |
| 56 | #include "mmu.h" | 57 | #include "mmu.h" |
| @@ -215,6 +216,7 @@ static __init void xen_init_cpuid_mask(void) | |||
| 215 | (1 << X86_FEATURE_ACPI)); /* disable ACPI */ | 216 | (1 << X86_FEATURE_ACPI)); /* disable ACPI */ |
| 216 | 217 | ||
| 217 | ax = 1; | 218 | ax = 1; |
| 219 | cx = 0; | ||
| 218 | xen_cpuid(&ax, &bx, &cx, &dx); | 220 | xen_cpuid(&ax, &bx, &cx, &dx); |
| 219 | 221 | ||
| 220 | /* cpuid claims we support xsave; try enabling it to see what happens */ | 222 | /* cpuid claims we support xsave; try enabling it to see what happens */ |
| @@ -329,18 +331,28 @@ static void xen_load_gdt(const struct desc_ptr *dtr) | |||
| 329 | unsigned long frames[pages]; | 331 | unsigned long frames[pages]; |
| 330 | int f; | 332 | int f; |
| 331 | 333 | ||
| 332 | /* A GDT can be up to 64k in size, which corresponds to 8192 | 334 | /* |
| 333 | 8-byte entries, or 16 4k pages.. */ | 335 | * A GDT can be up to 64k in size, which corresponds to 8192 |
| 336 | * 8-byte entries, or 16 4k pages.. | ||
| 337 | */ | ||
| 334 | 338 | ||
| 335 | BUG_ON(size > 65536); | 339 | BUG_ON(size > 65536); |
| 336 | BUG_ON(va & ~PAGE_MASK); | 340 | BUG_ON(va & ~PAGE_MASK); |
| 337 | 341 | ||
| 338 | for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) { | 342 | for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) { |
| 339 | int level; | 343 | int level; |
| 340 | pte_t *ptep = lookup_address(va, &level); | 344 | pte_t *ptep; |
| 341 | unsigned long pfn, mfn; | 345 | unsigned long pfn, mfn; |
| 342 | void *virt; | 346 | void *virt; |
| 343 | 347 | ||
| 348 | /* | ||
| 349 | * The GDT is per-cpu and is in the percpu data area. | ||
| 350 | * That can be virtually mapped, so we need to do a | ||
| 351 | * page-walk to get the underlying MFN for the | ||
| 352 | * hypercall. The page can also be in the kernel's | ||
| 353 | * linear range, so we need to RO that mapping too. | ||
| 354 | */ | ||
| 355 | ptep = lookup_address(va, &level); | ||
| 344 | BUG_ON(ptep == NULL); | 356 | BUG_ON(ptep == NULL); |
| 345 | 357 | ||
| 346 | pfn = pte_pfn(*ptep); | 358 | pfn = pte_pfn(*ptep); |
| @@ -357,6 +369,44 @@ static void xen_load_gdt(const struct desc_ptr *dtr) | |||
| 357 | BUG(); | 369 | BUG(); |
| 358 | } | 370 | } |
| 359 | 371 | ||
| 372 | /* | ||
| 373 | * load_gdt for early boot, when the gdt is only mapped once | ||
| 374 | */ | ||
| 375 | static __init void xen_load_gdt_boot(const struct desc_ptr *dtr) | ||
| 376 | { | ||
| 377 | unsigned long va = dtr->address; | ||
| 378 | unsigned int size = dtr->size + 1; | ||
| 379 | unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; | ||
| 380 | unsigned long frames[pages]; | ||
| 381 | int f; | ||
| 382 | |||
| 383 | /* | ||
| 384 | * A GDT can be up to 64k in size, which corresponds to 8192 | ||
| 385 | * 8-byte entries, or 16 4k pages.. | ||
| 386 | */ | ||
| 387 | |||
| 388 | BUG_ON(size > 65536); | ||
| 389 | BUG_ON(va & ~PAGE_MASK); | ||
| 390 | |||
| 391 | for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) { | ||
| 392 | pte_t pte; | ||
| 393 | unsigned long pfn, mfn; | ||
| 394 | |||
| 395 | pfn = virt_to_pfn(va); | ||
| 396 | mfn = pfn_to_mfn(pfn); | ||
| 397 | |||
| 398 | pte = pfn_pte(pfn, PAGE_KERNEL_RO); | ||
| 399 | |||
| 400 | if (HYPERVISOR_update_va_mapping((unsigned long)va, pte, 0)) | ||
| 401 | BUG(); | ||
| 402 | |||
| 403 | frames[f] = mfn; | ||
| 404 | } | ||
| 405 | |||
| 406 | if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct))) | ||
| 407 | BUG(); | ||
| 408 | } | ||
| 409 | |||
| 360 | static void load_TLS_descriptor(struct thread_struct *t, | 410 | static void load_TLS_descriptor(struct thread_struct *t, |
| 361 | unsigned int cpu, unsigned int i) | 411 | unsigned int cpu, unsigned int i) |
| 362 | { | 412 | { |
| @@ -580,6 +630,29 @@ static void xen_write_gdt_entry(struct desc_struct *dt, int entry, | |||
| 580 | preempt_enable(); | 630 | preempt_enable(); |
| 581 | } | 631 | } |
| 582 | 632 | ||
| 633 | /* | ||
| 634 | * Version of write_gdt_entry for use at early boot-time needed to | ||
| 635 | * update an entry as simply as possible. | ||
| 636 | */ | ||
| 637 | static __init void xen_write_gdt_entry_boot(struct desc_struct *dt, int entry, | ||
| 638 | const void *desc, int type) | ||
| 639 | { | ||
| 640 | switch (type) { | ||
| 641 | case DESC_LDT: | ||
| 642 | case DESC_TSS: | ||
| 643 | /* ignore */ | ||
| 644 | break; | ||
| 645 | |||
| 646 | default: { | ||
| 647 | xmaddr_t maddr = virt_to_machine(&dt[entry]); | ||
| 648 | |||
| 649 | if (HYPERVISOR_update_descriptor(maddr.maddr, *(u64 *)desc)) | ||
| 650 | dt[entry] = *(struct desc_struct *)desc; | ||
| 651 | } | ||
| 652 | |||
| 653 | } | ||
| 654 | } | ||
| 655 | |||
| 583 | static void xen_load_sp0(struct tss_struct *tss, | 656 | static void xen_load_sp0(struct tss_struct *tss, |
| 584 | struct thread_struct *thread) | 657 | struct thread_struct *thread) |
| 585 | { | 658 | { |
| @@ -713,7 +786,7 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) | |||
| 713 | set: | 786 | set: |
| 714 | base = ((u64)high << 32) | low; | 787 | base = ((u64)high << 32) | low; |
| 715 | if (HYPERVISOR_set_segment_base(which, base) != 0) | 788 | if (HYPERVISOR_set_segment_base(which, base) != 0) |
| 716 | ret = -EFAULT; | 789 | ret = -EIO; |
| 717 | break; | 790 | break; |
| 718 | #endif | 791 | #endif |
| 719 | 792 | ||
| @@ -964,6 +1037,23 @@ static const struct machine_ops __initdata xen_machine_ops = { | |||
| 964 | .emergency_restart = xen_emergency_restart, | 1037 | .emergency_restart = xen_emergency_restart, |
| 965 | }; | 1038 | }; |
| 966 | 1039 | ||
| 1040 | /* | ||
| 1041 | * Set up the GDT and segment registers for -fstack-protector. Until | ||
| 1042 | * we do this, we have to be careful not to call any stack-protected | ||
| 1043 | * function, which is most of the kernel. | ||
| 1044 | */ | ||
| 1045 | static void __init xen_setup_stackprotector(void) | ||
| 1046 | { | ||
| 1047 | pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry_boot; | ||
| 1048 | pv_cpu_ops.load_gdt = xen_load_gdt_boot; | ||
| 1049 | |||
| 1050 | setup_stack_canary_segment(0); | ||
| 1051 | switch_to_new_gdt(0); | ||
| 1052 | |||
| 1053 | pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry; | ||
| 1054 | pv_cpu_ops.load_gdt = xen_load_gdt; | ||
| 1055 | } | ||
| 1056 | |||
| 967 | /* First C function to be called on Xen boot */ | 1057 | /* First C function to be called on Xen boot */ |
| 968 | asmlinkage void __init xen_start_kernel(void) | 1058 | asmlinkage void __init xen_start_kernel(void) |
| 969 | { | 1059 | { |
| @@ -974,10 +1064,6 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 974 | 1064 | ||
| 975 | xen_domain_type = XEN_PV_DOMAIN; | 1065 | xen_domain_type = XEN_PV_DOMAIN; |
| 976 | 1066 | ||
| 977 | BUG_ON(memcmp(xen_start_info->magic, "xen-3", 5) != 0); | ||
| 978 | |||
| 979 | xen_setup_features(); | ||
| 980 | |||
| 981 | /* Install Xen paravirt ops */ | 1067 | /* Install Xen paravirt ops */ |
| 982 | pv_info = xen_info; | 1068 | pv_info = xen_info; |
| 983 | pv_init_ops = xen_init_ops; | 1069 | pv_init_ops = xen_init_ops; |
| @@ -986,8 +1072,30 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 986 | pv_apic_ops = xen_apic_ops; | 1072 | pv_apic_ops = xen_apic_ops; |
| 987 | pv_mmu_ops = xen_mmu_ops; | 1073 | pv_mmu_ops = xen_mmu_ops; |
| 988 | 1074 | ||
| 989 | xen_init_irq_ops(); | 1075 | /* |
| 1076 | * Set up some pagetable state before starting to set any ptes. | ||
| 1077 | */ | ||
| 990 | 1078 | ||
| 1079 | /* Prevent unwanted bits from being set in PTEs. */ | ||
| 1080 | __supported_pte_mask &= ~_PAGE_GLOBAL; | ||
| 1081 | if (!xen_initial_domain()) | ||
| 1082 | __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD); | ||
| 1083 | |||
| 1084 | __supported_pte_mask |= _PAGE_IOMAP; | ||
| 1085 | |||
| 1086 | xen_setup_features(); | ||
| 1087 | |||
| 1088 | /* Get mfn list */ | ||
| 1089 | if (!xen_feature(XENFEAT_auto_translated_physmap)) | ||
| 1090 | xen_build_dynamic_phys_to_machine(); | ||
| 1091 | |||
| 1092 | /* | ||
| 1093 | * Set up kernel GDT and segment registers, mainly so that | ||
| 1094 | * -fstack-protector code can be executed. | ||
| 1095 | */ | ||
| 1096 | xen_setup_stackprotector(); | ||
| 1097 | |||
| 1098 | xen_init_irq_ops(); | ||
| 991 | xen_init_cpuid_mask(); | 1099 | xen_init_cpuid_mask(); |
| 992 | 1100 | ||
| 993 | #ifdef CONFIG_X86_LOCAL_APIC | 1101 | #ifdef CONFIG_X86_LOCAL_APIC |
| @@ -1004,13 +1112,6 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 1004 | 1112 | ||
| 1005 | machine_ops = xen_machine_ops; | 1113 | machine_ops = xen_machine_ops; |
| 1006 | 1114 | ||
| 1007 | #ifdef CONFIG_X86_64 | ||
| 1008 | /* | ||
| 1009 | * Setup percpu state. We only need to do this for 64-bit | ||
| 1010 | * because 32-bit already has %fs set properly. | ||
| 1011 | */ | ||
| 1012 | load_percpu_segment(0); | ||
| 1013 | #endif | ||
| 1014 | /* | 1115 | /* |
| 1015 | * The only reliable way to retain the initial address of the | 1116 | * The only reliable way to retain the initial address of the |
| 1016 | * percpu gdt_page is to remember it here, so we can go and | 1117 | * percpu gdt_page is to remember it here, so we can go and |
| @@ -1020,17 +1121,8 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 1020 | 1121 | ||
| 1021 | xen_smp_init(); | 1122 | xen_smp_init(); |
| 1022 | 1123 | ||
| 1023 | /* Get mfn list */ | ||
| 1024 | if (!xen_feature(XENFEAT_auto_translated_physmap)) | ||
| 1025 | xen_build_dynamic_phys_to_machine(); | ||
| 1026 | |||
| 1027 | pgd = (pgd_t *)xen_start_info->pt_base; | 1124 | pgd = (pgd_t *)xen_start_info->pt_base; |
| 1028 | 1125 | ||
| 1029 | /* Prevent unwanted bits from being set in PTEs. */ | ||
| 1030 | __supported_pte_mask &= ~_PAGE_GLOBAL; | ||
| 1031 | if (!xen_initial_domain()) | ||
| 1032 | __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD); | ||
| 1033 | |||
| 1034 | #ifdef CONFIG_X86_64 | 1126 | #ifdef CONFIG_X86_64 |
| 1035 | /* Work out if we support NX */ | 1127 | /* Work out if we support NX */ |
| 1036 | check_efer(); | 1128 | check_efer(); |
| @@ -1061,6 +1153,7 @@ asmlinkage void __init xen_start_kernel(void) | |||
| 1061 | /* set up basic CPUID stuff */ | 1153 | /* set up basic CPUID stuff */ |
| 1062 | cpu_detect(&new_cpu_data); | 1154 | cpu_detect(&new_cpu_data); |
| 1063 | new_cpu_data.hard_math = 1; | 1155 | new_cpu_data.hard_math = 1; |
| 1156 | new_cpu_data.wp_works_ok = 1; | ||
| 1064 | new_cpu_data.x86_capability[0] = cpuid_edx(1); | 1157 | new_cpu_data.x86_capability[0] = cpuid_edx(1); |
| 1065 | #endif | 1158 | #endif |
| 1066 | 1159 | ||
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 429834ec1687..fe03eeed7b48 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
| @@ -236,6 +236,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle) | |||
| 236 | ctxt->user_regs.ss = __KERNEL_DS; | 236 | ctxt->user_regs.ss = __KERNEL_DS; |
| 237 | #ifdef CONFIG_X86_32 | 237 | #ifdef CONFIG_X86_32 |
| 238 | ctxt->user_regs.fs = __KERNEL_PERCPU; | 238 | ctxt->user_regs.fs = __KERNEL_PERCPU; |
| 239 | ctxt->user_regs.gs = __KERNEL_STACK_CANARY; | ||
| 239 | #else | 240 | #else |
| 240 | ctxt->gs_base_kernel = per_cpu_offset(cpu); | 241 | ctxt->gs_base_kernel = per_cpu_offset(cpu); |
| 241 | #endif | 242 | #endif |
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 5601506f2dd9..36a5141108df 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c | |||
| @@ -187,7 +187,6 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl | |||
| 187 | struct xen_spinlock *prev; | 187 | struct xen_spinlock *prev; |
| 188 | int irq = __get_cpu_var(lock_kicker_irq); | 188 | int irq = __get_cpu_var(lock_kicker_irq); |
| 189 | int ret; | 189 | int ret; |
| 190 | unsigned long flags; | ||
| 191 | u64 start; | 190 | u64 start; |
| 192 | 191 | ||
| 193 | /* If kicker interrupts not initialized yet, just spin */ | 192 | /* If kicker interrupts not initialized yet, just spin */ |
| @@ -199,16 +198,12 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl | |||
| 199 | /* announce we're spinning */ | 198 | /* announce we're spinning */ |
| 200 | prev = spinning_lock(xl); | 199 | prev = spinning_lock(xl); |
| 201 | 200 | ||
| 202 | flags = __raw_local_save_flags(); | ||
| 203 | if (irq_enable) { | ||
| 204 | ADD_STATS(taken_slow_irqenable, 1); | ||
| 205 | raw_local_irq_enable(); | ||
| 206 | } | ||
| 207 | |||
| 208 | ADD_STATS(taken_slow, 1); | 201 | ADD_STATS(taken_slow, 1); |
| 209 | ADD_STATS(taken_slow_nested, prev != NULL); | 202 | ADD_STATS(taken_slow_nested, prev != NULL); |
| 210 | 203 | ||
| 211 | do { | 204 | do { |
| 205 | unsigned long flags; | ||
| 206 | |||
| 212 | /* clear pending */ | 207 | /* clear pending */ |
| 213 | xen_clear_irq_pending(irq); | 208 | xen_clear_irq_pending(irq); |
| 214 | 209 | ||
| @@ -228,6 +223,12 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl | |||
| 228 | goto out; | 223 | goto out; |
| 229 | } | 224 | } |
| 230 | 225 | ||
| 226 | flags = __raw_local_save_flags(); | ||
| 227 | if (irq_enable) { | ||
| 228 | ADD_STATS(taken_slow_irqenable, 1); | ||
| 229 | raw_local_irq_enable(); | ||
| 230 | } | ||
| 231 | |||
| 231 | /* | 232 | /* |
| 232 | * Block until irq becomes pending. If we're | 233 | * Block until irq becomes pending. If we're |
| 233 | * interrupted at this point (after the trylock but | 234 | * interrupted at this point (after the trylock but |
| @@ -238,13 +239,15 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl | |||
| 238 | * pending. | 239 | * pending. |
| 239 | */ | 240 | */ |
| 240 | xen_poll_irq(irq); | 241 | xen_poll_irq(irq); |
| 242 | |||
| 243 | raw_local_irq_restore(flags); | ||
| 244 | |||
| 241 | ADD_STATS(taken_slow_spurious, !xen_test_irq_pending(irq)); | 245 | ADD_STATS(taken_slow_spurious, !xen_test_irq_pending(irq)); |
| 242 | } while (!xen_test_irq_pending(irq)); /* check for spurious wakeups */ | 246 | } while (!xen_test_irq_pending(irq)); /* check for spurious wakeups */ |
| 243 | 247 | ||
| 244 | kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); | 248 | kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq)); |
| 245 | 249 | ||
| 246 | out: | 250 | out: |
| 247 | raw_local_irq_restore(flags); | ||
| 248 | unspinning_lock(xl, prev); | 251 | unspinning_lock(xl, prev); |
| 249 | spin_time_accum_blocked(start); | 252 | spin_time_accum_blocked(start); |
| 250 | 253 | ||
| @@ -323,8 +326,13 @@ static void xen_spin_unlock(struct raw_spinlock *lock) | |||
| 323 | smp_wmb(); /* make sure no writes get moved after unlock */ | 326 | smp_wmb(); /* make sure no writes get moved after unlock */ |
| 324 | xl->lock = 0; /* release lock */ | 327 | xl->lock = 0; /* release lock */ |
| 325 | 328 | ||
| 326 | /* make sure unlock happens before kick */ | 329 | /* |
| 327 | barrier(); | 330 | * Make sure unlock happens before checking for waiting |
| 331 | * spinners. We need a strong barrier to enforce the | ||
| 332 | * write-read ordering to different memory locations, as the | ||
| 333 | * CPU makes no implied guarantees about their ordering. | ||
| 334 | */ | ||
| 335 | mb(); | ||
| 328 | 336 | ||
| 329 | if (unlikely(xl->spinners)) | 337 | if (unlikely(xl->spinners)) |
| 330 | xen_spin_unlock_slow(xl); | 338 | xen_spin_unlock_slow(xl); |
diff --git a/arch/xtensa/include/asm/socket.h b/arch/xtensa/include/asm/socket.h index dd1a7a4a1cea..beb3a6bdb61d 100644 --- a/arch/xtensa/include/asm/socket.h +++ b/arch/xtensa/include/asm/socket.h | |||
| @@ -68,4 +68,7 @@ | |||
| 68 | #define SO_TIMESTAMPING 37 | 68 | #define SO_TIMESTAMPING 37 |
| 69 | #define SCM_TIMESTAMPING SO_TIMESTAMPING | 69 | #define SCM_TIMESTAMPING SO_TIMESTAMPING |
| 70 | 70 | ||
| 71 | #define SO_PROTOCOL 38 | ||
| 72 | #define SO_DOMAIN 39 | ||
| 73 | |||
| 71 | #endif /* _XTENSA_SOCKET_H */ | 74 | #endif /* _XTENSA_SOCKET_H */ |
diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c index edad4156d89a..2f0b86b37cf9 100644 --- a/arch/xtensa/platforms/iss/network.c +++ b/arch/xtensa/platforms/iss/network.c | |||
| @@ -545,7 +545,7 @@ static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 545 | spin_unlock_irqrestore(&lp->lock, flags); | 545 | spin_unlock_irqrestore(&lp->lock, flags); |
| 546 | 546 | ||
| 547 | dev_kfree_skb(skb); | 547 | dev_kfree_skb(skb); |
| 548 | return 0; | 548 | return NETDEV_TX_OK; |
| 549 | } | 549 | } |
| 550 | 550 | ||
| 551 | 551 | ||
