From 60e76f512b1ffbdbc81c541bb5dbb275db8b939b Mon Sep 17 00:00:00 2001 From: Eric Van Hensbergen Date: Wed, 13 Jul 2011 19:12:18 -0500 Subject: [PATCH] --- yaml --- r: 257435 b: refs/heads/master c: b85f7d92d7bd7e3298159e8b1eed8cb8cbbb0348 h: refs/heads/master i: 257433: e6731be1cb77d777fc4fd3ff8888e8c97074b950 257431: b99b5ad0b09828103b6eb9331712db5012f70795 v: v3 --- [refs] | 2 +- trunk/Documentation/cgroups/cpuacct.txt | 2 +- trunk/Documentation/cgroups/cpusets.txt | 2 +- trunk/Documentation/sysctl/kernel.txt | 215 ++++++----- trunk/arch/ia64/kvm/Kconfig | 1 + trunk/arch/mips/Kconfig | 16 + trunk/arch/powerpc/kvm/Kconfig | 1 + trunk/arch/s390/kvm/Kconfig | 1 + trunk/arch/sh/Kconfig | 16 + trunk/arch/tile/kvm/Kconfig | 1 + trunk/arch/um/sys-i386/Makefile | 3 +- trunk/arch/x86/Kconfig | 16 +- trunk/arch/x86/Kconfig.cpu | 3 - trunk/arch/x86/boot/Makefile | 9 +- trunk/arch/x86/boot/tools/build.c | 33 +- trunk/arch/x86/include/asm/apb_timer.h | 22 +- trunk/arch/x86/include/asm/cmpxchg_32.h | 48 --- trunk/arch/x86/include/asm/cmpxchg_64.h | 45 --- trunk/arch/x86/include/asm/cpufeature.h | 2 - trunk/arch/x86/kernel/apb_timer.c | 409 +++++++++++++++++---- trunk/arch/x86/kernel/apic/apic.c | 22 +- trunk/arch/x86/kernel/cpu/bugs.c | 4 - trunk/arch/x86/kernel/cpu/hypervisor.c | 4 +- trunk/arch/x86/kernel/quirks.c | 5 +- trunk/arch/x86/kernel/relocate_kernel_32.S | 2 - trunk/arch/x86/kernel/relocate_kernel_64.S | 2 - trunk/arch/x86/kernel/tsc.c | 24 ++ trunk/arch/x86/kvm/Kconfig | 1 + trunk/drivers/Kconfig | 2 - trunk/drivers/clocksource/Kconfig | 3 - trunk/drivers/clocksource/Makefile | 1 - trunk/drivers/clocksource/dw_apb_timer.c | 401 -------------------- trunk/drivers/virtio/Kconfig | 3 - trunk/include/linux/dw_apb_timer.h | 56 --- trunk/include/linux/irq.h | 5 + trunk/init/Kconfig | 2 - trunk/net/9p/client.c | 3 +- trunk/tools/perf/Makefile | 5 +- 38 files changed, 584 insertions(+), 808 deletions(-) delete mode 100644 trunk/drivers/clocksource/dw_apb_timer.c delete mode 100644 trunk/include/linux/dw_apb_timer.h diff --git a/[refs] b/[refs] index ed6719b55a83..3d0235ae3b6b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 807094c0b1c41344def32b249d9faf7b5ebeb1e7 +refs/heads/master: b85f7d92d7bd7e3298159e8b1eed8cb8cbbb0348 diff --git a/trunk/Documentation/cgroups/cpuacct.txt b/trunk/Documentation/cgroups/cpuacct.txt index 9d73cc0cadb9..9ad85df4b983 100644 --- a/trunk/Documentation/cgroups/cpuacct.txt +++ b/trunk/Documentation/cgroups/cpuacct.txt @@ -23,7 +23,7 @@ New accounting groups can be created under the parent group /sys/fs/cgroup. # cd /sys/fs/cgroup # mkdir g1 -# echo $$ > g1/tasks +# echo $$ > g1 The above steps create a new group g1 and move the current shell process (bash) into it. CPU time consumed by this bash and its children diff --git a/trunk/Documentation/cgroups/cpusets.txt b/trunk/Documentation/cgroups/cpusets.txt index 5c51ed406d1d..5b0d78e55ccc 100644 --- a/trunk/Documentation/cgroups/cpusets.txt +++ b/trunk/Documentation/cgroups/cpusets.txt @@ -180,7 +180,7 @@ files describing that cpuset: - cpuset.sched_load_balance flag: if set, load balance within CPUs on that cpuset - cpuset.sched_relax_domain_level: the searching range when migrating tasks -In addition, only the root cpuset has the following file: +In addition, the root cpuset only has the following file: - cpuset.memory_pressure_enabled flag: compute memory_pressure? New cpusets are created using the mkdir system call or shell diff --git a/trunk/Documentation/sysctl/kernel.txt b/trunk/Documentation/sysctl/kernel.txt index 1c7fb0a94e28..5e7cb39ad195 100644 --- a/trunk/Documentation/sysctl/kernel.txt +++ b/trunk/Documentation/sysctl/kernel.txt @@ -17,21 +17,23 @@ before actually making adjustments. Currently, these files might (depending on your configuration) show up in /proc/sys/kernel: - -- acct - acpi_video_flags -- auto_msgmni +- acct - bootloader_type [ X86 only ] - bootloader_version [ X86 only ] - callhome [ S390 only ] +- auto_msgmni - core_pattern - core_pipe_limit - core_uses_pid - ctrl-alt-del +- dentry-state - dmesg_restrict - domainname - hostname - hotplug +- java-appletviewer [ binfmt_java, obsolete ] +- java-interpreter [ binfmt_java, obsolete ] - kptr_restrict - kstack_depth_to_print [ X86 only ] - l2cr [ PPC only ] @@ -46,14 +48,10 @@ show up in /proc/sys/kernel: - overflowgid - overflowuid - panic -- panic_on_oops -- panic_on_unrecovered_nmi - pid_max - powersave-nap [ PPC only ] +- panic_on_unrecovered_nmi - printk -- printk_delay -- printk_ratelimit -- printk_ratelimit_burst - randomize_va_space - real-root-dev ==> Documentation/initrd.txt - reboot-cmd [ SPARC only ] @@ -64,7 +62,6 @@ show up in /proc/sys/kernel: - shmall - shmmax [ sysv ipc ] - shmmni -- softlockup_thresh - stop-a [ SPARC only ] - sysrq ==> Documentation/sysrq.txt - tainted @@ -74,6 +71,15 @@ show up in /proc/sys/kernel: ============================================================== +acpi_video_flags: + +flags + +See Doc*/kernel/power/video.txt, it allows mode of video boot to be +set during run time. + +============================================================== + acct: highwater lowwater frequency @@ -89,25 +95,6 @@ That is, suspend accounting if there left <= 2% free; resume it if we got >=4%; consider information about amount of free space valid for 30 seconds. -============================================================== - -acpi_video_flags: - -flags - -See Doc*/kernel/power/video.txt, it allows mode of video boot to be -set during run time. - -============================================================== - -auto_msgmni: - -Enables/Disables automatic recomputing of msgmni upon memory add/remove -or upon ipc namespace creation/removal (see the msgmni description -above). Echoing "1" into this file enables msgmni automatic recomputing. -Echoing "0" turns it off. auto_msgmni default value is 1. - - ============================================================== bootloader_type: @@ -185,24 +172,22 @@ core_pattern is used to specify a core dumpfile pattern name. core_pipe_limit: -This sysctl is only applicable when core_pattern is configured to pipe -core files to a user space helper (when the first character of -core_pattern is a '|', see above). When collecting cores via a pipe -to an application, it is occasionally useful for the collecting -application to gather data about the crashing process from its -/proc/pid directory. In order to do this safely, the kernel must wait -for the collecting process to exit, so as not to remove the crashing -processes proc files prematurely. This in turn creates the -possibility that a misbehaving userspace collecting process can block -the reaping of a crashed process simply by never exiting. This sysctl -defends against that. It defines how many concurrent crashing -processes may be piped to user space applications in parallel. If -this value is exceeded, then those crashing processes above that value -are noted via the kernel log and their cores are skipped. 0 is a -special value, indicating that unlimited processes may be captured in -parallel, but that no waiting will take place (i.e. the collecting -process is not guaranteed access to /proc//). This -value defaults to 0. +This sysctl is only applicable when core_pattern is configured to pipe core +files to a user space helper (when the first character of core_pattern is a '|', +see above). When collecting cores via a pipe to an application, it is +occasionally useful for the collecting application to gather data about the +crashing process from its /proc/pid directory. In order to do this safely, the +kernel must wait for the collecting process to exit, so as not to remove the +crashing processes proc files prematurely. This in turn creates the possibility +that a misbehaving userspace collecting process can block the reaping of a +crashed process simply by never exiting. This sysctl defends against that. It +defines how many concurrent crashing processes may be piped to user space +applications in parallel. If this value is exceeded, then those crashing +processes above that value are noted via the kernel log and their cores are +skipped. 0 is a special value, indicating that unlimited processes may be +captured in parallel, but that no waiting will take place (i.e. the collecting +process is not guaranteed access to /proc//). This value defaults +to 0. ============================================================== @@ -233,14 +218,14 @@ to decide what to do with it. dmesg_restrict: -This toggle indicates whether unprivileged users are prevented -from using dmesg(8) to view messages from the kernel's log buffer. -When dmesg_restrict is set to (0) there are no restrictions. When +This toggle indicates whether unprivileged users are prevented from using +dmesg(8) to view messages from the kernel's log buffer. When +dmesg_restrict is set to (0) there are no restrictions. When dmesg_restrict is set set to (1), users must have CAP_SYSLOG to use dmesg(8). -The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the -default value of dmesg_restrict. +The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default +value of dmesg_restrict. ============================================================== @@ -271,6 +256,13 @@ Default value is "/sbin/hotplug". ============================================================== +l2cr: (PPC only) + +This flag controls the L2 cache of G3 processor boards. If +0, the cache is disabled. Enabled if nonzero. + +============================================================== + kptr_restrict: This toggle indicates whether restrictions are placed on @@ -291,13 +283,6 @@ kernel stack. ============================================================== -l2cr: (PPC only) - -This flag controls the L2 cache of G3 processor boards. If -0, the cache is disabled. Enabled if nonzero. - -============================================================== - modules_disabled: A toggle value indicating if modules are allowed to be loaded @@ -308,21 +293,6 @@ to false. ============================================================== -nmi_watchdog: - -Enables/Disables the NMI watchdog on x86 systems. When the value is -non-zero the NMI watchdog is enabled and will continuously test all -online cpus to determine whether or not they are still functioning -properly. Currently, passing "nmi_watchdog=" parameter at boot time is -required for this function to work. - -If LAPIC NMI watchdog method is in use (nmi_watchdog=2 kernel -parameter), the NMI watchdog shares registers with oprofile. By -disabling the NMI watchdog, oprofile may have more registers to -utilize. - -============================================================== - osrelease, ostype & version: # cat osrelease @@ -342,10 +312,10 @@ The only way to tune these values is to rebuild the kernel :-) overflowgid & overflowuid: -if your architecture did not always support 32-bit UIDs (i.e. arm, -i386, m68k, sh, and sparc32), a fixed UID and GID will be returned to -applications that use the old 16-bit UID/GID system calls, if the -actual UID or GID would exceed 65535. +if your architecture did not always support 32-bit UIDs (i.e. arm, i386, +m68k, sh, and sparc32), a fixed UID and GID will be returned to +applications that use the old 16-bit UID/GID system calls, if the actual +UID or GID would exceed 65535. These sysctls allow you to change the value of the fixed UID and GID. The default is 65534. @@ -354,22 +324,9 @@ The default is 65534. panic: -The value in this file represents the number of seconds the kernel -waits before rebooting on a panic. When you use the software watchdog, -the recommended setting is 60. - -============================================================== - -panic_on_unrecovered_nmi: - -The default Linux behaviour on an NMI of either memory or unknown is -to continue operation. For many environments such as scientific -computing it is preferable that the box is taken out and the error -dealt with than an uncorrected parity/ECC error get propagated. - -A small number of systems do generate NMI's for bizarre random reasons -such as power management so the default is off. That sysctl works like -the existing panic controls already in that directory. +The value in this file represents the number of seconds the +kernel waits before rebooting on a panic. When you use the +software watchdog, the recommended setting is 60. ============================================================== @@ -419,14 +376,6 @@ the different loglevels. ============================================================== -printk_delay: - -Delay each printk message in printk_delay milliseconds - -Value from 0 - 10000 is allowed. - -============================================================== - printk_ratelimit: Some warning messages are rate limited. printk_ratelimit specifies @@ -446,7 +395,15 @@ send before ratelimiting kicks in. ============================================================== -randomize_va_space: +printk_delay: + +Delay each printk message in printk_delay milliseconds + +Value from 0 - 10000 is allowed. + +============================================================== + +randomize-va-space: This option can be used to select the type of process address space randomization that is used in the system, for architectures @@ -509,11 +466,11 @@ are doing anyway :) ============================================================== -shmmax: +shmmax: This value can be used to query and set the run time limit on the maximum shared memory segment size that can be created. -Shared memory segments up to 1Gb are now supported in the +Shared memory segments up to 1Gb are now supported in the kernel. This value defaults to SHMMAX. ============================================================== @@ -527,7 +484,7 @@ tunable to zero will disable the softlockup detection altogether. ============================================================== -tainted: +tainted: Non-zero if the kernel has been tainted. Numeric values, which can be ORed together: @@ -552,11 +509,49 @@ can be ORed together: ============================================================== +auto_msgmni: + +Enables/Disables automatic recomputing of msgmni upon memory add/remove or +upon ipc namespace creation/removal (see the msgmni description above). +Echoing "1" into this file enables msgmni automatic recomputing. +Echoing "0" turns it off. +auto_msgmni default value is 1. + +============================================================== + +nmi_watchdog: + +Enables/Disables the NMI watchdog on x86 systems. When the value is non-zero +the NMI watchdog is enabled and will continuously test all online cpus to +determine whether or not they are still functioning properly. Currently, +passing "nmi_watchdog=" parameter at boot time is required for this function +to work. + +If LAPIC NMI watchdog method is in use (nmi_watchdog=2 kernel parameter), the +NMI watchdog shares registers with oprofile. By disabling the NMI watchdog, +oprofile may have more registers to utilize. + +============================================================== + unknown_nmi_panic: -The value in this file affects behavior of handling NMI. When the -value is non-zero, unknown NMI is trapped and then panic occurs. At -that time, kernel debugging information is displayed on console. +The value in this file affects behavior of handling NMI. When the value is +non-zero, unknown NMI is trapped and then panic occurs. At that time, kernel +debugging information is displayed on console. + +NMI switch that most IA32 servers have fires unknown NMI up, for example. +If a system hangs up, try pressing the NMI switch. + +============================================================== + +panic_on_unrecovered_nmi: + +The default Linux behaviour on an NMI of either memory or unknown is to continue +operation. For many environments such as scientific computing it is preferable +that the box is taken out and the error dealt with than an uncorrected +parity/ECC error get propogated. + +A small number of systems do generate NMI's for bizarre random reasons such as +power management so the default is off. That sysctl works like the existing +panic controls already in that directory. -NMI switch that most IA32 servers have fires unknown NMI up, for -example. If a system hangs up, try pressing the NMI switch. diff --git a/trunk/arch/ia64/kvm/Kconfig b/trunk/arch/ia64/kvm/Kconfig index 9806e55f91be..fa4d1e59deb0 100644 --- a/trunk/arch/ia64/kvm/Kconfig +++ b/trunk/arch/ia64/kvm/Kconfig @@ -49,5 +49,6 @@ config KVM_INTEL extensions. source drivers/vhost/Kconfig +source drivers/virtio/Kconfig endif # VIRTUALIZATION diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 177cdaf83564..6cb60adb7b30 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -2493,4 +2493,20 @@ source "security/Kconfig" source "crypto/Kconfig" +menuconfig VIRTUALIZATION + bool "Virtualization" + default n + ---help--- + Say Y here to get to see options for using your Linux host to run other + operating systems inside virtual machines (guests). + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + +if VIRTUALIZATION + +source drivers/virtio/Kconfig + +endif # VIRTUALIZATION + source "lib/Kconfig" diff --git a/trunk/arch/powerpc/kvm/Kconfig b/trunk/arch/powerpc/kvm/Kconfig index 105b6918b23e..b7baff78f90c 100644 --- a/trunk/arch/powerpc/kvm/Kconfig +++ b/trunk/arch/powerpc/kvm/Kconfig @@ -99,5 +99,6 @@ config KVM_E500 If unsure, say N. source drivers/vhost/Kconfig +source drivers/virtio/Kconfig endif # VIRTUALIZATION diff --git a/trunk/arch/s390/kvm/Kconfig b/trunk/arch/s390/kvm/Kconfig index a21634173a66..f66a1bdbb61d 100644 --- a/trunk/arch/s390/kvm/Kconfig +++ b/trunk/arch/s390/kvm/Kconfig @@ -37,5 +37,6 @@ config KVM # OK, it's a little counter-intuitive to do this, but it puts it neatly under # the virtualization menu. source drivers/vhost/Kconfig +source drivers/virtio/Kconfig endif # VIRTUALIZATION diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index 748ff1920068..bbdeb48bbf8e 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -897,4 +897,20 @@ source "security/Kconfig" source "crypto/Kconfig" +menuconfig VIRTUALIZATION + bool "Virtualization" + default n + ---help--- + Say Y here to get to see options for using your Linux host to run other + operating systems inside virtual machines (guests). + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + +if VIRTUALIZATION + +source drivers/virtio/Kconfig + +endif # VIRTUALIZATION + source "lib/Kconfig" diff --git a/trunk/arch/tile/kvm/Kconfig b/trunk/arch/tile/kvm/Kconfig index 669fcdba31ea..b88f9c047781 100644 --- a/trunk/arch/tile/kvm/Kconfig +++ b/trunk/arch/tile/kvm/Kconfig @@ -33,5 +33,6 @@ config KVM If unsure, say N. source drivers/vhost/Kconfig +source drivers/virtio/Kconfig endif # VIRTUALIZATION diff --git a/trunk/arch/um/sys-i386/Makefile b/trunk/arch/um/sys-i386/Makefile index 87b659dadf3f..15587ed9a361 100644 --- a/trunk/arch/um/sys-i386/Makefile +++ b/trunk/arch/um/sys-i386/Makefile @@ -8,8 +8,7 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ obj-$(CONFIG_BINFMT_ELF) += elfcore.o -subarch-obj-y = lib/string_32.o -subarch-obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += lib/rwsem.o +subarch-obj-y = lib/rwsem.o lib/string_32.o subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o subarch-obj-$(CONFIG_MODULES) += kernel/module.o diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index b2127544fbe7..5f60ea190d5b 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -390,21 +390,12 @@ config X86_INTEL_CE This option compiles in support for the CE4100 SOC for settop boxes and media devices. -config X86_INTEL_MID - bool "Intel MID platform support" - depends on X86_32 - depends on X86_EXTENDED_PLATFORM - ---help--- - Select to build a kernel capable of supporting Intel MID platform - systems which do not have the PCI legacy interfaces (Moorestown, - Medfield). If you are building for a PC class system say N here. - -if X86_INTEL_MID - config X86_MRST bool "Moorestown MID platform" depends on PCI depends on PCI_GOANY + depends on X86_32 + depends on X86_EXTENDED_PLATFORM depends on X86_IO_APIC select APB_TIMER select I2C @@ -419,8 +410,6 @@ config X86_MRST nor standard legacy replacement devices/features. e.g. Moorestown does not contain i8259, i8254, HPET, legacy BIOS, most of the io ports. -endif - config X86_RDC321X bool "RDC R-321x SoC" depends on X86_32 @@ -634,7 +623,6 @@ config HPET_EMULATE_RTC config APB_TIMER def_bool y if MRST prompt "Langwell APB Timer Support" if X86_MRST - select DW_APB_TIMER help APB timer is the replacement for 8254, HPET on X86 MID platforms. The APBT provides a stable time base on SMP diff --git a/trunk/arch/x86/Kconfig.cpu b/trunk/arch/x86/Kconfig.cpu index e3ca7e0d858c..6a7cfdf8ff69 100644 --- a/trunk/arch/x86/Kconfig.cpu +++ b/trunk/arch/x86/Kconfig.cpu @@ -312,9 +312,6 @@ config X86_CMPXCHG config CMPXCHG_LOCAL def_bool X86_64 || (X86_32 && !M386) -config CMPXCHG_DOUBLE - def_bool y - config X86_L1_CACHE_SHIFT int default "7" if MPENTIUM4 || MPSC diff --git a/trunk/arch/x86/boot/Makefile b/trunk/arch/x86/boot/Makefile index 95365a82b6a0..f7cb086b4add 100644 --- a/trunk/arch/x86/boot/Makefile +++ b/trunk/arch/x86/boot/Makefile @@ -9,6 +9,12 @@ # Changed by many, many contributors over the years. # +# ROOT_DEV specifies the default root-device when making the image. +# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case +# the default of FLOPPY is used by 'build'. + +ROOT_DEV := CURRENT + # If you want to preset the SVGA mode, uncomment the next line and # set SVGA_MODE to whatever number you want. # Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode. @@ -69,7 +75,8 @@ GCOV_PROFILE := n $(obj)/bzImage: asflags-y := $(SVGA_MODE) quiet_cmd_image = BUILD $@ -cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin > $@ +cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin \ + $(ROOT_DEV) > $@ $(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE $(call if_changed,image) diff --git a/trunk/arch/x86/boot/tools/build.c b/trunk/arch/x86/boot/tools/build.c index fdc60a0b3c20..ee3a4ea923ac 100644 --- a/trunk/arch/x86/boot/tools/build.c +++ b/trunk/arch/x86/boot/tools/build.c @@ -130,7 +130,7 @@ static void die(const char * str, ...) static void usage(void) { - die("Usage: build setup system [> image]"); + die("Usage: build setup system [rootdev] [> image]"); } int main(int argc, char ** argv) @@ -138,14 +138,39 @@ int main(int argc, char ** argv) unsigned int i, sz, setup_sectors; int c; u32 sys_size; + u8 major_root, minor_root; struct stat sb; FILE *file; int fd; void *kernel; u32 crc = 0xffffffffUL; - if (argc != 3) + if ((argc < 3) || (argc > 4)) usage(); + if (argc > 3) { + if (!strcmp(argv[3], "CURRENT")) { + if (stat("/", &sb)) { + perror("/"); + die("Couldn't stat /"); + } + major_root = major(sb.st_dev); + minor_root = minor(sb.st_dev); + } else if (strcmp(argv[3], "FLOPPY")) { + if (stat(argv[3], &sb)) { + perror(argv[3]); + die("Couldn't stat root device."); + } + major_root = major(sb.st_rdev); + minor_root = minor(sb.st_rdev); + } else { + major_root = 0; + minor_root = 0; + } + } else { + major_root = DEFAULT_MAJOR_ROOT; + minor_root = DEFAULT_MINOR_ROOT; + } + fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root); /* Copy the setup code */ file = fopen(argv[1], "r"); @@ -168,8 +193,8 @@ int main(int argc, char ** argv) memset(buf+c, 0, i-c); /* Set the default root device */ - buf[508] = DEFAULT_MINOR_ROOT; - buf[509] = DEFAULT_MAJOR_ROOT; + buf[508] = minor_root; + buf[509] = major_root; fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i); diff --git a/trunk/arch/x86/include/asm/apb_timer.h b/trunk/arch/x86/include/asm/apb_timer.h index 0acbac299e49..082cf8184935 100644 --- a/trunk/arch/x86/include/asm/apb_timer.h +++ b/trunk/arch/x86/include/asm/apb_timer.h @@ -18,6 +18,24 @@ #ifdef CONFIG_APB_TIMER +/* Langwell DW APB timer registers */ +#define APBTMR_N_LOAD_COUNT 0x00 +#define APBTMR_N_CURRENT_VALUE 0x04 +#define APBTMR_N_CONTROL 0x08 +#define APBTMR_N_EOI 0x0c +#define APBTMR_N_INT_STATUS 0x10 + +#define APBTMRS_INT_STATUS 0xa0 +#define APBTMRS_EOI 0xa4 +#define APBTMRS_RAW_INT_STATUS 0xa8 +#define APBTMRS_COMP_VERSION 0xac +#define APBTMRS_REG_SIZE 0x14 + +/* register bits */ +#define APBTMR_CONTROL_ENABLE (1<<0) +#define APBTMR_CONTROL_MODE_PERIODIC (1<<1) /*1: periodic 0:free running */ +#define APBTMR_CONTROL_INT (1<<2) + /* default memory mapped register base */ #define LNW_SCU_ADDR 0xFF100000 #define LNW_EXT_TIMER_OFFSET 0x1B800 @@ -25,8 +43,8 @@ #define LNW_EXT_TIMER_PGOFFSET 0x800 /* APBT clock speed range from PCLK to fabric base, 25-100MHz */ -#define APBT_MAX_FREQ 50000000 -#define APBT_MIN_FREQ 1000000 +#define APBT_MAX_FREQ 50 +#define APBT_MIN_FREQ 1 #define APBT_MMAP_SIZE 1024 #define APBT_DEV_USED 1 diff --git a/trunk/arch/x86/include/asm/cmpxchg_32.h b/trunk/arch/x86/include/asm/cmpxchg_32.h index 3deb7250624c..284a6e8f7ce1 100644 --- a/trunk/arch/x86/include/asm/cmpxchg_32.h +++ b/trunk/arch/x86/include/asm/cmpxchg_32.h @@ -280,52 +280,4 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old, #endif -#define cmpxchg8b(ptr, o1, o2, n1, n2) \ -({ \ - char __ret; \ - __typeof__(o2) __dummy; \ - __typeof__(*(ptr)) __old1 = (o1); \ - __typeof__(o2) __old2 = (o2); \ - __typeof__(*(ptr)) __new1 = (n1); \ - __typeof__(o2) __new2 = (n2); \ - asm volatile(LOCK_PREFIX "cmpxchg8b %2; setz %1" \ - : "=d"(__dummy), "=a" (__ret), "+m" (*ptr)\ - : "a" (__old1), "d"(__old2), \ - "b" (__new1), "c" (__new2) \ - : "memory"); \ - __ret; }) - - -#define cmpxchg8b_local(ptr, o1, o2, n1, n2) \ -({ \ - char __ret; \ - __typeof__(o2) __dummy; \ - __typeof__(*(ptr)) __old1 = (o1); \ - __typeof__(o2) __old2 = (o2); \ - __typeof__(*(ptr)) __new1 = (n1); \ - __typeof__(o2) __new2 = (n2); \ - asm volatile("cmpxchg8b %2; setz %1" \ - : "=d"(__dummy), "=a"(__ret), "+m" (*ptr)\ - : "a" (__old), "d"(__old2), \ - "b" (__new1), "c" (__new2), \ - : "memory"); \ - __ret; }) - - -#define cmpxchg_double(ptr, o1, o2, n1, n2) \ -({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 4); \ - VM_BUG_ON((unsigned long)(ptr) % 8); \ - cmpxchg8b((ptr), (o1), (o2), (n1), (n2)); \ -}) - -#define cmpxchg_double_local(ptr, o1, o2, n1, n2) \ -({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 4); \ - VM_BUG_ON((unsigned long)(ptr) % 8); \ - cmpxchg16b_local((ptr), (o1), (o2), (n1), (n2)); \ -}) - -#define system_has_cmpxchg_double() cpu_has_cx8 - #endif /* _ASM_X86_CMPXCHG_32_H */ diff --git a/trunk/arch/x86/include/asm/cmpxchg_64.h b/trunk/arch/x86/include/asm/cmpxchg_64.h index 7cf5c0a24434..423ae58aa020 100644 --- a/trunk/arch/x86/include/asm/cmpxchg_64.h +++ b/trunk/arch/x86/include/asm/cmpxchg_64.h @@ -151,49 +151,4 @@ extern void __cmpxchg_wrong_size(void); cmpxchg_local((ptr), (o), (n)); \ }) -#define cmpxchg16b(ptr, o1, o2, n1, n2) \ -({ \ - char __ret; \ - __typeof__(o2) __junk; \ - __typeof__(*(ptr)) __old1 = (o1); \ - __typeof__(o2) __old2 = (o2); \ - __typeof__(*(ptr)) __new1 = (n1); \ - __typeof__(o2) __new2 = (n2); \ - asm volatile(LOCK_PREFIX "cmpxchg16b %2;setz %1" \ - : "=d"(__junk), "=a"(__ret), "+m" (*ptr) \ - : "b"(__new1), "c"(__new2), \ - "a"(__old1), "d"(__old2)); \ - __ret; }) - - -#define cmpxchg16b_local(ptr, o1, o2, n1, n2) \ -({ \ - char __ret; \ - __typeof__(o2) __junk; \ - __typeof__(*(ptr)) __old1 = (o1); \ - __typeof__(o2) __old2 = (o2); \ - __typeof__(*(ptr)) __new1 = (n1); \ - __typeof__(o2) __new2 = (n2); \ - asm volatile("cmpxchg16b %2;setz %1" \ - : "=d"(__junk), "=a"(__ret), "+m" (*ptr) \ - : "b"(__new1), "c"(__new2), \ - "a"(__old1), "d"(__old2)); \ - __ret; }) - -#define cmpxchg_double(ptr, o1, o2, n1, n2) \ -({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ - VM_BUG_ON((unsigned long)(ptr) % 16); \ - cmpxchg16b((ptr), (o1), (o2), (n1), (n2)); \ -}) - -#define cmpxchg_double_local(ptr, o1, o2, n1, n2) \ -({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ - VM_BUG_ON((unsigned long)(ptr) % 16); \ - cmpxchg16b_local((ptr), (o1), (o2), (n1), (n2)); \ -}) - -#define system_has_cmpxchg_double() cpu_has_cx16 - #endif /* _ASM_X86_CMPXCHG_64_H */ diff --git a/trunk/arch/x86/include/asm/cpufeature.h b/trunk/arch/x86/include/asm/cpufeature.h index 4258aac99a6e..9929b35929ff 100644 --- a/trunk/arch/x86/include/asm/cpufeature.h +++ b/trunk/arch/x86/include/asm/cpufeature.h @@ -288,8 +288,6 @@ extern const char * const x86_power_flags[32]; #define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR) #define cpu_has_pclmulqdq boot_cpu_has(X86_FEATURE_PCLMULQDQ) #define cpu_has_perfctr_core boot_cpu_has(X86_FEATURE_PERFCTR_CORE) -#define cpu_has_cx8 boot_cpu_has(X86_FEATURE_CX8) -#define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16) #if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64) # define cpu_has_invlpg 1 diff --git a/trunk/arch/x86/kernel/apb_timer.c b/trunk/arch/x86/kernel/apb_timer.c index afdc3f756dea..2b6630d75e17 100644 --- a/trunk/arch/x86/kernel/apb_timer.c +++ b/trunk/arch/x86/kernel/apb_timer.c @@ -27,12 +27,15 @@ * timer, but by default APB timer has higher rating than local APIC timers. */ +#include +#include #include -#include #include #include +#include #include #include +#include #include #include #include @@ -43,46 +46,75 @@ #include #include +#define APBT_MASK CLOCKSOURCE_MASK(32) +#define APBT_SHIFT 22 #define APBT_CLOCKEVENT_RATING 110 #define APBT_CLOCKSOURCE_RATING 250 +#define APBT_MIN_DELTA_USEC 200 +#define EVT_TO_APBT_DEV(evt) container_of(evt, struct apbt_dev, evt) #define APBT_CLOCKEVENT0_NUM (0) +#define APBT_CLOCKEVENT1_NUM (1) #define APBT_CLOCKSOURCE_NUM (2) -static phys_addr_t apbt_address; +static unsigned long apbt_address; static int apb_timer_block_enabled; static void __iomem *apbt_virt_address; +static int phy_cs_timer_id; /* * Common DW APB timer info */ -static unsigned long apbt_freq; +static uint64_t apbt_freq; + +static void apbt_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt); +static int apbt_next_event(unsigned long delta, + struct clock_event_device *evt); +static cycle_t apbt_read_clocksource(struct clocksource *cs); +static void apbt_restart_clocksource(struct clocksource *cs); struct apbt_dev { - struct dw_apb_clock_event_device *timer; - unsigned int num; - int cpu; - unsigned int irq; - char name[10]; + struct clock_event_device evt; + unsigned int num; + int cpu; + unsigned int irq; + unsigned int tick; + unsigned int count; + unsigned int flags; + char name[10]; }; -static struct dw_apb_clocksource *clocksource_apbt; - -static inline void __iomem *adev_virt_addr(struct apbt_dev *adev) -{ - return apbt_virt_address + adev->num * APBTMRS_REG_SIZE; -} - static DEFINE_PER_CPU(struct apbt_dev, cpu_apbt_dev); #ifdef CONFIG_SMP static unsigned int apbt_num_timers_used; +static struct apbt_dev *apbt_devs; #endif +static inline unsigned long apbt_readl_reg(unsigned long a) +{ + return readl(apbt_virt_address + a); +} + +static inline void apbt_writel_reg(unsigned long d, unsigned long a) +{ + writel(d, apbt_virt_address + a); +} + +static inline unsigned long apbt_readl(int n, unsigned long a) +{ + return readl(apbt_virt_address + a + n * APBTMRS_REG_SIZE); +} + +static inline void apbt_writel(int n, unsigned long d, unsigned long a) +{ + writel(d, apbt_virt_address + a + n * APBTMRS_REG_SIZE); +} + static inline void apbt_set_mapping(void) { struct sfi_timer_table_entry *mtmr; - int phy_cs_timer_id = 0; if (apbt_virt_address) { pr_debug("APBT base already mapped\n"); @@ -94,18 +126,21 @@ static inline void apbt_set_mapping(void) APBT_CLOCKEVENT0_NUM); return; } - apbt_address = (phys_addr_t)mtmr->phys_addr; + apbt_address = (unsigned long)mtmr->phys_addr; if (!apbt_address) { printk(KERN_WARNING "No timer base from SFI, use default\n"); apbt_address = APBT_DEFAULT_BASE; } apbt_virt_address = ioremap_nocache(apbt_address, APBT_MMAP_SIZE); - if (!apbt_virt_address) { - pr_debug("Failed mapping APBT phy address at %lu\n",\ - (unsigned long)apbt_address); + if (apbt_virt_address) { + pr_debug("Mapped APBT physical addr %p at virtual addr %p\n",\ + (void *)apbt_address, (void *)apbt_virt_address); + } else { + pr_debug("Failed mapping APBT phy address at %p\n",\ + (void *)apbt_address); goto panic_noapbt; } - apbt_freq = mtmr->freq_hz; + apbt_freq = mtmr->freq_hz / USEC_PER_SEC; sfi_free_mtmr(mtmr); /* Now figure out the physical timer id for clocksource device */ @@ -114,14 +149,9 @@ static inline void apbt_set_mapping(void) goto panic_noapbt; /* Now figure out the physical timer id */ - pr_debug("Use timer %d for clocksource\n", - (int)(mtmr->phys_addr & 0xff) / APBTMRS_REG_SIZE); - phy_cs_timer_id = (unsigned int)(mtmr->phys_addr & 0xff) / - APBTMRS_REG_SIZE; - - clocksource_apbt = dw_apb_clocksource_init(APBT_CLOCKSOURCE_RATING, - "apbt0", apbt_virt_address + phy_cs_timer_id * - APBTMRS_REG_SIZE, apbt_freq); + phy_cs_timer_id = (unsigned int)(mtmr->phys_addr & 0xff) + / APBTMRS_REG_SIZE; + pr_debug("Use timer %d for clocksource\n", phy_cs_timer_id); return; panic_noapbt: @@ -143,6 +173,82 @@ static inline int is_apbt_capable(void) return apbt_virt_address ? 1 : 0; } +static struct clocksource clocksource_apbt = { + .name = "apbt", + .rating = APBT_CLOCKSOURCE_RATING, + .read = apbt_read_clocksource, + .mask = APBT_MASK, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, + .resume = apbt_restart_clocksource, +}; + +/* boot APB clock event device */ +static struct clock_event_device apbt_clockevent = { + .name = "apbt0", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_mode = apbt_set_mode, + .set_next_event = apbt_next_event, + .shift = APBT_SHIFT, + .irq = 0, + .rating = APBT_CLOCKEVENT_RATING, +}; + +/* + * start count down from 0xffff_ffff. this is done by toggling the enable bit + * then load initial load count to ~0. + */ +static void apbt_start_counter(int n) +{ + unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL); + + ctrl &= ~APBTMR_CONTROL_ENABLE; + apbt_writel(n, ctrl, APBTMR_N_CONTROL); + apbt_writel(n, ~0, APBTMR_N_LOAD_COUNT); + /* enable, mask interrupt */ + ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC; + ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT); + apbt_writel(n, ctrl, APBTMR_N_CONTROL); + /* read it once to get cached counter value initialized */ + apbt_read_clocksource(&clocksource_apbt); +} + +static irqreturn_t apbt_interrupt_handler(int irq, void *data) +{ + struct apbt_dev *dev = (struct apbt_dev *)data; + struct clock_event_device *aevt = &dev->evt; + + if (!aevt->event_handler) { + printk(KERN_INFO "Spurious APBT timer interrupt on %d\n", + dev->num); + return IRQ_NONE; + } + aevt->event_handler(aevt); + return IRQ_HANDLED; +} + +static void apbt_restart_clocksource(struct clocksource *cs) +{ + apbt_start_counter(phy_cs_timer_id); +} + +static void apbt_enable_int(int n) +{ + unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL); + /* clear pending intr */ + apbt_readl(n, APBTMR_N_EOI); + ctrl &= ~APBTMR_CONTROL_INT; + apbt_writel(n, ctrl, APBTMR_N_CONTROL); +} + +static void apbt_disable_int(int n) +{ + unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL); + + ctrl |= APBTMR_CONTROL_INT; + apbt_writel(n, ctrl, APBTMR_N_CONTROL); +} + + static int __init apbt_clockevent_register(void) { struct sfi_timer_table_entry *mtmr; @@ -155,21 +261,45 @@ static int __init apbt_clockevent_register(void) return -ENODEV; } + /* + * We need to calculate the scaled math multiplication factor for + * nanosecond to apbt tick conversion. + * mult = (nsec/cycle)*2^APBT_SHIFT + */ + apbt_clockevent.mult = div_sc((unsigned long) mtmr->freq_hz + , NSEC_PER_SEC, APBT_SHIFT); + + /* Calculate the min / max delta */ + apbt_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, + &apbt_clockevent); + apbt_clockevent.min_delta_ns = clockevent_delta2ns( + APBT_MIN_DELTA_USEC*apbt_freq, + &apbt_clockevent); + /* + * Start apbt with the boot cpu mask and make it + * global if not used for per cpu timer. + */ + apbt_clockevent.cpumask = cpumask_of(smp_processor_id()); adev->num = smp_processor_id(); - adev->timer = dw_apb_clockevent_init(smp_processor_id(), "apbt0", - mrst_timer_options == MRST_TIMER_LAPIC_APBT ? - APBT_CLOCKEVENT_RATING - 100 : APBT_CLOCKEVENT_RATING, - adev_virt_addr(adev), 0, apbt_freq); - /* Firmware does EOI handling for us. */ - adev->timer->eoi = NULL; + memcpy(&adev->evt, &apbt_clockevent, sizeof(struct clock_event_device)); if (mrst_timer_options == MRST_TIMER_LAPIC_APBT) { - global_clock_event = &adev->timer->ced; + adev->evt.rating = APBT_CLOCKEVENT_RATING - 100; + global_clock_event = &adev->evt; printk(KERN_DEBUG "%s clockevent registered as global\n", global_clock_event->name); } - dw_apb_clockevent_register(adev->timer); + if (request_irq(apbt_clockevent.irq, apbt_interrupt_handler, + IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING, + apbt_clockevent.name, adev)) { + printk(KERN_ERR "Failed request IRQ for APBT%d\n", + apbt_clockevent.irq); + } + + clockevents_register_device(&adev->evt); + /* Start APBT 0 interrupts */ + apbt_enable_int(APBT_CLOCKEVENT0_NUM); sfi_free_mtmr(mtmr); return 0; @@ -187,34 +317,52 @@ static void apbt_setup_irq(struct apbt_dev *adev) irq_set_affinity(adev->irq, cpumask_of(adev->cpu)); /* APB timer irqs are set up as mp_irqs, timer is edge type */ __irq_set_handler(adev->irq, handle_edge_irq, 0, "edge"); + + if (system_state == SYSTEM_BOOTING) { + if (request_irq(adev->irq, apbt_interrupt_handler, + IRQF_TIMER | IRQF_DISABLED | + IRQF_NOBALANCING, + adev->name, adev)) { + printk(KERN_ERR "Failed request IRQ for APBT%d\n", + adev->num); + } + } else + enable_irq(adev->irq); } /* Should be called with per cpu */ void apbt_setup_secondary_clock(void) { struct apbt_dev *adev; + struct clock_event_device *aevt; int cpu; /* Don't register boot CPU clockevent */ cpu = smp_processor_id(); if (!cpu) return; + /* + * We need to calculate the scaled math multiplication factor for + * nanosecond to apbt tick conversion. + * mult = (nsec/cycle)*2^APBT_SHIFT + */ + printk(KERN_INFO "Init per CPU clockevent %d\n", cpu); + adev = &per_cpu(cpu_apbt_dev, cpu); + aevt = &adev->evt; - adev = &__get_cpu_var(cpu_apbt_dev); - if (!adev->timer) { - adev->timer = dw_apb_clockevent_init(cpu, adev->name, - APBT_CLOCKEVENT_RATING, adev_virt_addr(adev), - adev->irq, apbt_freq); - adev->timer->eoi = NULL; - } else { - dw_apb_clockevent_resume(adev->timer); - } + memcpy(aevt, &apbt_clockevent, sizeof(*aevt)); + aevt->cpumask = cpumask_of(cpu); + aevt->name = adev->name; + aevt->mode = CLOCK_EVT_MODE_UNUSED; - printk(KERN_INFO "Registering CPU %d clockevent device %s, cpu %08x\n", - cpu, adev->name, adev->cpu); + printk(KERN_INFO "Registering CPU %d clockevent device %s, mask %08x\n", + cpu, aevt->name, *(u32 *)aevt->cpumask); apbt_setup_irq(adev); - dw_apb_clockevent_register(adev->timer); + + clockevents_register_device(aevt); + + apbt_enable_int(cpu); return; } @@ -237,12 +385,13 @@ static int apbt_cpuhp_notify(struct notifier_block *n, switch (action & 0xf) { case CPU_DEAD: - dw_apb_clockevent_pause(adev->timer); + disable_irq(adev->irq); + apbt_disable_int(cpu); if (system_state == SYSTEM_RUNNING) { pr_debug("skipping APBT CPU %lu offline\n", cpu); } else if (adev) { pr_debug("APBT clockevent for cpu %lu offline\n", cpu); - dw_apb_clockevent_stop(adev->timer); + free_irq(adev->irq, adev); } break; default: @@ -267,16 +416,116 @@ void apbt_setup_secondary_clock(void) {} #endif /* CONFIG_SMP */ +static void apbt_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned long ctrl; + uint64_t delta; + int timer_num; + struct apbt_dev *adev = EVT_TO_APBT_DEV(evt); + + BUG_ON(!apbt_virt_address); + + timer_num = adev->num; + pr_debug("%s CPU %d timer %d mode=%d\n", + __func__, first_cpu(*evt->cpumask), timer_num, mode); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * apbt_clockevent.mult; + delta >>= apbt_clockevent.shift; + ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL); + ctrl |= APBTMR_CONTROL_MODE_PERIODIC; + apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); + /* + * DW APB p. 46, have to disable timer before load counter, + * may cause sync problem. + */ + ctrl &= ~APBTMR_CONTROL_ENABLE; + apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); + udelay(1); + pr_debug("Setting clock period %d for HZ %d\n", (int)delta, HZ); + apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT); + ctrl |= APBTMR_CONTROL_ENABLE; + apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); + break; + /* APB timer does not have one-shot mode, use free running mode */ + case CLOCK_EVT_MODE_ONESHOT: + ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL); + /* + * set free running mode, this mode will let timer reload max + * timeout which will give time (3min on 25MHz clock) to rearm + * the next event, therefore emulate the one-shot mode. + */ + ctrl &= ~APBTMR_CONTROL_ENABLE; + ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC; + + apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); + /* write again to set free running mode */ + apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); + + /* + * DW APB p. 46, load counter with all 1s before starting free + * running mode. + */ + apbt_writel(timer_num, ~0, APBTMR_N_LOAD_COUNT); + ctrl &= ~APBTMR_CONTROL_INT; + ctrl |= APBTMR_CONTROL_ENABLE; + apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); + break; + + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + apbt_disable_int(timer_num); + ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL); + ctrl &= ~APBTMR_CONTROL_ENABLE; + apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); + break; + + case CLOCK_EVT_MODE_RESUME: + apbt_enable_int(timer_num); + break; + } +} + +static int apbt_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + unsigned long ctrl; + int timer_num; + + struct apbt_dev *adev = EVT_TO_APBT_DEV(evt); + + timer_num = adev->num; + /* Disable timer */ + ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL); + ctrl &= ~APBTMR_CONTROL_ENABLE; + apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); + /* write new count */ + apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT); + ctrl |= APBTMR_CONTROL_ENABLE; + apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL); + return 0; +} + +static cycle_t apbt_read_clocksource(struct clocksource *cs) +{ + unsigned long current_count; + + current_count = apbt_readl(phy_cs_timer_id, APBTMR_N_CURRENT_VALUE); + return (cycle_t)~current_count; +} + static int apbt_clocksource_register(void) { u64 start, now; cycle_t t1; /* Start the counter, use timer 2 as source, timer 0/1 for event */ - dw_apb_clocksource_start(clocksource_apbt); + apbt_start_counter(phy_cs_timer_id); /* Verify whether apbt counter works */ - t1 = dw_apb_clocksource_read(clocksource_apbt); + t1 = apbt_read_clocksource(&clocksource_apbt); rdtscll(start); /* @@ -291,10 +540,10 @@ static int apbt_clocksource_register(void) } while ((now - start) < 200000UL); /* APBT is the only always on clocksource, it has to work! */ - if (t1 == dw_apb_clocksource_read(clocksource_apbt)) + if (t1 == apbt_read_clocksource(&clocksource_apbt)) panic("APBT counter not counting. APBT disabled\n"); - dw_apb_clocksource_register(clocksource_apbt); + clocksource_register_khz(&clocksource_apbt, (u32)apbt_freq*1000); return 0; } @@ -318,7 +567,10 @@ void __init apbt_time_init(void) if (apb_timer_block_enabled) return; apbt_set_mapping(); - if (!apbt_virt_address) + if (apbt_virt_address) { + pr_debug("Found APBT version 0x%lx\n",\ + apbt_readl_reg(APBTMRS_COMP_VERSION)); + } else goto out_noapbt; /* * Read the frequency and check for a sane value, for ESL model @@ -326,7 +578,7 @@ void __init apbt_time_init(void) */ if (apbt_freq < APBT_MIN_FREQ || apbt_freq > APBT_MAX_FREQ) { - pr_debug("APBT has invalid freq 0x%lx\n", apbt_freq); + pr_debug("APBT has invalid freq 0x%llx\n", apbt_freq); goto out_noapbt; } if (apbt_clocksource_register()) { @@ -352,20 +604,30 @@ void __init apbt_time_init(void) } else { percpu_timer = 0; apbt_num_timers_used = 1; + adev = &per_cpu(cpu_apbt_dev, 0); + adev->flags &= ~APBT_DEV_USED; } pr_debug("%s: %d APB timers used\n", __func__, apbt_num_timers_used); /* here we set up per CPU timer data structure */ + apbt_devs = kzalloc(sizeof(struct apbt_dev) * apbt_num_timers_used, + GFP_KERNEL); + if (!apbt_devs) { + printk(KERN_ERR "Failed to allocate APB timer devices\n"); + return; + } for (i = 0; i < apbt_num_timers_used; i++) { adev = &per_cpu(cpu_apbt_dev, i); adev->num = i; adev->cpu = i; p_mtmr = sfi_get_mtmr(i); - if (p_mtmr) + if (p_mtmr) { + adev->tick = p_mtmr->freq_hz; adev->irq = p_mtmr->irq; - else + } else printk(KERN_ERR "Failed to get timer for cpu %d\n", i); - snprintf(adev->name, sizeof(adev->name) - 1, "apbt%d", i); + adev->count = 0; + sprintf(adev->name, "apbt%d", i); } #endif @@ -377,8 +639,17 @@ void __init apbt_time_init(void) panic("failed to enable APB timer\n"); } +static inline void apbt_disable(int n) +{ + if (is_apbt_capable()) { + unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL); + ctrl &= ~APBTMR_CONTROL_ENABLE; + apbt_writel(n, ctrl, APBTMR_N_CONTROL); + } +} + /* called before apb_timer_enable, use early map */ -unsigned long apbt_quick_calibrate(void) +unsigned long apbt_quick_calibrate() { int i, scale; u64 old, new; @@ -387,31 +658,31 @@ unsigned long apbt_quick_calibrate(void) u32 loop, shift; apbt_set_mapping(); - dw_apb_clocksource_start(clocksource_apbt); + apbt_start_counter(phy_cs_timer_id); /* check if the timer can count down, otherwise return */ - old = dw_apb_clocksource_read(clocksource_apbt); + old = apbt_read_clocksource(&clocksource_apbt); i = 10000; while (--i) { - if (old != dw_apb_clocksource_read(clocksource_apbt)) + if (old != apbt_read_clocksource(&clocksource_apbt)) break; } if (!i) goto failed; /* count 16 ms */ - loop = (apbt_freq / 1000) << 4; + loop = (apbt_freq * 1000) << 4; /* restart the timer to ensure it won't get to 0 in the calibration */ - dw_apb_clocksource_start(clocksource_apbt); + apbt_start_counter(phy_cs_timer_id); - old = dw_apb_clocksource_read(clocksource_apbt); + old = apbt_read_clocksource(&clocksource_apbt); old += loop; t1 = __native_read_tsc(); do { - new = dw_apb_clocksource_read(clocksource_apbt); + new = apbt_read_clocksource(&clocksource_apbt); } while (new < old); t2 = __native_read_tsc(); @@ -423,7 +694,7 @@ unsigned long apbt_quick_calibrate(void) return 0; } scale = (int)div_u64((t2 - t1), loop >> shift); - khz = (scale * (apbt_freq / 1000)) >> shift; + khz = (scale * apbt_freq * 1000) >> shift; printk(KERN_INFO "TSC freq calculated by APB timer is %lu khz\n", khz); return khz; failed: diff --git a/trunk/arch/x86/kernel/apic/apic.c b/trunk/arch/x86/kernel/apic/apic.c index b24be38c8cf8..9498b8445186 100644 --- a/trunk/arch/x86/kernel/apic/apic.c +++ b/trunk/arch/x86/kernel/apic/apic.c @@ -1944,28 +1944,10 @@ void disconnect_bsp_APIC(int virt_wire_setup) void __cpuinit generic_processor_info(int apicid, int version) { - int cpu, max = nr_cpu_ids; - bool boot_cpu_detected = physid_isset(boot_cpu_physical_apicid, - phys_cpu_present_map); - - /* - * If boot cpu has not been detected yet, then only allow upto - * nr_cpu_ids - 1 processors and keep one slot free for boot cpu - */ - if (!boot_cpu_detected && num_processors >= nr_cpu_ids - 1 && - apicid != boot_cpu_physical_apicid) { - int thiscpu = max + disabled_cpus - 1; - - pr_warning( - "ACPI: NR_CPUS/possible_cpus limit of %i almost" - " reached. Keeping one slot for boot cpu." - " Processor %d/0x%x ignored.\n", max, thiscpu, apicid); - - disabled_cpus++; - return; - } + int cpu; if (num_processors >= nr_cpu_ids) { + int max = nr_cpu_ids; int thiscpu = max + disabled_cpus; pr_warning( diff --git a/trunk/arch/x86/kernel/cpu/bugs.c b/trunk/arch/x86/kernel/cpu/bugs.c index 46674fbb62ba..525514cf33c3 100644 --- a/trunk/arch/x86/kernel/cpu/bugs.c +++ b/trunk/arch/x86/kernel/cpu/bugs.c @@ -62,8 +62,6 @@ static void __init check_fpu(void) return; } - kernel_fpu_begin(); - /* * trap_init() enabled FXSR and company _before_ testing for FP * problems here. @@ -82,8 +80,6 @@ static void __init check_fpu(void) : "=m" (*&fdiv_bug) : "m" (*&x), "m" (*&y)); - kernel_fpu_end(); - boot_cpu_data.fdiv_bug = fdiv_bug; if (boot_cpu_data.fdiv_bug) printk(KERN_WARNING "Hmm, FPU with FDIV bug.\n"); diff --git a/trunk/arch/x86/kernel/cpu/hypervisor.c b/trunk/arch/x86/kernel/cpu/hypervisor.c index 755f64fb0743..8095f8611f8a 100644 --- a/trunk/arch/x86/kernel/cpu/hypervisor.c +++ b/trunk/arch/x86/kernel/cpu/hypervisor.c @@ -32,11 +32,11 @@ */ static const __initconst struct hypervisor_x86 * const hypervisors[] = { + &x86_hyper_vmware, + &x86_hyper_ms_hyperv, #ifdef CONFIG_XEN_PVHVM &x86_hyper_xen_hvm, #endif - &x86_hyper_vmware, - &x86_hyper_ms_hyperv, }; const struct hypervisor_x86 *x86_hyper; diff --git a/trunk/arch/x86/kernel/quirks.c b/trunk/arch/x86/kernel/quirks.c index b78643d0f9a5..8bbe8c56916d 100644 --- a/trunk/arch/x86/kernel/quirks.c +++ b/trunk/arch/x86/kernel/quirks.c @@ -10,7 +10,7 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) { - u8 config; + u8 config, rev; u16 word; /* BIOS may enable hardware IRQ balancing for @@ -18,7 +18,8 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) * based platforms. * Disable SW irqbalance/affinity on those platforms. */ - if (dev->revision > 0x9) + pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); + if (rev > 0x9) return; /* enable access to config space*/ diff --git a/trunk/arch/x86/kernel/relocate_kernel_32.S b/trunk/arch/x86/kernel/relocate_kernel_32.S index 36818f8ec2be..41235531b11c 100644 --- a/trunk/arch/x86/kernel/relocate_kernel_32.S +++ b/trunk/arch/x86/kernel/relocate_kernel_32.S @@ -97,8 +97,6 @@ relocate_kernel: ret identity_mapped: - /* set return address to 0 if not preserving context */ - pushl $0 /* store the start address on the stack */ pushl %edx diff --git a/trunk/arch/x86/kernel/relocate_kernel_64.S b/trunk/arch/x86/kernel/relocate_kernel_64.S index 7a6f3b3be3cf..4de8f5b3d476 100644 --- a/trunk/arch/x86/kernel/relocate_kernel_64.S +++ b/trunk/arch/x86/kernel/relocate_kernel_64.S @@ -100,8 +100,6 @@ relocate_kernel: ret identity_mapped: - /* set return address to 0 if not preserving context */ - pushq $0 /* store the start address on the stack */ pushq %rdx diff --git a/trunk/arch/x86/kernel/tsc.c b/trunk/arch/x86/kernel/tsc.c index db483369f10b..56c633a5db72 100644 --- a/trunk/arch/x86/kernel/tsc.c +++ b/trunk/arch/x86/kernel/tsc.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -799,6 +800,27 @@ void mark_tsc_unstable(char *reason) EXPORT_SYMBOL_GPL(mark_tsc_unstable); +static int __init dmi_mark_tsc_unstable(const struct dmi_system_id *d) +{ + printk(KERN_NOTICE "%s detected: marking TSC unstable.\n", + d->ident); + tsc_unstable = 1; + return 0; +} + +/* List of systems that have known TSC problems */ +static struct dmi_system_id __initdata bad_tsc_dmi_table[] = { + { + .callback = dmi_mark_tsc_unstable, + .ident = "IBM Thinkpad 380XD", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), + DMI_MATCH(DMI_BOARD_NAME, "2635FA0"), + }, + }, + {} +}; + static void __init check_system_tsc_reliable(void) { #ifdef CONFIG_MGEODE_LX @@ -988,6 +1010,8 @@ void __init tsc_init(void) lpj_fine = lpj; use_tsc_delay(); + /* Check and install the TSC clocksource */ + dmi_check_system(bad_tsc_dmi_table); if (unsynchronized_tsc()) mark_tsc_unstable("TSCs unsynchronized"); diff --git a/trunk/arch/x86/kvm/Kconfig b/trunk/arch/x86/kvm/Kconfig index 65cf8233d25c..50f63648ce1b 100644 --- a/trunk/arch/x86/kvm/Kconfig +++ b/trunk/arch/x86/kvm/Kconfig @@ -76,5 +76,6 @@ config KVM_MMU_AUDIT # the virtualization menu. source drivers/vhost/Kconfig source drivers/lguest/Kconfig +source drivers/virtio/Kconfig endif # VIRTUALIZATION diff --git a/trunk/drivers/Kconfig b/trunk/drivers/Kconfig index 9e7a4f5b5c2e..52e306dd5010 100644 --- a/trunk/drivers/Kconfig +++ b/trunk/drivers/Kconfig @@ -112,8 +112,6 @@ source "drivers/uio/Kconfig" source "drivers/vlynq/Kconfig" -source "drivers/virtio/Kconfig" - source "drivers/xen/Kconfig" source "drivers/staging/Kconfig" diff --git a/trunk/drivers/clocksource/Kconfig b/trunk/drivers/clocksource/Kconfig index 34e9c4f88926..d8d3e02b912c 100644 --- a/trunk/drivers/clocksource/Kconfig +++ b/trunk/drivers/clocksource/Kconfig @@ -12,6 +12,3 @@ config CLKBLD_I8253 config CLKSRC_MMIO bool - -config DW_APB_TIMER - bool diff --git a/trunk/drivers/clocksource/Makefile b/trunk/drivers/clocksource/Makefile index 85ad1646a7b7..7922a0cfc99f 100644 --- a/trunk/drivers/clocksource/Makefile +++ b/trunk/drivers/clocksource/Makefile @@ -8,4 +8,3 @@ obj-$(CONFIG_SH_TIMER_MTU2) += sh_mtu2.o obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o obj-$(CONFIG_CLKBLD_I8253) += i8253.o obj-$(CONFIG_CLKSRC_MMIO) += mmio.o -obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o diff --git a/trunk/drivers/clocksource/dw_apb_timer.c b/trunk/drivers/clocksource/dw_apb_timer.c deleted file mode 100644 index 580f870541a3..000000000000 --- a/trunk/drivers/clocksource/dw_apb_timer.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * (C) Copyright 2009 Intel Corporation - * Author: Jacob Pan (jacob.jun.pan@intel.com) - * - * Shared with ARM platforms, Jamie Iles, Picochip 2011 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Support for the Synopsys DesignWare APB Timers. - */ -#include -#include -#include -#include -#include -#include -#include - -#define APBT_MIN_PERIOD 4 -#define APBT_MIN_DELTA_USEC 200 - -#define APBTMR_N_LOAD_COUNT 0x00 -#define APBTMR_N_CURRENT_VALUE 0x04 -#define APBTMR_N_CONTROL 0x08 -#define APBTMR_N_EOI 0x0c -#define APBTMR_N_INT_STATUS 0x10 - -#define APBTMRS_INT_STATUS 0xa0 -#define APBTMRS_EOI 0xa4 -#define APBTMRS_RAW_INT_STATUS 0xa8 -#define APBTMRS_COMP_VERSION 0xac - -#define APBTMR_CONTROL_ENABLE (1 << 0) -/* 1: periodic, 0:free running. */ -#define APBTMR_CONTROL_MODE_PERIODIC (1 << 1) -#define APBTMR_CONTROL_INT (1 << 2) - -static inline struct dw_apb_clock_event_device * -ced_to_dw_apb_ced(struct clock_event_device *evt) -{ - return container_of(evt, struct dw_apb_clock_event_device, ced); -} - -static inline struct dw_apb_clocksource * -clocksource_to_dw_apb_clocksource(struct clocksource *cs) -{ - return container_of(cs, struct dw_apb_clocksource, cs); -} - -static unsigned long apbt_readl(struct dw_apb_timer *timer, unsigned long offs) -{ - return readl(timer->base + offs); -} - -static void apbt_writel(struct dw_apb_timer *timer, unsigned long val, - unsigned long offs) -{ - writel(val, timer->base + offs); -} - -static void apbt_disable_int(struct dw_apb_timer *timer) -{ - unsigned long ctrl = apbt_readl(timer, APBTMR_N_CONTROL); - - ctrl |= APBTMR_CONTROL_INT; - apbt_writel(timer, ctrl, APBTMR_N_CONTROL); -} - -/** - * dw_apb_clockevent_pause() - stop the clock_event_device from running - * - * @dw_ced: The APB clock to stop generating events. - */ -void dw_apb_clockevent_pause(struct dw_apb_clock_event_device *dw_ced) -{ - disable_irq(dw_ced->timer.irq); - apbt_disable_int(&dw_ced->timer); -} - -static void apbt_eoi(struct dw_apb_timer *timer) -{ - apbt_readl(timer, APBTMR_N_EOI); -} - -static irqreturn_t dw_apb_clockevent_irq(int irq, void *data) -{ - struct clock_event_device *evt = data; - struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); - - if (!evt->event_handler) { - pr_info("Spurious APBT timer interrupt %d", irq); - return IRQ_NONE; - } - - if (dw_ced->eoi) - dw_ced->eoi(&dw_ced->timer); - - evt->event_handler(evt); - return IRQ_HANDLED; -} - -static void apbt_enable_int(struct dw_apb_timer *timer) -{ - unsigned long ctrl = apbt_readl(timer, APBTMR_N_CONTROL); - /* clear pending intr */ - apbt_readl(timer, APBTMR_N_EOI); - ctrl &= ~APBTMR_CONTROL_INT; - apbt_writel(timer, ctrl, APBTMR_N_CONTROL); -} - -static void apbt_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - unsigned long ctrl; - unsigned long period; - struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); - - pr_debug("%s CPU %d mode=%d\n", __func__, first_cpu(*evt->cpumask), - mode); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - period = DIV_ROUND_UP(dw_ced->timer.freq, HZ); - ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); - ctrl |= APBTMR_CONTROL_MODE_PERIODIC; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - /* - * DW APB p. 46, have to disable timer before load counter, - * may cause sync problem. - */ - ctrl &= ~APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - udelay(1); - pr_debug("Setting clock period %lu for HZ %d\n", period, HZ); - apbt_writel(&dw_ced->timer, period, APBTMR_N_LOAD_COUNT); - ctrl |= APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - break; - - case CLOCK_EVT_MODE_ONESHOT: - ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); - /* - * set free running mode, this mode will let timer reload max - * timeout which will give time (3min on 25MHz clock) to rearm - * the next event, therefore emulate the one-shot mode. - */ - ctrl &= ~APBTMR_CONTROL_ENABLE; - ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC; - - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - /* write again to set free running mode */ - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - - /* - * DW APB p. 46, load counter with all 1s before starting free - * running mode. - */ - apbt_writel(&dw_ced->timer, ~0, APBTMR_N_LOAD_COUNT); - ctrl &= ~APBTMR_CONTROL_INT; - ctrl |= APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - break; - - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); - ctrl &= ~APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - break; - - case CLOCK_EVT_MODE_RESUME: - apbt_enable_int(&dw_ced->timer); - break; - } -} - -static int apbt_next_event(unsigned long delta, - struct clock_event_device *evt) -{ - unsigned long ctrl; - struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); - - /* Disable timer */ - ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); - ctrl &= ~APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - /* write new count */ - apbt_writel(&dw_ced->timer, delta, APBTMR_N_LOAD_COUNT); - ctrl |= APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - - return 0; -} - -/** - * dw_apb_clockevent_init() - use an APB timer as a clock_event_device - * - * @cpu: The CPU the events will be targeted at. - * @name: The name used for the timer and the IRQ for it. - * @rating: The rating to give the timer. - * @base: I/O base for the timer registers. - * @irq: The interrupt number to use for the timer. - * @freq: The frequency that the timer counts at. - * - * This creates a clock_event_device for using with the generic clock layer - * but does not start and register it. This should be done with - * dw_apb_clockevent_register() as the next step. If this is the first time - * it has been called for a timer then the IRQ will be requested, if not it - * just be enabled to allow CPU hotplug to avoid repeatedly requesting and - * releasing the IRQ. - */ -struct dw_apb_clock_event_device * -dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, - void __iomem *base, int irq, unsigned long freq) -{ - struct dw_apb_clock_event_device *dw_ced = - kzalloc(sizeof(*dw_ced), GFP_KERNEL); - int err; - - if (!dw_ced) - return NULL; - - dw_ced->timer.base = base; - dw_ced->timer.irq = irq; - dw_ced->timer.freq = freq; - - clockevents_calc_mult_shift(&dw_ced->ced, freq, APBT_MIN_PERIOD); - dw_ced->ced.max_delta_ns = clockevent_delta2ns(0x7fffffff, - &dw_ced->ced); - dw_ced->ced.min_delta_ns = clockevent_delta2ns(5000, &dw_ced->ced); - dw_ced->ced.cpumask = cpumask_of(cpu); - dw_ced->ced.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; - dw_ced->ced.set_mode = apbt_set_mode; - dw_ced->ced.set_next_event = apbt_next_event; - dw_ced->ced.irq = dw_ced->timer.irq; - dw_ced->ced.rating = rating; - dw_ced->ced.name = name; - - dw_ced->irqaction.name = dw_ced->ced.name; - dw_ced->irqaction.handler = dw_apb_clockevent_irq; - dw_ced->irqaction.dev_id = &dw_ced->ced; - dw_ced->irqaction.irq = irq; - dw_ced->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | - IRQF_NOBALANCING | - IRQF_DISABLED; - - dw_ced->eoi = apbt_eoi; - err = setup_irq(irq, &dw_ced->irqaction); - if (err) { - pr_err("failed to request timer irq\n"); - kfree(dw_ced); - dw_ced = NULL; - } - - return dw_ced; -} - -/** - * dw_apb_clockevent_resume() - resume a clock that has been paused. - * - * @dw_ced: The APB clock to resume. - */ -void dw_apb_clockevent_resume(struct dw_apb_clock_event_device *dw_ced) -{ - enable_irq(dw_ced->timer.irq); -} - -/** - * dw_apb_clockevent_stop() - stop the clock_event_device and release the IRQ. - * - * @dw_ced: The APB clock to stop generating the events. - */ -void dw_apb_clockevent_stop(struct dw_apb_clock_event_device *dw_ced) -{ - free_irq(dw_ced->timer.irq, &dw_ced->ced); -} - -/** - * dw_apb_clockevent_register() - register the clock with the generic layer - * - * @dw_ced: The APB clock to register as a clock_event_device. - */ -void dw_apb_clockevent_register(struct dw_apb_clock_event_device *dw_ced) -{ - apbt_writel(&dw_ced->timer, 0, APBTMR_N_CONTROL); - clockevents_register_device(&dw_ced->ced); - apbt_enable_int(&dw_ced->timer); -} - -/** - * dw_apb_clocksource_start() - start the clocksource counting. - * - * @dw_cs: The clocksource to start. - * - * This is used to start the clocksource before registration and can be used - * to enable calibration of timers. - */ -void dw_apb_clocksource_start(struct dw_apb_clocksource *dw_cs) -{ - /* - * start count down from 0xffff_ffff. this is done by toggling the - * enable bit then load initial load count to ~0. - */ - unsigned long ctrl = apbt_readl(&dw_cs->timer, APBTMR_N_CONTROL); - - ctrl &= ~APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL); - apbt_writel(&dw_cs->timer, ~0, APBTMR_N_LOAD_COUNT); - /* enable, mask interrupt */ - ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC; - ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT); - apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL); - /* read it once to get cached counter value initialized */ - dw_apb_clocksource_read(dw_cs); -} - -static cycle_t __apbt_read_clocksource(struct clocksource *cs) -{ - unsigned long current_count; - struct dw_apb_clocksource *dw_cs = - clocksource_to_dw_apb_clocksource(cs); - - current_count = apbt_readl(&dw_cs->timer, APBTMR_N_CURRENT_VALUE); - - return (cycle_t)~current_count; -} - -static void apbt_restart_clocksource(struct clocksource *cs) -{ - struct dw_apb_clocksource *dw_cs = - clocksource_to_dw_apb_clocksource(cs); - - dw_apb_clocksource_start(dw_cs); -} - -/** - * dw_apb_clocksource_init() - use an APB timer as a clocksource. - * - * @rating: The rating to give the clocksource. - * @name: The name for the clocksource. - * @base: The I/O base for the timer registers. - * @freq: The frequency that the timer counts at. - * - * This creates a clocksource using an APB timer but does not yet register it - * with the clocksource system. This should be done with - * dw_apb_clocksource_register() as the next step. - */ -struct dw_apb_clocksource * -dw_apb_clocksource_init(unsigned rating, char *name, void __iomem *base, - unsigned long freq) -{ - struct dw_apb_clocksource *dw_cs = kzalloc(sizeof(*dw_cs), GFP_KERNEL); - - if (!dw_cs) - return NULL; - - dw_cs->timer.base = base; - dw_cs->timer.freq = freq; - dw_cs->cs.name = name; - dw_cs->cs.rating = rating; - dw_cs->cs.read = __apbt_read_clocksource; - dw_cs->cs.mask = CLOCKSOURCE_MASK(32); - dw_cs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS; - dw_cs->cs.resume = apbt_restart_clocksource; - - return dw_cs; -} - -/** - * dw_apb_clocksource_register() - register the APB clocksource. - * - * @dw_cs: The clocksource to register. - */ -void dw_apb_clocksource_register(struct dw_apb_clocksource *dw_cs) -{ - clocksource_register_hz(&dw_cs->cs, dw_cs->timer.freq); -} - -/** - * dw_apb_clocksource_read() - read the current value of a clocksource. - * - * @dw_cs: The clocksource to read. - */ -cycle_t dw_apb_clocksource_read(struct dw_apb_clocksource *dw_cs) -{ - return (cycle_t)~apbt_readl(&dw_cs->timer, APBTMR_N_CURRENT_VALUE); -} - -/** - * dw_apb_clocksource_unregister() - unregister and free a clocksource. - * - * @dw_cs: The clocksource to unregister/free. - */ -void dw_apb_clocksource_unregister(struct dw_apb_clocksource *dw_cs) -{ - clocksource_unregister(&dw_cs->cs); - - kfree(dw_cs); -} diff --git a/trunk/drivers/virtio/Kconfig b/trunk/drivers/virtio/Kconfig index 57e493b1bd20..3dd6294d10b6 100644 --- a/trunk/drivers/virtio/Kconfig +++ b/trunk/drivers/virtio/Kconfig @@ -7,8 +7,6 @@ config VIRTIO_RING tristate depends on VIRTIO -menu "Virtio drivers" - config VIRTIO_PCI tristate "PCI driver for virtio devices (EXPERIMENTAL)" depends on PCI && EXPERIMENTAL @@ -35,4 +33,3 @@ config VIRTIO_BALLOON If unsure, say M. -endmenu diff --git a/trunk/include/linux/dw_apb_timer.h b/trunk/include/linux/dw_apb_timer.h deleted file mode 100644 index 49638ea3b776..000000000000 --- a/trunk/include/linux/dw_apb_timer.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (C) Copyright 2009 Intel Corporation - * Author: Jacob Pan (jacob.jun.pan@intel.com) - * - * Shared with ARM platforms, Jamie Iles, Picochip 2011 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Support for the Synopsys DesignWare APB Timers. - */ -#ifndef __DW_APB_TIMER_H__ -#define __DW_APB_TIMER_H__ - -#include -#include -#include - -#define APBTMRS_REG_SIZE 0x14 - -struct dw_apb_timer { - void __iomem *base; - unsigned long freq; - int irq; -}; - -struct dw_apb_clock_event_device { - struct clock_event_device ced; - struct dw_apb_timer timer; - struct irqaction irqaction; - void (*eoi)(struct dw_apb_timer *); -}; - -struct dw_apb_clocksource { - struct dw_apb_timer timer; - struct clocksource cs; -}; - -void dw_apb_clockevent_register(struct dw_apb_clock_event_device *dw_ced); -void dw_apb_clockevent_pause(struct dw_apb_clock_event_device *dw_ced); -void dw_apb_clockevent_resume(struct dw_apb_clock_event_device *dw_ced); -void dw_apb_clockevent_stop(struct dw_apb_clock_event_device *dw_ced); - -struct dw_apb_clock_event_device * -dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, - void __iomem *base, int irq, unsigned long freq); -struct dw_apb_clocksource * -dw_apb_clocksource_init(unsigned rating, char *name, void __iomem *base, - unsigned long freq); -void dw_apb_clocksource_register(struct dw_apb_clocksource *dw_cs); -void dw_apb_clocksource_start(struct dw_apb_clocksource *dw_cs); -cycle_t dw_apb_clocksource_read(struct dw_apb_clocksource *dw_cs); -void dw_apb_clocksource_unregister(struct dw_apb_clocksource *dw_cs); - -#endif /* __DW_APB_TIMER_H__ */ diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index 5f695041090c..baa397eb9c33 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -96,6 +96,11 @@ enum { #define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING) +static inline __deprecated bool CHECK_IRQ_PER_CPU(unsigned int status) +{ + return status & IRQ_PER_CPU; +} + /* * Return value for chip->irq_set_affinity() * diff --git a/trunk/init/Kconfig b/trunk/init/Kconfig index e20aa3112240..27b8a7a43261 100644 --- a/trunk/init/Kconfig +++ b/trunk/init/Kconfig @@ -917,8 +917,6 @@ config ANON_INODES menuconfig EXPERT bool "Configure standard kernel features (expert users)" - # Unhide debug options, to make the on-by-default options visible - select DEBUG_KERNEL help This option allows certain base kernel options and settings to be disabled or tweaked. This is for specialized diff --git a/trunk/net/9p/client.c b/trunk/net/9p/client.c index 9e3b0e640da1..81e667b6bbbd 100644 --- a/trunk/net/9p/client.c +++ b/trunk/net/9p/client.c @@ -280,7 +280,8 @@ struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag) * buffer to read the data into */ tag++; - BUG_ON(tag >= c->max_tag); + if(tag >= c->max_tag) + return NULL; row = tag / P9_ROW_MAXTAG; col = tag % P9_ROW_MAXTAG; diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 56d62d3fb167..d0861bbd1d94 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -52,10 +52,7 @@ ifeq ($(ARCH),i386) endif ifeq ($(ARCH),x86_64) ARCH := x86 - IS_X86_64 := 0 - ifeq (, $(findstring m32,$(EXTRA_CFLAGS))) - IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1) - endif + IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1) ifeq (${IS_X86_64}, 1) RAW_ARCH := x86_64 ARCH_CFLAGS := -DARCH_X86_64