diff --git a/[refs] b/[refs] index 0c6f51f9d5dc..c31de38e1aff 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2d51daaa615e4724f24e43fa01e705c40551080a +refs/heads/master: 44ad56b7df54cbc8063b46883d183e4e2f09f831 diff --git a/trunk/Documentation/DocBook/debugobjects.tmpl b/trunk/Documentation/DocBook/debugobjects.tmpl index 24979f691e3e..08ff908aa7a2 100644 --- a/trunk/Documentation/DocBook/debugobjects.tmpl +++ b/trunk/Documentation/DocBook/debugobjects.tmpl @@ -96,7 +96,6 @@ debug_object_deactivate debug_object_destroy debug_object_free - debug_object_assert_init Each of these functions takes the address of the real object and a pointer to the object type specific debug description @@ -274,26 +273,6 @@ debug checks. - - - debug_object_assert_init - - This function is called to assert that an object has been - initialized. - - - When the real object is not tracked by debugobjects, it calls - fixup_assert_init of the object type description structure - provided by the caller, with the hardcoded object state - ODEBUG_NOT_AVAILABLE. The fixup function can correct the problem - by calling debug_object_init and other specific initializing - functions. - - - When the real object is already tracked by debugobjects it is - ignored. - - Fixup functions @@ -402,35 +381,6 @@ statistics. - - fixup_assert_init - - This function is called from the debug code whenever a problem - in debug_object_assert_init is detected. - - - Called from debug_object_assert_init() with a hardcoded state - ODEBUG_STATE_NOTAVAILABLE when the object is not found in the - debug bucket. - - - The function returns 1 when the fixup was successful, - otherwise 0. The return value is used to update the - statistics. - - - Note, this function should make sure debug_object_init() is - called before returning. - - - The handling of statically initialized objects is a special - case. The fixup function should check if this is a legitimate - case of a statically initialized object or not. In this case only - debug_object_init() should be called to make the object known to - the tracker. Then the function should return 0 because this is not - a real fixup. - - Known Bugs And Assumptions diff --git a/trunk/Documentation/HOWTO b/trunk/Documentation/HOWTO index f7ade3b3b40d..81bc1a9ab9d8 100644 --- a/trunk/Documentation/HOWTO +++ b/trunk/Documentation/HOWTO @@ -275,8 +275,8 @@ versions. If no 2.6.x.y kernel is available, then the highest numbered 2.6.x kernel is the current stable kernel. -2.6.x.y are maintained by the "stable" team , and -are released as needs dictate. The normal release period is approximately +2.6.x.y are maintained by the "stable" team , and are +released as needs dictate. The normal release period is approximately two weeks, but it can be longer if there are no pressing problems. A security-related problem, instead, can cause a release to happen almost instantly. diff --git a/trunk/Documentation/RCU/checklist.txt b/trunk/Documentation/RCU/checklist.txt index bff2d8be1e18..0c134f8afc6f 100644 --- a/trunk/Documentation/RCU/checklist.txt +++ b/trunk/Documentation/RCU/checklist.txt @@ -328,12 +328,6 @@ over a rather long period of time, but improvements are always welcome! RCU rather than SRCU, because RCU is almost always faster and easier to use than is SRCU. - If you need to enter your read-side critical section in a - hardirq or exception handler, and then exit that same read-side - critical section in the task that was interrupted, then you need - to srcu_read_lock_raw() and srcu_read_unlock_raw(), which avoid - the lockdep checking that would otherwise this practice illegal. - Also unlike other forms of RCU, explicit initialization and cleanup is required via init_srcu_struct() and cleanup_srcu_struct(). These are passed a "struct srcu_struct" diff --git a/trunk/Documentation/RCU/rcu.txt b/trunk/Documentation/RCU/rcu.txt index bf778332a28f..31852705b586 100644 --- a/trunk/Documentation/RCU/rcu.txt +++ b/trunk/Documentation/RCU/rcu.txt @@ -38,11 +38,11 @@ o How can the updater tell when a grace period has completed Preemptible variants of RCU (CONFIG_TREE_PREEMPT_RCU) get the same effect, but require that the readers manipulate CPU-local - counters. These counters allow limited types of blocking within - RCU read-side critical sections. SRCU also uses CPU-local - counters, and permits general blocking within RCU read-side - critical sections. These variants of RCU detect grace periods - by sampling these counters. + counters. These counters allow limited types of blocking + within RCU read-side critical sections. SRCU also uses + CPU-local counters, and permits general blocking within + RCU read-side critical sections. These two variants of + RCU detect grace periods by sampling these counters. o If I am running on a uniprocessor kernel, which can only do one thing at a time, why should I wait for a grace period? diff --git a/trunk/Documentation/RCU/stallwarn.txt b/trunk/Documentation/RCU/stallwarn.txt index 083d88cbc089..4e959208f736 100644 --- a/trunk/Documentation/RCU/stallwarn.txt +++ b/trunk/Documentation/RCU/stallwarn.txt @@ -101,11 +101,6 @@ o A CPU-bound real-time task in a CONFIG_PREEMPT_RT kernel that CONFIG_TREE_PREEMPT_RCU case, you might see stall-warning messages. -o A hardware or software issue shuts off the scheduler-clock - interrupt on a CPU that is not in dyntick-idle mode. This - problem really has happened, and seems to be most likely to - result in RCU CPU stall warnings for CONFIG_NO_HZ=n kernels. - o A bug in the RCU implementation. o A hardware failure. This is quite unlikely, but has occurred @@ -114,11 +109,12 @@ o A hardware failure. This is quite unlikely, but has occurred This resulted in a series of RCU CPU stall warnings, eventually leading the realization that the CPU had failed. -The RCU, RCU-sched, and RCU-bh implementations have CPU stall warning. -SRCU does not have its own CPU stall warnings, but its calls to -synchronize_sched() will result in RCU-sched detecting RCU-sched-related -CPU stalls. Please note that RCU only detects CPU stalls when there is -a grace period in progress. No grace period, no CPU stall warnings. +The RCU, RCU-sched, and RCU-bh implementations have CPU stall +warning. SRCU does not have its own CPU stall warnings, but its +calls to synchronize_sched() will result in RCU-sched detecting +RCU-sched-related CPU stalls. Please note that RCU only detects +CPU stalls when there is a grace period in progress. No grace period, +no CPU stall warnings. To diagnose the cause of the stall, inspect the stack traces. The offending function will usually be near the top of the stack. diff --git a/trunk/Documentation/RCU/torture.txt b/trunk/Documentation/RCU/torture.txt index d67068d0d2b9..783d6c134d3f 100644 --- a/trunk/Documentation/RCU/torture.txt +++ b/trunk/Documentation/RCU/torture.txt @@ -61,24 +61,11 @@ nreaders This is the number of RCU reading threads supported. To properly exercise RCU implementations with preemptible read-side critical sections. -onoff_interval - The number of seconds between each attempt to execute a - randomly selected CPU-hotplug operation. Defaults to - zero, which disables CPU hotplugging. In HOTPLUG_CPU=n - kernels, rcutorture will silently refuse to do any - CPU-hotplug operations regardless of what value is - specified for onoff_interval. - shuffle_interval The number of seconds to keep the test threads affinitied to a particular subset of the CPUs, defaults to 3 seconds. Used in conjunction with test_no_idle_hz. -shutdown_secs The number of seconds to run the test before terminating - the test and powering off the system. The default is - zero, which disables test termination and system shutdown. - This capability is useful for automated testing. - stat_interval The number of seconds between output of torture statistics (via printk()). Regardless of the interval, statistics are printed when the module is unloaded. diff --git a/trunk/Documentation/RCU/trace.txt b/trunk/Documentation/RCU/trace.txt index 49587abfc2f7..aaf65f6c6cd7 100644 --- a/trunk/Documentation/RCU/trace.txt +++ b/trunk/Documentation/RCU/trace.txt @@ -105,10 +105,14 @@ o "dt" is the current value of the dyntick counter that is incremented or one greater than the interrupt-nesting depth otherwise. The number after the second "/" is the NMI nesting depth. + This field is displayed only for CONFIG_NO_HZ kernels. + o "df" is the number of times that some other CPU has forced a quiescent state on behalf of this CPU due to this CPU being in dynticks-idle state. + This field is displayed only for CONFIG_NO_HZ kernels. + o "of" is the number of times that some other CPU has forced a quiescent state on behalf of this CPU due to this CPU being offline. In a perfect world, this might never happen, but it diff --git a/trunk/Documentation/RCU/whatisRCU.txt b/trunk/Documentation/RCU/whatisRCU.txt index 6bbe8dcdc3da..6ef692667e2f 100644 --- a/trunk/Documentation/RCU/whatisRCU.txt +++ b/trunk/Documentation/RCU/whatisRCU.txt @@ -4,7 +4,6 @@ to start learning about RCU: 1. What is RCU, Fundamentally? http://lwn.net/Articles/262464/ 2. What is RCU? Part 2: Usage http://lwn.net/Articles/263130/ 3. RCU part 3: the RCU API http://lwn.net/Articles/264090/ -4. The RCU API, 2010 Edition http://lwn.net/Articles/418853/ What is RCU? @@ -835,8 +834,6 @@ SRCU: Critical sections Grace period Barrier srcu_read_lock synchronize_srcu N/A srcu_read_unlock synchronize_srcu_expedited - srcu_read_lock_raw - srcu_read_unlock_raw srcu_dereference SRCU: Initialization/cleanup @@ -858,33 +855,27 @@ list can be helpful: a. Will readers need to block? If so, you need SRCU. -b. Is it necessary to start a read-side critical section in a - hardirq handler or exception handler, and then to complete - this read-side critical section in the task that was - interrupted? If so, you need SRCU's srcu_read_lock_raw() and - srcu_read_unlock_raw() primitives. - -c. What about the -rt patchset? If readers would need to block +b. What about the -rt patchset? If readers would need to block in an non-rt kernel, you need SRCU. If readers would block in a -rt kernel, but not in a non-rt kernel, SRCU is not necessary. -d. Do you need to treat NMI handlers, hardirq handlers, +c. Do you need to treat NMI handlers, hardirq handlers, and code segments with preemption disabled (whether via preempt_disable(), local_irq_save(), local_bh_disable(), or some other mechanism) as if they were explicit RCU readers? If so, you need RCU-sched. -e. Do you need RCU grace periods to complete even in the face +d. Do you need RCU grace periods to complete even in the face of softirq monopolization of one or more of the CPUs? For example, is your code subject to network-based denial-of-service attacks? If so, you need RCU-bh. -f. Is your workload too update-intensive for normal use of +e. Is your workload too update-intensive for normal use of RCU, but inappropriate for other synchronization mechanisms? If so, consider SLAB_DESTROY_BY_RCU. But please be careful! -g. Otherwise, use RCU. +f. Otherwise, use RCU. Of course, this all assumes that you have determined that RCU is in fact the right tool for your job. diff --git a/trunk/Documentation/arm/memory.txt b/trunk/Documentation/arm/memory.txt index 208a2d465b92..771d48d3b335 100644 --- a/trunk/Documentation/arm/memory.txt +++ b/trunk/Documentation/arm/memory.txt @@ -51,14 +51,15 @@ ffc00000 ffefffff DMA memory mapping region. Memory returned ff000000 ffbfffff Reserved for future expansion of DMA mapping region. +VMALLOC_END feffffff Free for platform use, recommended. + VMALLOC_END must be aligned to a 2MB + boundary. + VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space. Memory returned by vmalloc/ioremap will be dynamically placed in this region. - Machine specific static mappings are also - located here through iotable_init(). - VMALLOC_START is based upon the value - of the high_memory variable, and VMALLOC_END - is equal to 0xff000000. + VMALLOC_START may be based upon the value + of the high_memory variable. PAGE_OFFSET high_memory-1 Kernel direct-mapped RAM region. This maps the platforms RAM, and typically diff --git a/trunk/Documentation/atomic_ops.txt b/trunk/Documentation/atomic_ops.txt index 27f2b21a9d5c..3bd585b44927 100644 --- a/trunk/Documentation/atomic_ops.txt +++ b/trunk/Documentation/atomic_ops.txt @@ -84,93 +84,6 @@ compiler optimizes the section accessing atomic_t variables. *** YOU HAVE BEEN WARNED! *** -Properly aligned pointers, longs, ints, and chars (and unsigned -equivalents) may be atomically loaded from and stored to in the same -sense as described for atomic_read() and atomic_set(). The ACCESS_ONCE() -macro should be used to prevent the compiler from using optimizations -that might otherwise optimize accesses out of existence on the one hand, -or that might create unsolicited accesses on the other. - -For example consider the following code: - - while (a > 0) - do_something(); - -If the compiler can prove that do_something() does not store to the -variable a, then the compiler is within its rights transforming this to -the following: - - tmp = a; - if (a > 0) - for (;;) - do_something(); - -If you don't want the compiler to do this (and you probably don't), then -you should use something like the following: - - while (ACCESS_ONCE(a) < 0) - do_something(); - -Alternatively, you could place a barrier() call in the loop. - -For another example, consider the following code: - - tmp_a = a; - do_something_with(tmp_a); - do_something_else_with(tmp_a); - -If the compiler can prove that do_something_with() does not store to the -variable a, then the compiler is within its rights to manufacture an -additional load as follows: - - tmp_a = a; - do_something_with(tmp_a); - tmp_a = a; - do_something_else_with(tmp_a); - -This could fatally confuse your code if it expected the same value -to be passed to do_something_with() and do_something_else_with(). - -The compiler would be likely to manufacture this additional load if -do_something_with() was an inline function that made very heavy use -of registers: reloading from variable a could save a flush to the -stack and later reload. To prevent the compiler from attacking your -code in this manner, write the following: - - tmp_a = ACCESS_ONCE(a); - do_something_with(tmp_a); - do_something_else_with(tmp_a); - -For a final example, consider the following code, assuming that the -variable a is set at boot time before the second CPU is brought online -and never changed later, so that memory barriers are not needed: - - if (a) - b = 9; - else - b = 42; - -The compiler is within its rights to manufacture an additional store -by transforming the above code into the following: - - b = 42; - if (a) - b = 9; - -This could come as a fatal surprise to other code running concurrently -that expected b to never have the value 42 if a was zero. To prevent -the compiler from doing this, write something like: - - if (a) - ACCESS_ONCE(b) = 9; - else - ACCESS_ONCE(b) = 42; - -Don't even -think- about doing this without proper use of memory barriers, -locks, or atomic operations if variable a can change at runtime! - -*** WARNING: ACCESS_ONCE() DOES NOT IMPLY A BARRIER! *** - Now, we move onto the atomic operation interfaces typically implemented with the help of assembly code. diff --git a/trunk/Documentation/cgroups/memory.txt b/trunk/Documentation/cgroups/memory.txt index 4d8774f6f48a..cc0ebc5241b3 100644 --- a/trunk/Documentation/cgroups/memory.txt +++ b/trunk/Documentation/cgroups/memory.txt @@ -44,8 +44,8 @@ Features: - oom-killer disable knob and oom-notifier - Root cgroup has no limit controls. - Kernel memory support is work in progress, and the current version provides - basically functionality. (See Section 2.7) + Kernel memory and Hugepages are not under control yet. We just manage + pages on LRU. To add more controls, we have to take care of performance. Brief summary of control files. @@ -72,9 +72,6 @@ Brief summary of control files. memory.oom_control # set/show oom controls. memory.numa_stat # show the number of memory usage per numa node - memory.kmem.tcp.limit_in_bytes # set/show hard limit for tcp buf memory - memory.kmem.tcp.usage_in_bytes # show current tcp buf memory allocation - 1. History The memory controller has a long history. A request for comments for the memory @@ -258,27 +255,6 @@ When oom event notifier is registered, event will be delivered. per-zone-per-cgroup LRU (cgroup's private LRU) is just guarded by zone->lru_lock, it has no lock of its own. -2.7 Kernel Memory Extension (CONFIG_CGROUP_MEM_RES_CTLR_KMEM) - -With the Kernel memory extension, the Memory Controller is able to limit -the amount of kernel memory used by the system. Kernel memory is fundamentally -different than user memory, since it can't be swapped out, which makes it -possible to DoS the system by consuming too much of this precious resource. - -Kernel memory limits are not imposed for the root cgroup. Usage for the root -cgroup may or may not be accounted. - -Currently no soft limit is implemented for kernel memory. It is future work -to trigger slab reclaim when those limits are reached. - -2.7.1 Current Kernel Memory resources accounted - -* sockets memory pressure: some sockets protocols have memory pressure -thresholds. The Memory Controller allows them to be controlled individually -per cgroup, instead of globally. - -* tcp memory pressure: sockets memory pressure for the tcp protocol. - 3. User Interface 0. Configuration diff --git a/trunk/Documentation/cgroups/net_prio.txt b/trunk/Documentation/cgroups/net_prio.txt deleted file mode 100644 index 01b322635591..000000000000 --- a/trunk/Documentation/cgroups/net_prio.txt +++ /dev/null @@ -1,53 +0,0 @@ -Network priority cgroup -------------------------- - -The Network priority cgroup provides an interface to allow an administrator to -dynamically set the priority of network traffic generated by various -applications - -Nominally, an application would set the priority of its traffic via the -SO_PRIORITY socket option. This however, is not always possible because: - -1) The application may not have been coded to set this value -2) The priority of application traffic is often a site-specific administrative - decision rather than an application defined one. - -This cgroup allows an administrator to assign a process to a group which defines -the priority of egress traffic on a given interface. Network priority groups can -be created by first mounting the cgroup filesystem. - -# mount -t cgroup -onet_prio none /sys/fs/cgroup/net_prio - -With the above step, the initial group acting as the parent accounting group -becomes visible at '/sys/fs/cgroup/net_prio'. This group includes all tasks in -the system. '/sys/fs/cgroup/net_prio/tasks' lists the tasks in this cgroup. - -Each net_prio cgroup contains two files that are subsystem specific - -net_prio.prioidx -This file is read-only, and is simply informative. It contains a unique integer -value that the kernel uses as an internal representation of this cgroup. - -net_prio.ifpriomap -This file contains a map of the priorities assigned to traffic originating from -processes in this group and egressing the system on various interfaces. It -contains a list of tuples in the form . Contents of this file -can be modified by echoing a string into the file using the same tuple format. -for example: - -echo "eth0 5" > /sys/fs/cgroups/net_prio/iscsi/net_prio.ifpriomap - -This command would force any traffic originating from processes belonging to the -iscsi net_prio cgroup and egressing on interface eth0 to have the priority of -said traffic set to the value 5. The parent accounting group also has a -writeable 'net_prio.ifpriomap' file that can be used to set a system default -priority. - -Priorities are set immediately prior to queueing a frame to the device -queueing discipline (qdisc) so priorities will be assigned prior to the hardware -queue selection being made. - -One usage for the net_prio cgroup is with mqprio qdisc allowing application -traffic to be steered to hardware/driver based traffic classes. These mappings -can then be managed by administrators or other networking protocols such as -DCBX. diff --git a/trunk/Documentation/development-process/5.Posting b/trunk/Documentation/development-process/5.Posting index 8a48c9b62864..903a2546f138 100644 --- a/trunk/Documentation/development-process/5.Posting +++ b/trunk/Documentation/development-process/5.Posting @@ -271,10 +271,10 @@ copies should go to: the linux-kernel list. - If you are fixing a bug, think about whether the fix should go into the - next stable update. If so, stable@vger.kernel.org should get a copy of - the patch. Also add a "Cc: stable@vger.kernel.org" to the tags within - the patch itself; that will cause the stable team to get a notification - when your fix goes into the mainline. + next stable update. If so, stable@kernel.org should get a copy of the + patch. Also add a "Cc: stable@kernel.org" to the tags within the patch + itself; that will cause the stable team to get a notification when your + fix goes into the mainline. When selecting recipients for a patch, it is good to have an idea of who you think will eventually accept the patch and get it merged. While it diff --git a/trunk/Documentation/devicetree/bindings/arm/gic.txt b/trunk/Documentation/devicetree/bindings/arm/gic.txt index 9b4b82a721b6..52916b4aa1fe 100644 --- a/trunk/Documentation/devicetree/bindings/arm/gic.txt +++ b/trunk/Documentation/devicetree/bindings/arm/gic.txt @@ -42,10 +42,6 @@ Optional - interrupts : Interrupt source of the parent interrupt controller. Only present on secondary GICs. -- cpu-offset : per-cpu offset within the distributor and cpu interface - regions, used when the GIC doesn't have banked registers. The offset is - cpu-offset * cpu-nr. - Example: intc: interrupt-controller@fff11000 { diff --git a/trunk/Documentation/devicetree/bindings/arm/vic.txt b/trunk/Documentation/devicetree/bindings/arm/vic.txt deleted file mode 100644 index 266716b23437..000000000000 --- a/trunk/Documentation/devicetree/bindings/arm/vic.txt +++ /dev/null @@ -1,29 +0,0 @@ -* ARM Vectored Interrupt Controller - -One or more Vectored Interrupt Controllers (VIC's) can be connected in an ARM -system for interrupt routing. For multiple controllers they can either be -nested or have the outputs wire-OR'd together. - -Required properties: - -- compatible : should be one of - "arm,pl190-vic" - "arm,pl192-vic" -- interrupt-controller : Identifies the node as an interrupt controller -- #interrupt-cells : The number of cells to define the interrupts. Must be 1 as - the VIC has no configuration options for interrupt sources. The cell is a u32 - and defines the interrupt number. -- reg : The register bank for the VIC. - -Optional properties: - -- interrupts : Interrupt source for parent controllers if the VIC is nested. - -Example: - - vic0: interrupt-controller@60000 { - compatible = "arm,pl192-vic"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0x60000 0x1000>; - }; diff --git a/trunk/Documentation/devicetree/bindings/net/calxeda-xgmac.txt b/trunk/Documentation/devicetree/bindings/net/calxeda-xgmac.txt deleted file mode 100644 index 411727a3f82d..000000000000 --- a/trunk/Documentation/devicetree/bindings/net/calxeda-xgmac.txt +++ /dev/null @@ -1,15 +0,0 @@ -* Calxeda Highbank 10Gb XGMAC Ethernet - -Required properties: -- compatible : Should be "calxeda,hb-xgmac" -- reg : Address and length of the register set for the device -- interrupts : Should contain 3 xgmac interrupts. The 1st is main interrupt. - The 2nd is pwr mgt interrupt. The 3rd is low power state interrupt. - -Example: - -ethernet@fff50000 { - compatible = "calxeda,hb-xgmac"; - reg = <0xfff50000 0x1000>; - interrupts = <0 77 4 0 78 4 0 79 4>; -}; diff --git a/trunk/Documentation/devicetree/bindings/net/can/cc770.txt b/trunk/Documentation/devicetree/bindings/net/can/cc770.txt deleted file mode 100644 index 77027bf6460a..000000000000 --- a/trunk/Documentation/devicetree/bindings/net/can/cc770.txt +++ /dev/null @@ -1,53 +0,0 @@ -Memory mapped Bosch CC770 and Intel AN82527 CAN controller - -Note: The CC770 is a CAN controller from Bosch, which is 100% -compatible with the old AN82527 from Intel, but with "bugs" being fixed. - -Required properties: - -- compatible : should be "bosch,cc770" for the CC770 and "intc,82527" - for the AN82527. - -- reg : should specify the chip select, address offset and size required - to map the registers of the controller. The size is usually 0x80. - -- interrupts : property with a value describing the interrupt source - (number and sensitivity) required for the controller. - -Optional properties: - -- bosch,external-clock-frequency : frequency of the external oscillator - clock in Hz. Note that the internal clock frequency used by the - controller is half of that value. If not specified, a default - value of 16000000 (16 MHz) is used. - -- bosch,clock-out-frequency : slock frequency in Hz on the CLKOUT pin. - If not specified or if the specified value is 0, the CLKOUT pin - will be disabled. - -- bosch,slew-rate : slew rate of the CLKOUT signal. If not specified, - a resonable value will be calculated. - -- bosch,disconnect-rx0-input : see data sheet. - -- bosch,disconnect-rx1-input : see data sheet. - -- bosch,disconnect-tx1-output : see data sheet. - -- bosch,polarity-dominant : see data sheet. - -- bosch,divide-memory-clock : see data sheet. - -- bosch,iso-low-speed-mux : see data sheet. - -For further information, please have a look to the CC770 or AN82527. - -Examples: - -can@3,100 { - compatible = "bosch,cc770"; - reg = <3 0x100 0x80>; - interrupts = <2 0>; - interrupt-parent = <&mpic>; - bosch,external-clock-frequency = <16000000>; -}; diff --git a/trunk/Documentation/devicetree/bindings/powerpc/fsl/srio-rmu.txt b/trunk/Documentation/devicetree/bindings/powerpc/fsl/srio-rmu.txt deleted file mode 100644 index b9a8a2bcfae7..000000000000 --- a/trunk/Documentation/devicetree/bindings/powerpc/fsl/srio-rmu.txt +++ /dev/null @@ -1,163 +0,0 @@ -Message unit node: - -For SRIO controllers that implement the message unit as part of the controller -this node is required. For devices with RMAN this node should NOT exist. The -node is composed of three types of sub-nodes ("fsl-srio-msg-unit", -"fsl-srio-dbell-unit" and "fsl-srio-port-write-unit"). - -See srio.txt for more details about generic SRIO controller details. - - - compatible - Usage: required - Value type: - Definition: Must include "fsl,srio-rmu-vX.Y", "fsl,srio-rmu". - - The version X.Y should match the general SRIO controller's IP Block - revision register's Major(X) and Minor (Y) value. - - - reg - Usage: required - Value type: - Definition: A standard property. Specifies the physical address and - length of the SRIO configuration registers for message units - and doorbell units. - - - fsl,liodn - Usage: optional-but-recommended (for devices with PAMU) - Value type: - Definition: The logical I/O device number for the PAMU (IOMMU) to be - correctly configured for SRIO accesses. The property should - not exist on devices that do not support PAMU. - - The LIODN value is associated with all RMU transactions - (msg-unit, doorbell, port-write). - -Sub-Nodes for RMU: The RMU node is composed of multiple sub-nodes that -correspond to the actual sub-controllers in the RMU. The manual for a given -SoC will detail which and how many of these sub-controllers are implemented. - -Message Unit: - - - compatible - Usage: required - Value type: - Definition: Must include "fsl,srio-msg-unit-vX.Y", "fsl,srio-msg-unit". - - The version X.Y should match the general SRIO controller's IP Block - revision register's Major(X) and Minor (Y) value. - - - reg - Usage: required - Value type: - Definition: A standard property. Specifies the physical address and - length of the SRIO configuration registers for message units - and doorbell units. - - - interrupts - Usage: required - Value type: - Definition: Specifies the interrupts generated by this device. The - value of the interrupts property consists of one interrupt - specifier. The format of the specifier is defined by the - binding document describing the node's interrupt parent. - - A pair of IRQs are specified in this property. The first - element is associated with the transmit (TX) interrupt and the - second element is associated with the receive (RX) interrupt. - -Doorbell Unit: - - - compatible - Usage: required - Value type: - Definition: Must include: - "fsl,srio-dbell-unit-vX.Y", "fsl,srio-dbell-unit" - - The version X.Y should match the general SRIO controller's IP Block - revision register's Major(X) and Minor (Y) value. - - - reg - Usage: required - Value type: - Definition: A standard property. Specifies the physical address and - length of the SRIO configuration registers for message units - and doorbell units. - - - interrupts - Usage: required - Value type: - Definition: Specifies the interrupts generated by this device. The - value of the interrupts property consists of one interrupt - specifier. The format of the specifier is defined by the - binding document describing the node's interrupt parent. - - A pair of IRQs are specified in this property. The first - element is associated with the transmit (TX) interrupt and the - second element is associated with the receive (RX) interrupt. - -Port-Write Unit: - - - compatible - Usage: required - Value type: - Definition: Must include: - "fsl,srio-port-write-unit-vX.Y", "fsl,srio-port-write-unit" - - The version X.Y should match the general SRIO controller's IP Block - revision register's Major(X) and Minor (Y) value. - - - reg - Usage: required - Value type: - Definition: A standard property. Specifies the physical address and - length of the SRIO configuration registers for message units - and doorbell units. - - - interrupts - Usage: required - Value type: - Definition: Specifies the interrupts generated by this device. The - value of the interrupts property consists of one interrupt - specifier. The format of the specifier is defined by the - binding document describing the node's interrupt parent. - - A single IRQ that handles port-write conditions is - specified by this property. (Typically shared with error). - - Note: All other standard properties (see the ePAPR) are allowed - but are optional. - -Example: - rmu: rmu@d3000 { - compatible = "fsl,srio-rmu"; - reg = <0xd3000 0x400>; - ranges = <0x0 0xd3000 0x400>; - fsl,liodn = <0xc8>; - - message-unit@0 { - compatible = "fsl,srio-msg-unit"; - reg = <0x0 0x100>; - interrupts = < - 60 2 0 0 /* msg1_tx_irq */ - 61 2 0 0>;/* msg1_rx_irq */ - }; - message-unit@100 { - compatible = "fsl,srio-msg-unit"; - reg = <0x100 0x100>; - interrupts = < - 62 2 0 0 /* msg2_tx_irq */ - 63 2 0 0>;/* msg2_rx_irq */ - }; - doorbell-unit@400 { - compatible = "fsl,srio-dbell-unit"; - reg = <0x400 0x80>; - interrupts = < - 56 2 0 0 /* bell_outb_irq */ - 57 2 0 0>;/* bell_inb_irq */ - }; - port-write-unit@4e0 { - compatible = "fsl,srio-port-write-unit"; - reg = <0x4e0 0x20>; - interrupts = <16 2 1 11>; - }; - }; diff --git a/trunk/Documentation/devicetree/bindings/powerpc/fsl/srio.txt b/trunk/Documentation/devicetree/bindings/powerpc/fsl/srio.txt deleted file mode 100644 index b039bcbee134..000000000000 --- a/trunk/Documentation/devicetree/bindings/powerpc/fsl/srio.txt +++ /dev/null @@ -1,103 +0,0 @@ -* Freescale Serial RapidIO (SRIO) Controller - -RapidIO port node: -Properties: - - compatible - Usage: required - Value type: - Definition: Must include "fsl,srio" for IP blocks with IP Block - Revision Register (SRIO IPBRR1) Major ID equal to 0x01c0. - - Optionally, a compatiable string of "fsl,srio-vX.Y" where X is Major - version in IP Block Revision Register and Y is Minor version. If this - compatiable is provided it should be ordered before "fsl,srio". - - - reg - Usage: required - Value type: - Definition: A standard property. Specifies the physical address and - length of the SRIO configuration registers. The size should - be set to 0x11000. - - - interrupts - Usage: required - Value type: - Definition: Specifies the interrupts generated by this device. The - value of the interrupts property consists of one interrupt - specifier. The format of the specifier is defined by the - binding document describing the node's interrupt parent. - - A single IRQ that handles error conditions is specified by this - property. (Typically shared with port-write). - - - fsl,srio-rmu-handle: - Usage: required if rmu node is defined - Value type: - Definition: A single value that points to the RMU. - (See srio-rmu.txt for more details on RMU node binding) - -Port Child Nodes: There should a port child node for each port that exists in -the controller. The ports are numbered starting at one (1) and should have -the following properties: - - - cell-index - Usage: required - Value type: - Definition: A standard property. Matches the port id. - - - ranges - Usage: required if local access windows preset - Value type: - Definition: A standard property. Utilized to describe the memory mapped - IO space utilized by the controller. This corresponds to the - setting of the local access windows that are targeted to this - SRIO port. - - - fsl,liodn - Usage: optional-but-recommended (for devices with PAMU) - Value type: - Definition: The logical I/O device number for the PAMU (IOMMU) to be - correctly configured for SRIO accesses. The property should - not exist on devices that do not support PAMU. - - For HW (ie, the P4080) that only supports a LIODN for both - memory and maintenance transactions then a single LIODN is - represented in the property for both transactions. - - For HW (ie, the P304x/P5020, etc) that supports an LIODN for - memory transactions and a unique LIODN for maintenance - transactions then a pair of LIODNs are represented in the - property. Within the pair, the first element represents the - LIODN associated with memory transactions and the second element - represents the LIODN associated with maintenance transactions - for the port. - -Note: All other standard properties (see ePAPR) are allowed but are optional. - -Example: - - rapidio: rapidio@ffe0c0000 { - #address-cells = <2>; - #size-cells = <2>; - reg = <0xf 0xfe0c0000 0 0x11000>; - compatible = "fsl,srio"; - interrupts = <16 2 1 11>; /* err_irq */ - fsl,srio-rmu-handle = <&rmu>; - ranges; - - port1 { - cell-index = <1>; - #address-cells = <2>; - #size-cells = <2>; - fsl,liodn = <34>; - ranges = <0 0 0xc 0x20000000 0 0x10000000>; - }; - - port2 { - cell-index = <2>; - #address-cells = <2>; - #size-cells = <2>; - fsl,liodn = <48>; - ranges = <0 0 0xc 0x30000000 0 0x10000000>; - }; - }; diff --git a/trunk/Documentation/devicetree/bindings/vendor-prefixes.txt b/trunk/Documentation/devicetree/bindings/vendor-prefixes.txt index 874921e97802..18626965159e 100644 --- a/trunk/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/trunk/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -8,7 +8,9 @@ amcc Applied Micro Circuits Corporation (APM, formally AMCC) apm Applied Micro Circuits Corporation (APM) arm ARM Ltd. atmel Atmel Corporation +cavium Cavium, Inc. chrp Common Hardware Reference Platform +cortina Cortina Systems, Inc. dallas Maxim Integrated Products (formerly Dallas Semiconductor) denx Denx Software Engineering epson Seiko Epson Corp. @@ -36,6 +38,7 @@ schindler Schindler sil Silicon Image simtek sirf SiRF Technology, Inc. +st STMicroelectronics stericsson ST-Ericsson ti Texas Instruments xlnx Xilinx diff --git a/trunk/Documentation/driver-model/devres.txt b/trunk/Documentation/driver-model/devres.txt index 10c64c8a13d4..d79aead9418b 100644 --- a/trunk/Documentation/driver-model/devres.txt +++ b/trunk/Documentation/driver-model/devres.txt @@ -262,7 +262,6 @@ IOMAP devm_ioremap() devm_ioremap_nocache() devm_iounmap() - devm_request_and_ioremap() : checks resource, requests region, ioremaps pcim_iomap() pcim_iounmap() pcim_iomap_table() : array of mapped addresses indexed by BAR diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 33f7327d0451..3d849122b5b1 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -263,7 +263,8 @@ Who: Ravikiran Thirumalai What: Code that is now under CONFIG_WIRELESS_EXT_SYSFS (in net/core/net-sysfs.c) -When: 3.5 +When: After the only user (hal) has seen a release with the patches + for enough time, probably some time in 2010. Why: Over 1K .text/.data size reduction, data is available in other ways (ioctls) Who: Johannes Berg diff --git a/trunk/Documentation/filesystems/debugfs.txt b/trunk/Documentation/filesystems/debugfs.txt index f04066a37f4c..742cc06e138f 100644 --- a/trunk/Documentation/filesystems/debugfs.txt +++ b/trunk/Documentation/filesystems/debugfs.txt @@ -97,8 +97,7 @@ A read on the resulting file will yield either Y (for non-zero values) or N, followed by a newline. If written to, it will accept either upper- or lower-case values, or 1 or 0. Any other input will be silently ignored. -Another option is exporting a block of arbitrary binary data, with -this structure and function: +Finally, a block of arbitrary binary data can be exported with: struct debugfs_blob_wrapper { void *data; @@ -116,35 +115,6 @@ can be used to export binary information, but there does not appear to be any code which does so in the mainline. Note that all files created with debugfs_create_blob() are read-only. -If you want to dump a block of registers (something that happens quite -often during development, even if little such code reaches mainline. -Debugfs offers two functions: one to make a registers-only file, and -another to insert a register block in the middle of another sequential -file. - - struct debugfs_reg32 { - char *name; - unsigned long offset; - }; - - struct debugfs_regset32 { - struct debugfs_reg32 *regs; - int nregs; - void __iomem *base; - }; - - struct dentry *debugfs_create_regset32(const char *name, mode_t mode, - struct dentry *parent, - struct debugfs_regset32 *regset); - - int debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs, - int nregs, void __iomem *base, char *prefix); - -The "base" argument may be 0, but you may want to build the reg32 array -using __stringify, and a number of register names (macros) are actually -byte offsets over a base for the register block. - - There are a couple of other directory-oriented helper functions: struct dentry *debugfs_rename(struct dentry *old_dir, diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index e229769606f2..81c287fad79d 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -1885,11 +1885,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. arch_perfmon: [X86] Force use of architectural perfmon on Intel CPUs instead of the CPU specific event set. - timer: [X86] Force use of architectural NMI - timer mode (see also oprofile.timer - for generic hr timer mode) - [s390] Force legacy basic mode sampling - (report cpu_type "timer") oops=panic Always panic on oopses. Default is to just kill the process, but there is a small probability of @@ -2755,10 +2750,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. functions are at fixed addresses, they make nice targets for exploits that can control RIP. - emulate [default] Vsyscalls turn into traps and are - emulated reasonably safely. + emulate Vsyscalls turn into traps and are emulated + reasonably safely. - native Vsyscalls are native syscall instructions. + native [default] Vsyscalls are native syscall + instructions. This is a little bit faster than trapping and makes a few dynamic recompilers work better than they would in emulation mode. diff --git a/trunk/Documentation/lockdep-design.txt b/trunk/Documentation/lockdep-design.txt index 5dbc99c04f6e..abf768c681e2 100644 --- a/trunk/Documentation/lockdep-design.txt +++ b/trunk/Documentation/lockdep-design.txt @@ -221,66 +221,3 @@ when the chain is validated for the first time, is then put into a hash table, which hash-table can be checked in a lockfree manner. If the locking chain occurs again later on, the hash table tells us that we dont have to validate the chain again. - -Troubleshooting: ----------------- - -The validator tracks a maximum of MAX_LOCKDEP_KEYS number of lock classes. -Exceeding this number will trigger the following lockdep warning: - - (DEBUG_LOCKS_WARN_ON(id >= MAX_LOCKDEP_KEYS)) - -By default, MAX_LOCKDEP_KEYS is currently set to 8191, and typical -desktop systems have less than 1,000 lock classes, so this warning -normally results from lock-class leakage or failure to properly -initialize locks. These two problems are illustrated below: - -1. Repeated module loading and unloading while running the validator - will result in lock-class leakage. The issue here is that each - load of the module will create a new set of lock classes for - that module's locks, but module unloading does not remove old - classes (see below discussion of reuse of lock classes for why). - Therefore, if that module is loaded and unloaded repeatedly, - the number of lock classes will eventually reach the maximum. - -2. Using structures such as arrays that have large numbers of - locks that are not explicitly initialized. For example, - a hash table with 8192 buckets where each bucket has its own - spinlock_t will consume 8192 lock classes -unless- each spinlock - is explicitly initialized at runtime, for example, using the - run-time spin_lock_init() as opposed to compile-time initializers - such as __SPIN_LOCK_UNLOCKED(). Failure to properly initialize - the per-bucket spinlocks would guarantee lock-class overflow. - In contrast, a loop that called spin_lock_init() on each lock - would place all 8192 locks into a single lock class. - - The moral of this story is that you should always explicitly - initialize your locks. - -One might argue that the validator should be modified to allow -lock classes to be reused. However, if you are tempted to make this -argument, first review the code and think through the changes that would -be required, keeping in mind that the lock classes to be removed are -likely to be linked into the lock-dependency graph. This turns out to -be harder to do than to say. - -Of course, if you do run out of lock classes, the next thing to do is -to find the offending lock classes. First, the following command gives -you the number of lock classes currently in use along with the maximum: - - grep "lock-classes" /proc/lockdep_stats - -This command produces the following output on a modest system: - - lock-classes: 748 [max: 8191] - -If the number allocated (748 above) increases continually over time, -then there is likely a leak. The following command can be used to -identify the leaking lock classes: - - grep "BD" /proc/lockdep - -Run the command and save the output, then compare against the output from -a later run of this command to identify the leakers. This same output -can also help you find situations where runtime lock initialization has -been omitted. diff --git a/trunk/Documentation/networking/00-INDEX b/trunk/Documentation/networking/00-INDEX index 9ad9ddeb384c..bbce1215434a 100644 --- a/trunk/Documentation/networking/00-INDEX +++ b/trunk/Documentation/networking/00-INDEX @@ -144,8 +144,6 @@ nfc.txt - The Linux Near Field Communication (NFS) subsystem. olympic.txt - IBM PCI Pit/Pit-Phy/Olympic Token Ring driver info. -openvswitch.txt - - Open vSwitch developer documentation. operstates.txt - Overview of network interface operational states. packet_mmap.txt diff --git a/trunk/Documentation/networking/batman-adv.txt b/trunk/Documentation/networking/batman-adv.txt index 221ad0cdf11f..c86d03f18a5b 100644 --- a/trunk/Documentation/networking/batman-adv.txt +++ b/trunk/Documentation/networking/batman-adv.txt @@ -200,16 +200,15 @@ abled during run time. Following log_levels are defined: 0 - All debug output disabled 1 - Enable messages related to routing / flooding / broadcasting -2 - Enable messages related to route added / changed / deleted -4 - Enable messages related to translation table operations -7 - Enable all messages +2 - Enable route or tt entry added / changed / deleted +3 - Enable all messages The debug output can be changed at runtime using the file /sys/class/net/bat0/mesh/log_level. e.g. # echo 2 > /sys/class/net/bat0/mesh/log_level -will enable debug messages for when routes change. +will enable debug messages for when routes or TTs change. BATCTL diff --git a/trunk/Documentation/networking/bonding.txt b/trunk/Documentation/networking/bonding.txt index 080ad26690ae..91df678fb7f8 100644 --- a/trunk/Documentation/networking/bonding.txt +++ b/trunk/Documentation/networking/bonding.txt @@ -196,23 +196,6 @@ or, for backwards compatibility, the option value. E.g., The parameters are as follows: -active_slave - - Specifies the new active slave for modes that support it - (active-backup, balance-alb and balance-tlb). Possible values - are the name of any currently enslaved interface, or an empty - string. If a name is given, the slave and its link must be up in order - to be selected as the new active slave. If an empty string is - specified, the current active slave is cleared, and a new active - slave is selected automatically. - - Note that this is only available through the sysfs interface. No module - parameter by this name exists. - - The normal value of this option is the name of the currently - active slave, or the empty string if there is no active slave or - the current mode does not use an active slave. - ad_select Specifies the 802.3ad aggregation selection logic to use. The diff --git a/trunk/Documentation/networking/ieee802154.txt b/trunk/Documentation/networking/ieee802154.txt index 1dc1c24a7547..f41ea2405220 100644 --- a/trunk/Documentation/networking/ieee802154.txt +++ b/trunk/Documentation/networking/ieee802154.txt @@ -78,30 +78,3 @@ in software. This is currently WIP. See header include/net/mac802154.h and several drivers in drivers/ieee802154/. -6LoWPAN Linux implementation -============================ - -The IEEE 802.15.4 standard specifies an MTU of 128 bytes, yielding about 80 -octets of actual MAC payload once security is turned on, on a wireless link -with a link throughput of 250 kbps or less. The 6LoWPAN adaptation format -[RFC4944] was specified to carry IPv6 datagrams over such constrained links, -taking into account limited bandwidth, memory, or energy resources that are -expected in applications such as wireless Sensor Networks. [RFC4944] defines -a Mesh Addressing header to support sub-IP forwarding, a Fragmentation header -to support the IPv6 minimum MTU requirement [RFC2460], and stateless header -compression for IPv6 datagrams (LOWPAN_HC1 and LOWPAN_HC2) to reduce the -relatively large IPv6 and UDP headers down to (in the best case) several bytes. - -In Semptember 2011 the standard update was published - [RFC6282]. -It deprecates HC1 and HC2 compression and defines IPHC encoding format which is -used in this Linux implementation. - -All the code related to 6lowpan you may find in files: net/ieee802154/6lowpan.* - -To setup 6lowpan interface you need (busybox release > 1.17.0): -1. Add IEEE802.15.4 interface and initialize PANid; -2. Add 6lowpan interface by command like: - # ip link add link wpan0 name lowpan0 type lowpan -3. Set MAC (if needs): - # ip link set lowpan0 address de:ad:be:ef:ca:fe:ba:be -4. Bring up 'lowpan0' interface diff --git a/trunk/Documentation/networking/ifenslave.c b/trunk/Documentation/networking/ifenslave.c index ac5debb2f16c..65968fbf1e49 100644 --- a/trunk/Documentation/networking/ifenslave.c +++ b/trunk/Documentation/networking/ifenslave.c @@ -539,14 +539,12 @@ static int if_getconfig(char *ifname) metric = 0; } else metric = ifr.ifr_metric; - printf("The result of SIOCGIFMETRIC is %d\n", metric); strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0) mtu = 0; else mtu = ifr.ifr_mtu; - printf("The result of SIOCGIFMTU is %d\n", mtu); strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, SIOCGIFDSTADDR, &ifr) < 0) { diff --git a/trunk/Documentation/networking/ip-sysctl.txt b/trunk/Documentation/networking/ip-sysctl.txt index ad3e80e17b4f..589f2da5d545 100644 --- a/trunk/Documentation/networking/ip-sysctl.txt +++ b/trunk/Documentation/networking/ip-sysctl.txt @@ -31,16 +31,6 @@ neigh/default/gc_thresh3 - INTEGER when using large numbers of interfaces and when communicating with large numbers of directly-connected peers. -neigh/default/unres_qlen_bytes - INTEGER - The maximum number of bytes which may be used by packets - queued for each unresolved address by other network layers. - (added in linux 3.3) - -neigh/default/unres_qlen - INTEGER - The maximum number of packets which may be queued for each - unresolved address by other network layers. - (deprecated in linux 3.3) : use unres_qlen_bytes instead. - mtu_expires - INTEGER Time, in seconds, that cached PMTU information is kept. @@ -175,9 +165,6 @@ tcp_congestion_control - STRING connections. The algorithm "reno" is always available, but additional choices may be available based on kernel configuration. Default is set as part of kernel configuration. - For passive connections, the listener congestion control choice - is inherited. - [see setsockopt(listenfd, SOL_TCP, TCP_CONGESTION, "name" ...) ] tcp_cookie_size - INTEGER Default size of TCP Cookie Transactions (TCPCT) option, that may be diff --git a/trunk/Documentation/networking/openvswitch.txt b/trunk/Documentation/networking/openvswitch.txt deleted file mode 100644 index b8a048b8df3a..000000000000 --- a/trunk/Documentation/networking/openvswitch.txt +++ /dev/null @@ -1,195 +0,0 @@ -Open vSwitch datapath developer documentation -============================================= - -The Open vSwitch kernel module allows flexible userspace control over -flow-level packet processing on selected network devices. It can be -used to implement a plain Ethernet switch, network device bonding, -VLAN processing, network access control, flow-based network control, -and so on. - -The kernel module implements multiple "datapaths" (analogous to -bridges), each of which can have multiple "vports" (analogous to ports -within a bridge). Each datapath also has associated with it a "flow -table" that userspace populates with "flows" that map from keys based -on packet headers and metadata to sets of actions. The most common -action forwards the packet to another vport; other actions are also -implemented. - -When a packet arrives on a vport, the kernel module processes it by -extracting its flow key and looking it up in the flow table. If there -is a matching flow, it executes the associated actions. If there is -no match, it queues the packet to userspace for processing (as part of -its processing, userspace will likely set up a flow to handle further -packets of the same type entirely in-kernel). - - -Flow key compatibility ----------------------- - -Network protocols evolve over time. New protocols become important -and existing protocols lose their prominence. For the Open vSwitch -kernel module to remain relevant, it must be possible for newer -versions to parse additional protocols as part of the flow key. It -might even be desirable, someday, to drop support for parsing -protocols that have become obsolete. Therefore, the Netlink interface -to Open vSwitch is designed to allow carefully written userspace -applications to work with any version of the flow key, past or future. - -To support this forward and backward compatibility, whenever the -kernel module passes a packet to userspace, it also passes along the -flow key that it parsed from the packet. Userspace then extracts its -own notion of a flow key from the packet and compares it against the -kernel-provided version: - - - If userspace's notion of the flow key for the packet matches the - kernel's, then nothing special is necessary. - - - If the kernel's flow key includes more fields than the userspace - version of the flow key, for example if the kernel decoded IPv6 - headers but userspace stopped at the Ethernet type (because it - does not understand IPv6), then again nothing special is - necessary. Userspace can still set up a flow in the usual way, - as long as it uses the kernel-provided flow key to do it. - - - If the userspace flow key includes more fields than the - kernel's, for example if userspace decoded an IPv6 header but - the kernel stopped at the Ethernet type, then userspace can - forward the packet manually, without setting up a flow in the - kernel. This case is bad for performance because every packet - that the kernel considers part of the flow must go to userspace, - but the forwarding behavior is correct. (If userspace can - determine that the values of the extra fields would not affect - forwarding behavior, then it could set up a flow anyway.) - -How flow keys evolve over time is important to making this work, so -the following sections go into detail. - - -Flow key format ---------------- - -A flow key is passed over a Netlink socket as a sequence of Netlink -attributes. Some attributes represent packet metadata, defined as any -information about a packet that cannot be extracted from the packet -itself, e.g. the vport on which the packet was received. Most -attributes, however, are extracted from headers within the packet, -e.g. source and destination addresses from Ethernet, IP, or TCP -headers. - -The header file defines the exact format of the -flow key attributes. For informal explanatory purposes here, we write -them as comma-separated strings, with parentheses indicating arguments -and nesting. For example, the following could represent a flow key -corresponding to a TCP packet that arrived on vport 1: - - in_port(1), eth(src=e0:91:f5:21:d0:b2, dst=00:02:e3:0f:80:a4), - eth_type(0x0800), ipv4(src=172.16.0.20, dst=172.18.0.52, proto=17, tos=0, - frag=no), tcp(src=49163, dst=80) - -Often we ellipsize arguments not important to the discussion, e.g.: - - in_port(1), eth(...), eth_type(0x0800), ipv4(...), tcp(...) - - -Basic rule for evolving flow keys ---------------------------------- - -Some care is needed to really maintain forward and backward -compatibility for applications that follow the rules listed under -"Flow key compatibility" above. - -The basic rule is obvious: - - ------------------------------------------------------------------ - New network protocol support must only supplement existing flow - key attributes. It must not change the meaning of already defined - flow key attributes. - ------------------------------------------------------------------ - -This rule does have less-obvious consequences so it is worth working -through a few examples. Suppose, for example, that the kernel module -did not already implement VLAN parsing. Instead, it just interpreted -the 802.1Q TPID (0x8100) as the Ethertype then stopped parsing the -packet. The flow key for any packet with an 802.1Q header would look -essentially like this, ignoring metadata: - - eth(...), eth_type(0x8100) - -Naively, to add VLAN support, it makes sense to add a new "vlan" flow -key attribute to contain the VLAN tag, then continue to decode the -encapsulated headers beyond the VLAN tag using the existing field -definitions. With this change, an TCP packet in VLAN 10 would have a -flow key much like this: - - eth(...), vlan(vid=10, pcp=0), eth_type(0x0800), ip(proto=6, ...), tcp(...) - -But this change would negatively affect a userspace application that -has not been updated to understand the new "vlan" flow key attribute. -The application could, following the flow compatibility rules above, -ignore the "vlan" attribute that it does not understand and therefore -assume that the flow contained IP packets. This is a bad assumption -(the flow only contains IP packets if one parses and skips over the -802.1Q header) and it could cause the application's behavior to change -across kernel versions even though it follows the compatibility rules. - -The solution is to use a set of nested attributes. This is, for -example, why 802.1Q support uses nested attributes. A TCP packet in -VLAN 10 is actually expressed as: - - eth(...), eth_type(0x8100), vlan(vid=10, pcp=0), encap(eth_type(0x0800), - ip(proto=6, ...), tcp(...))) - -Notice how the "eth_type", "ip", and "tcp" flow key attributes are -nested inside the "encap" attribute. Thus, an application that does -not understand the "vlan" key will not see either of those attributes -and therefore will not misinterpret them. (Also, the outer eth_type -is still 0x8100, not changed to 0x0800.) - -Handling malformed packets --------------------------- - -Don't drop packets in the kernel for malformed protocol headers, bad -checksums, etc. This would prevent userspace from implementing a -simple Ethernet switch that forwards every packet. - -Instead, in such a case, include an attribute with "empty" content. -It doesn't matter if the empty content could be valid protocol values, -as long as those values are rarely seen in practice, because userspace -can always forward all packets with those values to userspace and -handle them individually. - -For example, consider a packet that contains an IP header that -indicates protocol 6 for TCP, but which is truncated just after the IP -header, so that the TCP header is missing. The flow key for this -packet would include a tcp attribute with all-zero src and dst, like -this: - - eth(...), eth_type(0x0800), ip(proto=6, ...), tcp(src=0, dst=0) - -As another example, consider a packet with an Ethernet type of 0x8100, -indicating that a VLAN TCI should follow, but which is truncated just -after the Ethernet type. The flow key for this packet would include -an all-zero-bits vlan and an empty encap attribute, like this: - - eth(...), eth_type(0x8100), vlan(0), encap() - -Unlike a TCP packet with source and destination ports 0, an -all-zero-bits VLAN TCI is not that rare, so the CFI bit (aka -VLAN_TAG_PRESENT inside the kernel) is ordinarily set in a vlan -attribute expressly to allow this situation to be distinguished. -Thus, the flow key in this second example unambiguously indicates a -missing or malformed VLAN TCI. - -Other rules ------------ - -The other rules for flow keys are much less subtle: - - - Duplicate attributes are not allowed at a given nesting level. - - - Ordering of attributes is not significant. - - - When the kernel sends a given flow key to userspace, it always - composes it the same way. This allows userspace to hash and - compare entire flow keys that it may not be able to fully - interpret. diff --git a/trunk/Documentation/networking/packet_mmap.txt b/trunk/Documentation/networking/packet_mmap.txt index 1c08a4b0981f..4acea6603720 100644 --- a/trunk/Documentation/networking/packet_mmap.txt +++ b/trunk/Documentation/networking/packet_mmap.txt @@ -155,7 +155,7 @@ As capture, each frame contains two parts: /* fill sockaddr_ll struct to prepare binding */ my_addr.sll_family = AF_PACKET; - my_addr.sll_protocol = htons(ETH_P_ALL); + my_addr.sll_protocol = ETH_P_ALL; my_addr.sll_ifindex = s_ifr.ifr_ifindex; /* bind socket to eth0 */ diff --git a/trunk/Documentation/networking/scaling.txt b/trunk/Documentation/networking/scaling.txt index 579994afbe06..a177de21d28e 100644 --- a/trunk/Documentation/networking/scaling.txt +++ b/trunk/Documentation/networking/scaling.txt @@ -208,7 +208,7 @@ The counter in rps_dev_flow_table values records the length of the current CPU's backlog when a packet in this flow was last enqueued. Each backlog queue has a head counter that is incremented on dequeue. A tail counter is computed as head counter + queue length. In other words, the counter -in rps_dev_flow[i] records the last element in flow i that has +in rps_dev_flow_table[i] records the last element in flow i that has been enqueued onto the currently designated CPU for flow i (of course, entry i is actually selected by hash and multiple flows may hash to the same entry i). @@ -224,7 +224,7 @@ following is true: - The current CPU's queue head counter >= the recorded tail counter value in rps_dev_flow[i] -- The current CPU is unset (equal to RPS_NO_CPU) +- The current CPU is unset (equal to NR_CPUS) - The current CPU is offline After this check, the packet is sent to the (possibly updated) current @@ -235,7 +235,7 @@ CPU. ==== RFS Configuration -RFS is only available if the kconfig symbol CONFIG_RPS is enabled (on +RFS is only available if the kconfig symbol CONFIG_RFS is enabled (on by default for SMP). The functionality remains disabled until explicitly configured. The number of entries in the global flow table is set through: @@ -258,7 +258,7 @@ For a single queue device, the rps_flow_cnt value for the single queue would normally be configured to the same value as rps_sock_flow_entries. For a multi-queue device, the rps_flow_cnt for each queue might be configured as rps_sock_flow_entries / N, where N is the number of -queues. So for instance, if rps_sock_flow_entries is set to 32768 and there +queues. So for instance, if rps_flow_entries is set to 32768 and there are 16 configured receive queues, rps_flow_cnt for each queue might be configured as 2048. diff --git a/trunk/Documentation/networking/stmmac.txt b/trunk/Documentation/networking/stmmac.txt index d0aeeadd264b..8d67980fabe8 100644 --- a/trunk/Documentation/networking/stmmac.txt +++ b/trunk/Documentation/networking/stmmac.txt @@ -4,16 +4,14 @@ Copyright (C) 2007-2010 STMicroelectronics Ltd Author: Giuseppe Cavallaro This is the driver for the MAC 10/100/1000 on-chip Ethernet controllers -(Synopsys IP blocks). +(Synopsys IP blocks); it has been fully tested on STLinux platforms. Currently this network device driver is for all STM embedded MAC/GMAC -(i.e. 7xxx/5xxx SoCs), SPEAr (arm), Loongson1B (mips) and XLINX XC2V3000 -FF1152AMT0221 D1215994A VIRTEX FPGA board. +(i.e. 7xxx/5xxx SoCs) and it's known working on other platforms i.e. ARM SPEAr. -DWC Ether MAC 10/100/1000 Universal version 3.60a (and older) and DWC Ether MAC 10/100 -Universal version 4.0 have been used for developing this driver. - -This driver supports both the platform bus and PCI. +DWC Ether MAC 10/100/1000 Universal version 3.41a and DWC Ether MAC 10/100 +Universal version 4.0 have been used for developing the first code +implementation. Please, for more information also visit: www.stlinux.com @@ -279,5 +277,5 @@ In fact, these can generate an huge amount of debug messages. 6) TODO: o XGMAC is not supported. - o Add the EEE - Energy Efficient Ethernet - o Add the PTP - precision time protocol + o Review the timer optimisation code to use an embedded device that will be + available in new chip generations. diff --git a/trunk/Documentation/networking/team.txt b/trunk/Documentation/networking/team.txt deleted file mode 100644 index 5a013686b9ea..000000000000 --- a/trunk/Documentation/networking/team.txt +++ /dev/null @@ -1,2 +0,0 @@ -Team devices are driven from userspace via libteam library which is here: - https://github.com/jpirko/libteam diff --git a/trunk/Documentation/trace/events.txt b/trunk/Documentation/trace/events.txt index bb24c2a0e870..b510564aac7e 100644 --- a/trunk/Documentation/trace/events.txt +++ b/trunk/Documentation/trace/events.txt @@ -191,6 +191,8 @@ And for string fields they are: Currently, only exact string matches are supported. +Currently, the maximum number of predicates in a filter is 16. + 5.2 Setting filters ------------------- diff --git a/trunk/Documentation/virtual/kvm/api.txt b/trunk/Documentation/virtual/kvm/api.txt index e2a4b5287361..7945b0bd35e2 100644 --- a/trunk/Documentation/virtual/kvm/api.txt +++ b/trunk/Documentation/virtual/kvm/api.txt @@ -1100,15 +1100,6 @@ emulate them efficiently. The fields in each entry are defined as follows: eax, ebx, ecx, edx: the values returned by the cpuid instruction for this function/index combination -The TSC deadline timer feature (CPUID leaf 1, ecx[24]) is always returned -as false, since the feature depends on KVM_CREATE_IRQCHIP for local APIC -support. Instead it is reported via - - ioctl(KVM_CHECK_EXTENSION, KVM_CAP_TSC_DEADLINE_TIMER) - -if that returns true and you use KVM_CREATE_IRQCHIP, or if you emulate the -feature in userspace, then you can enable the feature for KVM_SET_CPUID2. - 4.47 KVM_PPC_GET_PVINFO Capability: KVM_CAP_PPC_GET_PVINFO @@ -1160,13 +1151,6 @@ following flags are specified: /* Depends on KVM_CAP_IOMMU */ #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) -The KVM_DEV_ASSIGN_ENABLE_IOMMU flag is a mandatory option to ensure -isolation of the device. Usages not specifying this flag are deprecated. - -Only PCI header type 0 devices with PCI BAR resources are supported by -device assignment. The user requesting this ioctl must have read/write -access to the PCI sysfs resource files associated with the device. - 4.49 KVM_DEASSIGN_PCI_DEVICE Capability: KVM_CAP_DEVICE_DEASSIGNMENT diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index c00e3cc22352..b9db108f01c8 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1124,6 +1124,13 @@ S: Supported F: arch/arm/mach-shmobile/ F: drivers/sh/ +ARM/TELECHIPS ARM ARCHITECTURE +M: "Hans J. Koch" +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm/plat-tcc/ +F: arch/arm/mach-tcc8k/ + ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT M: Lennert Buytenhek L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -1691,9 +1698,11 @@ F: arch/x86/include/asm/tce.h CAN NETWORK LAYER M: Oliver Hartkopp +M: Oliver Hartkopp +M: Urs Thuermann L: linux-can@vger.kernel.org -W: http://gitorious.org/linux-can -T: git git://gitorious.org/linux-can/linux-can-next.git +L: netdev@vger.kernel.org +W: http://developer.berlios.de/projects/socketcan/ S: Maintained F: net/can/ F: include/linux/can.h @@ -1704,10 +1713,9 @@ F: include/linux/can/gw.h CAN NETWORK DRIVERS M: Wolfgang Grandegger -M: Marc Kleine-Budde L: linux-can@vger.kernel.org -W: http://gitorious.org/linux-can -T: git git://gitorious.org/linux-can/linux-can-next.git +L: netdev@vger.kernel.org +W: http://developer.berlios.de/projects/socketcan/ S: Maintained F: drivers/net/can/ F: include/linux/can/dev.h @@ -2692,7 +2700,7 @@ FIREWIRE SUBSYSTEM M: Stefan Richter L: linux1394-devel@lists.sourceforge.net W: http://ieee1394.wiki.kernel.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git S: Maintained F: drivers/firewire/ F: include/linux/firewire*.h @@ -2912,7 +2920,6 @@ F: include/linux/gigaset_dev.h GPIO SUBSYSTEM M: Grant Likely -M: Linus Walleij S: Maintained T: git git://git.secretlab.ca/git/linux-2.6.git F: Documentation/gpio.txt @@ -3094,7 +3101,6 @@ F: include/linux/hid* HIGH-RESOLUTION TIMERS, CLOCKEVENTS, DYNTICKS M: Thomas Gleixner -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core S: Maintained F: Documentation/timers/ F: kernel/hrtimer.c @@ -3604,7 +3610,7 @@ F: net/irda/ IRQ SUBSYSTEM M: Thomas Gleixner S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git irq/core F: kernel/irq/ ISAPNP @@ -4005,7 +4011,7 @@ M: Josh Boyer M: Matt Porter W: http://www.penguinppc.org/ L: linuxppc-dev@lists.ozlabs.org -T: git git://git.infradead.org/users/jwboyer/powerpc-4xx.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git S: Maintained F: arch/powerpc/platforms/40x/ F: arch/powerpc/platforms/44x/ @@ -4092,7 +4098,7 @@ F: drivers/hwmon/lm90.c LOCKDEP AND LOCKSTAT M: Peter Zijlstra M: Ingo Molnar -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core/locking +T: git git://git.kernel.org/pub/scm/linux/kernel/git/peterz/linux-2.6-lockdep.git S: Maintained F: Documentation/lockdep*.txt F: Documentation/lockstat.txt @@ -4274,9 +4280,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git S: Maintained F: Documentation/dvb/ F: Documentation/video4linux/ -F: Documentation/DocBook/media/ F: drivers/media/ -F: drivers/staging/media/ F: include/media/ F: include/linux/dvb/ F: include/linux/videodev*.h @@ -4848,14 +4852,6 @@ S: Maintained T: git git://openrisc.net/~jonas/linux F: arch/openrisc -OPENVSWITCH -M: Jesse Gross -L: dev@openvswitch.org -W: http://openvswitch.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/jesse/openvswitch.git -S: Maintained -F: net/openvswitch/ - OPL4 DRIVER M: Clemens Ladisch L: alsa-devel@alsa-project.org (moderated for non-subscribers) @@ -5090,7 +5086,6 @@ M: Peter Zijlstra M: Paul Mackerras M: Ingo Molnar M: Arnaldo Carvalho de Melo -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core S: Supported F: kernel/events/* F: include/linux/perf_event.h @@ -5170,7 +5165,6 @@ F: drivers/scsi/pm8001/ POSIX CLOCKS and TIMERS M: Thomas Gleixner -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core S: Supported F: fs/timerfd.c F: include/linux/timer* @@ -5375,7 +5369,6 @@ S: Supported F: drivers/scsi/qla4xxx/ QLOGIC QLA3XXX NETWORK DRIVER -M: Jitendra Kalsaria M: Ron Mercer M: linux-driver@qlogic.com L: netdev@vger.kernel.org @@ -5687,7 +5680,6 @@ F: drivers/dma/dw_dmac.c TIMEKEEPING, NTP M: John Stultz M: Thomas Gleixner -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core S: Supported F: include/linux/clocksource.h F: include/linux/time.h @@ -5712,7 +5704,6 @@ F: drivers/watchdog/sc1200wdt.c SCHEDULER M: Ingo Molnar M: Peter Zijlstra -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git sched/core S: Maintained F: kernel/sched* F: include/linux/sched.h @@ -5895,6 +5886,7 @@ F: drivers/net/ethernet/emulex/benet/ SFC NETWORK DRIVER M: Solarflare linux maintainers +M: Steve Hodgson M: Ben Hutchings L: netdev@vger.kernel.org S: Supported @@ -6260,7 +6252,7 @@ F: arch/alpha/kernel/srm_env.c STABLE BRANCH M: Greg Kroah-Hartman -L: stable@vger.kernel.org +L: stable@kernel.org S: Maintained STAGING SUBSYSTEM @@ -6502,13 +6494,6 @@ W: http://tcp-lp-mod.sourceforge.net/ S: Maintained F: net/ipv4/tcp_lp.c -TEAM DRIVER -M: Jiri Pirko -L: netdev@vger.kernel.org -S: Supported -F: drivers/net/team/ -F: include/linux/if_team.h - TEGRA SUPPORT M: Colin Cross M: Olof Johansson @@ -6646,7 +6631,7 @@ TRACING M: Steven Rostedt M: Frederic Weisbecker M: Ingo Molnar -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git perf/core S: Maintained F: Documentation/trace/ftrace.txt F: arch/*/*/*/ftrace.h @@ -7396,7 +7381,7 @@ M: Thomas Gleixner M: Ingo Molnar M: "H. Peter Anvin" M: x86@kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/core +T: git git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git S: Maintained F: Documentation/x86/ F: arch/x86/ diff --git a/trunk/Makefile b/trunk/Makefile index adddd11c3b3b..a43733df3978 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 2 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc6 NAME = Saber-toothed Squirrel # *DOCUMENTATION* diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig index 2505740b81d2..4b0669cbb3b0 100644 --- a/trunk/arch/Kconfig +++ b/trunk/arch/Kconfig @@ -30,10 +30,6 @@ config OPROFILE_EVENT_MULTIPLEX config HAVE_OPROFILE bool -config OPROFILE_NMI_TIMER - def_bool y - depends on PERF_EVENTS && HAVE_PERF_EVENTS_NMI - config KPROBES bool "Kprobes" depends on MODULES diff --git a/trunk/arch/alpha/include/asm/socket.h b/trunk/arch/alpha/include/asm/socket.h index 082355f159e6..06edfefc3373 100644 --- a/trunk/arch/alpha/include/asm/socket.h +++ b/trunk/arch/alpha/include/asm/socket.h @@ -69,9 +69,6 @@ #define SO_RXQ_OVFL 40 -#define SO_WIFI_STATUS 41 -#define SCM_WIFI_STATUS SO_WIFI_STATUS - /* O_NONBLOCK clashes with the bits used for socket types. Therefore we * have to define SOCK_NONBLOCK to a different value here. */ diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 444822526a07..776d76b8cb69 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -258,7 +258,6 @@ config ARCH_INTEGRATOR select ARCH_HAS_CPUFREQ select CLKDEV_LOOKUP select HAVE_MACH_CLKDEV - select HAVE_TCM select ICST select GENERIC_CLOCKEVENTS select PLAT_VERSATILE @@ -342,12 +341,10 @@ config ARCH_HIGHBANK select ARM_AMBA select ARM_GIC select ARM_TIMER_SP804 - select CACHE_L2X0 select CLKDEV_LOOKUP select CPU_V7 select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU - select HAVE_SMP select USE_OF help Support for the Calxeda Highbank SoC based boards. @@ -365,7 +362,6 @@ config ARCH_CNS3XXX select CPU_V6K select GENERIC_CLOCKEVENTS select ARM_GIC - select MIGHT_HAVE_CACHE_L2X0 select MIGHT_HAVE_PCI select PCI_DOMAINS if PCI help @@ -386,7 +382,6 @@ config ARCH_PRIMA2 select GENERIC_CLOCKEVENTS select CLKDEV_LOOKUP select GENERIC_IRQ_CHIP - select MIGHT_HAVE_CACHE_L2X0 select USE_OF select ZONE_DMA help @@ -639,8 +634,6 @@ config ARCH_TEGRA select GENERIC_GPIO select HAVE_CLK select HAVE_SCHED_CLOCK - select HAVE_SMP - select MIGHT_HAVE_CACHE_L2X0 select ARCH_HAS_CPUFREQ help This enables support for NVIDIA Tegra based systems (Tegra APX, @@ -710,9 +703,7 @@ config ARCH_SHMOBILE select HAVE_CLK select CLKDEV_LOOKUP select HAVE_MACH_CLKDEV - select HAVE_SMP select GENERIC_CLOCKEVENTS - select MIGHT_HAVE_CACHE_L2X0 select NO_IOPORT select SPARSE_IRQ select MULTI_IRQ_HANDLER @@ -877,6 +868,16 @@ config ARCH_SHARK Support for the StrongARM based Digital DNARD machine, also known as "Shark" (). +config ARCH_TCC_926 + bool "Telechips TCC ARM926-based systems" + select CLKSRC_MMIO + select CPU_ARM926T + select HAVE_CLK + select CLKDEV_LOOKUP + select GENERIC_CLOCKEVENTS + help + Support for Telechips TCC ARM926-based systems. + config ARCH_U300 bool "ST-Ericsson U300 Series" depends on MMU @@ -904,8 +905,6 @@ config ARCH_U8500 select CLKDEV_LOOKUP select ARCH_REQUIRE_GPIOLIB select ARCH_HAS_CPUFREQ - select HAVE_SMP - select MIGHT_HAVE_CACHE_L2X0 help Support for ST-Ericsson's Ux500 architecture @@ -916,7 +915,6 @@ config ARCH_NOMADIK select CPU_ARM926T select CLKDEV_LOOKUP select GENERIC_CLOCKEVENTS - select MIGHT_HAVE_CACHE_L2X0 select ARCH_REQUIRE_GPIOLIB help Support for the Nomadik platform by ST-Ericsson @@ -976,7 +974,6 @@ config ARCH_ZYNQ select ARM_GIC select ARM_AMBA select ICST - select MIGHT_HAVE_CACHE_L2X0 select USE_OF help Support for Xilinx Zynq ARM Cortex A9 Platform @@ -1063,6 +1060,8 @@ source "arch/arm/plat-s5p/Kconfig" source "arch/arm/plat-spear/Kconfig" +source "arch/arm/plat-tcc/Kconfig" + if ARCH_S3C2410 source "arch/arm/mach-s3c2410/Kconfig" source "arch/arm/mach-s3c2412/Kconfig" @@ -1127,11 +1126,6 @@ config ARM_TIMER_SP804 source arch/arm/mm/Kconfig -config ARM_NR_BANKS - int - default 16 if ARCH_EP93XX - default 8 - config IWMMXT bool "Enable iWMMXt support" depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 @@ -1252,7 +1246,7 @@ config PL310_ERRATA_588369 config ARM_ERRATA_720789 bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" - depends on CPU_V7 + depends on CPU_V7 && SMP help This option enables the workaround for the 720789 Cortex-A9 (prior to r2p0) erratum. A faulty ASID can be sent to the other CPUs for the @@ -1288,7 +1282,7 @@ config ARM_ERRATA_743622 config ARM_ERRATA_751472 bool "ARM errata: Interrupted ICIALLUIS may prevent completion of broadcasted operation" - depends on CPU_V7 + depends on CPU_V7 && SMP help This option enables the workaround for the 751472 Cortex-A9 (prior to r3p0) erratum. An interrupted ICIALLUIS operation may prevent the @@ -1441,20 +1435,14 @@ menu "Kernel Features" source "kernel/time/Kconfig" -config HAVE_SMP - bool - help - This option should be selected by machines which have an SMP- - capable CPU. - - The only effect of this option is to make the SMP-related - options available to the user for configuration. - config SMP bool "Symmetric Multi-Processing" depends on CPU_V6K || CPU_V7 depends on GENERIC_CLOCKEVENTS - depends on HAVE_SMP + depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \ + MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ + ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \ + ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE || ARCH_HIGHBANK || SOC_IMX6Q depends on MMU select USE_GENERIC_SMP_HELPERS select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP @@ -1572,16 +1560,6 @@ config LOCAL_TIMERS accounting to be spread across the timer interval, preventing a "thundering herd" at every timer tick. -config ARCH_NR_GPIO - int - default 1024 if ARCH_SHMOBILE || ARCH_TEGRA - default 350 if ARCH_U8500 - default 0 - help - Maximum number of GPIOs in the system. - - If unsure, leave the default value. - source kernel/Kconfig.preempt config HZ @@ -1994,7 +1972,7 @@ endchoice config XIP_KERNEL bool "Kernel Execute-In-Place from ROM" - depends on !ZBOOT_ROM && !ARM_LPAE + depends on !ZBOOT_ROM help Execute-In-Place allows the kernel to run from non-volatile storage directly addressable by the CPU, such as NOR flash. This saves RAM @@ -2024,7 +2002,7 @@ config XIP_PHYS_ADDR config KEXEC bool "Kexec system call (EXPERIMENTAL)" - depends on EXPERIMENTAL && (!SMP || HOTPLUG_CPU) + depends on EXPERIMENTAL help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index 40319d91bb7f..dfcf3b033e10 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -184,6 +184,7 @@ machine-$(CONFIG_ARCH_EXYNOS4) := exynos machine-$(CONFIG_ARCH_SA1100) := sa1100 machine-$(CONFIG_ARCH_SHARK) := shark machine-$(CONFIG_ARCH_SHMOBILE) := shmobile +machine-$(CONFIG_ARCH_TCC8K) := tcc8k machine-$(CONFIG_ARCH_TEGRA) := tegra machine-$(CONFIG_ARCH_U300) := u300 machine-$(CONFIG_ARCH_U8500) := ux500 @@ -203,6 +204,7 @@ machine-$(CONFIG_ARCH_ZYNQ) := zynq plat-$(CONFIG_ARCH_MXC) := mxc plat-$(CONFIG_ARCH_OMAP) := omap plat-$(CONFIG_ARCH_S3C64XX) := samsung +plat-$(CONFIG_ARCH_TCC_926) := tcc plat-$(CONFIG_ARCH_ZYNQ) := versatile plat-$(CONFIG_PLAT_IOP) := iop plat-$(CONFIG_PLAT_NOMADIK) := nomadik diff --git a/trunk/arch/arm/boot/compressed/Makefile b/trunk/arch/arm/boot/compressed/Makefile index cf0a64ce4b83..21f56ff32797 100644 --- a/trunk/arch/arm/boot/compressed/Makefile +++ b/trunk/arch/arm/boot/compressed/Makefile @@ -126,8 +126,7 @@ ccflags-y := -fpic -fno-builtin -I$(obj) asflags-y := -Wa,-march=all # Supply kernel BSS size to the decompressor via a linker symbol. -KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \ - awk 'END{print $$3}') +KBSS_SZ = $(shell size $(obj)/../../../../vmlinux | awk 'END{print $$3}') LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ) # Supply ZRELADDR to the decompressor via a linker symbol. ifneq ($(CONFIG_AUTO_ZRELADDR),y) diff --git a/trunk/arch/arm/boot/compressed/head.S b/trunk/arch/arm/boot/compressed/head.S index c5d60250d43d..c2effc917254 100644 --- a/trunk/arch/arm/boot/compressed/head.S +++ b/trunk/arch/arm/boot/compressed/head.S @@ -659,7 +659,6 @@ __armv7_mmu_cache_on: mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer mcrne p15, 0, r1, c3, c0, 0 @ load domain access control #endif - mcr p15, 0, r0, c7, c5, 4 @ ISB mcr p15, 0, r0, c1, c0, 0 @ load control register mrc p15, 0, r0, c1, c0, 0 @ and read it back mov r0, #0 diff --git a/trunk/arch/arm/boot/dts/testcases/tests-phandle.dtsi b/trunk/arch/arm/boot/dts/testcases/tests-phandle.dtsi deleted file mode 100644 index ec0c4e6212c9..000000000000 --- a/trunk/arch/arm/boot/dts/testcases/tests-phandle.dtsi +++ /dev/null @@ -1,37 +0,0 @@ - -/ { - testcase-data { - phandle-tests { - provider0: provider0 { - #phandle-cells = <0>; - }; - - provider1: provider1 { - #phandle-cells = <1>; - }; - - provider2: provider2 { - #phandle-cells = <2>; - }; - - provider3: provider3 { - #phandle-cells = <3>; - }; - - consumer-a { - phandle-list = <&provider1 1>, - <&provider2 2 0>, - <0>, - <&provider3 4 4 3>, - <&provider2 5 100>, - <&provider0>, - <&provider1 7>; - phandle-list-names = "first", "second", "third"; - - phandle-list-bad-phandle = <12345678 0 0>; - phandle-list-bad-args = <&provider2 1 0>, - <&provider3 0>; - }; - }; - }; -}; diff --git a/trunk/arch/arm/boot/dts/testcases/tests.dtsi b/trunk/arch/arm/boot/dts/testcases/tests.dtsi deleted file mode 100644 index a7c5067622e8..000000000000 --- a/trunk/arch/arm/boot/dts/testcases/tests.dtsi +++ /dev/null @@ -1 +0,0 @@ -/include/ "tests-phandle.dtsi" diff --git a/trunk/arch/arm/boot/dts/versatile-pb.dts b/trunk/arch/arm/boot/dts/versatile-pb.dts index 166461073b78..8a614e398004 100644 --- a/trunk/arch/arm/boot/dts/versatile-pb.dts +++ b/trunk/arch/arm/boot/dts/versatile-pb.dts @@ -46,5 +46,3 @@ }; }; }; - -/include/ "testcases/tests.dtsi" diff --git a/trunk/arch/arm/common/Kconfig b/trunk/arch/arm/common/Kconfig index 81a933eb0903..74df9ca2be31 100644 --- a/trunk/arch/arm/common/Kconfig +++ b/trunk/arch/arm/common/Kconfig @@ -1,14 +1,8 @@ config ARM_GIC select IRQ_DOMAIN - select MULTI_IRQ_HANDLER - bool - -config GIC_NON_BANKED bool config ARM_VIC - select IRQ_DOMAIN - select MULTI_IRQ_HANDLER bool config ARM_VIC_NR diff --git a/trunk/arch/arm/common/gic.c b/trunk/arch/arm/common/gic.c index b2dc2dd7f1df..410a546060a2 100644 --- a/trunk/arch/arm/common/gic.c +++ b/trunk/arch/arm/common/gic.c @@ -40,37 +40,14 @@ #include #include -#include #include #include -union gic_base { - void __iomem *common_base; - void __percpu __iomem **percpu_base; -}; - -struct gic_chip_data { - unsigned int irq_offset; - union gic_base dist_base; - union gic_base cpu_base; -#ifdef CONFIG_CPU_PM - u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)]; - u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)]; - u32 saved_spi_target[DIV_ROUND_UP(1020, 4)]; - u32 __percpu *saved_ppi_enable; - u32 __percpu *saved_ppi_conf; -#endif -#ifdef CONFIG_IRQ_DOMAIN - struct irq_domain domain; -#endif - unsigned int gic_irqs; -#ifdef CONFIG_GIC_NON_BANKED - void __iomem *(*get_base)(union gic_base *); -#endif -}; - static DEFINE_RAW_SPINLOCK(irq_controller_lock); +/* Address of GIC 0 CPU interface */ +void __iomem *gic_cpu_base_addr __read_mostly; + /* * Supported arch specific GIC irq extension. * Default make them NULL. @@ -90,48 +67,16 @@ struct irq_chip gic_arch_extn = { static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly; -#ifdef CONFIG_GIC_NON_BANKED -static void __iomem *gic_get_percpu_base(union gic_base *base) -{ - return *__this_cpu_ptr(base->percpu_base); -} - -static void __iomem *gic_get_common_base(union gic_base *base) -{ - return base->common_base; -} - -static inline void __iomem *gic_data_dist_base(struct gic_chip_data *data) -{ - return data->get_base(&data->dist_base); -} - -static inline void __iomem *gic_data_cpu_base(struct gic_chip_data *data) -{ - return data->get_base(&data->cpu_base); -} - -static inline void gic_set_base_accessor(struct gic_chip_data *data, - void __iomem *(*f)(union gic_base *)) -{ - data->get_base = f; -} -#else -#define gic_data_dist_base(d) ((d)->dist_base.common_base) -#define gic_data_cpu_base(d) ((d)->cpu_base.common_base) -#define gic_set_base_accessor(d,f) -#endif - static inline void __iomem *gic_dist_base(struct irq_data *d) { struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); - return gic_data_dist_base(gic_data); + return gic_data->dist_base; } static inline void __iomem *gic_cpu_base(struct irq_data *d) { struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); - return gic_data_cpu_base(gic_data); + return gic_data->cpu_base; } static inline unsigned int gic_irq(struct irq_data *d) @@ -270,32 +215,6 @@ static int gic_set_wake(struct irq_data *d, unsigned int on) #define gic_set_wake NULL #endif -asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) -{ - u32 irqstat, irqnr; - struct gic_chip_data *gic = &gic_data[0]; - void __iomem *cpu_base = gic_data_cpu_base(gic); - - do { - irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); - irqnr = irqstat & ~0x1c00; - - if (likely(irqnr > 15 && irqnr < 1021)) { - irqnr = irq_domain_to_irq(&gic->domain, irqnr); - handle_IRQ(irqnr, regs); - continue; - } - if (irqnr < 16) { - writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); -#ifdef CONFIG_SMP - handle_IPI(irqnr, regs); -#endif - continue; - } - break; - } while (1); -} - static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) { struct gic_chip_data *chip_data = irq_get_handler_data(irq); @@ -306,7 +225,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) chained_irq_enter(chip, desc); raw_spin_lock(&irq_controller_lock); - status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK); + status = readl_relaxed(chip_data->cpu_base + GIC_CPU_INTACK); raw_spin_unlock(&irq_controller_lock); gic_irq = (status & 0x3ff); @@ -351,7 +270,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic) u32 cpumask; unsigned int gic_irqs = gic->gic_irqs; struct irq_domain *domain = &gic->domain; - void __iomem *base = gic_data_dist_base(gic); + void __iomem *base = gic->dist_base; u32 cpu = 0; #ifdef CONFIG_SMP @@ -411,8 +330,8 @@ static void __init gic_dist_init(struct gic_chip_data *gic) static void __cpuinit gic_cpu_init(struct gic_chip_data *gic) { - void __iomem *dist_base = gic_data_dist_base(gic); - void __iomem *base = gic_data_cpu_base(gic); + void __iomem *dist_base = gic->dist_base; + void __iomem *base = gic->cpu_base; int i; /* @@ -449,7 +368,7 @@ static void gic_dist_save(unsigned int gic_nr) BUG(); gic_irqs = gic_data[gic_nr].gic_irqs; - dist_base = gic_data_dist_base(&gic_data[gic_nr]); + dist_base = gic_data[gic_nr].dist_base; if (!dist_base) return; @@ -484,7 +403,7 @@ static void gic_dist_restore(unsigned int gic_nr) BUG(); gic_irqs = gic_data[gic_nr].gic_irqs; - dist_base = gic_data_dist_base(&gic_data[gic_nr]); + dist_base = gic_data[gic_nr].dist_base; if (!dist_base) return; @@ -520,8 +439,8 @@ static void gic_cpu_save(unsigned int gic_nr) if (gic_nr >= MAX_GIC_NR) BUG(); - dist_base = gic_data_dist_base(&gic_data[gic_nr]); - cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); + dist_base = gic_data[gic_nr].dist_base; + cpu_base = gic_data[gic_nr].cpu_base; if (!dist_base || !cpu_base) return; @@ -546,8 +465,8 @@ static void gic_cpu_restore(unsigned int gic_nr) if (gic_nr >= MAX_GIC_NR) BUG(); - dist_base = gic_data_dist_base(&gic_data[gic_nr]); - cpu_base = gic_data_cpu_base(&gic_data[gic_nr]); + dist_base = gic_data[gic_nr].dist_base; + cpu_base = gic_data[gic_nr].cpu_base; if (!dist_base || !cpu_base) return; @@ -572,11 +491,6 @@ static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) int i; for (i = 0; i < MAX_GIC_NR; i++) { -#ifdef CONFIG_GIC_NON_BANKED - /* Skip over unused GICs */ - if (!gic_data[i].get_base) - continue; -#endif switch (cmd) { case CPU_PM_ENTER: gic_cpu_save(i); @@ -650,9 +564,8 @@ const struct irq_domain_ops gic_irq_domain_ops = { #endif }; -void __init gic_init_bases(unsigned int gic_nr, int irq_start, - void __iomem *dist_base, void __iomem *cpu_base, - u32 percpu_offset) +void __init gic_init(unsigned int gic_nr, int irq_start, + void __iomem *dist_base, void __iomem *cpu_base) { struct gic_chip_data *gic; struct irq_domain *domain; @@ -662,36 +575,8 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, gic = &gic_data[gic_nr]; domain = &gic->domain; -#ifdef CONFIG_GIC_NON_BANKED - if (percpu_offset) { /* Frankein-GIC without banked registers... */ - unsigned int cpu; - - gic->dist_base.percpu_base = alloc_percpu(void __iomem *); - gic->cpu_base.percpu_base = alloc_percpu(void __iomem *); - if (WARN_ON(!gic->dist_base.percpu_base || - !gic->cpu_base.percpu_base)) { - free_percpu(gic->dist_base.percpu_base); - free_percpu(gic->cpu_base.percpu_base); - return; - } - - for_each_possible_cpu(cpu) { - unsigned long offset = percpu_offset * cpu_logical_map(cpu); - *per_cpu_ptr(gic->dist_base.percpu_base, cpu) = dist_base + offset; - *per_cpu_ptr(gic->cpu_base.percpu_base, cpu) = cpu_base + offset; - } - - gic_set_base_accessor(gic, gic_get_percpu_base); - } else -#endif - { /* Normal, sane GIC... */ - WARN(percpu_offset, - "GIC_NON_BANKED not enabled, ignoring %08x offset!", - percpu_offset); - gic->dist_base.common_base = dist_base; - gic->cpu_base.common_base = cpu_base; - gic_set_base_accessor(gic, gic_get_common_base); - } + gic->dist_base = dist_base; + gic->cpu_base = cpu_base; /* * For primary GICs, skip over SGIs. @@ -699,6 +584,8 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, */ domain->hwirq_base = 32; if (gic_nr == 0) { + gic_cpu_base_addr = cpu_base; + if ((irq_start & 31) > 0) { domain->hwirq_base = 16; if (irq_start != -1) @@ -710,7 +597,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, * Find out how many interrupts are supported. * The GIC only supports up to 1020 interrupt sources. */ - gic_irqs = readl_relaxed(gic_data_dist_base(gic) + GIC_DIST_CTR) & 0x1f; + gic_irqs = readl_relaxed(dist_base + GIC_DIST_CTR) & 0x1f; gic_irqs = (gic_irqs + 1) * 32; if (gic_irqs > 1020) gic_irqs = 1020; @@ -758,7 +645,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) dsb(); /* this always happens on GIC0 */ - writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); + writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT); } #endif @@ -769,7 +656,6 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) { void __iomem *cpu_base; void __iomem *dist_base; - u32 percpu_offset; int irq; struct irq_domain *domain = &gic_data[gic_cnt].domain; @@ -782,12 +668,9 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) cpu_base = of_iomap(node, 1); WARN(!cpu_base, "unable to map gic cpu registers\n"); - if (of_property_read_u32(node, "cpu-offset", &percpu_offset)) - percpu_offset = 0; - domain->of_node = of_node_get(node); - gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset); + gic_init(gic_cnt, -1, dist_base, cpu_base); if (parent) { irq = irq_of_parse_and_map(node, 0); diff --git a/trunk/arch/arm/common/pl330.c b/trunk/arch/arm/common/pl330.c index d8e44a43047c..f407a6b35d3d 100644 --- a/trunk/arch/arm/common/pl330.c +++ b/trunk/arch/arm/common/pl330.c @@ -221,6 +221,17 @@ */ #define MCODE_BUFF_PER_REQ 256 +/* + * Mark a _pl330_req as free. + * We do it by writing DMAEND as the first instruction + * because no valid request is going to have DMAEND as + * its first instruction to execute. + */ +#define MARK_FREE(req) do { \ + _emit_END(0, (req)->mc_cpu); \ + (req)->mc_len = 0; \ + } while (0) + /* If the _pl330_req is available to the client */ #define IS_FREE(req) (*((u8 *)((req)->mc_cpu)) == CMD_DMAEND) @@ -290,10 +301,8 @@ struct pl330_thread { struct pl330_dmac *dmac; /* Only two at a time */ struct _pl330_req req[2]; - /* Index of the last enqueued request */ + /* Index of the last submitted request */ unsigned lstenq; - /* Index of the last submitted request or -1 if the DMA is stopped */ - int req_running; }; enum pl330_dmac_state { @@ -769,22 +778,6 @@ static inline void _execute_DBGINSN(struct pl330_thread *thrd, writel(0, regs + DBGCMD); } -/* - * Mark a _pl330_req as free. - * We do it by writing DMAEND as the first instruction - * because no valid request is going to have DMAEND as - * its first instruction to execute. - */ -static void mark_free(struct pl330_thread *thrd, int idx) -{ - struct _pl330_req *req = &thrd->req[idx]; - - _emit_END(0, req->mc_cpu); - req->mc_len = 0; - - thrd->req_running = -1; -} - static inline u32 _state(struct pl330_thread *thrd) { void __iomem *regs = thrd->dmac->pinfo->base; @@ -843,6 +836,31 @@ static inline u32 _state(struct pl330_thread *thrd) } } +/* If the request 'req' of thread 'thrd' is currently active */ +static inline bool _req_active(struct pl330_thread *thrd, + struct _pl330_req *req) +{ + void __iomem *regs = thrd->dmac->pinfo->base; + u32 buf = req->mc_bus, pc = readl(regs + CPC(thrd->id)); + + if (IS_FREE(req)) + return false; + + return (pc >= buf && pc <= buf + req->mc_len) ? true : false; +} + +/* Returns 0 if the thread is inactive, ID of active req + 1 otherwise */ +static inline unsigned _thrd_active(struct pl330_thread *thrd) +{ + if (_req_active(thrd, &thrd->req[0])) + return 1; /* First req active */ + + if (_req_active(thrd, &thrd->req[1])) + return 2; /* Second req active */ + + return 0; +} + static void _stop(struct pl330_thread *thrd) { void __iomem *regs = thrd->dmac->pinfo->base; @@ -874,22 +892,17 @@ static bool _trigger(struct pl330_thread *thrd) struct _arg_GO go; unsigned ns; u8 insn[6] = {0, 0, 0, 0, 0, 0}; - int idx; /* Return if already ACTIVE */ if (_state(thrd) != PL330_STATE_STOPPED) return true; - idx = 1 - thrd->lstenq; - if (!IS_FREE(&thrd->req[idx])) - req = &thrd->req[idx]; - else { - idx = thrd->lstenq; - if (!IS_FREE(&thrd->req[idx])) - req = &thrd->req[idx]; - else - req = NULL; - } + if (!IS_FREE(&thrd->req[1 - thrd->lstenq])) + req = &thrd->req[1 - thrd->lstenq]; + else if (!IS_FREE(&thrd->req[thrd->lstenq])) + req = &thrd->req[thrd->lstenq]; + else + req = NULL; /* Return if no request */ if (!req || !req->r) @@ -920,8 +933,6 @@ static bool _trigger(struct pl330_thread *thrd) /* Only manager can execute GO */ _execute_DBGINSN(thrd, insn, true); - thrd->req_running = idx; - return true; } @@ -1371,8 +1382,8 @@ static void pl330_dotask(unsigned long data) thrd->req[0].r = NULL; thrd->req[1].r = NULL; - mark_free(thrd, 0); - mark_free(thrd, 1); + MARK_FREE(&thrd->req[0]); + MARK_FREE(&thrd->req[1]); /* Clear the reset flag */ pl330->dmac_tbd.reset_chan &= ~(1 << i); @@ -1450,12 +1461,14 @@ int pl330_update(const struct pl330_info *pi) thrd = &pl330->channels[id]; - active = thrd->req_running; - if (active == -1) /* Aborted */ + active = _thrd_active(thrd); + if (!active) /* Aborted */ continue; + active -= 1; + rqdone = &thrd->req[active]; - mark_free(thrd, active); + MARK_FREE(rqdone); /* Get going again ASAP */ _start(thrd); @@ -1467,19 +1480,13 @@ int pl330_update(const struct pl330_info *pi) /* Now that we are in no hurry, do the callbacks */ while (!list_empty(&pl330->req_done)) { - struct pl330_req *r; - rqdone = container_of(pl330->req_done.next, struct _pl330_req, rqd); list_del_init(&rqdone->rqd); - /* Detach the req */ - r = rqdone->r; - rqdone->r = NULL; - spin_unlock_irqrestore(&pl330->lock, flags); - _callback(r, PL330_ERR_NONE); + _callback(rqdone->r, PL330_ERR_NONE); spin_lock_irqsave(&pl330->lock, flags); } @@ -1502,7 +1509,7 @@ int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op) struct pl330_thread *thrd = ch_id; struct pl330_dmac *pl330; unsigned long flags; - int ret = 0, active = thrd->req_running; + int ret = 0, active; if (!thrd || thrd->free || thrd->dmac->state == DYING) return -EINVAL; @@ -1518,24 +1525,28 @@ int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op) thrd->req[0].r = NULL; thrd->req[1].r = NULL; - mark_free(thrd, 0); - mark_free(thrd, 1); + MARK_FREE(&thrd->req[0]); + MARK_FREE(&thrd->req[1]); break; case PL330_OP_ABORT: + active = _thrd_active(thrd); + /* Make sure the channel is stopped */ _stop(thrd); /* ABORT is only for the active req */ - if (active == -1) + if (!active) break; + active--; + thrd->req[active].r = NULL; - mark_free(thrd, active); + MARK_FREE(&thrd->req[active]); /* Start the next */ case PL330_OP_START: - if ((active == -1) && !_start(thrd)) + if (!_thrd_active(thrd) && !_start(thrd)) ret = -EIO; break; @@ -1576,13 +1587,14 @@ int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus) else pstatus->faulting = false; - active = thrd->req_running; + active = _thrd_active(thrd); - if (active == -1) { + if (!active) { /* Indicate that the thread is not running */ pstatus->top_req = NULL; pstatus->wait_req = NULL; } else { + active--; pstatus->top_req = thrd->req[active].r; pstatus->wait_req = !IS_FREE(&thrd->req[1 - active]) ? thrd->req[1 - active].r : NULL; @@ -1647,9 +1659,9 @@ void *pl330_request_channel(const struct pl330_info *pi) thrd->free = false; thrd->lstenq = 1; thrd->req[0].r = NULL; - mark_free(thrd, 0); + MARK_FREE(&thrd->req[0]); thrd->req[1].r = NULL; - mark_free(thrd, 1); + MARK_FREE(&thrd->req[1]); break; } } @@ -1755,14 +1767,14 @@ static inline void _reset_thread(struct pl330_thread *thrd) thrd->req[0].mc_bus = pl330->mcode_bus + (thrd->id * pi->mcbufsz); thrd->req[0].r = NULL; - mark_free(thrd, 0); + MARK_FREE(&thrd->req[0]); thrd->req[1].mc_cpu = thrd->req[0].mc_cpu + pi->mcbufsz / 2; thrd->req[1].mc_bus = thrd->req[0].mc_bus + pi->mcbufsz / 2; thrd->req[1].r = NULL; - mark_free(thrd, 1); + MARK_FREE(&thrd->req[1]); } static int dmac_alloc_threads(struct pl330_dmac *pl330) diff --git a/trunk/arch/arm/common/timer-sp.c b/trunk/arch/arm/common/timer-sp.c index 8794a34eae61..2393b5bc96fa 100644 --- a/trunk/arch/arm/common/timer-sp.c +++ b/trunk/arch/arm/common/timer-sp.c @@ -143,6 +143,7 @@ static int sp804_set_next_event(unsigned long next, } static struct clock_event_device sp804_clockevent = { + .shift = 32, .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .set_mode = sp804_set_mode, .set_next_event = sp804_set_next_event, @@ -168,9 +169,13 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, clkevt_base = base; clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ); + evt->name = name; evt->irq = irq; + evt->mult = div_sc(rate, NSEC_PER_SEC, evt->shift); + evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt); + evt->min_delta_ns = clockevent_delta2ns(0xf, evt); setup_irq(irq, &sp804_timer_irq); - clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); + clockevents_register_device(evt); } diff --git a/trunk/arch/arm/common/vic.c b/trunk/arch/arm/common/vic.c index dcb004a804c7..01f18a421b17 100644 --- a/trunk/arch/arm/common/vic.c +++ b/trunk/arch/arm/common/vic.c @@ -19,22 +19,17 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include #include #include -#include -#include -#include -#include #include #include #include -#include #include #include +#ifdef CONFIG_PM /** * struct vic_device - VIC PM device * @irq: The IRQ number for the base of the VIC. @@ -45,7 +40,6 @@ * @int_enable: Save for VIC_INT_ENABLE. * @soft_int: Save for VIC_INT_SOFT. * @protect: Save for VIC_PROTECT. - * @domain: The IRQ domain for the VIC. */ struct vic_device { void __iomem *base; @@ -56,13 +50,13 @@ struct vic_device { u32 int_enable; u32 soft_int; u32 protect; - struct irq_domain domain; }; /* we cannot allocate memory when VICs are initially registered */ static struct vic_device vic_devices[CONFIG_ARM_VIC_NR]; static int vic_id; +#endif /* CONFIG_PM */ /** * vic_init2 - common initialisation code @@ -162,50 +156,39 @@ static int __init vic_pm_init(void) return 0; } late_initcall(vic_pm_init); -#endif /* CONFIG_PM */ /** - * vic_register() - Register a VIC. + * vic_pm_register - Register a VIC for later power management control * @base: The base address of the VIC. * @irq: The base IRQ for the VIC. * @resume_sources: bitmask of interrupts allowed for resume sources. - * @node: The device tree node associated with the VIC. * * Register the VIC with the system device tree so that it can be notified * of suspend and resume requests and ensure that the correct actions are * taken to re-instate the settings on resume. - * - * This also configures the IRQ domain for the VIC. */ -static void __init vic_register(void __iomem *base, unsigned int irq, - u32 resume_sources, struct device_node *node) +static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources) { struct vic_device *v; - if (vic_id >= ARRAY_SIZE(vic_devices)) { + if (vic_id >= ARRAY_SIZE(vic_devices)) printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__); - return; + else { + v = &vic_devices[vic_id]; + v->base = base; + v->resume_sources = resume_sources; + v->irq = irq; + vic_id++; } - - v = &vic_devices[vic_id]; - v->base = base; - v->resume_sources = resume_sources; - v->irq = irq; - vic_id++; - - v->domain.irq_base = irq; - v->domain.nr_irq = 32; -#ifdef CONFIG_OF_IRQ - v->domain.of_node = of_node_get(node); -#endif /* CONFIG_OF */ - v->domain.ops = &irq_domain_simple_ops; - irq_domain_add(&v->domain); } +#else +static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { } +#endif /* CONFIG_PM */ static void vic_ack_irq(struct irq_data *d) { void __iomem *base = irq_data_get_irq_chip_data(d); - unsigned int irq = d->hwirq; + unsigned int irq = d->irq & 31; writel(1 << irq, base + VIC_INT_ENABLE_CLEAR); /* moreover, clear the soft-triggered, in case it was the reason */ writel(1 << irq, base + VIC_INT_SOFT_CLEAR); @@ -214,14 +197,14 @@ static void vic_ack_irq(struct irq_data *d) static void vic_mask_irq(struct irq_data *d) { void __iomem *base = irq_data_get_irq_chip_data(d); - unsigned int irq = d->hwirq; + unsigned int irq = d->irq & 31; writel(1 << irq, base + VIC_INT_ENABLE_CLEAR); } static void vic_unmask_irq(struct irq_data *d) { void __iomem *base = irq_data_get_irq_chip_data(d); - unsigned int irq = d->hwirq; + unsigned int irq = d->irq & 31; writel(1 << irq, base + VIC_INT_ENABLE); } @@ -243,7 +226,7 @@ static struct vic_device *vic_from_irq(unsigned int irq) static int vic_set_wake(struct irq_data *d, unsigned int on) { struct vic_device *v = vic_from_irq(d->irq); - unsigned int off = d->hwirq; + unsigned int off = d->irq & 31; u32 bit = 1 << off; if (!v) @@ -318,7 +301,7 @@ static void __init vic_set_irq_sources(void __iomem *base, * and 020 within the page. We call this "second block". */ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, - u32 vic_sources, struct device_node *node) + u32 vic_sources) { unsigned int i; int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0; @@ -345,12 +328,17 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, } vic_set_irq_sources(base, irq_start, vic_sources); - vic_register(base, irq_start, 0, node); } -static void __init __vic_init(void __iomem *base, unsigned int irq_start, - u32 vic_sources, u32 resume_sources, - struct device_node *node) +/** + * vic_init - initialise a vectored interrupt controller + * @base: iomem base address + * @irq_start: starting interrupt number, must be muliple of 32 + * @vic_sources: bitmask of interrupt sources to allow + * @resume_sources: bitmask of interrupt sources to allow for resume + */ +void __init vic_init(void __iomem *base, unsigned int irq_start, + u32 vic_sources, u32 resume_sources) { unsigned int i; u32 cellid = 0; @@ -368,7 +356,7 @@ static void __init __vic_init(void __iomem *base, unsigned int irq_start, switch(vendor) { case AMBA_VENDOR_ST: - vic_init_st(base, irq_start, vic_sources, node); + vic_init_st(base, irq_start, vic_sources); return; default: printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n"); @@ -387,81 +375,5 @@ static void __init __vic_init(void __iomem *base, unsigned int irq_start, vic_set_irq_sources(base, irq_start, vic_sources); - vic_register(base, irq_start, resume_sources, node); -} - -/** - * vic_init() - initialise a vectored interrupt controller - * @base: iomem base address - * @irq_start: starting interrupt number, must be muliple of 32 - * @vic_sources: bitmask of interrupt sources to allow - * @resume_sources: bitmask of interrupt sources to allow for resume - */ -void __init vic_init(void __iomem *base, unsigned int irq_start, - u32 vic_sources, u32 resume_sources) -{ - __vic_init(base, irq_start, vic_sources, resume_sources, NULL); -} - -#ifdef CONFIG_OF -int __init vic_of_init(struct device_node *node, struct device_node *parent) -{ - void __iomem *regs; - int irq_base; - - if (WARN(parent, "non-root VICs are not supported")) - return -EINVAL; - - regs = of_iomap(node, 0); - if (WARN_ON(!regs)) - return -EIO; - - irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id()); - if (WARN_ON(irq_base < 0)) - goto out_unmap; - - __vic_init(regs, irq_base, ~0, ~0, node); - - return 0; - - out_unmap: - iounmap(regs); - - return -EIO; -} -#endif /* CONFIG OF */ - -/* - * Handle each interrupt in a single VIC. Returns non-zero if we've - * handled at least one interrupt. This does a single read of the - * status register and handles all interrupts in order from LSB first. - */ -static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) -{ - u32 stat, irq; - int handled = 0; - - stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); - while (stat) { - irq = ffs(stat) - 1; - handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs); - stat &= ~(1 << irq); - handled = 1; - } - - return handled; -} - -/* - * Keep iterating over all registered VIC's until there are no pending - * interrupts. - */ -asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs) -{ - int i, handled; - - do { - for (i = 0, handled = 0; i < vic_id; ++i) - handled |= handle_one_vic(&vic_devices[i], regs); - } while (handled); + vic_pm_register(base, irq_start, resume_sources); } diff --git a/trunk/arch/arm/configs/imx_v4_v5_defconfig b/trunk/arch/arm/configs/imx_v4_v5_defconfig index cf497ce41dfe..11a4192197c8 100644 --- a/trunk/arch/arm/configs/imx_v4_v5_defconfig +++ b/trunk/arch/arm/configs/imx_v4_v5_defconfig @@ -18,10 +18,9 @@ CONFIG_ARCH_MXC=y CONFIG_ARCH_IMX_V4_V5=y CONFIG_ARCH_MX1ADS=y CONFIG_MACH_SCB9328=y -CONFIG_MACH_APF9328=y CONFIG_MACH_MX21ADS=y CONFIG_MACH_MX25_3DS=y -CONFIG_MACH_EUKREA_CPUIMX25SD=y +CONFIG_MACH_EUKREA_CPUIMX25=y CONFIG_MACH_MX27ADS=y CONFIG_MACH_PCM038=y CONFIG_MACH_CPUIMX27=y @@ -73,16 +72,17 @@ CONFIG_MTD_CFI_GEOMETRY=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_PHYSMAP=y CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_MXC=y CONFIG_MTD_UBI=y CONFIG_MISC_DEVICES=y CONFIG_EEPROM_AT24=y CONFIG_EEPROM_AT25=y CONFIG_NETDEVICES=y -CONFIG_DM9000=y +CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y +CONFIG_DM9000=y CONFIG_SMC911X=y -CONFIG_SMSC_PHY=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set @@ -100,7 +100,6 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_IMX=y CONFIG_SPI=y CONFIG_SPI_IMX=y -CONFIG_SPI_SPIDEV=y CONFIG_W1=y CONFIG_W1_MASTER_MXC=y CONFIG_W1_SLAVE_THERM=y @@ -140,7 +139,6 @@ CONFIG_MMC=y CONFIG_MMC_MXC=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y CONFIG_LEDS_MC13783=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y diff --git a/trunk/arch/arm/include/asm/assembler.h b/trunk/arch/arm/include/asm/assembler.h index b6e65dedfd71..29035e86a59d 100644 --- a/trunk/arch/arm/include/asm/assembler.h +++ b/trunk/arch/arm/include/asm/assembler.h @@ -186,17 +186,6 @@ #define ALT_UP_B(label) b label #endif -/* - * Instruction barrier - */ - .macro instr_sync -#if __LINUX_ARM_ARCH__ >= 7 - isb -#elif __LINUX_ARM_ARCH__ == 6 - mcr p15, 0, r0, c7, c5, 4 -#endif - .endm - /* * SMP data memory barrier */ diff --git a/trunk/arch/arm/include/asm/bug.h b/trunk/arch/arm/include/asm/bug.h index fac79dceb736..9abe7a07d5ac 100644 --- a/trunk/arch/arm/include/asm/bug.h +++ b/trunk/arch/arm/include/asm/bug.h @@ -32,6 +32,7 @@ #define __BUG(__file, __line, __value) \ do { \ + BUILD_BUG_ON(sizeof(struct bug_entry) != 12); \ asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n" \ ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \ "2:\t.asciz " #__file "\n" \ diff --git a/trunk/arch/arm/include/asm/cti.h b/trunk/arch/arm/include/asm/cti.h deleted file mode 100644 index a0ada3ea4358..000000000000 --- a/trunk/arch/arm/include/asm/cti.h +++ /dev/null @@ -1,179 +0,0 @@ -#ifndef __ASMARM_CTI_H -#define __ASMARM_CTI_H - -#include - -/* The registers' definition is from section 3.2 of - * Embedded Cross Trigger Revision: r0p0 - */ -#define CTICONTROL 0x000 -#define CTISTATUS 0x004 -#define CTILOCK 0x008 -#define CTIPROTECTION 0x00C -#define CTIINTACK 0x010 -#define CTIAPPSET 0x014 -#define CTIAPPCLEAR 0x018 -#define CTIAPPPULSE 0x01c -#define CTIINEN 0x020 -#define CTIOUTEN 0x0A0 -#define CTITRIGINSTATUS 0x130 -#define CTITRIGOUTSTATUS 0x134 -#define CTICHINSTATUS 0x138 -#define CTICHOUTSTATUS 0x13c -#define CTIPERIPHID0 0xFE0 -#define CTIPERIPHID1 0xFE4 -#define CTIPERIPHID2 0xFE8 -#define CTIPERIPHID3 0xFEC -#define CTIPCELLID0 0xFF0 -#define CTIPCELLID1 0xFF4 -#define CTIPCELLID2 0xFF8 -#define CTIPCELLID3 0xFFC - -/* The below are from section 3.6.4 of - * CoreSight v1.0 Architecture Specification - */ -#define LOCKACCESS 0xFB0 -#define LOCKSTATUS 0xFB4 - -/* write this value to LOCKACCESS will unlock the module, and - * other value will lock the module - */ -#define LOCKCODE 0xC5ACCE55 - -/** - * struct cti - cross trigger interface struct - * @base: mapped virtual address for the cti base - * @irq: irq number for the cti - * @trig_out_for_irq: triger out number which will cause - * the @irq happen - * - * cti struct used to operate cti registers. - */ -struct cti { - void __iomem *base; - int irq; - int trig_out_for_irq; -}; - -/** - * cti_init - initialize the cti instance - * @cti: cti instance - * @base: mapped virtual address for the cti base - * @irq: irq number for the cti - * @trig_out: triger out number which will cause - * the @irq happen - * - * called by machine code to pass the board dependent - * @base, @irq and @trig_out to cti. - */ -static inline void cti_init(struct cti *cti, - void __iomem *base, int irq, int trig_out) -{ - cti->base = base; - cti->irq = irq; - cti->trig_out_for_irq = trig_out; -} - -/** - * cti_map_trigger - use the @chan to map @trig_in to @trig_out - * @cti: cti instance - * @trig_in: trigger in number - * @trig_out: trigger out number - * @channel: channel number - * - * This function maps one trigger in of @trig_in to one trigger - * out of @trig_out using the channel @chan. - */ -static inline void cti_map_trigger(struct cti *cti, - int trig_in, int trig_out, int chan) -{ - void __iomem *base = cti->base; - unsigned long val; - - val = __raw_readl(base + CTIINEN + trig_in * 4); - val |= BIT(chan); - __raw_writel(val, base + CTIINEN + trig_in * 4); - - val = __raw_readl(base + CTIOUTEN + trig_out * 4); - val |= BIT(chan); - __raw_writel(val, base + CTIOUTEN + trig_out * 4); -} - -/** - * cti_enable - enable the cti module - * @cti: cti instance - * - * enable the cti module - */ -static inline void cti_enable(struct cti *cti) -{ - __raw_writel(0x1, cti->base + CTICONTROL); -} - -/** - * cti_disable - disable the cti module - * @cti: cti instance - * - * enable the cti module - */ -static inline void cti_disable(struct cti *cti) -{ - __raw_writel(0, cti->base + CTICONTROL); -} - -/** - * cti_irq_ack - clear the cti irq - * @cti: cti instance - * - * clear the cti irq - */ -static inline void cti_irq_ack(struct cti *cti) -{ - void __iomem *base = cti->base; - unsigned long val; - - val = __raw_readl(base + CTIINTACK); - val |= BIT(cti->trig_out_for_irq); - __raw_writel(val, base + CTIINTACK); -} - -/** - * cti_unlock - unlock cti module - * @cti: cti instance - * - * unlock the cti module, or else any writes to the cti - * module is not allowed. - */ -static inline void cti_unlock(struct cti *cti) -{ - void __iomem *base = cti->base; - unsigned long val; - - val = __raw_readl(base + LOCKSTATUS); - - if (val & 1) { - val = LOCKCODE; - __raw_writel(val, base + LOCKACCESS); - } -} - -/** - * cti_lock - lock cti module - * @cti: cti instance - * - * lock the cti module, so any writes to the cti - * module will be not allowed. - */ -static inline void cti_lock(struct cti *cti) -{ - void __iomem *base = cti->base; - unsigned long val; - - val = __raw_readl(base + LOCKSTATUS); - - if (!(val & 1)) { - val = ~LOCKCODE; - __raw_writel(val, base + LOCKACCESS); - } -} -#endif diff --git a/trunk/arch/arm/include/asm/edac.h b/trunk/arch/arm/include/asm/edac.h deleted file mode 100644 index 0df7a2c1fc3d..000000000000 --- a/trunk/arch/arm/include/asm/edac.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2011 Calxeda, Inc. - * Based on PPC version Copyright 2007 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ -#ifndef ASM_EDAC_H -#define ASM_EDAC_H -/* - * ECC atomic, DMA, SMP and interrupt safe scrub function. - * Implements the per arch atomic_scrub() that EDAC use for software - * ECC scrubbing. It reads memory and then writes back the original - * value, allowing the hardware to detect and correct memory errors. - */ -static inline void atomic_scrub(void *va, u32 size) -{ -#if __LINUX_ARM_ARCH__ >= 6 - unsigned int *virt_addr = va; - unsigned int temp, temp2; - unsigned int i; - - for (i = 0; i < size / sizeof(*virt_addr); i++, virt_addr++) { - /* Very carefully read and write to memory atomically - * so we are interrupt, DMA and SMP safe. - */ - __asm__ __volatile__("\n" - "1: ldrex %0, [%2]\n" - " strex %1, %0, [%2]\n" - " teq %1, #0\n" - " bne 1b\n" - : "=&r"(temp), "=&r"(temp2) - : "r"(virt_addr) - : "cc"); - } -#endif -} - -#endif diff --git a/trunk/arch/arm/include/asm/entry-macro-vic2.S b/trunk/arch/arm/include/asm/entry-macro-vic2.S new file mode 100644 index 000000000000..3ceb85e43850 --- /dev/null +++ b/trunk/arch/arm/include/asm/entry-macro-vic2.S @@ -0,0 +1,57 @@ +/* arch/arm/include/asm/entry-macro-vic2.S + * + * Originally arch/arm/mach-s3c6400/include/mach/entry-macro.S + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * Low-level IRQ helper macros for a device with two VICs + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. +*/ + +/* This should be included from with the necessary + * defines for virtual addresses and IRQ bases for the two vics. + * + * The code needs the following defined: + * IRQ_VIC0_BASE IRQ number of VIC0's first IRQ + * IRQ_VIC1_BASE IRQ number of VIC1's first IRQ + * VA_VIC0 Virtual address of VIC0 + * VA_VIC1 Virtual address of VIC1 + * + * Note, code assumes VIC0's virtual address is an ARM immediate constant + * away from VIC1. +*/ + +#include + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + ldr \base, =VA_VIC0 + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + @ check the vic0 + mov \irqnr, #IRQ_VIC0_BASE + 31 + ldr \irqstat, [ \base, # VIC_IRQ_STATUS ] + teq \irqstat, #0 + + @ otherwise try vic1 + addeq \tmp, \base, #(VA_VIC1 - VA_VIC0) + addeq \irqnr, \irqnr, #(IRQ_VIC1_BASE - IRQ_VIC0_BASE) + ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ] + teqeq \irqstat, #0 + + clzne \irqstat, \irqstat + subne \irqnr, \irqnr, \irqstat + .endm diff --git a/trunk/arch/arm/include/asm/gpio.h b/trunk/arch/arm/include/asm/gpio.h index 7151753b0989..11ad0bfbb0ad 100644 --- a/trunk/arch/arm/include/asm/gpio.h +++ b/trunk/arch/arm/include/asm/gpio.h @@ -1,10 +1,6 @@ #ifndef _ARCH_ARM_GPIO_H #define _ARCH_ARM_GPIO_H -#if CONFIG_ARCH_NR_GPIO > 0 -#define ARCH_NR_GPIO CONFIG_ARCH_NR_GPIO -#endif - /* not all ARM platforms necessarily support this API ... */ #include diff --git a/trunk/arch/arm/include/asm/hardirq.h b/trunk/arch/arm/include/asm/hardirq.h index 436e60b2cf7a..ddf07a92a6c8 100644 --- a/trunk/arch/arm/include/asm/hardirq.h +++ b/trunk/arch/arm/include/asm/hardirq.h @@ -27,6 +27,23 @@ u64 smp_irq_stat_cpu(unsigned int cpu); #define arch_irq_stat_cpu smp_irq_stat_cpu +#if NR_IRQS > 512 +#define HARDIRQ_BITS 10 +#elif NR_IRQS > 256 +#define HARDIRQ_BITS 9 +#else +#define HARDIRQ_BITS 8 +#endif + +/* + * The hardirq mask has to be large enough to have space + * for potentially all IRQ sources in the system nesting + * on a single CPU: + */ +#if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +#endif + #define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 #endif /* __ASM_HARDIRQ_H */ diff --git a/trunk/arch/arm/include/asm/hardware/entry-macro-gic.S b/trunk/arch/arm/include/asm/hardware/entry-macro-gic.S new file mode 100644 index 000000000000..74ebc803904d --- /dev/null +++ b/trunk/arch/arm/include/asm/hardware/entry-macro-gic.S @@ -0,0 +1,60 @@ +/* + * arch/arm/include/asm/hardware/entry-macro-gic.S + * + * Low-level IRQ helper macros for GIC + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include + +#ifndef HAVE_GET_IRQNR_PREAMBLE + .macro get_irqnr_preamble, base, tmp + ldr \base, =gic_cpu_base_addr + ldr \base, [\base] + .endm +#endif + +/* + * The interrupt numbering scheme is defined in the + * interrupt controller spec. To wit: + * + * Interrupts 0-15 are IPI + * 16-31 are local. We allow 30 to be used for the watchdog. + * 32-1020 are global + * 1021-1022 are reserved + * 1023 is "spurious" (no interrupt) + * + * A simple read from the controller will tell us the number of the highest + * priority enabled interrupt. We then just need to check whether it is in the + * valid range for an IRQ (30-1020 inclusive). + */ + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + ldr \irqstat, [\base, #GIC_CPU_INTACK] + /* bits 12-10 = src CPU, 9-0 = int # */ + + ldr \tmp, =1021 + bic \irqnr, \irqstat, #0x1c00 + cmp \irqnr, #15 + cmpcc \irqnr, \irqnr + cmpne \irqnr, \tmp + cmpcs \irqnr, \irqnr + .endm + +/* We assume that irqstat (the raw value of the IRQ acknowledge + * register) is preserved from the macro above. + * If there is an IPI, we immediately signal end of interrupt on the + * controller, since this requires the original irqstat value which + * we won't easily be able to recreate later. + */ + + .macro test_for_ipi, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + cmp \irqnr, #16 + strcc \irqstat, [\base, #GIC_CPU_EOI] + cmpcs \irqnr, \irqnr + .endm diff --git a/trunk/arch/arm/include/asm/hardware/gic.h b/trunk/arch/arm/include/asm/hardware/gic.h index 4bdfe0018696..3e91f22046f5 100644 --- a/trunk/arch/arm/include/asm/hardware/gic.h +++ b/trunk/arch/arm/include/asm/hardware/gic.h @@ -36,22 +36,30 @@ #include struct device_node; +extern void __iomem *gic_cpu_base_addr; extern struct irq_chip gic_arch_extn; -void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, - u32 offset); +void gic_init(unsigned int, int, void __iomem *, void __iomem *); int gic_of_init(struct device_node *node, struct device_node *parent); void gic_secondary_init(unsigned int); -void gic_handle_irq(struct pt_regs *regs); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); -static inline void gic_init(unsigned int nr, int start, - void __iomem *dist , void __iomem *cpu) -{ - gic_init_bases(nr, start, dist, cpu, 0); -} - +struct gic_chip_data { + void __iomem *dist_base; + void __iomem *cpu_base; +#ifdef CONFIG_CPU_PM + u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)]; + u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)]; + u32 saved_spi_target[DIV_ROUND_UP(1020, 4)]; + u32 __percpu *saved_ppi_enable; + u32 __percpu *saved_ppi_conf; +#endif +#ifdef CONFIG_IRQ_DOMAIN + struct irq_domain domain; +#endif + unsigned int gic_irqs; +}; #endif #endif diff --git a/trunk/arch/arm/include/asm/hardware/iop3xx.h b/trunk/arch/arm/include/asm/hardware/iop3xx.h index 077c32326c63..5daea2961d48 100644 --- a/trunk/arch/arm/include/asm/hardware/iop3xx.h +++ b/trunk/arch/arm/include/asm/hardware/iop3xx.h @@ -234,7 +234,6 @@ extern int iop3xx_get_init_atu(void); void iop3xx_map_io(void); void iop_init_cp6_handler(void); void iop_init_time(unsigned long tickrate); -void iop3xx_restart(char, const char *); static inline u32 read_tmr0(void) { diff --git a/trunk/arch/arm/include/asm/hardware/vic.h b/trunk/arch/arm/include/asm/hardware/vic.h index f42ebd619590..5d72550a8097 100644 --- a/trunk/arch/arm/include/asm/hardware/vic.h +++ b/trunk/arch/arm/include/asm/hardware/vic.h @@ -41,15 +41,7 @@ #define VIC_PL192_VECT_ADDR 0xF00 #ifndef __ASSEMBLY__ -#include -#include - -struct device_node; -struct pt_regs; - void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); -int vic_of_init(struct device_node *node, struct device_node *parent); -void vic_handle_irq(struct pt_regs *regs); +#endif -#endif /* __ASSEMBLY__ */ #endif diff --git a/trunk/arch/arm/include/asm/idmap.h b/trunk/arch/arm/include/asm/idmap.h deleted file mode 100644 index bf863edb517d..000000000000 --- a/trunk/arch/arm/include/asm/idmap.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __ASM_IDMAP_H -#define __ASM_IDMAP_H - -#include -#include - -/* Tag a function as requiring to be executed via an identity mapping. */ -#define __idmap __section(.idmap.text) noinline notrace - -extern pgd_t *idmap_pgd; - -void setup_mm_for_reboot(void); - -#endif /* __ASM_IDMAP_H */ diff --git a/trunk/arch/arm/include/asm/mach/arch.h b/trunk/arch/arm/include/asm/mach/arch.h index bcb0c883e21e..2b0efc3104ac 100644 --- a/trunk/arch/arm/include/asm/mach/arch.h +++ b/trunk/arch/arm/include/asm/mach/arch.h @@ -31,10 +31,10 @@ struct machine_desc { unsigned int video_start; /* start of video RAM */ unsigned int video_end; /* end of video RAM */ - unsigned char reserve_lp0 :1; /* never has lp0 */ - unsigned char reserve_lp1 :1; /* never has lp1 */ - unsigned char reserve_lp2 :1; /* never has lp2 */ - char restart_mode; /* default restart mode */ + unsigned int reserve_lp0 :1; /* never has lp0 */ + unsigned int reserve_lp1 :1; /* never has lp1 */ + unsigned int reserve_lp2 :1; /* never has lp2 */ + unsigned int soft_reboot :1; /* soft reboot */ void (*fixup)(struct tag *, char **, struct meminfo *); void (*reserve)(void);/* reserve mem blocks */ @@ -46,7 +46,6 @@ struct machine_desc { #ifdef CONFIG_MULTI_IRQ_HANDLER void (*handle_irq)(struct pt_regs *); #endif - void (*restart)(char, const char *); }; /* diff --git a/trunk/arch/arm/include/asm/mach/time.h b/trunk/arch/arm/include/asm/mach/time.h index f73c908b7fa0..d5adaae5ee2c 100644 --- a/trunk/arch/arm/include/asm/mach/time.h +++ b/trunk/arch/arm/include/asm/mach/time.h @@ -10,6 +10,8 @@ #ifndef __ASM_ARM_MACH_TIME_H #define __ASM_ARM_MACH_TIME_H +#include + /* * This is our kernel timer structure. * diff --git a/trunk/arch/arm/include/asm/opcodes.h b/trunk/arch/arm/include/asm/opcodes.h deleted file mode 100644 index c0efdd60966f..000000000000 --- a/trunk/arch/arm/include/asm/opcodes.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/arm/include/asm/opcodes.h - * - * 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. - */ - -#ifndef __ASM_ARM_OPCODES_H -#define __ASM_ARM_OPCODES_H - -#ifndef __ASSEMBLY__ -extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); -#endif - -#define ARM_OPCODE_CONDTEST_FAIL 0 -#define ARM_OPCODE_CONDTEST_PASS 1 -#define ARM_OPCODE_CONDTEST_UNCOND 2 - -#endif /* __ASM_ARM_OPCODES_H */ diff --git a/trunk/arch/arm/include/asm/page.h b/trunk/arch/arm/include/asm/page.h index 97b440c25c58..ca94653f1ecb 100644 --- a/trunk/arch/arm/include/asm/page.h +++ b/trunk/arch/arm/include/asm/page.h @@ -151,11 +151,7 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from, #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) extern void copy_page(void *to, const void *from); -#ifdef CONFIG_ARM_LPAE -#include -#else #include -#endif #endif /* CONFIG_MMU */ diff --git a/trunk/arch/arm/include/asm/perf_event.h b/trunk/arch/arm/include/asm/perf_event.h index 99cfe3607989..0f8e3827a89b 100644 --- a/trunk/arch/arm/include/asm/perf_event.h +++ b/trunk/arch/arm/include/asm/perf_event.h @@ -32,4 +32,7 @@ enum arm_perf_pmu_ids { extern enum arm_perf_pmu_ids armpmu_get_pmu_id(void); +extern int +armpmu_get_max_events(void); + #endif /* __ARM_PERF_EVENT_H__ */ diff --git a/trunk/arch/arm/include/asm/pgalloc.h b/trunk/arch/arm/include/asm/pgalloc.h index 943504f53f57..3e08fd3fbb6b 100644 --- a/trunk/arch/arm/include/asm/pgalloc.h +++ b/trunk/arch/arm/include/asm/pgalloc.h @@ -25,34 +25,12 @@ #define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER)) #define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL)) -#ifdef CONFIG_ARM_LPAE - -static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) -{ - return (pmd_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT); -} - -static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) -{ - BUG_ON((unsigned long)pmd & (PAGE_SIZE-1)); - free_page((unsigned long)pmd); -} - -static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) -{ - set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE)); -} - -#else /* !CONFIG_ARM_LPAE */ - /* * Since we have only two-level page tables, these are trivial */ #define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(mm, pmd) do { } while (0) -#define pud_populate(mm,pmd,pte) BUG() - -#endif /* CONFIG_ARM_LPAE */ +#define pgd_populate(mm,pmd,pte) BUG() extern pgd_t *pgd_alloc(struct mm_struct *mm); extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); @@ -131,9 +109,7 @@ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte, { pmdval_t pmdval = (pte + PTE_HWTABLE_OFF) | prot; pmdp[0] = __pmd(pmdval); -#ifndef CONFIG_ARM_LPAE pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); -#endif flush_pmd_entry(pmdp); } diff --git a/trunk/arch/arm/include/asm/pgtable-2level.h b/trunk/arch/arm/include/asm/pgtable-2level.h index 2317a71c8f8e..470457e1cfc5 100644 --- a/trunk/arch/arm/include/asm/pgtable-2level.h +++ b/trunk/arch/arm/include/asm/pgtable-2level.h @@ -140,45 +140,4 @@ #define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */ #define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2) -#ifndef __ASSEMBLY__ - -/* - * The "pud_xxx()" functions here are trivial when the pmd is folded into - * the pud: the pud entry is never bad, always exists, and can't be set or - * cleared. - */ -#define pud_none(pud) (0) -#define pud_bad(pud) (0) -#define pud_present(pud) (1) -#define pud_clear(pudp) do { } while (0) -#define set_pud(pud,pudp) do { } while (0) - -static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) -{ - return (pmd_t *)pud; -} - -#define pmd_bad(pmd) (pmd_val(pmd) & 2) - -#define copy_pmd(pmdpd,pmdps) \ - do { \ - pmdpd[0] = pmdps[0]; \ - pmdpd[1] = pmdps[1]; \ - flush_pmd_entry(pmdpd); \ - } while (0) - -#define pmd_clear(pmdp) \ - do { \ - pmdp[0] = __pmd(0); \ - pmdp[1] = __pmd(0); \ - clean_pmd_entry(pmdp); \ - } while (0) - -/* we don't need complex calculations here as the pmd is folded into the pgd */ -#define pmd_addr_end(addr,end) (end) - -#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) - -#endif /* __ASSEMBLY__ */ - #endif /* _ASM_PGTABLE_2LEVEL_H */ diff --git a/trunk/arch/arm/include/asm/pgtable-3level-hwdef.h b/trunk/arch/arm/include/asm/pgtable-3level-hwdef.h deleted file mode 100644 index d7952824c5c4..000000000000 --- a/trunk/arch/arm/include/asm/pgtable-3level-hwdef.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * arch/arm/include/asm/pgtable-3level-hwdef.h - * - * Copyright (C) 2011 ARM Ltd. - * Author: Catalin Marinas - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef _ASM_PGTABLE_3LEVEL_HWDEF_H -#define _ASM_PGTABLE_3LEVEL_HWDEF_H - -/* - * Hardware page table definitions. - * - * + Level 1/2 descriptor - * - common - */ -#define PMD_TYPE_MASK (_AT(pmdval_t, 3) << 0) -#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0) -#define PMD_TYPE_TABLE (_AT(pmdval_t, 3) << 0) -#define PMD_TYPE_SECT (_AT(pmdval_t, 1) << 0) -#define PMD_BIT4 (_AT(pmdval_t, 0)) -#define PMD_DOMAIN(x) (_AT(pmdval_t, 0)) - -/* - * - section - */ -#define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2) -#define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3) -#define PMD_SECT_S (_AT(pmdval_t, 3) << 8) -#define PMD_SECT_AF (_AT(pmdval_t, 1) << 10) -#define PMD_SECT_nG (_AT(pmdval_t, 1) << 11) -#define PMD_SECT_XN (_AT(pmdval_t, 1) << 54) -#define PMD_SECT_AP_WRITE (_AT(pmdval_t, 0)) -#define PMD_SECT_AP_READ (_AT(pmdval_t, 0)) -#define PMD_SECT_TEX(x) (_AT(pmdval_t, 0)) - -/* - * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). - */ -#define PMD_SECT_UNCACHED (_AT(pmdval_t, 0) << 2) /* strongly ordered */ -#define PMD_SECT_BUFFERED (_AT(pmdval_t, 1) << 2) /* normal non-cacheable */ -#define PMD_SECT_WT (_AT(pmdval_t, 2) << 2) /* normal inner write-through */ -#define PMD_SECT_WB (_AT(pmdval_t, 3) << 2) /* normal inner write-back */ -#define PMD_SECT_WBWA (_AT(pmdval_t, 7) << 2) /* normal inner write-alloc */ - -/* - * + Level 3 descriptor (PTE) - */ -#define PTE_TYPE_MASK (_AT(pteval_t, 3) << 0) -#define PTE_TYPE_FAULT (_AT(pteval_t, 0) << 0) -#define PTE_TYPE_PAGE (_AT(pteval_t, 3) << 0) -#define PTE_BUFFERABLE (_AT(pteval_t, 1) << 2) /* AttrIndx[0] */ -#define PTE_CACHEABLE (_AT(pteval_t, 1) << 3) /* AttrIndx[1] */ -#define PTE_EXT_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ -#define PTE_EXT_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ -#define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* nG */ -#define PTE_EXT_XN (_AT(pteval_t, 1) << 54) /* XN */ - -/* - * 40-bit physical address supported. - */ -#define PHYS_MASK_SHIFT (40) -#define PHYS_MASK ((1ULL << PHYS_MASK_SHIFT) - 1) - -#endif diff --git a/trunk/arch/arm/include/asm/pgtable-3level-types.h b/trunk/arch/arm/include/asm/pgtable-3level-types.h deleted file mode 100644 index 921aa30259c4..000000000000 --- a/trunk/arch/arm/include/asm/pgtable-3level-types.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * arch/arm/include/asm/pgtable-3level-types.h - * - * Copyright (C) 2011 ARM Ltd. - * Author: Catalin Marinas - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef _ASM_PGTABLE_3LEVEL_TYPES_H -#define _ASM_PGTABLE_3LEVEL_TYPES_H - -#include - -typedef u64 pteval_t; -typedef u64 pmdval_t; -typedef u64 pgdval_t; - -#undef STRICT_MM_TYPECHECKS - -#ifdef STRICT_MM_TYPECHECKS - -/* - * These are used to make use of C type-checking.. - */ -typedef struct { pteval_t pte; } pte_t; -typedef struct { pmdval_t pmd; } pmd_t; -typedef struct { pgdval_t pgd; } pgd_t; -typedef struct { pteval_t pgprot; } pgprot_t; - -#define pte_val(x) ((x).pte) -#define pmd_val(x) ((x).pmd) -#define pgd_val(x) ((x).pgd) -#define pgprot_val(x) ((x).pgprot) - -#define __pte(x) ((pte_t) { (x) } ) -#define __pmd(x) ((pmd_t) { (x) } ) -#define __pgd(x) ((pgd_t) { (x) } ) -#define __pgprot(x) ((pgprot_t) { (x) } ) - -#else /* !STRICT_MM_TYPECHECKS */ - -typedef pteval_t pte_t; -typedef pmdval_t pmd_t; -typedef pgdval_t pgd_t; -typedef pteval_t pgprot_t; - -#define pte_val(x) (x) -#define pmd_val(x) (x) -#define pgd_val(x) (x) -#define pgprot_val(x) (x) - -#define __pte(x) (x) -#define __pmd(x) (x) -#define __pgd(x) (x) -#define __pgprot(x) (x) - -#endif /* STRICT_MM_TYPECHECKS */ - -#endif /* _ASM_PGTABLE_3LEVEL_TYPES_H */ diff --git a/trunk/arch/arm/include/asm/pgtable-3level.h b/trunk/arch/arm/include/asm/pgtable-3level.h deleted file mode 100644 index 759af70f9a0a..000000000000 --- a/trunk/arch/arm/include/asm/pgtable-3level.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * arch/arm/include/asm/pgtable-3level.h - * - * Copyright (C) 2011 ARM Ltd. - * Author: Catalin Marinas - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef _ASM_PGTABLE_3LEVEL_H -#define _ASM_PGTABLE_3LEVEL_H - -/* - * With LPAE, there are 3 levels of page tables. Each level has 512 entries of - * 8 bytes each, occupying a 4K page. The first level table covers a range of - * 512GB, each entry representing 1GB. Since we are limited to 4GB input - * address range, only 4 entries in the PGD are used. - * - * There are enough spare bits in a page table entry for the kernel specific - * state. - */ -#define PTRS_PER_PTE 512 -#define PTRS_PER_PMD 512 -#define PTRS_PER_PGD 4 - -#define PTE_HWTABLE_PTRS (PTRS_PER_PTE) -#define PTE_HWTABLE_OFF (0) -#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u64)) - -/* - * PGDIR_SHIFT determines the size a top-level page table entry can map. - */ -#define PGDIR_SHIFT 30 - -/* - * PMD_SHIFT determines the size a middle-level page table entry can map. - */ -#define PMD_SHIFT 21 - -#define PMD_SIZE (1UL << PMD_SHIFT) -#define PMD_MASK (~(PMD_SIZE-1)) -#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -#define PGDIR_MASK (~(PGDIR_SIZE-1)) - -/* - * section address mask and size definitions. - */ -#define SECTION_SHIFT 21 -#define SECTION_SIZE (1UL << SECTION_SHIFT) -#define SECTION_MASK (~(SECTION_SIZE-1)) - -#define USER_PTRS_PER_PGD (PAGE_OFFSET / PGDIR_SIZE) - -/* - * "Linux" PTE definitions for LPAE. - * - * These bits overlap with the hardware bits but the naming is preserved for - * consistency with the classic page table format. - */ -#define L_PTE_PRESENT (_AT(pteval_t, 3) << 0) /* Valid */ -#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */ -#define L_PTE_BUFFERABLE (_AT(pteval_t, 1) << 2) /* AttrIndx[0] */ -#define L_PTE_CACHEABLE (_AT(pteval_t, 1) << 3) /* AttrIndx[1] */ -#define L_PTE_USER (_AT(pteval_t, 1) << 6) /* AP[1] */ -#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7) /* AP[2] */ -#define L_PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ -#define L_PTE_YOUNG (_AT(pteval_t, 1) << 10) /* AF */ -#define L_PTE_XN (_AT(pteval_t, 1) << 54) /* XN */ -#define L_PTE_DIRTY (_AT(pteval_t, 1) << 55) /* unused */ -#define L_PTE_SPECIAL (_AT(pteval_t, 1) << 56) /* unused */ - -/* - * To be used in assembly code with the upper page attributes. - */ -#define L_PTE_XN_HIGH (1 << (54 - 32)) -#define L_PTE_DIRTY_HIGH (1 << (55 - 32)) - -/* - * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). - */ -#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0) << 2) /* strongly ordered */ -#define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 1) << 2) /* normal non-cacheable */ -#define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 2) << 2) /* normal inner write-through */ -#define L_PTE_MT_WRITEBACK (_AT(pteval_t, 3) << 2) /* normal inner write-back */ -#define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 7) << 2) /* normal inner write-alloc */ -#define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 4) << 2) /* device */ -#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 4) << 2) /* device */ -#define L_PTE_MT_DEV_WC (_AT(pteval_t, 1) << 2) /* normal non-cacheable */ -#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 3) << 2) /* normal inner write-back */ -#define L_PTE_MT_MASK (_AT(pteval_t, 7) << 2) - -/* - * Software PGD flags. - */ -#define L_PGD_SWAPPER (_AT(pgdval_t, 1) << 55) /* swapper_pg_dir entry */ - -#ifndef __ASSEMBLY__ - -#define pud_none(pud) (!pud_val(pud)) -#define pud_bad(pud) (!(pud_val(pud) & 2)) -#define pud_present(pud) (pud_val(pud)) - -#define pud_clear(pudp) \ - do { \ - *pudp = __pud(0); \ - clean_pmd_entry(pudp); \ - } while (0) - -#define set_pud(pudp, pud) \ - do { \ - *pudp = pud; \ - flush_pmd_entry(pudp); \ - } while (0) - -static inline pmd_t *pud_page_vaddr(pud_t pud) -{ - return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK); -} - -/* Find an entry in the second-level page table.. */ -#define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) -static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) -{ - return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr); -} - -#define pmd_bad(pmd) (!(pmd_val(pmd) & 2)) - -#define copy_pmd(pmdpd,pmdps) \ - do { \ - *pmdpd = *pmdps; \ - flush_pmd_entry(pmdpd); \ - } while (0) - -#define pmd_clear(pmdp) \ - do { \ - *pmdp = __pmd(0); \ - clean_pmd_entry(pmdp); \ - } while (0) - -#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,__pte(pte_val(pte)|(ext))) - -#endif /* __ASSEMBLY__ */ - -#endif /* _ASM_PGTABLE_3LEVEL_H */ diff --git a/trunk/arch/arm/include/asm/pgtable-hwdef.h b/trunk/arch/arm/include/asm/pgtable-hwdef.h index 8426229ba292..183111164ce9 100644 --- a/trunk/arch/arm/include/asm/pgtable-hwdef.h +++ b/trunk/arch/arm/include/asm/pgtable-hwdef.h @@ -10,10 +10,6 @@ #ifndef _ASMARM_PGTABLE_HWDEF_H #define _ASMARM_PGTABLE_HWDEF_H -#ifdef CONFIG_ARM_LPAE -#include -#else #include -#endif #endif diff --git a/trunk/arch/arm/include/asm/pgtable.h b/trunk/arch/arm/include/asm/pgtable.h index f66626d71e7d..9451dce3a553 100644 --- a/trunk/arch/arm/include/asm/pgtable.h +++ b/trunk/arch/arm/include/asm/pgtable.h @@ -11,24 +11,20 @@ #define _ASMARM_PGTABLE_H #include +#include #include #ifndef CONFIG_MMU -#include #include "pgtable-nommu.h" #else -#include #include +#include #include -#ifdef CONFIG_ARM_LPAE -#include -#else #include -#endif /* * Just any arbitrary offset to the start of the vmalloc VM area: the @@ -37,10 +33,15 @@ * any out-of-bounds memory accesses will hopefully be caught. * The vmalloc() routines leaves a hole of 4kB between each vmalloced * area for the same reason. ;) + * + * Note that platforms may override VMALLOC_START, but they must provide + * VMALLOC_END. VMALLOC_END defines the (exclusive) limit of this space, + * which may not overlap IO space. */ +#ifndef VMALLOC_START #define VMALLOC_OFFSET (8*1024*1024) #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) -#define VMALLOC_END 0xff000000UL +#endif #define LIBRARY_TEXT_START 0x0c000000 @@ -162,8 +163,39 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* to find an entry in a kernel page-table-directory */ #define pgd_offset_k(addr) pgd_offset(&init_mm, addr) +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pgd is never bad, and a pmd always exists (as it's folded + * into the pgd entry) + */ +#define pgd_none(pgd) (0) +#define pgd_bad(pgd) (0) +#define pgd_present(pgd) (1) +#define pgd_clear(pgdp) do { } while (0) +#define set_pgd(pgd,pgdp) do { } while (0) +#define set_pud(pud,pudp) do { } while (0) + + +/* Find an entry in the second-level page table.. */ +#define pmd_offset(dir, addr) ((pmd_t *)(dir)) + #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_present(pmd) (pmd_val(pmd)) +#define pmd_bad(pmd) (pmd_val(pmd) & 2) + +#define copy_pmd(pmdpd,pmdps) \ + do { \ + pmdpd[0] = pmdps[0]; \ + pmdpd[1] = pmdps[1]; \ + flush_pmd_entry(pmdpd); \ + } while (0) + +#define pmd_clear(pmdp) \ + do { \ + pmdp[0] = __pmd(0); \ + pmdp[1] = __pmd(0); \ + clean_pmd_entry(pmdp); \ + } while (0) static inline pte_t *pmd_page_vaddr(pmd_t pmd) { @@ -172,6 +204,10 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) #define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK)) +/* we don't need complex calculations here as the pmd is folded into the pgd */ +#define pmd_addr_end(addr,end) (end) + + #ifndef CONFIG_HIGHPTE #define __pte_map(pmd) pmd_page_vaddr(*(pmd)) #define __pte_unmap(pte) do { } while (0) @@ -193,6 +229,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) #define pte_page(pte) pfn_to_page(pte_pfn(pte)) #define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot) +#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) #define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) #if __LINUX_ARM_ARCH__ < 6 @@ -299,7 +336,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) * We provide our own arch_get_unmapped_area to cope with VIPT caches. */ #define HAVE_ARCH_UNMAPPED_AREA -#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN /* * remap a physical page `pfn' of size `size' with page protection `prot' @@ -310,6 +346,9 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define pgtable_cache_init() do { } while (0) +void identity_mapping_add(pgd_t *, unsigned long, unsigned long); +void identity_mapping_del(pgd_t *, unsigned long, unsigned long); + #endif /* !__ASSEMBLY__ */ #endif /* CONFIG_MMU */ diff --git a/trunk/arch/arm/include/asm/pmu.h b/trunk/arch/arm/include/asm/pmu.h index b5a5be2536c1..0bda22c094a6 100644 --- a/trunk/arch/arm/include/asm/pmu.h +++ b/trunk/arch/arm/include/asm/pmu.h @@ -27,22 +27,13 @@ enum arm_pmu_type { /* * struct arm_pmu_platdata - ARM PMU platform data * - * @handle_irq: an optional handler which will be called from the - * interrupt and passed the address of the low level handler, - * and can be used to implement any platform specific handling - * before or after calling it. - * @enable_irq: an optional handler which will be called after - * request_irq and be used to handle some platform specific - * irq enablement - * @disable_irq: an optional handler which will be called before - * free_irq and be used to handle some platform specific - * irq disablement + * @handle_irq: an optional handler which will be called from the interrupt and + * passed the address of the low level handler, and can be used to implement + * any platform specific handling before or after calling it. */ struct arm_pmu_platdata { irqreturn_t (*handle_irq)(int irq, void *dev, irq_handler_t pmu_handler); - void (*enable_irq)(int irq); - void (*disable_irq)(int irq); }; #ifdef CONFIG_CPU_HAS_PMU diff --git a/trunk/arch/arm/include/asm/proc-fns.h b/trunk/arch/arm/include/asm/proc-fns.h index f3628fb3d2b3..9e92cb205e65 100644 --- a/trunk/arch/arm/include/asm/proc-fns.h +++ b/trunk/arch/arm/include/asm/proc-fns.h @@ -65,11 +65,7 @@ extern struct processor { * Set a possibly extended PTE. Non-extended PTEs should * ignore 'ext'. */ -#ifdef CONFIG_ARM_LPAE - void (*set_pte_ext)(pte_t *ptep, pte_t pte); -#else void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext); -#endif /* Suspend/resume */ unsigned int suspend_size; @@ -83,11 +79,7 @@ extern void cpu_proc_fin(void); extern int cpu_do_idle(void); extern void cpu_dcache_clean_area(void *, int); extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); -#ifdef CONFIG_ARM_LPAE -extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte); -#else extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext); -#endif extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); /* These three are private to arch/arm/kernel/suspend.c */ @@ -115,18 +107,6 @@ extern void cpu_resume(void); #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm) -#ifdef CONFIG_ARM_LPAE -#define cpu_get_pgd() \ - ({ \ - unsigned long pg, pg2; \ - __asm__("mrrc p15, 0, %0, %1, c2" \ - : "=r" (pg), "=r" (pg2) \ - : \ - : "cc"); \ - pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1); \ - (pgd_t *)phys_to_virt(pg); \ - }) -#else #define cpu_get_pgd() \ ({ \ unsigned long pg; \ @@ -135,7 +115,6 @@ extern void cpu_resume(void); pg &= ~0x3fff; \ (pgd_t *)phys_to_virt(pg); \ }) -#endif #endif diff --git a/trunk/arch/arm/include/asm/processor.h b/trunk/arch/arm/include/asm/processor.h index ce280b8d613c..b2d9df5667af 100644 --- a/trunk/arch/arm/include/asm/processor.h +++ b/trunk/arch/arm/include/asm/processor.h @@ -123,8 +123,6 @@ static inline void prefetch(const void *ptr) #endif -#define HAVE_ARCH_PICK_MMAP_LAYOUT - #endif #endif /* __ASM_ARM_PROCESSOR_H */ diff --git a/trunk/arch/arm/include/asm/sched_clock.h b/trunk/arch/arm/include/asm/sched_clock.h index e3f757263438..c8e6ddf3e860 100644 --- a/trunk/arch/arm/include/asm/sched_clock.h +++ b/trunk/arch/arm/include/asm/sched_clock.h @@ -8,7 +8,113 @@ #ifndef ASM_SCHED_CLOCK #define ASM_SCHED_CLOCK +#include +#include + +struct clock_data { + u64 epoch_ns; + u32 epoch_cyc; + u32 epoch_cyc_copy; + u32 mult; + u32 shift; +}; + +#define DEFINE_CLOCK_DATA(name) struct clock_data name + +static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift) +{ + return (cyc * mult) >> shift; +} + +/* + * Atomically update the sched_clock epoch. Your update callback will + * be called from a timer before the counter wraps - read the current + * counter value, and call this function to safely move the epochs + * forward. Only use this from the update callback. + */ +static inline void update_sched_clock(struct clock_data *cd, u32 cyc, u32 mask) +{ + unsigned long flags; + u64 ns = cd->epoch_ns + + cyc_to_ns((cyc - cd->epoch_cyc) & mask, cd->mult, cd->shift); + + /* + * Write epoch_cyc and epoch_ns in a way that the update is + * detectable in cyc_to_fixed_sched_clock(). + */ + raw_local_irq_save(flags); + cd->epoch_cyc = cyc; + smp_wmb(); + cd->epoch_ns = ns; + smp_wmb(); + cd->epoch_cyc_copy = cyc; + raw_local_irq_restore(flags); +} + +/* + * If your clock rate is known at compile time, using this will allow + * you to optimize the mult/shift loads away. This is paired with + * init_fixed_sched_clock() to ensure that your mult/shift are correct. + */ +static inline unsigned long long cyc_to_fixed_sched_clock(struct clock_data *cd, + u32 cyc, u32 mask, u32 mult, u32 shift) +{ + u64 epoch_ns; + u32 epoch_cyc; + + /* + * Load the epoch_cyc and epoch_ns atomically. We do this by + * ensuring that we always write epoch_cyc, epoch_ns and + * epoch_cyc_copy in strict order, and read them in strict order. + * If epoch_cyc and epoch_cyc_copy are not equal, then we're in + * the middle of an update, and we should repeat the load. + */ + do { + epoch_cyc = cd->epoch_cyc; + smp_rmb(); + epoch_ns = cd->epoch_ns; + smp_rmb(); + } while (epoch_cyc != cd->epoch_cyc_copy); + + return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, mult, shift); +} + +/* + * Otherwise, you need to use this, which will obtain the mult/shift + * from the clock_data structure. Use init_sched_clock() with this. + */ +static inline unsigned long long cyc_to_sched_clock(struct clock_data *cd, + u32 cyc, u32 mask) +{ + return cyc_to_fixed_sched_clock(cd, cyc, mask, cd->mult, cd->shift); +} + +/* + * Initialize the clock data - calculate the appropriate multiplier + * and shift. Also setup a timer to ensure that the epoch is refreshed + * at the appropriate time interval, which will call your update + * handler. + */ +void init_sched_clock(struct clock_data *, void (*)(void), + unsigned int, unsigned long); + +/* + * Use this initialization function rather than init_sched_clock() if + * you're using cyc_to_fixed_sched_clock, which will warn if your + * constants are incorrect. + */ +static inline void init_fixed_sched_clock(struct clock_data *cd, + void (*update)(void), unsigned int bits, unsigned long rate, + u32 mult, u32 shift) +{ + init_sched_clock(cd, update, bits, rate); + if (cd->mult != mult || cd->shift != shift) { + pr_crit("sched_clock: wrong multiply/shift: %u>>%u vs calculated %u>>%u\n" + "sched_clock: fix multiply/shift to avoid scheduler hiccups\n", + mult, shift, cd->mult, cd->shift); + } +} + extern void sched_clock_postinit(void); -extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); #endif diff --git a/trunk/arch/arm/include/asm/setup.h b/trunk/arch/arm/include/asm/setup.h index 23ebc0c82a39..915696dd9c7c 100644 --- a/trunk/arch/arm/include/asm/setup.h +++ b/trunk/arch/arm/include/asm/setup.h @@ -192,7 +192,11 @@ static const struct tagtable __tagtable_##fn __tag = { tag, fn } /* * Memory map description */ -#define NR_BANKS CONFIG_ARM_NR_BANKS +#ifdef CONFIG_ARCH_EP93XX +# define NR_BANKS 16 +#else +# define NR_BANKS 8 +#endif struct membank { phys_addr_t start; diff --git a/trunk/arch/arm/include/asm/socket.h b/trunk/arch/arm/include/asm/socket.h index dec6f9afb3cf..90ffd04b8e74 100644 --- a/trunk/arch/arm/include/asm/socket.h +++ b/trunk/arch/arm/include/asm/socket.h @@ -62,7 +62,4 @@ #define SO_RXQ_OVFL 40 -#define SO_WIFI_STATUS 41 -#define SCM_WIFI_STATUS SO_WIFI_STATUS - #endif /* _ASM_SOCKET_H */ diff --git a/trunk/arch/arm/include/asm/swab.h b/trunk/arch/arm/include/asm/swab.h index 32ee164a2f6b..9997ad20eff1 100644 --- a/trunk/arch/arm/include/asm/swab.h +++ b/trunk/arch/arm/include/asm/swab.h @@ -24,13 +24,12 @@ #if defined(__KERNEL__) && __LINUX_ARM_ARCH__ >= 6 -static inline __attribute_const__ __u32 __arch_swahb32(__u32 x) +static inline __attribute_const__ __u16 __arch_swab16(__u16 x) { __asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x)); return x; } -#define __arch_swahb32 __arch_swahb32 -#define __arch_swab16(x) ((__u16)__arch_swahb32(x)) +#define __arch_swab16 __arch_swab16 static inline __attribute_const__ __u32 __arch_swab32(__u32 x) { diff --git a/trunk/arch/arm/include/asm/system.h b/trunk/arch/arm/include/asm/system.h index e4c96cc6ec0c..984014b92647 100644 --- a/trunk/arch/arm/include/asm/system.h +++ b/trunk/arch/arm/include/asm/system.h @@ -80,14 +80,6 @@ struct siginfo; void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, unsigned long err, unsigned long trap); -#ifdef CONFIG_ARM_LPAE -#define FAULT_CODE_ALIGNMENT 33 -#define FAULT_CODE_DEBUG 34 -#else -#define FAULT_CODE_ALIGNMENT 1 -#define FAULT_CODE_DEBUG 2 -#endif - void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *), int sig, int code, const char *name); @@ -108,7 +100,7 @@ extern void __show_regs(struct pt_regs *); extern int __pure cpu_architecture(void); extern void cpu_init(void); -void soft_restart(unsigned long); +void arm_machine_restart(char mode, const char *cmd); extern void (*arm_pm_restart)(char str, const char *cmd); #define UDBG_UNDEFINED (1 << 0) diff --git a/trunk/arch/arm/include/asm/tlb.h b/trunk/arch/arm/include/asm/tlb.h index 5d3ed7e38561..265f908c4a6e 100644 --- a/trunk/arch/arm/include/asm/tlb.h +++ b/trunk/arch/arm/include/asm/tlb.h @@ -202,18 +202,8 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, tlb_remove_page(tlb, pte); } -static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, - unsigned long addr) -{ -#ifdef CONFIG_ARM_LPAE - tlb_add_flush(tlb, addr); - tlb_remove_page(tlb, virt_to_page(pmdp)); -#endif -} - #define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr) -#define pmd_free_tlb(tlb, pmdp, addr) __pmd_free_tlb(tlb, pmdp, addr) -#define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp) +#define pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, pmdp) #define tlb_migrate_finish(mm) do { } while (0) diff --git a/trunk/arch/arm/kernel/Makefile b/trunk/arch/arm/kernel/Makefile index 43b740d0e374..16eed6aebfa4 100644 --- a/trunk/arch/arm/kernel/Makefile +++ b/trunk/arch/arm/kernel/Makefile @@ -13,7 +13,7 @@ CFLAGS_REMOVE_return_address.o = -pg # Object file lists. -obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \ +obj-y := elf.o entry-armv.o entry-common.o irq.o \ process.o ptrace.o return_address.o setup.o signal.o \ sys_arm.o stacktrace.o time.o traps.o diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index 3a456c6c7005..b145f16c91bc 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -36,11 +36,12 @@ #ifdef CONFIG_MULTI_IRQ_HANDLER ldr r1, =handle_arch_irq mov r0, sp + ldr r1, [r1] adr lr, BSYM(9997f) - ldr pc, [r1] -#else - arch_irq_handler_default + teq r1, #0 + movne pc, r1 #endif + arch_irq_handler_default 9997: .endm diff --git a/trunk/arch/arm/kernel/head.S b/trunk/arch/arm/kernel/head.S index 14e277d2ff91..08c82fd844a8 100644 --- a/trunk/arch/arm/kernel/head.S +++ b/trunk/arch/arm/kernel/head.S @@ -39,14 +39,8 @@ #error KERNEL_RAM_VADDR must start at 0xXXXX8000 #endif -#ifdef CONFIG_ARM_LPAE - /* LPAE requires an additional page for the PGD */ -#define PG_DIR_SIZE 0x5000 -#define PMD_ORDER 3 -#else #define PG_DIR_SIZE 0x4000 #define PMD_ORDER 2 -#endif .globl swapper_pg_dir .equ swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE @@ -170,36 +164,17 @@ __create_page_tables: teq r0, r6 bne 1b -#ifdef CONFIG_ARM_LPAE - /* - * Build the PGD table (first level) to point to the PMD table. A PGD - * entry is 64-bit wide. - */ - mov r0, r4 - add r3, r4, #0x1000 @ first PMD table address - orr r3, r3, #3 @ PGD block type - mov r6, #4 @ PTRS_PER_PGD - mov r7, #1 << (55 - 32) @ L_PGD_SWAPPER -1: str r3, [r0], #4 @ set bottom PGD entry bits - str r7, [r0], #4 @ set top PGD entry bits - add r3, r3, #0x1000 @ next PMD table - subs r6, r6, #1 - bne 1b - - add r4, r4, #0x1000 @ point to the PMD tables -#endif - ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags /* * Create identity mapping to cater for __enable_mmu. * This identity mapping will be removed by paging_init(). */ - adr r0, __turn_mmu_on_loc + adr r0, __enable_mmu_loc ldmia r0, {r3, r5, r6} sub r0, r0, r3 @ virt->phys offset - add r5, r5, r0 @ phys __turn_mmu_on - add r6, r6, r0 @ phys __turn_mmu_on_end + add r5, r5, r0 @ phys __enable_mmu + add r6, r6, r0 @ phys __enable_mmu_end mov r5, r5, lsr #SECTION_SHIFT mov r6, r6, lsr #SECTION_SHIFT @@ -244,8 +219,8 @@ __create_page_tables: #endif /* - * Then map boot params address in r2 or the first 1MB (2MB with LPAE) - * of ram if boot params address is not specified. + * Then map boot params address in r2 or + * the first 1MB of ram if boot params address is not specified. */ mov r0, r2, lsr #SECTION_SHIFT movs r0, r0, lsl #SECTION_SHIFT @@ -276,15 +251,7 @@ __create_page_tables: mov r3, r7, lsr #SECTION_SHIFT ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags orr r3, r7, r3, lsl #SECTION_SHIFT -#ifdef CONFIG_ARM_LPAE - mov r7, #1 << (54 - 32) @ XN -#else - orr r3, r3, #PMD_SECT_XN -#endif 1: str r3, [r0], #4 -#ifdef CONFIG_ARM_LPAE - str r7, [r0], #4 -#endif add r3, r3, #1 << SECTION_SHIFT cmp r0, r6 blo 1b @@ -315,18 +282,15 @@ __create_page_tables: add r0, r4, #0xd8000000 >> (SECTION_SHIFT - PMD_ORDER) str r3, [r0] #endif -#endif -#ifdef CONFIG_ARM_LPAE - sub r4, r4, #0x1000 @ point to the PGD table #endif mov pc, lr ENDPROC(__create_page_tables) .ltorg .align -__turn_mmu_on_loc: +__enable_mmu_loc: .long . - .long __turn_mmu_on - .long __turn_mmu_on_end + .long __enable_mmu + .long __enable_mmu_end #if defined(CONFIG_SMP) __CPUINIT @@ -410,17 +374,12 @@ __enable_mmu: #ifdef CONFIG_CPU_ICACHE_DISABLE bic r0, r0, #CR_I #endif -#ifdef CONFIG_ARM_LPAE - mov r5, #0 - mcrr p15, 0, r4, r5, c2 @ load TTBR0 -#else mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \ domain_val(DOMAIN_IO, DOMAIN_CLIENT)) mcr p15, 0, r5, c3, c0, 0 @ load domain access register mcr p15, 0, r4, c2, c0, 0 @ load page table pointer -#endif b __turn_mmu_on ENDPROC(__enable_mmu) @@ -439,19 +398,15 @@ ENDPROC(__enable_mmu) * other registers depend on the function called upon completion */ .align 5 - .pushsection .idmap.text, "ax" -ENTRY(__turn_mmu_on) +__turn_mmu_on: mov r0, r0 - instr_sync mcr p15, 0, r0, c1, c0, 0 @ write control reg mrc p15, 0, r3, c0, c0, 0 @ read id reg - instr_sync mov r3, r3 mov r3, r13 mov pc, r3 -__turn_mmu_on_end: +__enable_mmu_end: ENDPROC(__turn_mmu_on) - .popsection #ifdef CONFIG_SMP_ON_UP diff --git a/trunk/arch/arm/kernel/hw_breakpoint.c b/trunk/arch/arm/kernel/hw_breakpoint.c index d6a95ef9131d..814a52a9dc39 100644 --- a/trunk/arch/arm/kernel/hw_breakpoint.c +++ b/trunk/arch/arm/kernel/hw_breakpoint.c @@ -1016,10 +1016,10 @@ static int __init arch_hw_breakpoint_init(void) } /* Register debug fault handler. */ - hook_fault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP, - TRAP_HWBKPT, "watchpoint debug exception"); - hook_ifault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP, - TRAP_HWBKPT, "breakpoint debug exception"); + hook_fault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT, + "watchpoint debug exception"); + hook_ifault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT, + "breakpoint debug exception"); /* Register hotplug notifier. */ register_cpu_notifier(&dbg_reset_nb); diff --git a/trunk/arch/arm/kernel/kprobes-test.c b/trunk/arch/arm/kernel/kprobes-test.c index 1862d8f2fd44..e17cdd6d90d8 100644 --- a/trunk/arch/arm/kernel/kprobes-test.c +++ b/trunk/arch/arm/kernel/kprobes-test.c @@ -202,8 +202,6 @@ #include #include -#include - #include "kprobes.h" #include "kprobes-test.h" @@ -1052,9 +1050,65 @@ static int test_instance; static unsigned long test_check_cc(int cc, unsigned long cpsr) { - int ret = arm_check_condition(cc << 28, cpsr); + unsigned long temp; + + switch (cc) { + case 0x0: /* eq */ + return cpsr & PSR_Z_BIT; + + case 0x1: /* ne */ + return (~cpsr) & PSR_Z_BIT; + + case 0x2: /* cs */ + return cpsr & PSR_C_BIT; + + case 0x3: /* cc */ + return (~cpsr) & PSR_C_BIT; + + case 0x4: /* mi */ + return cpsr & PSR_N_BIT; + + case 0x5: /* pl */ + return (~cpsr) & PSR_N_BIT; + + case 0x6: /* vs */ + return cpsr & PSR_V_BIT; + + case 0x7: /* vc */ + return (~cpsr) & PSR_V_BIT; - return (ret != ARM_OPCODE_CONDTEST_FAIL); + case 0x8: /* hi */ + cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ + return cpsr & PSR_C_BIT; + + case 0x9: /* ls */ + cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ + return (~cpsr) & PSR_C_BIT; + + case 0xa: /* ge */ + cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ + return (~cpsr) & PSR_N_BIT; + + case 0xb: /* lt */ + cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ + return cpsr & PSR_N_BIT; + + case 0xc: /* gt */ + temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ + temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ + return (~temp) & PSR_N_BIT; + + case 0xd: /* le */ + temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ + temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ + return temp & PSR_N_BIT; + + case 0xe: /* al */ + case 0xf: /* unconditional */ + return true; + } + BUG(); + return false; } static int is_last_scenario; @@ -1074,9 +1128,7 @@ static unsigned long test_context_cpsr(int scenario) if (!test_case_is_thumb) { /* Testing ARM code */ - int cc = current_instruction >> 28; - - probe_should_run = test_check_cc(cc, cpsr) != 0; + probe_should_run = test_check_cc(current_instruction >> 28, cpsr) != 0; if (scenario == 15) is_last_scenario = true; diff --git a/trunk/arch/arm/kernel/leds.c b/trunk/arch/arm/kernel/leds.c index 1911dae19e4f..0bcd38341573 100644 --- a/trunk/arch/arm/kernel/leds.c +++ b/trunk/arch/arm/kernel/leds.c @@ -9,7 +9,7 @@ */ #include #include -#include +#include #include #include @@ -34,8 +34,8 @@ static const struct leds_evt_name evt_names[] = { { "red", led_red_on, led_red_off }, }; -static ssize_t leds_store(struct device *dev, - struct device_attribute *attr, +static ssize_t leds_store(struct sys_device *dev, + struct sysdev_attribute *attr, const char *buf, size_t size) { int ret = -EINVAL, len = strcspn(buf, " "); @@ -69,16 +69,15 @@ static ssize_t leds_store(struct device *dev, return ret; } -static DEVICE_ATTR(event, 0200, NULL, leds_store); +static SYSDEV_ATTR(event, 0200, NULL, leds_store); -static struct bus_type leds_subsys = { +static struct sysdev_class leds_sysclass = { .name = "leds", - .dev_name = "leds", }; -static struct device leds_device = { +static struct sys_device leds_device = { .id = 0, - .bus = &leds_subsys, + .cls = &leds_sysclass, }; static int leds_suspend(void) @@ -106,11 +105,11 @@ static struct syscore_ops leds_syscore_ops = { static int __init leds_init(void) { int ret; - ret = subsys_system_register(&leds_subsys, NULL); + ret = sysdev_class_register(&leds_sysclass); if (ret == 0) - ret = device_register(&leds_device); + ret = sysdev_register(&leds_device); if (ret == 0) - ret = device_create_file(&leds_device, &dev_attr_event); + ret = sysdev_create_file(&leds_device, &attr_event); if (ret == 0) register_syscore_ops(&leds_syscore_ops); return ret; diff --git a/trunk/arch/arm/kernel/machine_kexec.c b/trunk/arch/arm/kernel/machine_kexec.c index 764bd456d84f..e59bbd496c39 100644 --- a/trunk/arch/arm/kernel/machine_kexec.c +++ b/trunk/arch/arm/kernel/machine_kexec.c @@ -12,11 +12,12 @@ #include #include #include -#include extern const unsigned char relocate_new_kernel[]; extern const unsigned int relocate_new_kernel_size; +extern void setup_mm_for_reboot(char mode); + extern unsigned long kexec_start_address; extern unsigned long kexec_indirection_page; extern unsigned long kexec_mach_type; @@ -110,6 +111,14 @@ void machine_kexec(struct kimage *image) if (kexec_reinit) kexec_reinit(); - - soft_restart(reboot_code_buffer_phys); + local_irq_disable(); + local_fiq_disable(); + setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/ + flush_cache_all(); + outer_flush_all(); + outer_disable(); + cpu_proc_fin(); + outer_inv_all(); + flush_cache_all(); + cpu_reset(reboot_code_buffer_phys); } diff --git a/trunk/arch/arm/kernel/opcodes.c b/trunk/arch/arm/kernel/opcodes.c deleted file mode 100644 index f8179c6a817f..000000000000 --- a/trunk/arch/arm/kernel/opcodes.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * linux/arch/arm/kernel/opcodes.c - * - * A32 condition code lookup feature moved from nwfpe/fpopcode.c - * - * 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. - */ - -#include -#include - -#define ARM_OPCODE_CONDITION_UNCOND 0xf - -/* - * condition code lookup table - * index into the table is test code: EQ, NE, ... LT, GT, AL, NV - * - * bit position in short is condition code: NZCV - */ -static const unsigned short cc_map[16] = { - 0xF0F0, /* EQ == Z set */ - 0x0F0F, /* NE */ - 0xCCCC, /* CS == C set */ - 0x3333, /* CC */ - 0xFF00, /* MI == N set */ - 0x00FF, /* PL */ - 0xAAAA, /* VS == V set */ - 0x5555, /* VC */ - 0x0C0C, /* HI == C set && Z clear */ - 0xF3F3, /* LS == C clear || Z set */ - 0xAA55, /* GE == (N==V) */ - 0x55AA, /* LT == (N!=V) */ - 0x0A05, /* GT == (!Z && (N==V)) */ - 0xF5FA, /* LE == (Z || (N!=V)) */ - 0xFFFF, /* AL always */ - 0 /* NV */ -}; - -/* - * Returns: - * ARM_OPCODE_CONDTEST_FAIL - if condition fails - * ARM_OPCODE_CONDTEST_PASS - if condition passes (including AL) - * ARM_OPCODE_CONDTEST_UNCOND - if NV condition, or separate unconditional - * opcode space from v5 onwards - * - * Code that tests whether a conditional instruction would pass its condition - * check should check that return value == ARM_OPCODE_CONDTEST_PASS. - * - * Code that tests if a condition means that the instruction would be executed - * (regardless of conditional or unconditional) should instead check that the - * return value != ARM_OPCODE_CONDTEST_FAIL. - */ -asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr) -{ - u32 cc_bits = opcode >> 28; - u32 psr_cond = psr >> 28; - unsigned int ret; - - if (cc_bits != ARM_OPCODE_CONDITION_UNCOND) { - if ((cc_map[cc_bits] >> (psr_cond)) & 1) - ret = ARM_OPCODE_CONDTEST_PASS; - else - ret = ARM_OPCODE_CONDTEST_FAIL; - } else { - ret = ARM_OPCODE_CONDTEST_UNCOND; - } - - return ret; -} -EXPORT_SYMBOL_GPL(arm_check_condition); diff --git a/trunk/arch/arm/kernel/perf_event.c b/trunk/arch/arm/kernel/perf_event.c index 5bb91bf3d47f..88b0941ce51e 100644 --- a/trunk/arch/arm/kernel/perf_event.c +++ b/trunk/arch/arm/kernel/perf_event.c @@ -59,7 +59,8 @@ armpmu_get_pmu_id(void) } EXPORT_SYMBOL_GPL(armpmu_get_pmu_id); -int perf_num_counters(void) +int +armpmu_get_max_events(void) { int max_events = 0; @@ -68,6 +69,12 @@ int perf_num_counters(void) return max_events; } +EXPORT_SYMBOL_GPL(armpmu_get_max_events); + +int perf_num_counters(void) +{ + return armpmu_get_max_events(); +} EXPORT_SYMBOL_GPL(perf_num_counters); #define HW_OP_UNSUPPORTED 0xFFFF @@ -373,8 +380,6 @@ armpmu_release_hardware(struct arm_pmu *armpmu) { int i, irq, irqs; struct platform_device *pmu_device = armpmu->plat_device; - struct arm_pmu_platdata *plat = - dev_get_platdata(&pmu_device->dev); irqs = min(pmu_device->num_resources, num_possible_cpus()); @@ -382,11 +387,8 @@ armpmu_release_hardware(struct arm_pmu *armpmu) if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs)) continue; irq = platform_get_irq(pmu_device, i); - if (irq >= 0) { - if (plat && plat->disable_irq) - plat->disable_irq(irq); + if (irq >= 0) free_irq(irq, armpmu); - } } release_pmu(armpmu->type); @@ -446,8 +448,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu) irq); armpmu_release_hardware(armpmu); return err; - } else if (plat && plat->enable_irq) - plat->enable_irq(irq); + } cpumask_set_cpu(i, &armpmu->active_irqs); } diff --git a/trunk/arch/arm/kernel/perf_event_v6.c b/trunk/arch/arm/kernel/perf_event_v6.c index 533be9930ec2..e63d8115c01b 100644 --- a/trunk/arch/arm/kernel/perf_event_v6.c +++ b/trunk/arch/arm/kernel/perf_event_v6.c @@ -65,15 +65,13 @@ enum armv6_counters { * accesses/misses in hardware. */ static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC, - [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT, - [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV6_PERFCTR_IBUF_STALL, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV6_PERFCTR_LSU_FULL_STALL, + [PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES, + [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC, + [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC, + [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT, + [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, }; static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] @@ -220,15 +218,13 @@ enum armv6mpcore_perf_types { * accesses/misses in hardware. */ static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = ARMV6MPCORE_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_INSTR_EXEC, - [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6MPCORE_PERFCTR_BR_MISPREDICT, - [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV6MPCORE_PERFCTR_IBUF_STALL, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV6MPCORE_PERFCTR_LSU_FULL_STALL, + [PERF_COUNT_HW_CPU_CYCLES] = ARMV6MPCORE_PERFCTR_CPU_CYCLES, + [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_INSTR_EXEC, + [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC, + [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6MPCORE_PERFCTR_BR_MISPREDICT, + [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, }; static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] diff --git a/trunk/arch/arm/kernel/perf_event_v7.c b/trunk/arch/arm/kernel/perf_event_v7.c index 460bbbb6b885..1ef6d0034b85 100644 --- a/trunk/arch/arm/kernel/perf_event_v7.c +++ b/trunk/arch/arm/kernel/perf_event_v7.c @@ -28,87 +28,165 @@ static struct arm_pmu armv7pmu; * they are not available. */ enum armv7_perf_types { - ARMV7_PERFCTR_PMNC_SW_INCR = 0x00, - ARMV7_PERFCTR_L1_ICACHE_REFILL = 0x01, - ARMV7_PERFCTR_ITLB_REFILL = 0x02, - ARMV7_PERFCTR_L1_DCACHE_REFILL = 0x03, - ARMV7_PERFCTR_L1_DCACHE_ACCESS = 0x04, - ARMV7_PERFCTR_DTLB_REFILL = 0x05, - ARMV7_PERFCTR_MEM_READ = 0x06, - ARMV7_PERFCTR_MEM_WRITE = 0x07, - ARMV7_PERFCTR_INSTR_EXECUTED = 0x08, - ARMV7_PERFCTR_EXC_TAKEN = 0x09, - ARMV7_PERFCTR_EXC_EXECUTED = 0x0A, - ARMV7_PERFCTR_CID_WRITE = 0x0B, - - /* - * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS. + ARMV7_PERFCTR_PMNC_SW_INCR = 0x00, + ARMV7_PERFCTR_IFETCH_MISS = 0x01, + ARMV7_PERFCTR_ITLB_MISS = 0x02, + ARMV7_PERFCTR_DCACHE_REFILL = 0x03, /* L1 */ + ARMV7_PERFCTR_DCACHE_ACCESS = 0x04, /* L1 */ + ARMV7_PERFCTR_DTLB_REFILL = 0x05, + ARMV7_PERFCTR_DREAD = 0x06, + ARMV7_PERFCTR_DWRITE = 0x07, + ARMV7_PERFCTR_INSTR_EXECUTED = 0x08, + ARMV7_PERFCTR_EXC_TAKEN = 0x09, + ARMV7_PERFCTR_EXC_EXECUTED = 0x0A, + ARMV7_PERFCTR_CID_WRITE = 0x0B, + /* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS. * It counts: - * - all (taken) branch instructions, + * - all branch instructions, * - instructions that explicitly write the PC, * - exception generating instructions. */ - ARMV7_PERFCTR_PC_WRITE = 0x0C, - ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D, - ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E, - ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS = 0x0F, - ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10, - ARMV7_PERFCTR_CLOCK_CYCLES = 0x11, - ARMV7_PERFCTR_PC_BRANCH_PRED = 0x12, + ARMV7_PERFCTR_PC_WRITE = 0x0C, + ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D, + ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E, + ARMV7_PERFCTR_UNALIGNED_ACCESS = 0x0F, /* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */ - ARMV7_PERFCTR_MEM_ACCESS = 0x13, - ARMV7_PERFCTR_L1_ICACHE_ACCESS = 0x14, - ARMV7_PERFCTR_L1_DCACHE_WB = 0x15, - ARMV7_PERFCTR_L2_CACHE_ACCESS = 0x16, - ARMV7_PERFCTR_L2_CACHE_REFILL = 0x17, - ARMV7_PERFCTR_L2_CACHE_WB = 0x18, - ARMV7_PERFCTR_BUS_ACCESS = 0x19, - ARMV7_PERFCTR_MEM_ERROR = 0x1A, - ARMV7_PERFCTR_INSTR_SPEC = 0x1B, - ARMV7_PERFCTR_TTBR_WRITE = 0x1C, - ARMV7_PERFCTR_BUS_CYCLES = 0x1D, - - ARMV7_PERFCTR_CPU_CYCLES = 0xFF + ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10, + ARMV7_PERFCTR_CLOCK_CYCLES = 0x11, + ARMV7_PERFCTR_PC_BRANCH_PRED = 0x12, + ARMV7_PERFCTR_MEM_ACCESS = 0x13, + ARMV7_PERFCTR_L1_ICACHE_ACCESS = 0x14, + ARMV7_PERFCTR_L1_DCACHE_WB = 0x15, + ARMV7_PERFCTR_L2_DCACHE_ACCESS = 0x16, + ARMV7_PERFCTR_L2_DCACHE_REFILL = 0x17, + ARMV7_PERFCTR_L2_DCACHE_WB = 0x18, + ARMV7_PERFCTR_BUS_ACCESS = 0x19, + ARMV7_PERFCTR_MEMORY_ERROR = 0x1A, + ARMV7_PERFCTR_INSTR_SPEC = 0x1B, + ARMV7_PERFCTR_TTBR_WRITE = 0x1C, + ARMV7_PERFCTR_BUS_CYCLES = 0x1D, + + ARMV7_PERFCTR_CPU_CYCLES = 0xFF }; /* ARMv7 Cortex-A8 specific event types */ enum armv7_a8_perf_types { - ARMV7_A8_PERFCTR_L2_CACHE_ACCESS = 0x43, - ARMV7_A8_PERFCTR_L2_CACHE_REFILL = 0x44, - ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS = 0x50, - ARMV7_A8_PERFCTR_STALL_ISIDE = 0x56, + ARMV7_PERFCTR_WRITE_BUFFER_FULL = 0x40, + ARMV7_PERFCTR_L2_STORE_MERGED = 0x41, + ARMV7_PERFCTR_L2_STORE_BUFF = 0x42, + ARMV7_PERFCTR_L2_ACCESS = 0x43, + ARMV7_PERFCTR_L2_CACH_MISS = 0x44, + ARMV7_PERFCTR_AXI_READ_CYCLES = 0x45, + ARMV7_PERFCTR_AXI_WRITE_CYCLES = 0x46, + ARMV7_PERFCTR_MEMORY_REPLAY = 0x47, + ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY = 0x48, + ARMV7_PERFCTR_L1_DATA_MISS = 0x49, + ARMV7_PERFCTR_L1_INST_MISS = 0x4A, + ARMV7_PERFCTR_L1_DATA_COLORING = 0x4B, + ARMV7_PERFCTR_L1_NEON_DATA = 0x4C, + ARMV7_PERFCTR_L1_NEON_CACH_DATA = 0x4D, + ARMV7_PERFCTR_L2_NEON = 0x4E, + ARMV7_PERFCTR_L2_NEON_HIT = 0x4F, + ARMV7_PERFCTR_L1_INST = 0x50, + ARMV7_PERFCTR_PC_RETURN_MIS_PRED = 0x51, + ARMV7_PERFCTR_PC_BRANCH_FAILED = 0x52, + ARMV7_PERFCTR_PC_BRANCH_TAKEN = 0x53, + ARMV7_PERFCTR_PC_BRANCH_EXECUTED = 0x54, + ARMV7_PERFCTR_OP_EXECUTED = 0x55, + ARMV7_PERFCTR_CYCLES_INST_STALL = 0x56, + ARMV7_PERFCTR_CYCLES_INST = 0x57, + ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL = 0x58, + ARMV7_PERFCTR_CYCLES_NEON_INST_STALL = 0x59, + ARMV7_PERFCTR_NEON_CYCLES = 0x5A, + + ARMV7_PERFCTR_PMU0_EVENTS = 0x70, + ARMV7_PERFCTR_PMU1_EVENTS = 0x71, + ARMV7_PERFCTR_PMU_EVENTS = 0x72, }; /* ARMv7 Cortex-A9 specific event types */ enum armv7_a9_perf_types { - ARMV7_A9_PERFCTR_INSTR_CORE_RENAME = 0x68, - ARMV7_A9_PERFCTR_STALL_ICACHE = 0x60, - ARMV7_A9_PERFCTR_STALL_DISPATCH = 0x66, + ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC = 0x40, + ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC = 0x41, + ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC = 0x42, + + ARMV7_PERFCTR_COHERENT_LINE_MISS = 0x50, + ARMV7_PERFCTR_COHERENT_LINE_HIT = 0x51, + + ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES = 0x60, + ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES = 0x61, + ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES = 0x62, + ARMV7_PERFCTR_STREX_EXECUTED_PASSED = 0x63, + ARMV7_PERFCTR_STREX_EXECUTED_FAILED = 0x64, + ARMV7_PERFCTR_DATA_EVICTION = 0x65, + ARMV7_PERFCTR_ISSUE_STAGE_NO_INST = 0x66, + ARMV7_PERFCTR_ISSUE_STAGE_EMPTY = 0x67, + ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE = 0x68, + + ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS = 0x6E, + + ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST = 0x70, + ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST = 0x71, + ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST = 0x72, + ARMV7_PERFCTR_FP_EXECUTED_INST = 0x73, + ARMV7_PERFCTR_NEON_EXECUTED_INST = 0x74, + + ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES = 0x80, + ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES = 0x81, + ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES = 0x82, + ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES = 0x83, + ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES = 0x84, + ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES = 0x85, + ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES = 0x86, + + ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES = 0x8A, + ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES = 0x8B, + + ARMV7_PERFCTR_ISB_INST = 0x90, + ARMV7_PERFCTR_DSB_INST = 0x91, + ARMV7_PERFCTR_DMB_INST = 0x92, + ARMV7_PERFCTR_EXT_INTERRUPTS = 0x93, + + ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED = 0xA0, + ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED = 0xA1, + ARMV7_PERFCTR_PLE_FIFO_FLUSH = 0xA2, + ARMV7_PERFCTR_PLE_RQST_COMPLETED = 0xA3, + ARMV7_PERFCTR_PLE_FIFO_OVERFLOW = 0xA4, + ARMV7_PERFCTR_PLE_RQST_PROG = 0xA5 }; /* ARMv7 Cortex-A5 specific event types */ enum armv7_a5_perf_types { - ARMV7_A5_PERFCTR_PREFETCH_LINEFILL = 0xc2, - ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP = 0xc3, + ARMV7_PERFCTR_IRQ_TAKEN = 0x86, + ARMV7_PERFCTR_FIQ_TAKEN = 0x87, + + ARMV7_PERFCTR_EXT_MEM_RQST = 0xc0, + ARMV7_PERFCTR_NC_EXT_MEM_RQST = 0xc1, + ARMV7_PERFCTR_PREFETCH_LINEFILL = 0xc2, + ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP = 0xc3, + ARMV7_PERFCTR_ENTER_READ_ALLOC = 0xc4, + ARMV7_PERFCTR_READ_ALLOC = 0xc5, + + ARMV7_PERFCTR_STALL_SB_FULL = 0xc9, }; /* ARMv7 Cortex-A15 specific event types */ enum armv7_a15_perf_types { - ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40, - ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41, - ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ = 0x42, - ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE = 0x43, + ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS = 0x40, + ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS = 0x41, + ARMV7_PERFCTR_L1_DCACHE_READ_REFILL = 0x42, + ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL = 0x43, - ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ = 0x4C, - ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE = 0x4D, + ARMV7_PERFCTR_L1_DTLB_READ_REFILL = 0x4C, + ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL = 0x4D, - ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ = 0x50, - ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51, - ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ = 0x52, - ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE = 0x53, + ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS = 0x50, + ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS = 0x51, + ARMV7_PERFCTR_L2_DCACHE_READ_REFILL = 0x52, + ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL = 0x53, - ARMV7_A15_PERFCTR_PC_WRITE_SPEC = 0x76, + ARMV7_PERFCTR_SPEC_PC_WRITE = 0x76, }; /* @@ -119,15 +197,13 @@ enum armv7_a15_perf_types { * accesses/misses in hardware. */ static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, - [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A8_PERFCTR_STALL_ISIDE, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, + [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, + [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, + [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES, }; static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] @@ -141,12 +217,12 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] * combined. */ [C(OP_READ)] = { - [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL, + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, }, [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL, + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -155,12 +231,12 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] }, [C(L1I)] = { [C(OP_READ)] = { - [C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS, }, [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -169,12 +245,12 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] }, [C(LL)] = { [C(OP_READ)] = { - [C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL, + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS, }, [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL, + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -198,11 +274,11 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(ITLB)] = { [C(OP_READ)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, }, [C(OP_WRITE)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -211,12 +287,14 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] }, [C(BPU)] = { [C(OP_READ)] = { - [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, }, [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -243,15 +321,14 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] * Cortex-A9 HW events mapping */ static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_A9_PERFCTR_INSTR_CORE_RENAME, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, - [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A9_PERFCTR_STALL_ICACHE, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV7_A9_PERFCTR_STALL_DISPATCH, + [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, + [PERF_COUNT_HW_INSTRUCTIONS] = + ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE, + [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_DCACHE_ACCESS, + [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_DCACHE_REFILL, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, + [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES, }; static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] @@ -265,12 +342,12 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] * combined. */ [C(OP_READ)] = { - [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL, + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, }, [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL, + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -280,11 +357,11 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(L1I)] = { [C(OP_READ)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, }, [C(OP_WRITE)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -322,11 +399,11 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(ITLB)] = { [C(OP_READ)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, }, [C(OP_WRITE)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -335,12 +412,14 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] }, [C(BPU)] = { [C(OP_READ)] = { - [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, }, [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -367,15 +446,13 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] * Cortex-A5 HW events mapping */ static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, - [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, + [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, + [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, + [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, }; static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] @@ -383,34 +460,42 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = { [C(L1D)] = { [C(OP_READ)] = { - [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL, + [C(RESULT_ACCESS)] + = ARMV7_PERFCTR_DCACHE_ACCESS, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_DCACHE_REFILL, }, [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL, + [C(RESULT_ACCESS)] + = ARMV7_PERFCTR_DCACHE_ACCESS, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_DCACHE_REFILL, }, [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL, - [C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP, + [C(RESULT_ACCESS)] + = ARMV7_PERFCTR_PREFETCH_LINEFILL, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP, }, }, [C(L1I)] = { [C(OP_READ)] = { [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, }, [C(OP_WRITE)] = { [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, }, /* * The prefetch counters don't differentiate between the I * side and the D side. */ [C(OP_PREFETCH)] = { - [C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL, - [C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP, + [C(RESULT_ACCESS)] + = ARMV7_PERFCTR_PREFETCH_LINEFILL, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP, }, }, [C(LL)] = { @@ -444,11 +529,11 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(ITLB)] = { [C(OP_READ)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, }, [C(OP_WRITE)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -458,11 +543,13 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(BPU)] = { [C(OP_READ)] = { [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, }, [C(OP_WRITE)] = { [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -475,15 +562,13 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] * Cortex-A15 HW events mapping */ static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A15_PERFCTR_PC_WRITE_SPEC, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, - [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, + [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, + [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_SPEC_PC_WRITE, + [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES, }; static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] @@ -491,12 +576,16 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = { [C(L1D)] = { [C(OP_READ)] = { - [C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ, - [C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ, + [C(RESULT_ACCESS)] + = ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_L1_DCACHE_READ_REFILL, }, [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE, - [C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE, + [C(RESULT_ACCESS)] + = ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -512,11 +601,11 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] */ [C(OP_READ)] = { [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, }, [C(OP_WRITE)] = { [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, - [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -525,12 +614,16 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] }, [C(LL)] = { [C(OP_READ)] = { - [C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ, - [C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ, + [C(RESULT_ACCESS)] + = ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_L2_DCACHE_READ_REFILL, }, [C(OP_WRITE)] = { - [C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE, - [C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE, + [C(RESULT_ACCESS)] + = ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -540,11 +633,13 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(DTLB)] = { [C(OP_READ)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_L1_DTLB_READ_REFILL, }, [C(OP_WRITE)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -554,11 +649,11 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(ITLB)] = { [C(OP_READ)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, }, [C(OP_WRITE)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL, + [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, @@ -568,11 +663,13 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(BPU)] = { [C(OP_READ)] = { [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, }, [C(OP_WRITE)] = { [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, - [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [C(RESULT_MISS)] + = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, }, [C(OP_PREFETCH)] = { [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, diff --git a/trunk/arch/arm/kernel/perf_event_xscale.c b/trunk/arch/arm/kernel/perf_event_xscale.c index 3b99d8269829..e0cca10a8411 100644 --- a/trunk/arch/arm/kernel/perf_event_xscale.c +++ b/trunk/arch/arm/kernel/perf_event_xscale.c @@ -48,15 +48,13 @@ enum xscale_counters { }; static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = { - [PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT, - [PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION, - [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH, - [PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS, - [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = XSCALE_PERFCTR_ICACHE_NO_DELIVER, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT, + [PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION, + [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH, + [PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS, + [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, }; static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index 971d65c253a9..3d0c6fb74ae4 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -57,7 +57,7 @@ static const char *isa_modes[] = { "ARM" , "Thumb" , "Jazelle", "ThumbEE" }; -extern void setup_mm_for_reboot(void); +extern void setup_mm_for_reboot(char mode); static volatile int hlt_counter; @@ -92,24 +92,18 @@ static int __init hlt_setup(char *__unused) __setup("nohlt", nohlt_setup); __setup("hlt", hlt_setup); -extern void call_with_stack(void (*fn)(void *), void *arg, void *sp); -typedef void (*phys_reset_t)(unsigned long); - -/* - * A temporary stack to use for CPU reset. This is static so that we - * don't clobber it with the identity mapping. When running with this - * stack, any references to the current task *will not work* so you - * should really do as little as possible before jumping to your reset - * code. - */ -static u64 soft_restart_stack[16]; - -static void __soft_restart(void *addr) +void arm_machine_restart(char mode, const char *cmd) { - phys_reset_t phys_reset; + /* Disable interrupts first */ + local_irq_disable(); + local_fiq_disable(); - /* Take out a flat memory mapping. */ - setup_mm_for_reboot(); + /* + * Tell the mm system that we are going to reboot - + * we may need it to insert some 1:1 mappings so that + * soft boot works. + */ + setup_mm_for_reboot(mode); /* Clean and invalidate caches */ flush_cache_all(); @@ -120,35 +114,18 @@ static void __soft_restart(void *addr) /* Push out any further dirty data, and ensure cache is empty */ flush_cache_all(); - /* Switch to the identity mapping. */ - phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset); - phys_reset((unsigned long)addr); - - /* Should never get here. */ - BUG(); -} - -void soft_restart(unsigned long addr) -{ - u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack); - - /* Disable interrupts first */ - local_irq_disable(); - local_fiq_disable(); + /* + * Now call the architecture specific reboot code. + */ + arch_reset(mode, cmd); - /* Disable the L2 if we're the last man standing. */ - if (num_online_cpus() == 1) - outer_disable(); - - /* Change to the new stack and continue with the reset. */ - call_with_stack(__soft_restart, (void *)addr, (void *)stack); - - /* Should never get here. */ - BUG(); -} - -static void null_restart(char mode, const char *cmd) -{ + /* + * Whoops - the architecture was unable to reboot. + * Tell the user! + */ + mdelay(1000); + printk("Reboot failed -- System halted\n"); + while (1); } /* @@ -157,7 +134,7 @@ static void null_restart(char mode, const char *cmd) void (*pm_power_off)(void); EXPORT_SYMBOL(pm_power_off); -void (*arm_pm_restart)(char str, const char *cmd) = null_restart; +void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart; EXPORT_SYMBOL_GPL(arm_pm_restart); static void do_nothing(void *unused) @@ -206,8 +183,7 @@ void cpu_idle(void) /* endless idle loop with no priority at all */ while (1) { - tick_nohz_idle_enter(); - rcu_idle_enter(); + tick_nohz_stop_sched_tick(1); leds_event(led_idle_start); while (!need_resched()) { #ifdef CONFIG_HOTPLUG_CPU @@ -237,8 +213,7 @@ void cpu_idle(void) } } leds_event(led_idle_end); - rcu_idle_exit(); - tick_nohz_idle_exit(); + tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); schedule(); preempt_disable(); @@ -278,15 +253,7 @@ void machine_power_off(void) void machine_restart(char *cmd) { machine_shutdown(); - arm_pm_restart(reboot_mode, cmd); - - /* Give a grace period for failure to restart of 1s */ - mdelay(1000); - - /* Whoops - the platform was unable to reboot. Tell the user! */ - printk("Reboot failed -- System halted\n"); - while (1); } void __show_regs(struct pt_regs *regs) diff --git a/trunk/arch/arm/kernel/sched_clock.c b/trunk/arch/arm/kernel/sched_clock.c index 5416c7c12528..9a46370fe9da 100644 --- a/trunk/arch/arm/kernel/sched_clock.c +++ b/trunk/arch/arm/kernel/sched_clock.c @@ -14,153 +14,61 @@ #include -struct clock_data { - u64 epoch_ns; - u32 epoch_cyc; - u32 epoch_cyc_copy; - u32 mult; - u32 shift; -}; - static void sched_clock_poll(unsigned long wrap_ticks); static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0); - -static struct clock_data cd = { - .mult = NSEC_PER_SEC / HZ, -}; - -static u32 __read_mostly sched_clock_mask = 0xffffffff; - -static u32 notrace jiffy_sched_clock_read(void) -{ - return (u32)(jiffies - INITIAL_JIFFIES); -} - -static u32 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read; - -static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift) -{ - return (cyc * mult) >> shift; -} - -static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask) -{ - u64 epoch_ns; - u32 epoch_cyc; - - /* - * Load the epoch_cyc and epoch_ns atomically. We do this by - * ensuring that we always write epoch_cyc, epoch_ns and - * epoch_cyc_copy in strict order, and read them in strict order. - * If epoch_cyc and epoch_cyc_copy are not equal, then we're in - * the middle of an update, and we should repeat the load. - */ - do { - epoch_cyc = cd.epoch_cyc; - smp_rmb(); - epoch_ns = cd.epoch_ns; - smp_rmb(); - } while (epoch_cyc != cd.epoch_cyc_copy); - - return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, cd.mult, cd.shift); -} - -/* - * Atomically update the sched_clock epoch. - */ -static void notrace update_sched_clock(void) -{ - unsigned long flags; - u32 cyc; - u64 ns; - - cyc = read_sched_clock(); - ns = cd.epoch_ns + - cyc_to_ns((cyc - cd.epoch_cyc) & sched_clock_mask, - cd.mult, cd.shift); - /* - * Write epoch_cyc and epoch_ns in a way that the update is - * detectable in cyc_to_fixed_sched_clock(). - */ - raw_local_irq_save(flags); - cd.epoch_cyc = cyc; - smp_wmb(); - cd.epoch_ns = ns; - smp_wmb(); - cd.epoch_cyc_copy = cyc; - raw_local_irq_restore(flags); -} +static void (*sched_clock_update_fn)(void); static void sched_clock_poll(unsigned long wrap_ticks) { mod_timer(&sched_clock_timer, round_jiffies(jiffies + wrap_ticks)); - update_sched_clock(); + sched_clock_update_fn(); } -void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) +void __init init_sched_clock(struct clock_data *cd, void (*update)(void), + unsigned int clock_bits, unsigned long rate) { unsigned long r, w; u64 res, wrap; char r_unit; - BUG_ON(bits > 32); - WARN_ON(!irqs_disabled()); - WARN_ON(read_sched_clock != jiffy_sched_clock_read); - read_sched_clock = read; - sched_clock_mask = (1 << bits) - 1; + sched_clock_update_fn = update; /* calculate the mult/shift to convert counter ticks to ns. */ - clocks_calc_mult_shift(&cd.mult, &cd.shift, rate, NSEC_PER_SEC, 0); + clocks_calc_mult_shift(&cd->mult, &cd->shift, rate, NSEC_PER_SEC, 0); r = rate; if (r >= 4000000) { r /= 1000000; r_unit = 'M'; - } else if (r >= 1000) { + } else { r /= 1000; r_unit = 'k'; - } else - r_unit = ' '; + } /* calculate how many ns until we wrap */ - wrap = cyc_to_ns((1ULL << bits) - 1, cd.mult, cd.shift); + wrap = cyc_to_ns((1ULL << clock_bits) - 1, cd->mult, cd->shift); do_div(wrap, NSEC_PER_MSEC); w = wrap; /* calculate the ns resolution of this counter */ - res = cyc_to_ns(1ULL, cd.mult, cd.shift); + res = cyc_to_ns(1ULL, cd->mult, cd->shift); pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lums\n", - bits, r, r_unit, res, w); + clock_bits, r, r_unit, res, w); /* * Start the timer to keep sched_clock() properly updated and * sets the initial epoch. */ sched_clock_timer.data = msecs_to_jiffies(w - (w / 10)); - update_sched_clock(); + update(); /* * Ensure that sched_clock() starts off at 0ns */ - cd.epoch_ns = 0; - - pr_debug("Registered %pF as sched_clock source\n", read); -} - -unsigned long long notrace sched_clock(void) -{ - u32 cyc = read_sched_clock(); - return cyc_to_sched_clock(cyc, sched_clock_mask); + cd->epoch_ns = 0; } void __init sched_clock_postinit(void) { - /* - * If no sched_clock function has been provided at that point, - * make it the final one one. - */ - if (read_sched_clock == jiffy_sched_clock_read) - setup_sched_clock(jiffy_sched_clock_read, 32, HZ); - sched_clock_poll(sched_clock_timer.data); } diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index 129fbd55bde8..8fc2c8fcbdc6 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -53,7 +52,6 @@ #include #include #include -#include #if defined(CONFIG_DEPRECATED_PARAM_STRUCT) #include "compat.h" @@ -892,12 +890,6 @@ static struct machine_desc * __init setup_machine_tags(unsigned int nr) return mdesc; } -static int __init meminfo_cmp(const void *_a, const void *_b) -{ - const struct membank *a = _a, *b = _b; - long cmp = bank_pfn_start(a) - bank_pfn_start(b); - return cmp < 0 ? -1 : cmp > 0 ? 1 : 0; -} void __init setup_arch(char **cmdline_p) { @@ -916,8 +908,8 @@ void __init setup_arch(char **cmdline_p) arm_dma_zone_size = mdesc->dma_zone_size; } #endif - if (mdesc->restart_mode) - reboot_setup(&mdesc->restart_mode); + if (mdesc->soft_reboot) + reboot_setup("s"); init_mm.start_code = (unsigned long) _text; init_mm.end_code = (unsigned long) _etext; @@ -930,16 +922,12 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); - sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL); sanity_check_meminfo(); arm_memblock_init(&meminfo, mdesc); paging_init(mdesc); request_standard_resources(mdesc); - if (mdesc->restart) - arm_pm_restart = mdesc->restart; - unflatten_device_tree(); #ifdef CONFIG_SMP diff --git a/trunk/arch/arm/kernel/sleep.S b/trunk/arch/arm/kernel/sleep.S index 1f268bda4552..020e99c845e7 100644 --- a/trunk/arch/arm/kernel/sleep.S +++ b/trunk/arch/arm/kernel/sleep.S @@ -54,18 +54,14 @@ ENDPROC(cpu_suspend_abort) * r0 = control register value */ .align 5 - .pushsection .idmap.text,"ax" ENTRY(cpu_resume_mmu) ldr r3, =cpu_resume_after_mmu - instr_sync mcr p15, 0, r0, c1, c0, 0 @ turn on MMU, I-cache, etc mrc p15, 0, r0, c0, c0, 0 @ read id reg - instr_sync mov r0, r0 mov r0, r0 mov pc, r3 @ jump to virtual address ENDPROC(cpu_resume_mmu) - .popsection cpu_resume_after_mmu: bl cpu_init @ restore the und/abt/irq banked regs mov r0, #0 @ return zero on success diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index 57db122a4f62..ef5640b9e218 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -62,6 +61,7 @@ int __cpuinit __cpu_up(unsigned int cpu) { struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu); struct task_struct *idle = ci->idle; + pgd_t *pgd; int ret; /* @@ -83,12 +83,30 @@ int __cpuinit __cpu_up(unsigned int cpu) init_idle(idle, cpu); } + /* + * Allocate initial page tables to allow the new CPU to + * enable the MMU safely. This essentially means a set + * of our "standard" page tables, with the addition of + * a 1:1 mapping for the physical address of the kernel. + */ + pgd = pgd_alloc(&init_mm); + if (!pgd) + return -ENOMEM; + + if (PHYS_OFFSET != PAGE_OFFSET) { +#ifndef CONFIG_HOTPLUG_CPU + identity_mapping_add(pgd, __pa(__init_begin), __pa(__init_end)); +#endif + identity_mapping_add(pgd, __pa(_stext), __pa(_etext)); + identity_mapping_add(pgd, __pa(_sdata), __pa(_edata)); + } + /* * We need to tell the secondary core where to find * its stack and the page tables. */ secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; - secondary_data.pgdir = virt_to_phys(idmap_pgd); + secondary_data.pgdir = virt_to_phys(pgd); secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir); __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data)); outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1)); @@ -124,6 +142,16 @@ int __cpuinit __cpu_up(unsigned int cpu) secondary_data.stack = NULL; secondary_data.pgdir = 0; + if (PHYS_OFFSET != PAGE_OFFSET) { +#ifndef CONFIG_HOTPLUG_CPU + identity_mapping_del(pgd, __pa(__init_begin), __pa(__init_end)); +#endif + identity_mapping_del(pgd, __pa(_stext), __pa(_etext)); + identity_mapping_del(pgd, __pa(_sdata), __pa(_edata)); + } + + pgd_free(&init_mm, pgd); + return ret; } @@ -522,10 +550,6 @@ static void ipi_cpu_stop(unsigned int cpu) local_fiq_disable(); local_irq_disable(); -#ifdef CONFIG_HOTPLUG_CPU - platform_cpu_kill(cpu); -#endif - while (1) cpu_relax(); } diff --git a/trunk/arch/arm/kernel/smp_twd.c b/trunk/arch/arm/kernel/smp_twd.c index c8e938553d47..a8a6682d6b52 100644 --- a/trunk/arch/arm/kernel/smp_twd.c +++ b/trunk/arch/arm/kernel/smp_twd.c @@ -10,11 +10,8 @@ */ #include #include -#include -#include #include #include -#include #include #include #include @@ -28,7 +25,6 @@ /* set up by the platform code */ void __iomem *twd_base; -static struct clk *twd_clk; static unsigned long twd_timer_rate; static struct clock_event_device __percpu **twd_evt; @@ -93,52 +89,6 @@ void twd_timer_stop(struct clock_event_device *clk) disable_percpu_irq(clk->irq); } -#ifdef CONFIG_CPU_FREQ - -/* - * Updates clockevent frequency when the cpu frequency changes. - * Called on the cpu that is changing frequency with interrupts disabled. - */ -static void twd_update_frequency(void *data) -{ - twd_timer_rate = clk_get_rate(twd_clk); - - clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate); -} - -static int twd_cpufreq_transition(struct notifier_block *nb, - unsigned long state, void *data) -{ - struct cpufreq_freqs *freqs = data; - - /* - * The twd clock events must be reprogrammed to account for the new - * frequency. The timer is local to a cpu, so cross-call to the - * changing cpu. - */ - if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE) - smp_call_function_single(freqs->cpu, twd_update_frequency, - NULL, 1); - - return NOTIFY_OK; -} - -static struct notifier_block twd_cpufreq_nb = { - .notifier_call = twd_cpufreq_transition, -}; - -static int twd_cpufreq_init(void) -{ - if (!IS_ERR(twd_clk)) - return cpufreq_register_notifier(&twd_cpufreq_nb, - CPUFREQ_TRANSITION_NOTIFIER); - - return 0; -} -core_initcall(twd_cpufreq_init); - -#endif - static void __cpuinit twd_calibrate_rate(void) { unsigned long count; @@ -190,35 +140,6 @@ static irqreturn_t twd_handler(int irq, void *dev_id) return IRQ_NONE; } -static struct clk *twd_get_clock(void) -{ - struct clk *clk; - int err; - - clk = clk_get_sys("smp_twd", NULL); - if (IS_ERR(clk)) { - pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk)); - return clk; - } - - err = clk_prepare(clk); - if (err) { - pr_err("smp_twd: clock failed to prepare: %d\n", err); - clk_put(clk); - return ERR_PTR(err); - } - - err = clk_enable(clk); - if (err) { - pr_err("smp_twd: clock failed to enable: %d\n", err); - clk_unprepare(clk); - clk_put(clk); - return ERR_PTR(err); - } - - return clk; -} - /* * Setup the local clock events for a CPU. */ @@ -244,13 +165,7 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) } } - if (!twd_clk) - twd_clk = twd_get_clock(); - - if (!IS_ERR_OR_NULL(twd_clk)) - twd_timer_rate = clk_get_rate(twd_clk); - else - twd_calibrate_rate(); + twd_calibrate_rate(); clk->name = "local_timer"; clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | @@ -258,11 +173,15 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) clk->rating = 350; clk->set_mode = twd_set_mode; clk->set_next_event = twd_set_next_event; + clk->shift = 20; + clk->mult = div_sc(twd_timer_rate, NSEC_PER_SEC, clk->shift); + clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk); + clk->min_delta_ns = clockevent_delta2ns(0xf, clk); this_cpu_clk = __this_cpu_ptr(twd_evt); *this_cpu_clk = clk; - clockevents_config_and_register(clk, twd_timer_rate, - 0xf, 0xffffffff); + clockevents_register_device(clk); + enable_percpu_irq(clk->irq, 0); } diff --git a/trunk/arch/arm/kernel/suspend.c b/trunk/arch/arm/kernel/suspend.c index 1794cc3b0f18..93a22d282c16 100644 --- a/trunk/arch/arm/kernel/suspend.c +++ b/trunk/arch/arm/kernel/suspend.c @@ -1,12 +1,13 @@ #include -#include #include #include #include #include #include +static pgd_t *suspend_pgd; + extern int __cpu_suspend(unsigned long, int (*)(unsigned long)); extern void cpu_resume_mmu(void); @@ -20,7 +21,7 @@ void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr) *save_ptr = virt_to_phys(ptr); /* This must correspond to the LDM in cpu_resume() assembly */ - *ptr++ = virt_to_phys(idmap_pgd); + *ptr++ = virt_to_phys(suspend_pgd); *ptr++ = sp; *ptr++ = virt_to_phys(cpu_do_resume); @@ -41,7 +42,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) struct mm_struct *mm = current->active_mm; int ret; - if (!idmap_pgd) + if (!suspend_pgd) return -EINVAL; /* @@ -58,3 +59,14 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) return ret; } + +static int __init cpu_suspend_init(void) +{ + suspend_pgd = pgd_alloc(&init_mm); + if (suspend_pgd) { + unsigned long addr = virt_to_phys(cpu_resume_mmu); + identity_mapping_add(suspend_pgd, addr, addr + SECTION_SIZE); + } + return suspend_pgd ? 0 : -ENOMEM; +} +core_initcall(cpu_suspend_init); diff --git a/trunk/arch/arm/kernel/swp_emulate.c b/trunk/arch/arm/kernel/swp_emulate.c index df745188f5de..5f452f8fde05 100644 --- a/trunk/arch/arm/kernel/swp_emulate.c +++ b/trunk/arch/arm/kernel/swp_emulate.c @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -186,21 +185,6 @@ static int swp_handler(struct pt_regs *regs, unsigned int instr) perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->ARM_pc); - res = arm_check_condition(instr, regs->ARM_cpsr); - switch (res) { - case ARM_OPCODE_CONDTEST_PASS: - break; - case ARM_OPCODE_CONDTEST_FAIL: - /* Condition failed - return to next instruction */ - regs->ARM_pc += 4; - return 0; - case ARM_OPCODE_CONDTEST_UNCOND: - /* If unconditional encoding - not a SWP, undef */ - return -EFAULT; - default: - return -EINVAL; - } - if (current->pid != previous_pid) { pr_debug("\"%s\" (%ld) uses deprecated SWP{B} instruction\n", current->comm, (unsigned long)current->pid); diff --git a/trunk/arch/arm/kernel/tcm.c b/trunk/arch/arm/kernel/tcm.c index 01ec453bb924..30e302d33e0a 100644 --- a/trunk/arch/arm/kernel/tcm.c +++ b/trunk/arch/arm/kernel/tcm.c @@ -180,9 +180,9 @@ static int __init setup_tcm_bank(u8 type, u8 bank, u8 banks, */ void __init tcm_init(void) { - u32 tcm_status; - u8 dtcm_banks; - u8 itcm_banks; + u32 tcm_status = read_cpuid_tcmstatus(); + u8 dtcm_banks = (tcm_status >> 16) & 0x03; + u8 itcm_banks = (tcm_status & 0x03); size_t dtcm_code_sz = &__edtcm_data - &__sdtcm_data; size_t itcm_code_sz = &__eitcm_text - &__sitcm_text; char *start; @@ -191,22 +191,6 @@ void __init tcm_init(void) int ret; int i; - /* - * Prior to ARMv5 there is no TCM, and trying to read the status - * register will hang the processor. - */ - if (cpu_architecture() < CPU_ARCH_ARMv5) { - if (dtcm_code_sz || itcm_code_sz) - pr_info("CPU TCM: %u bytes of DTCM and %u bytes of " - "ITCM code compiled in, but no TCM present " - "in pre-v5 CPU\n", dtcm_code_sz, itcm_code_sz); - return; - } - - tcm_status = read_cpuid_tcmstatus(); - dtcm_banks = (tcm_status >> 16) & 0x03; - itcm_banks = (tcm_status & 0x03); - /* Values greater than 2 for D/ITCM banks are "reserved" */ if (dtcm_banks > 2) dtcm_banks = 0; diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S index f76e75548670..20b3041e0860 100644 --- a/trunk/arch/arm/kernel/vmlinux.lds.S +++ b/trunk/arch/arm/kernel/vmlinux.lds.S @@ -13,12 +13,6 @@ *(.proc.info.init) \ VMLINUX_SYMBOL(__proc_info_end) = .; -#define IDMAP_TEXT \ - ALIGN_FUNCTION(); \ - VMLINUX_SYMBOL(__idmap_text_start) = .; \ - *(.idmap.text) \ - VMLINUX_SYMBOL(__idmap_text_end) = .; - #ifdef CONFIG_HOTPLUG_CPU #define ARM_CPU_DISCARD(x) #define ARM_CPU_KEEP(x) x @@ -98,7 +92,6 @@ SECTIONS SCHED_TEXT LOCK_TEXT KPROBES_TEXT - IDMAP_TEXT #ifdef CONFIG_MMU *(.fixup) #endif diff --git a/trunk/arch/arm/lib/Makefile b/trunk/arch/arm/lib/Makefile index 0ade0acc1ed9..cf73a7f742dd 100644 --- a/trunk/arch/arm/lib/Makefile +++ b/trunk/arch/arm/lib/Makefile @@ -13,8 +13,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ testchangebit.o testclearbit.o testsetbit.o \ ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ ucmpdi2.o lib1funcs.o div64.o \ - io-readsb.o io-writesb.o io-readsl.o io-writesl.o \ - call_with_stack.o + io-readsb.o io-writesb.o io-readsl.o io-writesl.o mmu-y := clear_user.o copy_page.o getuser.o putuser.o diff --git a/trunk/arch/arm/lib/call_with_stack.S b/trunk/arch/arm/lib/call_with_stack.S deleted file mode 100644 index 916c80f13ae7..000000000000 --- a/trunk/arch/arm/lib/call_with_stack.S +++ /dev/null @@ -1,44 +0,0 @@ -/* - * arch/arm/lib/call_with_stack.S - * - * Copyright (C) 2011 ARM Ltd. - * Written by Will Deacon - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -/* - * void call_with_stack(void (*fn)(void *), void *arg, void *sp) - * - * Change the stack to that pointed at by sp, then invoke fn(arg) with - * the new stack. - */ -ENTRY(call_with_stack) - str sp, [r2, #-4]! - str lr, [r2, #-4]! - - mov sp, r2 - mov r2, r0 - mov r0, r1 - - adr lr, BSYM(1f) - mov pc, r2 - -1: ldr lr, [sp] - ldr sp, [sp, #4] - mov pc, lr -ENDPROC(call_with_stack) diff --git a/trunk/arch/arm/mach-at91/at91cap9.c b/trunk/arch/arm/mach-at91/at91cap9.c index 29373397d2df..ecdd54dd68c6 100644 --- a/trunk/arch/arm/mach-at91/at91cap9.c +++ b/trunk/arch/arm/mach-at91/at91cap9.c @@ -313,7 +313,7 @@ static struct at91_gpio_bank at91cap9_gpio[] = { } }; -static void at91cap9_restart(char mode, const char *cmd) +static void at91cap9_reset(void) { at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); } @@ -335,7 +335,7 @@ static void __init at91cap9_map_io(void) static void __init at91cap9_initialize(void) { - arm_pm_restart = at91cap9_restart; + at91_arch_reset = at91cap9_reset; pm_power_off = at91cap9_poweroff; at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); diff --git a/trunk/arch/arm/mach-at91/at91rm9200.c b/trunk/arch/arm/mach-at91/at91rm9200.c index 430a9fdc3dbf..713d3bdbd284 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200.c +++ b/trunk/arch/arm/mach-at91/at91rm9200.c @@ -288,7 +288,7 @@ static struct at91_gpio_bank at91rm9200_gpio[] = { } }; -static void at91rm9200_restart(char mode, const char *cmd) +static void at91rm9200_reset(void) { /* * Perform a hardware reset with the use of the Watchdog timer. @@ -309,7 +309,7 @@ static void __init at91rm9200_map_io(void) static void __init at91rm9200_initialize(void) { - arm_pm_restart = at91rm9200_restart; + at91_arch_reset = at91rm9200_reset; at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1) | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3) | (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5) diff --git a/trunk/arch/arm/mach-at91/at91sam9260.c b/trunk/arch/arm/mach-at91/at91sam9260.c index e76cd49ebc9e..0d20677fbef0 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260.c +++ b/trunk/arch/arm/mach-at91/at91sam9260.c @@ -327,7 +327,7 @@ static void __init at91sam9260_map_io(void) static void __init at91sam9260_initialize(void) { - arm_pm_restart = at91sam9_alt_restart; + at91_arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9260_poweroff; at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) | (1 << AT91SAM9260_ID_IRQ2); diff --git a/trunk/arch/arm/mach-at91/at91sam9261.c b/trunk/arch/arm/mach-at91/at91sam9261.c index 19ac7c0729a0..658a5185abfd 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261.c +++ b/trunk/arch/arm/mach-at91/at91sam9261.c @@ -287,7 +287,7 @@ static void __init at91sam9261_map_io(void) static void __init at91sam9261_initialize(void) { - arm_pm_restart = at91sam9_alt_restart; + at91_arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9261_poweroff; at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) | (1 << AT91SAM9261_ID_IRQ2); diff --git a/trunk/arch/arm/mach-at91/at91sam9263.c b/trunk/arch/arm/mach-at91/at91sam9263.c index 50d016310031..f83fbb0ee0c5 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263.c +++ b/trunk/arch/arm/mach-at91/at91sam9263.c @@ -305,7 +305,7 @@ static void __init at91sam9263_map_io(void) static void __init at91sam9263_initialize(void) { - arm_pm_restart = at91sam9_alt_restart; + at91_arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9263_poweroff; at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1); diff --git a/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S b/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S index d3f931c5942e..e0256deb91fb 100644 --- a/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S +++ b/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S @@ -14,15 +14,20 @@ */ #include +#include #include #include #include .arm - .globl at91sam9_alt_restart + .globl at91sam9_alt_reset -at91sam9_alt_restart: ldr r0, .at91_va_base_sdramc @ preload constants +at91sam9_alt_reset: mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #CR_I + mcr p15, 0, r0, c1, c0, 0 @ enable I-cache + + ldr r0, .at91_va_base_sdramc @ preload constants ldr r1, .at91_va_base_rstc_cr mov r2, #1 diff --git a/trunk/arch/arm/mach-at91/at91sam9g45.c b/trunk/arch/arm/mach-at91/at91sam9g45.c index ff21f7a60c63..318b0407ea04 100644 --- a/trunk/arch/arm/mach-at91/at91sam9g45.c +++ b/trunk/arch/arm/mach-at91/at91sam9g45.c @@ -317,7 +317,7 @@ static struct at91_gpio_bank at91sam9g45_gpio[] = { } }; -static void at91sam9g45_restart(char mode, const char *cmd) +static void at91sam9g45_reset(void) { at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); } @@ -340,7 +340,7 @@ static void __init at91sam9g45_map_io(void) static void __init at91sam9g45_initialize(void) { - arm_pm_restart = at91sam9g45_restart; + at91_arch_reset = at91sam9g45_reset; pm_power_off = at91sam9g45_poweroff; at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0); diff --git a/trunk/arch/arm/mach-at91/at91sam9rl.c b/trunk/arch/arm/mach-at91/at91sam9rl.c index 61cbb46f5b0e..a238105d2c11 100644 --- a/trunk/arch/arm/mach-at91/at91sam9rl.c +++ b/trunk/arch/arm/mach-at91/at91sam9rl.c @@ -292,7 +292,7 @@ static void __init at91sam9rl_map_io(void) static void __init at91sam9rl_initialize(void) { - arm_pm_restart = at91sam9_alt_restart; + at91_arch_reset = at91sam9_alt_reset; pm_power_off = at91sam9rl_poweroff; at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0); diff --git a/trunk/arch/arm/mach-at91/generic.h b/trunk/arch/arm/mach-at91/generic.h index 7f4503bc4cbb..938b34f57741 100644 --- a/trunk/arch/arm/mach-at91/generic.h +++ b/trunk/arch/arm/mach-at91/generic.h @@ -57,7 +57,7 @@ extern void at91_irq_suspend(void); extern void at91_irq_resume(void); /* reset */ -extern void at91sam9_alt_restart(char, const char *); +extern void at91sam9_alt_reset(void); /* GPIO */ #define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */ @@ -71,4 +71,5 @@ struct at91_gpio_bank { extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); extern void __init at91_gpio_irq_setup(void); +extern void (*at91_arch_reset)(void); extern int at91_extern_irq; diff --git a/trunk/arch/arm/mach-at91/include/mach/io.h b/trunk/arch/arm/mach-at91/include/mach/io.h index 4ca09ef7ca29..4298e7806c76 100644 --- a/trunk/arch/arm/mach-at91/include/mach/io.h +++ b/trunk/arch/arm/mach-at91/include/mach/io.h @@ -30,6 +30,14 @@ #ifndef __ASSEMBLY__ +#ifndef CONFIG_ARCH_AT91X40 +#define __arch_ioremap at91_ioremap +#define __arch_iounmap at91_iounmap +#endif + +void __iomem *at91_ioremap(unsigned long phys, size_t size, unsigned int type); +void at91_iounmap(volatile void __iomem *addr); + static inline unsigned int at91_sys_read(unsigned int reg_offset) { void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS; diff --git a/trunk/arch/arm/mach-at91/include/mach/system.h b/trunk/arch/arm/mach-at91/include/mach/system.h index cbd64f3bcecd..36af14bc13bb 100644 --- a/trunk/arch/arm/mach-at91/include/mach/system.h +++ b/trunk/arch/arm/mach-at91/include/mach/system.h @@ -47,4 +47,13 @@ static inline void arch_idle(void) #endif } +void (*at91_arch_reset)(void); + +static inline void arch_reset(char mode, const char *cmd) +{ + /* call the CPU-specific reset function */ + if (at91_arch_reset) + (at91_arch_reset)(); +} + #endif diff --git a/trunk/arch/arm/mach-at91/include/mach/vmalloc.h b/trunk/arch/arm/mach-at91/include/mach/vmalloc.h new file mode 100644 index 000000000000..8e4a1bd0ab1d --- /dev/null +++ b/trunk/arch/arm/mach-at91/include/mach/vmalloc.h @@ -0,0 +1,28 @@ +/* + * arch/arm/mach-at91/include/mach/vmalloc.h + * + * Copyright (C) 2003 SAN People + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_VMALLOC_H +#define __ASM_ARCH_VMALLOC_H + +#include + +#define VMALLOC_END (AT91_VIRT_BASE & PGDIR_MASK) + +#endif diff --git a/trunk/arch/arm/mach-at91/setup.c b/trunk/arch/arm/mach-at91/setup.c index cf98a8f94dc5..aa64294c7db3 100644 --- a/trunk/arch/arm/mach-at91/setup.c +++ b/trunk/arch/arm/mach-at91/setup.c @@ -73,6 +73,24 @@ static struct map_desc at91_io_desc __initdata = { .type = MT_DEVICE, }; +void __iomem *at91_ioremap(unsigned long p, size_t size, unsigned int type) +{ + if (p >= AT91_BASE_SYS && p <= (AT91_BASE_SYS + SZ_16K - 1)) + return (void __iomem *)AT91_IO_P2V(p); + + return __arm_ioremap_caller(p, size, type, __builtin_return_address(0)); +} +EXPORT_SYMBOL(at91_ioremap); + +void at91_iounmap(volatile void __iomem *addr) +{ + unsigned long virt = (unsigned long)addr; + + if (virt >= VMALLOC_START && virt < VMALLOC_END) + __iounmap(addr); +} +EXPORT_SYMBOL(at91_iounmap); + #define AT91_DBGU0 0xfffff200 #define AT91_DBGU1 0xffffee00 diff --git a/trunk/arch/arm/mach-bcmring/arch.c b/trunk/arch/arm/mach-bcmring/arch.c index 9e5e7552498c..31a143592c81 100644 --- a/trunk/arch/arm/mach-bcmring/arch.c +++ b/trunk/arch/arm/mach-bcmring/arch.c @@ -49,29 +49,7 @@ HW_DECLARE_SPINLOCK(gpio) #endif /* sysctl */ -static int bcmring_arch_warm_reboot; /* do a warm reboot on hard reset */ - -static void bcmring_restart(char mode, const char *cmd) -{ - printk("arch_reset:%c %x\n", mode, bcmring_arch_warm_reboot); - - if (mode == 'h') { - /* Reboot configured in proc entry */ - if (bcmring_arch_warm_reboot) { - printk("warm reset\n"); - /* Issue Warm reset (do not reset ethernet switch, keep alive) */ - chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_WARM); - } else { - /* Force reset of everything */ - printk("force reset\n"); - chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_SOFT); - } - } else { - /* Force reset of everything */ - printk("force reset\n"); - chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_SOFT); - } -} +int bcmring_arch_warm_reboot; /* do a warm reboot on hard reset */ static struct ctl_table_header *bcmring_sysctl_header; @@ -195,5 +173,4 @@ MACHINE_START(BCMRING, "BCMRING") .init_irq = bcmring_init_irq, .timer = &bcmring_timer, .init_machine = bcmring_init_machine - .restart = bcmring_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-bcmring/core.c b/trunk/arch/arm/mach-bcmring/core.c index 6b67b7e8426c..430da120a297 100644 --- a/trunk/arch/arm/mach-bcmring/core.c +++ b/trunk/arch/arm/mach-bcmring/core.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/arm/mach-bcmring/dma.c b/trunk/arch/arm/mach-bcmring/dma.c index 1a1a27dd5654..f4d4d6d174d0 100644 --- a/trunk/arch/arm/mach-bcmring/dma.c +++ b/trunk/arch/arm/mach-bcmring/dma.c @@ -1615,7 +1615,7 @@ DMA_MemType_t dma_mem_type(void *addr) { unsigned long addrVal = (unsigned long)addr; - if (addrVal >= CONSISTENT_BASE) { + if (addrVal >= VMALLOC_END) { /* NOTE: DMA virtual memory space starts at 0xFFxxxxxx */ /* dma_alloc_xxx pages are physically and virtually contiguous */ diff --git a/trunk/arch/arm/mach-bcmring/include/mach/system.h b/trunk/arch/arm/mach-bcmring/include/mach/system.h index cb78250db649..38b37060d426 100644 --- a/trunk/arch/arm/mach-bcmring/include/mach/system.h +++ b/trunk/arch/arm/mach-bcmring/include/mach/system.h @@ -20,9 +20,35 @@ #ifndef __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H +#include + +extern int bcmring_arch_warm_reboot; + static inline void arch_idle(void) { cpu_do_idle(); } +static inline void arch_reset(char mode, const char *cmd) +{ + printk("arch_reset:%c %x\n", mode, bcmring_arch_warm_reboot); + + if (mode == 'h') { + /* Reboot configured in proc entry */ + if (bcmring_arch_warm_reboot) { + printk("warm reset\n"); + /* Issue Warm reset (do not reset ethernet switch, keep alive) */ + chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_WARM); + } else { + /* Force reset of everything */ + printk("force reset\n"); + chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_SOFT); + } + } else { + /* Force reset of everything */ + printk("force reset\n"); + chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_SOFT); + } +} + #endif diff --git a/trunk/arch/arm/mach-bcmring/include/mach/vmalloc.h b/trunk/arch/arm/mach-bcmring/include/mach/vmalloc.h new file mode 100644 index 000000000000..7397bd7817d9 --- /dev/null +++ b/trunk/arch/arm/mach-bcmring/include/mach/vmalloc.h @@ -0,0 +1,25 @@ +/* + * + * Copyright (C) 2000 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Move VMALLOC_END to 0xf0000000 so that the vm space can range from + * 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles + * larger physical memory designs better. + */ +#define VMALLOC_END 0xf0000000UL diff --git a/trunk/arch/arm/mach-clps711x/Makefile b/trunk/arch/arm/mach-clps711x/Makefile index f2f0256232e3..4a197315f0cf 100644 --- a/trunk/arch/arm/mach-clps711x/Makefile +++ b/trunk/arch/arm/mach-clps711x/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-y := common.o +obj-y := irq.o mm.o time.o obj-m := obj-n := obj- := diff --git a/trunk/arch/arm/mach-clps711x/autcpu12.c b/trunk/arch/arm/mach-clps711x/autcpu12.c index 3fb79a1d0bde..0276091b7f86 100644 --- a/trunk/arch/arm/mach-clps711x/autcpu12.c +++ b/trunk/arch/arm/mach-clps711x/autcpu12.c @@ -68,6 +68,5 @@ MACHINE_START(AUTCPU12, "autronix autcpu12") .map_io = autcpu12_map_io, .init_irq = clps711x_init_irq, .timer = &clps711x_timer, - .restart = clps711x_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-clps711x/cdb89712.c b/trunk/arch/arm/mach-clps711x/cdb89712.c index c314f49d6ef6..25b3bfd0e85a 100644 --- a/trunk/arch/arm/mach-clps711x/cdb89712.c +++ b/trunk/arch/arm/mach-clps711x/cdb89712.c @@ -59,5 +59,4 @@ MACHINE_START(CDB89712, "Cirrus-CDB89712") .map_io = cdb89712_map_io, .init_irq = clps711x_init_irq, .timer = &clps711x_timer, - .restart = clps711x_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-clps711x/ceiva.c b/trunk/arch/arm/mach-clps711x/ceiva.c index a70147e347ac..1df9ec67aa92 100644 --- a/trunk/arch/arm/mach-clps711x/ceiva.c +++ b/trunk/arch/arm/mach-clps711x/ceiva.c @@ -60,5 +60,4 @@ MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame") .map_io = ceiva_map_io, .init_irq = clps711x_init_irq, .timer = &clps711x_timer, - .restart = clps711x_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-clps711x/clep7312.c b/trunk/arch/arm/mach-clps711x/clep7312.c index dbc7842639dc..80496c09ac59 100644 --- a/trunk/arch/arm/mach-clps711x/clep7312.c +++ b/trunk/arch/arm/mach-clps711x/clep7312.c @@ -41,6 +41,5 @@ MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312") .map_io = clps711x_map_io, .init_irq = clps711x_init_irq, .timer = &clps711x_timer, - .restart = clps711x_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-clps711x/common.h b/trunk/arch/arm/mach-clps711x/common.h index fc0f0650dcb5..2b8b801f1dc3 100644 --- a/trunk/arch/arm/mach-clps711x/common.h +++ b/trunk/arch/arm/mach-clps711x/common.h @@ -9,4 +9,3 @@ struct sys_timer; extern void clps711x_map_io(void); extern void clps711x_init_irq(void); extern struct sys_timer clps711x_timer; -extern void clps711x_restart(char mode, const char *cmd); diff --git a/trunk/arch/arm/mach-clps711x/edb7211-arch.c b/trunk/arch/arm/mach-clps711x/edb7211-arch.c index 5fad0b4f40ad..9721f6111dc0 100644 --- a/trunk/arch/arm/mach-clps711x/edb7211-arch.c +++ b/trunk/arch/arm/mach-clps711x/edb7211-arch.c @@ -62,5 +62,4 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)") .reserve = edb7211_reserve, .init_irq = clps711x_init_irq, .timer = &clps711x_timer, - .restart = clps711x_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-clps711x/fortunet.c b/trunk/arch/arm/mach-clps711x/fortunet.c index 3a3f0b702cb4..d99256687298 100644 --- a/trunk/arch/arm/mach-clps711x/fortunet.c +++ b/trunk/arch/arm/mach-clps711x/fortunet.c @@ -78,5 +78,4 @@ MACHINE_START(FORTUNET, "ARM-FortuNet") .map_io = clps711x_map_io, .init_irq = clps711x_init_irq, .timer = &clps711x_timer, - .restart = clps711x_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-clps711x/include/mach/system.h b/trunk/arch/arm/mach-clps711x/include/mach/system.h index 23d6ef8c84da..f916cd7a477d 100644 --- a/trunk/arch/arm/mach-clps711x/include/mach/system.h +++ b/trunk/arch/arm/mach-clps711x/include/mach/system.h @@ -32,4 +32,9 @@ static inline void arch_idle(void) mov r0, r0"); } +static inline void arch_reset(char mode, const char *cmd) +{ + cpu_reset(0); +} + #endif diff --git a/trunk/arch/arm/mach-clps711x/include/mach/vmalloc.h b/trunk/arch/arm/mach-clps711x/include/mach/vmalloc.h new file mode 100644 index 000000000000..467b96137e47 --- /dev/null +++ b/trunk/arch/arm/mach-clps711x/include/mach/vmalloc.h @@ -0,0 +1,20 @@ +/* + * arch/arm/mach-clps711x/include/mach/vmalloc.h + * + * Copyright (C) 2000 Deep Blue Solutions Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define VMALLOC_END 0xd0000000UL diff --git a/trunk/arch/arm/mach-clps711x/common.c b/trunk/arch/arm/mach-clps711x/irq.c similarity index 58% rename from trunk/arch/arm/mach-clps711x/common.c rename to trunk/arch/arm/mach-clps711x/irq.c index ab1711b9b4d6..c2eceee645e3 100644 --- a/trunk/arch/arm/mach-clps711x/common.c +++ b/trunk/arch/arm/mach-clps711x/irq.c @@ -1,9 +1,7 @@ /* - * linux/arch/arm/mach-clps711x/core.c + * linux/arch/arm/mach-clps711x/irq.c * - * Core support for the CLPS711x-based machines. - * - * Copyright (C) 2001,2011 Deep Blue Solutions Ltd + * Copyright (C) 2000 Deep Blue Solutions Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,41 +17,15 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include #include -#include +#include #include -#include -#include -#include -#include +#include #include #include -#include -#include -#include -#include -#include -#include - -/* - * This maps the generic CLPS711x registers - */ -static struct map_desc clps711x_io_desc[] __initdata = { - { - .virtual = CLPS7111_VIRT_BASE, - .pfn = __phys_to_pfn(CLPS7111_PHYS_BASE), - .length = SZ_1M, - .type = MT_DEVICE - } -}; -void __init clps711x_map_io(void) -{ - iotable_init(clps711x_io_desc, ARRAY_SIZE(clps711x_io_desc)); -} +#include static void int1_mask(struct irq_data *d) { @@ -140,15 +112,15 @@ void __init clps711x_init_irq(void) for (i = 0; i < NR_IRQS; i++) { if (INT1_IRQS & (1 << i)) { - irq_set_chip_and_handler(i, &int1_chip, + irq_set_chip_and_handler(i, &int1_chip, handle_level_irq); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } if (INT2_IRQS & (1 << i)) { irq_set_chip_and_handler(i, &int2_chip, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - } + } } /* @@ -169,59 +141,3 @@ void __init clps711x_init_irq(void) clps_writel(0, SYNCIO); clps_writel(0, KBDEOI); } - -/* - * gettimeoffset() returns time since last timer tick, in usecs. - * - * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy. - * 'tick' is usecs per jiffy. - */ -static unsigned long clps711x_gettimeoffset(void) -{ - unsigned long hwticks; - hwticks = LATCH - (clps_readl(TC2D) & 0xffff); /* since last underflow */ - return (hwticks * (tick_nsec / 1000)) / LATCH; -} - -/* - * IRQ handler for the timer - */ -static irqreturn_t p720t_timer_interrupt(int irq, void *dev_id) -{ - timer_tick(); - return IRQ_HANDLED; -} - -static struct irqaction clps711x_timer_irq = { - .name = "CLPS711x Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = p720t_timer_interrupt, -}; - -static void __init clps711x_timer_init(void) -{ - struct timespec tv; - unsigned int syscon; - - syscon = clps_readl(SYSCON1); - syscon |= SYSCON1_TC2S | SYSCON1_TC2M; - clps_writel(syscon, SYSCON1); - - clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */ - - setup_irq(IRQ_TC2OI, &clps711x_timer_irq); - - tv.tv_nsec = 0; - tv.tv_sec = clps_readl(RTCDR); - do_settimeofday(&tv); -} - -struct sys_timer clps711x_timer = { - .init = clps711x_timer_init, - .offset = clps711x_gettimeoffset, -}; - -void clps711x_restart(char mode, const char *cmd) -{ - soft_restart(0); -} diff --git a/trunk/arch/arm/mach-clps711x/mm.c b/trunk/arch/arm/mach-clps711x/mm.c new file mode 100644 index 000000000000..986592176767 --- /dev/null +++ b/trunk/arch/arm/mach-clps711x/mm.c @@ -0,0 +1,48 @@ +/* + * linux/arch/arm/mach-clps711x/mm.c + * + * Generic MM setup for the CLPS711x-based machines. + * + * Copyright (C) 2001 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * This maps the generic CLPS711x registers + */ +static struct map_desc clps711x_io_desc[] __initdata = { + { + .virtual = CLPS7111_VIRT_BASE, + .pfn = __phys_to_pfn(CLPS7111_PHYS_BASE), + .length = SZ_1M, + .type = MT_DEVICE + } +}; + +void __init clps711x_map_io(void) +{ + iotable_init(clps711x_io_desc, ARRAY_SIZE(clps711x_io_desc)); +} diff --git a/trunk/arch/arm/mach-clps711x/p720t.c b/trunk/arch/arm/mach-clps711x/p720t.c index 42ee8f33eafb..6ecea95f38b2 100644 --- a/trunk/arch/arm/mach-clps711x/p720t.c +++ b/trunk/arch/arm/mach-clps711x/p720t.c @@ -93,7 +93,6 @@ MACHINE_START(P720T, "ARM-Prospector720T") .map_io = p720t_map_io, .init_irq = clps711x_init_irq, .timer = &clps711x_timer, - .restart = clps711x_restart, MACHINE_END static int p720t_hw_init(void) diff --git a/trunk/arch/arm/mach-clps711x/time.c b/trunk/arch/arm/mach-clps711x/time.c new file mode 100644 index 000000000000..d581ef0bcd24 --- /dev/null +++ b/trunk/arch/arm/mach-clps711x/time.c @@ -0,0 +1,84 @@ +/* + * linux/arch/arm/mach-clps711x/time.c + * + * Copyright (C) 2001 Deep Blue Solutions Ltd. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + + +/* + * gettimeoffset() returns time since last timer tick, in usecs. + * + * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy. + * 'tick' is usecs per jiffy. + */ +static unsigned long clps711x_gettimeoffset(void) +{ + unsigned long hwticks; + hwticks = LATCH - (clps_readl(TC2D) & 0xffff); /* since last underflow */ + return (hwticks * (tick_nsec / 1000)) / LATCH; +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t +p720t_timer_interrupt(int irq, void *dev_id) +{ + timer_tick(); + return IRQ_HANDLED; +} + +static struct irqaction clps711x_timer_irq = { + .name = "CLPS711x Timer Tick", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = p720t_timer_interrupt, +}; + +static void __init clps711x_timer_init(void) +{ + struct timespec tv; + unsigned int syscon; + + syscon = clps_readl(SYSCON1); + syscon |= SYSCON1_TC2S | SYSCON1_TC2M; + clps_writel(syscon, SYSCON1); + + clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */ + + setup_irq(IRQ_TC2OI, &clps711x_timer_irq); + + tv.tv_nsec = 0; + tv.tv_sec = clps_readl(RTCDR); + do_settimeofday(&tv); +} + +struct sys_timer clps711x_timer = { + .init = clps711x_timer_init, + .offset = clps711x_gettimeoffset, +}; diff --git a/trunk/arch/arm/mach-cns3xxx/cns3420vb.c b/trunk/arch/arm/mach-cns3xxx/cns3420vb.c index 2c5fb4c7e509..55f7b4b08ab9 100644 --- a/trunk/arch/arm/mach-cns3xxx/cns3420vb.c +++ b/trunk/arch/arm/mach-cns3xxx/cns3420vb.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -202,7 +201,5 @@ MACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board") .map_io = cns3420_map_io, .init_irq = cns3xxx_init_irq, .timer = &cns3xxx_timer, - .handle_irq = gic_handle_irq, .init_machine = cns3420_init, - .restart = cns3xxx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-cns3xxx/core.h b/trunk/arch/arm/mach-cns3xxx/core.h index 4894b8c17151..fcd225343c61 100644 --- a/trunk/arch/arm/mach-cns3xxx/core.h +++ b/trunk/arch/arm/mach-cns3xxx/core.h @@ -22,6 +22,5 @@ static inline void cns3xxx_l2x0_init(void) {} void __init cns3xxx_map_io(void); void __init cns3xxx_init_irq(void); void cns3xxx_power_off(void); -void cns3xxx_restart(char, const char *); #endif /* __CNS3XXX_CORE_H */ diff --git a/trunk/arch/arm/mach-cns3xxx/include/mach/entry-macro.S b/trunk/arch/arm/mach-cns3xxx/include/mach/entry-macro.S index 01c57df5f716..d87bfc397d39 100644 --- a/trunk/arch/arm/mach-cns3xxx/include/mach/entry-macro.S +++ b/trunk/arch/arm/mach-cns3xxx/include/mach/entry-macro.S @@ -8,6 +8,8 @@ * published by the Free Software Foundation. */ +#include + .macro disable_fiq .endm diff --git a/trunk/arch/arm/mach-cns3xxx/include/mach/system.h b/trunk/arch/arm/mach-cns3xxx/include/mach/system.h index 9e56b7dc133a..4f16c9b79f78 100644 --- a/trunk/arch/arm/mach-cns3xxx/include/mach/system.h +++ b/trunk/arch/arm/mach-cns3xxx/include/mach/system.h @@ -11,6 +11,7 @@ #ifndef __MACH_SYSTEM_H #define __MACH_SYSTEM_H +#include #include static inline void arch_idle(void) @@ -22,4 +23,6 @@ static inline void arch_idle(void) cpu_do_idle(); } +void arch_reset(char mode, const char *cmd); + #endif diff --git a/trunk/arch/arm/mach-cns3xxx/include/mach/vmalloc.h b/trunk/arch/arm/mach-cns3xxx/include/mach/vmalloc.h new file mode 100644 index 000000000000..1dd231d2f772 --- /dev/null +++ b/trunk/arch/arm/mach-cns3xxx/include/mach/vmalloc.h @@ -0,0 +1,11 @@ +/* + * Copyright 2000 Russell King. + * Copyright 2003 ARM Limited + * Copyright 2008 Cavium Networks + * + * This file 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. + */ + +#define VMALLOC_END 0xd8000000UL diff --git a/trunk/arch/arm/mach-cns3xxx/pm.c b/trunk/arch/arm/mach-cns3xxx/pm.c index 36458080332a..0c04678615ce 100644 --- a/trunk/arch/arm/mach-cns3xxx/pm.c +++ b/trunk/arch/arm/mach-cns3xxx/pm.c @@ -11,9 +11,9 @@ #include #include #include +#include #include #include -#include "core.h" void cns3xxx_pwr_clk_en(unsigned int block) { @@ -89,7 +89,7 @@ void cns3xxx_pwr_soft_rst(unsigned int block) } EXPORT_SYMBOL(cns3xxx_pwr_soft_rst); -void cns3xxx_restart(char mode, const char *cmd) +void arch_reset(char mode, const char *cmd) { /* * To reset, we hit the on-board reset register diff --git a/trunk/arch/arm/mach-davinci/Makefile b/trunk/arch/arm/mach-davinci/Makefile index 2db78bd5c835..495e31306fc0 100644 --- a/trunk/arch/arm/mach-davinci/Makefile +++ b/trunk/arch/arm/mach-davinci/Makefile @@ -4,7 +4,7 @@ # # Common objects -obj-y := time.o clock.o serial.o psc.o \ +obj-y := time.o clock.o serial.o io.o psc.o \ dma.o usb.o common.o sram.o aemif.o obj-$(CONFIG_DAVINCI_MUX) += mux.o diff --git a/trunk/arch/arm/mach-davinci/board-da830-evm.c b/trunk/arch/arm/mach-davinci/board-da830-evm.c index dc1afe5be20c..11c3db985285 100644 --- a/trunk/arch/arm/mach-davinci/board-da830-evm.c +++ b/trunk/arch/arm/mach-davinci/board-da830-evm.c @@ -682,5 +682,4 @@ MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM") .timer = &davinci_timer, .init_machine = da830_evm_init, .dma_zone_size = SZ_128M, - .restart = da8xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-da850-evm.c b/trunk/arch/arm/mach-davinci/board-da850-evm.c index f8a682f60a42..6659a90dbcad 100644 --- a/trunk/arch/arm/mach-davinci/board-da850-evm.c +++ b/trunk/arch/arm/mach-davinci/board-da850-evm.c @@ -1411,5 +1411,4 @@ MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM") .timer = &davinci_timer, .init_machine = da850_evm_init, .dma_zone_size = SZ_128M, - .restart = da8xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-dm355-evm.c b/trunk/arch/arm/mach-davinci/board-dm355-evm.c index 275341f159fb..4e0e707c313d 100644 --- a/trunk/arch/arm/mach-davinci/board-dm355-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm355-evm.c @@ -357,5 +357,4 @@ MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM") .timer = &davinci_timer, .init_machine = dm355_evm_init, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-dm355-leopard.c b/trunk/arch/arm/mach-davinci/board-dm355-leopard.c index e99db28181ae..ff2d2413279a 100644 --- a/trunk/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/trunk/arch/arm/mach-davinci/board-dm355-leopard.c @@ -276,5 +276,4 @@ MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard") .timer = &davinci_timer, .init_machine = dm355_leopard_init, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-dm365-evm.c b/trunk/arch/arm/mach-davinci/board-dm365-evm.c index 346e1de2f5a8..46e1f4173b97 100644 --- a/trunk/arch/arm/mach-davinci/board-dm365-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm365-evm.c @@ -618,6 +618,5 @@ MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM") .timer = &davinci_timer, .init_machine = dm365_evm_init, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-dm644x-evm.c b/trunk/arch/arm/mach-davinci/board-dm644x-evm.c index a64b49cfedca..0cf8abf78d33 100644 --- a/trunk/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm644x-evm.c @@ -719,5 +719,4 @@ MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM") .timer = &davinci_timer, .init_machine = davinci_evm_init, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-dm646x-evm.c b/trunk/arch/arm/mach-davinci/board-dm646x-evm.c index 64017558860b..635bf7740157 100644 --- a/trunk/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/trunk/arch/arm/mach-davinci/board-dm646x-evm.c @@ -799,7 +799,6 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM") .timer = &davinci_timer, .init_machine = evm_init, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM") @@ -809,6 +808,5 @@ MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM") .timer = &davinci_timer, .init_machine = evm_init, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-mityomapl138.c b/trunk/arch/arm/mach-davinci/board-mityomapl138.c index 672d820e2aa4..3cfff555e8f2 100644 --- a/trunk/arch/arm/mach-davinci/board-mityomapl138.c +++ b/trunk/arch/arm/mach-davinci/board-mityomapl138.c @@ -573,5 +573,4 @@ MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808") .timer = &davinci_timer, .init_machine = mityomapl138_init, .dma_zone_size = SZ_128M, - .restart = da8xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-neuros-osd2.c b/trunk/arch/arm/mach-davinci/board-neuros-osd2.c index 6c4a16415d47..e5f231aefee4 100644 --- a/trunk/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/trunk/arch/arm/mach-davinci/board-neuros-osd2.c @@ -278,5 +278,4 @@ MACHINE_START(NEUROS_OSD2, "Neuros OSD2") .timer = &davinci_timer, .init_machine = davinci_ntosd2_init, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c b/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c index e7c0c7c53493..c6701e4a795c 100644 --- a/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/trunk/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -344,5 +344,4 @@ MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard") .timer = &davinci_timer, .init_machine = omapl138_hawk_init, .dma_zone_size = SZ_128M, - .restart = da8xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-sffsdr.c b/trunk/arch/arm/mach-davinci/board-sffsdr.c index 0b136a831c59..5dd4da9d2308 100644 --- a/trunk/arch/arm/mach-davinci/board-sffsdr.c +++ b/trunk/arch/arm/mach-davinci/board-sffsdr.c @@ -157,5 +157,4 @@ MACHINE_START(SFFSDR, "Lyrtech SFFSDR") .timer = &davinci_timer, .init_machine = davinci_sffsdr_init, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/board-tnetv107x-evm.c b/trunk/arch/arm/mach-davinci/board-tnetv107x-evm.c index 5f14e30b00d8..f69e40a29e02 100644 --- a/trunk/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/trunk/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -283,5 +283,4 @@ MACHINE_START(TNETV107X, "TNETV107X EVM") .timer = &davinci_timer, .init_machine = tnetv107x_evm_board_init, .dma_zone_size = SZ_128M, - .restart = tnetv107x_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-davinci/common.c b/trunk/arch/arm/mach-davinci/common.c index cb9b2e47510c..865ffe5899ac 100644 --- a/trunk/arch/arm/mach-davinci/common.c +++ b/trunk/arch/arm/mach-davinci/common.c @@ -97,6 +97,9 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) local_flush_tlb_all(); flush_cache_all(); + if (!davinci_soc_info.reset) + davinci_soc_info.reset = davinci_watchdog_reset; + /* * We want to check CPU revision early for cpu_is_xxxx() macros. * IO space mapping must be initialized before we can do that. diff --git a/trunk/arch/arm/mach-davinci/da830.c b/trunk/arch/arm/mach-davinci/da830.c index deee5c2da754..a6bf5dcaef13 100644 --- a/trunk/arch/arm/mach-davinci/da830.c +++ b/trunk/arch/arm/mach-davinci/da830.c @@ -1201,6 +1201,7 @@ static struct davinci_soc_info davinci_soc_info_da830 = { .gpio_irq = IRQ_DA8XX_GPIO0, .serial_dev = &da8xx_serial_device, .emac_pdata = &da8xx_emac_pdata, + .reset_device = &da8xx_wdt_device, }; void __init da830_init(void) diff --git a/trunk/arch/arm/mach-davinci/da850.c b/trunk/arch/arm/mach-davinci/da850.c index 0ed7fdb64efb..b047f8702278 100644 --- a/trunk/arch/arm/mach-davinci/da850.c +++ b/trunk/arch/arm/mach-davinci/da850.c @@ -1121,6 +1121,7 @@ static struct davinci_soc_info davinci_soc_info_da850 = { .emac_pdata = &da8xx_emac_pdata, .sram_dma = DA8XX_ARM_RAM_BASE, .sram_len = SZ_8K, + .reset_device = &da8xx_wdt_device, }; void __init da850_init(void) diff --git a/trunk/arch/arm/mach-davinci/devices-da8xx.c b/trunk/arch/arm/mach-davinci/devices-da8xx.c index 42dbf3dc11ab..68def7188868 100644 --- a/trunk/arch/arm/mach-davinci/devices-da8xx.c +++ b/trunk/arch/arm/mach-davinci/devices-da8xx.c @@ -363,11 +363,6 @@ struct platform_device da8xx_wdt_device = { .resource = da8xx_watchdog_resources, }; -void da8xx_restart(char mode, const char *cmd) -{ - davinci_watchdog_reset(&da8xx_wdt_device); -} - int __init da8xx_register_watchdog(void) { return platform_device_register(&da8xx_wdt_device); diff --git a/trunk/arch/arm/mach-davinci/devices.c b/trunk/arch/arm/mach-davinci/devices.c index 50c0156b4262..806a2f02b980 100644 --- a/trunk/arch/arm/mach-davinci/devices.c +++ b/trunk/arch/arm/mach-davinci/devices.c @@ -291,11 +291,6 @@ struct platform_device davinci_wdt_device = { .resource = wdt_resources, }; -void davinci_restart(char mode, const char *cmd) -{ - davinci_watchdog_reset(&davinci_wdt_device); -} - static void davinci_init_wdt(void) { platform_device_register(&davinci_wdt_device); diff --git a/trunk/arch/arm/mach-davinci/dm355.c b/trunk/arch/arm/mach-davinci/dm355.c index 19667cfc5de0..fe520d4167a2 100644 --- a/trunk/arch/arm/mach-davinci/dm355.c +++ b/trunk/arch/arm/mach-davinci/dm355.c @@ -853,6 +853,7 @@ static struct davinci_soc_info davinci_soc_info_dm355 = { .serial_dev = &dm355_serial_device, .sram_dma = 0x00010000, .sram_len = SZ_32K, + .reset_device = &davinci_wdt_device, }; void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata) diff --git a/trunk/arch/arm/mach-davinci/dm365.c b/trunk/arch/arm/mach-davinci/dm365.c index f15b435cc655..679e168dce34 100644 --- a/trunk/arch/arm/mach-davinci/dm365.c +++ b/trunk/arch/arm/mach-davinci/dm365.c @@ -1083,6 +1083,7 @@ static struct davinci_soc_info davinci_soc_info_dm365 = { .emac_pdata = &dm365_emac_pdata, .sram_dma = 0x00010000, .sram_len = SZ_32K, + .reset_device = &davinci_wdt_device, }; void __init dm365_init_asp(struct snd_platform_data *pdata) diff --git a/trunk/arch/arm/mach-davinci/dm644x.c b/trunk/arch/arm/mach-davinci/dm644x.c index 0800f9cf33bb..3470983aa343 100644 --- a/trunk/arch/arm/mach-davinci/dm644x.c +++ b/trunk/arch/arm/mach-davinci/dm644x.c @@ -767,6 +767,7 @@ static struct davinci_soc_info davinci_soc_info_dm644x = { .emac_pdata = &dm644x_emac_pdata, .sram_dma = 0x00008000, .sram_len = SZ_16K, + .reset_device = &davinci_wdt_device, }; void __init dm644x_init_asp(struct snd_platform_data *pdata) diff --git a/trunk/arch/arm/mach-davinci/dm646x.c b/trunk/arch/arm/mach-davinci/dm646x.c index 00f774394b16..af27c130595f 100644 --- a/trunk/arch/arm/mach-davinci/dm646x.c +++ b/trunk/arch/arm/mach-davinci/dm646x.c @@ -854,6 +854,7 @@ static struct davinci_soc_info davinci_soc_info_dm646x = { .emac_pdata = &dm646x_emac_pdata, .sram_dma = 0x10010000, .sram_len = SZ_32K, + .reset_device = &davinci_wdt_device, }; void __init dm646x_init_mcasp0(struct snd_platform_data *pdata) diff --git a/trunk/arch/arm/mach-davinci/include/mach/common.h b/trunk/arch/arm/mach-davinci/include/mach/common.h index 5cd39a4e0c96..a57cba21e21e 100644 --- a/trunk/arch/arm/mach-davinci/include/mach/common.h +++ b/trunk/arch/arm/mach-davinci/include/mach/common.h @@ -77,13 +77,14 @@ struct davinci_soc_info { struct emac_platform_data *emac_pdata; dma_addr_t sram_dma; unsigned sram_len; + struct platform_device *reset_device; + void (*reset)(struct platform_device *); }; extern struct davinci_soc_info davinci_soc_info; extern void davinci_common_init(struct davinci_soc_info *soc_info); extern void davinci_init_ide(void); -void davinci_restart(char mode, const char *cmd); /* standard place to map on-chip SRAMs; they *may* support DMA */ #define SRAM_VIRT 0xfffe0000 diff --git a/trunk/arch/arm/mach-davinci/include/mach/da8xx.h b/trunk/arch/arm/mach-davinci/include/mach/da8xx.h index ee3461d7ec1b..eaca7d8b9d68 100644 --- a/trunk/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/trunk/arch/arm/mach-davinci/include/mach/da8xx.h @@ -91,7 +91,6 @@ int da8xx_register_cpuidle(void); void __iomem * __init da8xx_get_mem_ctlr(void); int da850_register_pm(struct platform_device *pdev); int __init da850_register_sata(unsigned long refclkpn); -void da8xx_restart(char mode, const char *cmd); extern struct platform_device da8xx_serial_device; extern struct emac_platform_data da8xx_emac_pdata; diff --git a/trunk/arch/arm/mach-davinci/include/mach/io.h b/trunk/arch/arm/mach-davinci/include/mach/io.h index b2267d1e1a71..d1b954955c12 100644 --- a/trunk/arch/arm/mach-davinci/include/mach/io.h +++ b/trunk/arch/arm/mach-davinci/include/mach/io.h @@ -21,4 +21,12 @@ #define __mem_pci(a) (a) #define __mem_isa(a) (a) +#ifndef __ASSEMBLER__ +#define __arch_ioremap davinci_ioremap +#define __arch_iounmap davinci_iounmap + +void __iomem *davinci_ioremap(unsigned long phys, size_t size, + unsigned int type); +void davinci_iounmap(volatile void __iomem *addr); +#endif #endif /* __ASM_ARCH_IO_H */ diff --git a/trunk/arch/arm/mach-davinci/include/mach/system.h b/trunk/arch/arm/mach-davinci/include/mach/system.h index fcb7a015aba5..e65629c20769 100644 --- a/trunk/arch/arm/mach-davinci/include/mach/system.h +++ b/trunk/arch/arm/mach-davinci/include/mach/system.h @@ -18,4 +18,10 @@ static inline void arch_idle(void) cpu_do_idle(); } +static inline void arch_reset(char mode, const char *cmd) +{ + if (davinci_soc_info.reset) + davinci_soc_info.reset(davinci_soc_info.reset_device); +} + #endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/trunk/arch/arm/mach-davinci/include/mach/tnetv107x.h b/trunk/arch/arm/mach-davinci/include/mach/tnetv107x.h index 83e5926f3c46..89c1fdc63c0b 100644 --- a/trunk/arch/arm/mach-davinci/include/mach/tnetv107x.h +++ b/trunk/arch/arm/mach-davinci/include/mach/tnetv107x.h @@ -54,7 +54,6 @@ extern struct platform_device tnetv107x_serial_device; extern void __init tnetv107x_init(void); extern void __init tnetv107x_devices_init(struct tnetv107x_device_info *); extern void __init tnetv107x_irq_init(void); -void tnetv107x_restart(char mode, const char *cmd); #endif diff --git a/trunk/arch/arm/mach-davinci/include/mach/vmalloc.h b/trunk/arch/arm/mach-davinci/include/mach/vmalloc.h new file mode 100644 index 000000000000..d49646a8e206 --- /dev/null +++ b/trunk/arch/arm/mach-davinci/include/mach/vmalloc.h @@ -0,0 +1,14 @@ +/* + * DaVinci vmalloc definitions + * + * Author: Kevin Hilman, MontaVista Software, Inc. + * + * 2007 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include + +/* Allow vmalloc range until the IO virtual range minus a 2M "hole" */ +#define VMALLOC_END (IO_VIRT - (2<<20)) diff --git a/trunk/arch/arm/mach-davinci/io.c b/trunk/arch/arm/mach-davinci/io.c new file mode 100644 index 000000000000..8ea60a8b2495 --- /dev/null +++ b/trunk/arch/arm/mach-davinci/io.c @@ -0,0 +1,48 @@ +/* + * DaVinci I/O mapping code + * + * Copyright (C) 2005-2006 Texas Instruments + * + * 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. + */ + +#include +#include + +#include +#include + +#include + +/* + * Intercept ioremap() requests for addresses in our fixed mapping regions. + */ +void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type) +{ + struct map_desc *desc = davinci_soc_info.io_desc; + int desc_num = davinci_soc_info.io_desc_num; + int i; + + for (i = 0; i < desc_num; i++, desc++) { + unsigned long iophys = __pfn_to_phys(desc->pfn); + unsigned long iosize = desc->length; + + if (p >= iophys && (p + size) <= (iophys + iosize)) + return __io(desc->virtual + p - iophys); + } + + return __arm_ioremap_caller(p, size, type, + __builtin_return_address(0)); +} +EXPORT_SYMBOL(davinci_ioremap); + +void davinci_iounmap(volatile void __iomem *addr) +{ + unsigned long virt = (unsigned long)addr; + + if (virt >= VMALLOC_START && virt < VMALLOC_END) + __iounmap(addr); +} +EXPORT_SYMBOL(davinci_iounmap); diff --git a/trunk/arch/arm/mach-davinci/tnetv107x.c b/trunk/arch/arm/mach-davinci/tnetv107x.c index dc1a209b9b66..409bb869c7c7 100644 --- a/trunk/arch/arm/mach-davinci/tnetv107x.c +++ b/trunk/arch/arm/mach-davinci/tnetv107x.c @@ -730,11 +730,6 @@ static void tnetv107x_watchdog_reset(struct platform_device *pdev) __raw_writel(1, ®s->kick); } -void tnetv107x_restart(char mode, const char *cmd) -{ - tnetv107x_watchdog_reset(&tnetv107x_wdt_device); -} - static struct davinci_soc_info tnetv107x_soc_info = { .io_desc = io_desc, .io_desc_num = ARRAY_SIZE(io_desc), @@ -757,6 +752,8 @@ static struct davinci_soc_info tnetv107x_soc_info = { .gpio_num = TNETV107X_N_GPIO, .timer_info = &timer_info, .serial_dev = &tnetv107x_serial_device, + .reset = tnetv107x_watchdog_reset, + .reset_device = &tnetv107x_wdt_device, }; void __init tnetv107x_init(void) diff --git a/trunk/arch/arm/mach-dove/cm-a510.c b/trunk/arch/arm/mach-dove/cm-a510.c index 792b4e2e24f1..c8a406f7e946 100644 --- a/trunk/arch/arm/mach-dove/cm-a510.c +++ b/trunk/arch/arm/mach-dove/cm-a510.c @@ -93,5 +93,4 @@ MACHINE_START(CM_A510, "Compulab CM-A510 Board") .init_early = dove_init_early, .init_irq = dove_init_irq, .timer = &dove_timer, - .restart = dove_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-dove/common.c b/trunk/arch/arm/mach-dove/common.c index 13bb236cd0cd..a9e0dae86a26 100644 --- a/trunk/arch/arm/mach-dove/common.c +++ b/trunk/arch/arm/mach-dove/common.c @@ -292,19 +292,3 @@ void __init dove_init(void) dove_xor0_init(); dove_xor1_init(); } - -void dove_restart(char mode, const char *cmd) -{ - /* - * Enable soft reset to assert RSTOUTn. - */ - writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK); - - /* - * Assert soft reset. - */ - writel(SOFT_RESET, SYSTEM_SOFT_RESET); - - while (1) - ; -} diff --git a/trunk/arch/arm/mach-dove/common.h b/trunk/arch/arm/mach-dove/common.h index 42027305c107..6a2046e44706 100644 --- a/trunk/arch/arm/mach-dove/common.h +++ b/trunk/arch/arm/mach-dove/common.h @@ -39,6 +39,5 @@ void dove_spi1_init(void); void dove_i2c_init(void); void dove_sdio0_init(void); void dove_sdio1_init(void); -void dove_restart(char, const char *); #endif diff --git a/trunk/arch/arm/mach-dove/dove-db-setup.c b/trunk/arch/arm/mach-dove/dove-db-setup.c index ea77ae430b2d..11ea34e4fc76 100644 --- a/trunk/arch/arm/mach-dove/dove-db-setup.c +++ b/trunk/arch/arm/mach-dove/dove-db-setup.c @@ -100,5 +100,4 @@ MACHINE_START(DOVE_DB, "Marvell DB-MV88AP510-BP Development Board") .init_early = dove_init_early, .init_irq = dove_init_irq, .timer = &dove_timer, - .restart = dove_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-dove/include/mach/dove.h b/trunk/arch/arm/mach-dove/include/mach/dove.h index ad1165d488c1..b20ec9af7882 100644 --- a/trunk/arch/arm/mach-dove/include/mach/dove.h +++ b/trunk/arch/arm/mach-dove/include/mach/dove.h @@ -11,6 +11,8 @@ #ifndef __ASM_ARCH_DOVE_H #define __ASM_ARCH_DOVE_H +#include + /* * Marvell Dove address maps. * diff --git a/trunk/arch/arm/mach-dove/include/mach/system.h b/trunk/arch/arm/mach-dove/include/mach/system.h index 3027954f6162..356afda56853 100644 --- a/trunk/arch/arm/mach-dove/include/mach/system.h +++ b/trunk/arch/arm/mach-dove/include/mach/system.h @@ -9,9 +9,28 @@ #ifndef __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H +#include + static inline void arch_idle(void) { cpu_do_idle(); } +static inline void arch_reset(char mode, const char *cmd) +{ + /* + * Enable soft reset to assert RSTOUTn. + */ + writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK); + + /* + * Assert soft reset. + */ + writel(SOFT_RESET, SYSTEM_SOFT_RESET); + + while (1) + ; +} + + #endif diff --git a/trunk/arch/arm/mach-dove/include/mach/vmalloc.h b/trunk/arch/arm/mach-dove/include/mach/vmalloc.h new file mode 100644 index 000000000000..a28792cf761e --- /dev/null +++ b/trunk/arch/arm/mach-dove/include/mach/vmalloc.h @@ -0,0 +1,5 @@ +/* + * arch/arm/mach-dove/include/mach/vmalloc.h + */ + +#define VMALLOC_END 0xfd800000UL diff --git a/trunk/arch/arm/mach-ebsa110/core.c b/trunk/arch/arm/mach-ebsa110/core.c index 294aad07f7a0..d0ce8abdd4b6 100644 --- a/trunk/arch/arm/mach-ebsa110/core.c +++ b/trunk/arch/arm/mach-ebsa110/core.c @@ -278,19 +278,13 @@ static int __init ebsa110_init(void) arch_initcall(ebsa110_init); -static void ebsa110_restart(char mode, const char *cmd) -{ - soft_restart(0x80000000); -} - MACHINE_START(EBSA110, "EBSA110") /* Maintainer: Russell King */ .atag_offset = 0x400, .reserve_lp0 = 1, .reserve_lp2 = 1, - .restart_mode = 's', + .soft_reboot = 1, .map_io = ebsa110_map_io, .init_irq = ebsa110_init_irq, .timer = &ebsa110_timer, - .restart = ebsa110_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-ebsa110/include/mach/system.h b/trunk/arch/arm/mach-ebsa110/include/mach/system.h index 2e4af65edb6f..9a26245bf1fc 100644 --- a/trunk/arch/arm/mach-ebsa110/include/mach/system.h +++ b/trunk/arch/arm/mach-ebsa110/include/mach/system.h @@ -34,4 +34,6 @@ static inline void arch_idle(void) asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc"); } +#define arch_reset(mode, cmd) cpu_reset(0x80000000) + #endif diff --git a/trunk/arch/arm/mach-ebsa110/include/mach/vmalloc.h b/trunk/arch/arm/mach-ebsa110/include/mach/vmalloc.h new file mode 100644 index 000000000000..ea141b7a3e03 --- /dev/null +++ b/trunk/arch/arm/mach-ebsa110/include/mach/vmalloc.h @@ -0,0 +1,10 @@ +/* + * arch/arm/mach-ebsa110/include/mach/vmalloc.h + * + * Copyright (C) 1998 Russell King + * + * 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. + */ +#define VMALLOC_END 0xdf000000UL diff --git a/trunk/arch/arm/mach-ep93xx/adssphere.c b/trunk/arch/arm/mach-ep93xx/adssphere.c index 681e939407d4..0713448206a5 100644 --- a/trunk/arch/arm/mach-ep93xx/adssphere.c +++ b/trunk/arch/arm/mach-ep93xx/adssphere.c @@ -16,7 +16,6 @@ #include -#include #include #include @@ -37,8 +36,6 @@ MACHINE_START(ADSSPHERE, "ADS Sphere board") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = adssphere_init_machine, - .restart = ep93xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-ep93xx/core.c b/trunk/arch/arm/mach-ep93xx/core.c index 24203f9a6796..2432a6b7dcac 100644 --- a/trunk/arch/arm/mach-ep93xx/core.c +++ b/trunk/arch/arm/mach-ep93xx/core.c @@ -906,15 +906,3 @@ void __init ep93xx_init_devices(void) platform_device_register(&ep93xx_ohci_device); platform_device_register(&ep93xx_leds); } - -void ep93xx_restart(char mode, const char *cmd) -{ - /* - * Set then clear the SWRST bit to initiate a software reset - */ - ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_SWRST); - ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_SWRST); - - while (1) - ; -} diff --git a/trunk/arch/arm/mach-ep93xx/edb93xx.c b/trunk/arch/arm/mach-ep93xx/edb93xx.c index d115653edca3..70ef8c527d27 100644 --- a/trunk/arch/arm/mach-ep93xx/edb93xx.c +++ b/trunk/arch/arm/mach-ep93xx/edb93xx.c @@ -39,7 +39,6 @@ #include #include -#include #include #include @@ -251,10 +250,8 @@ MACHINE_START(EDB9301, "Cirrus Logic EDB9301 Evaluation Board") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, - .restart = ep93xx_restart, MACHINE_END #endif @@ -264,10 +261,8 @@ MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, - .restart = ep93xx_restart, MACHINE_END #endif @@ -277,10 +272,8 @@ MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, - .restart = ep93xx_restart, MACHINE_END #endif @@ -290,10 +283,8 @@ MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, - .restart = ep93xx_restart, MACHINE_END #endif @@ -303,10 +294,8 @@ MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, - .restart = ep93xx_restart, MACHINE_END #endif @@ -316,10 +305,8 @@ MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, - .restart = ep93xx_restart, MACHINE_END #endif @@ -329,10 +316,8 @@ MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, - .restart = ep93xx_restart, MACHINE_END #endif @@ -342,9 +327,7 @@ MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = edb93xx_init_machine, - .restart = ep93xx_restart, MACHINE_END #endif diff --git a/trunk/arch/arm/mach-ep93xx/gesbc9312.c b/trunk/arch/arm/mach-ep93xx/gesbc9312.c index af46970dc58e..45ee205856f8 100644 --- a/trunk/arch/arm/mach-ep93xx/gesbc9312.c +++ b/trunk/arch/arm/mach-ep93xx/gesbc9312.c @@ -16,7 +16,6 @@ #include -#include #include #include @@ -37,8 +36,6 @@ MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = gesbc9312_init_machine, - .restart = ep93xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-ep93xx/include/mach/entry-macro.S b/trunk/arch/arm/mach-ep93xx/include/mach/entry-macro.S index 9be6edcf9045..96b85e2c2c0b 100644 --- a/trunk/arch/arm/mach-ep93xx/include/mach/entry-macro.S +++ b/trunk/arch/arm/mach-ep93xx/include/mach/entry-macro.S @@ -9,9 +9,51 @@ * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. */ +#include .macro disable_fiq .endm + .macro get_irqnr_preamble, base, tmp + .endm + .macro arch_ret_to_user, tmp1, tmp2 .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \base, =(EP93XX_AHB_VIRT_BASE) + orr \base, \base, #0x000b0000 + mov \irqnr, #0 + ldr \irqstat, [\base] @ lower 32 interrupts + cmp \irqstat, #0 + bne 1001f + + eor \base, \base, #0x00070000 + ldr \irqstat, [\base] @ upper 32 interrupts + cmp \irqstat, #0 + beq 1002f + mov \irqnr, #0x20 + +1001: + movs \tmp, \irqstat, lsl #16 + movne \irqstat, \tmp + addeq \irqnr, \irqnr, #16 + + movs \tmp, \irqstat, lsl #8 + movne \irqstat, \tmp + addeq \irqnr, \irqnr, #8 + + movs \tmp, \irqstat, lsl #4 + movne \irqstat, \tmp + addeq \irqnr, \irqnr, #4 + + movs \tmp, \irqstat, lsl #2 + movne \irqstat, \tmp + addeq \irqnr, \irqnr, #2 + + movs \tmp, \irqstat, lsl #1 + addeq \irqnr, \irqnr, #1 + orrs \base, \base, #1 + +1002: + .endm diff --git a/trunk/arch/arm/mach-ep93xx/include/mach/platform.h b/trunk/arch/arm/mach-ep93xx/include/mach/platform.h index d4c934931f9d..50660455b1d8 100644 --- a/trunk/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/trunk/arch/arm/mach-ep93xx/include/mach/platform.h @@ -66,6 +66,4 @@ void ep93xx_register_ac97(void); void ep93xx_init_devices(void); extern struct sys_timer ep93xx_timer; -void ep93xx_restart(char, const char *); - #endif diff --git a/trunk/arch/arm/mach-ep93xx/include/mach/system.h b/trunk/arch/arm/mach-ep93xx/include/mach/system.h index b5bec7cb9b52..6d661fe9d66c 100644 --- a/trunk/arch/arm/mach-ep93xx/include/mach/system.h +++ b/trunk/arch/arm/mach-ep93xx/include/mach/system.h @@ -1,7 +1,24 @@ /* * arch/arm/mach-ep93xx/include/mach/system.h */ + +#include + static inline void arch_idle(void) { cpu_do_idle(); } + +static inline void arch_reset(char mode, const char *cmd) +{ + local_irq_disable(); + + /* + * Set then clear the SWRST bit to initiate a software reset + */ + ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_SWRST); + ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_SWRST); + + while (1) + ; +} diff --git a/trunk/arch/arm/mach-ep93xx/include/mach/vmalloc.h b/trunk/arch/arm/mach-ep93xx/include/mach/vmalloc.h new file mode 100644 index 000000000000..1b3f25d03d39 --- /dev/null +++ b/trunk/arch/arm/mach-ep93xx/include/mach/vmalloc.h @@ -0,0 +1,5 @@ +/* + * arch/arm/mach-ep93xx/include/mach/vmalloc.h + */ + +#define VMALLOC_END 0xfe800000UL diff --git a/trunk/arch/arm/mach-ep93xx/micro9.c b/trunk/arch/arm/mach-ep93xx/micro9.c index 7b98084f0c97..e72f7368876e 100644 --- a/trunk/arch/arm/mach-ep93xx/micro9.c +++ b/trunk/arch/arm/mach-ep93xx/micro9.c @@ -18,7 +18,6 @@ #include -#include #include #include @@ -81,10 +80,8 @@ MACHINE_START(MICRO9, "Contec Micro9-High") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = micro9_init_machine, - .restart = ep93xx_restart, MACHINE_END #endif @@ -94,10 +91,8 @@ MACHINE_START(MICRO9M, "Contec Micro9-Mid") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = micro9_init_machine, - .restart = ep93xx_restart, MACHINE_END #endif @@ -107,10 +102,8 @@ MACHINE_START(MICRO9L, "Contec Micro9-Lite") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = micro9_init_machine, - .restart = ep93xx_restart, MACHINE_END #endif @@ -120,9 +113,7 @@ MACHINE_START(MICRO9S, "Contec Micro9-Slim") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = micro9_init_machine, - .restart = ep93xx_restart, MACHINE_END #endif diff --git a/trunk/arch/arm/mach-ep93xx/simone.c b/trunk/arch/arm/mach-ep93xx/simone.c index f4e553eca21c..52e090dc9d27 100644 --- a/trunk/arch/arm/mach-ep93xx/simone.c +++ b/trunk/arch/arm/mach-ep93xx/simone.c @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -81,8 +80,6 @@ MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = simone_init_machine, - .restart = ep93xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-ep93xx/snappercl15.c b/trunk/arch/arm/mach-ep93xx/snappercl15.c index fd846331ddff..8121e3aedc0a 100644 --- a/trunk/arch/arm/mach-ep93xx/snappercl15.c +++ b/trunk/arch/arm/mach-ep93xx/snappercl15.c @@ -31,7 +31,6 @@ #include #include -#include #include #include @@ -178,8 +177,6 @@ MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15") .atag_offset = 0x100, .map_io = ep93xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = snappercl15_init_machine, - .restart = ep93xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-ep93xx/ts72xx.c b/trunk/arch/arm/mach-ep93xx/ts72xx.c index 79f8ecf07a19..8b2f1435bcac 100644 --- a/trunk/arch/arm/mach-ep93xx/ts72xx.c +++ b/trunk/arch/arm/mach-ep93xx/ts72xx.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -248,8 +247,6 @@ MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC") .atag_offset = 0x100, .map_io = ts72xx_map_io, .init_irq = ep93xx_init_irq, - .handle_irq = vic_handle_irq, .timer = &ep93xx_timer, .init_machine = ts72xx_init_machine, - .restart = ep93xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-ep93xx/vision_ep9307.c b/trunk/arch/arm/mach-ep93xx/vision_ep9307.c index 03dd4012043e..d96e4dbec6a8 100644 --- a/trunk/arch/arm/mach-ep93xx/vision_ep9307.c +++ b/trunk/arch/arm/mach-ep93xx/vision_ep9307.c @@ -361,5 +361,4 @@ MACHINE_START(VISION_EP9307, "Vision Engraving Systems EP9307") .init_irq = ep93xx_init_irq, .timer = &ep93xx_timer, .init_machine = vision_init_machine, - .restart = ep93xx_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-exynos/Kconfig b/trunk/arch/arm/mach-exynos/Kconfig index e1efbca2a539..724ec0f3560d 100644 --- a/trunk/arch/arm/mach-exynos/Kconfig +++ b/trunk/arch/arm/mach-exynos/Kconfig @@ -17,8 +17,6 @@ choice config ARCH_EXYNOS4 bool "SAMSUNG EXYNOS4" - select HAVE_SMP - select MIGHT_HAVE_CACHE_L2X0 help Samsung EXYNOS4 SoCs based systems diff --git a/trunk/arch/arm/mach-exynos/Makefile b/trunk/arch/arm/mach-exynos/Makefile index bcb9efc576e9..59069a35e40b 100644 --- a/trunk/arch/arm/mach-exynos/Makefile +++ b/trunk/arch/arm/mach-exynos/Makefile @@ -10,17 +10,15 @@ obj-m := obj-n := obj- := -# Core +# Core support for EXYNOS4 system -obj-$(CONFIG_ARCH_EXYNOS4) += common.o clock.o +obj-$(CONFIG_ARCH_EXYNOS4) += cpu.o init.o clock.o irq-combiner.o setup-i2c0.o +obj-$(CONFIG_ARCH_EXYNOS4) += irq-eint.o dma.o pmu.o obj-$(CONFIG_CPU_EXYNOS4210) += clock-exynos4210.o obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o - obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o -obj-$(CONFIG_ARCH_EXYNOS4) += dma.o pmu.o - obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_EXYNOS4_MCT) += mct.o @@ -47,7 +45,6 @@ obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o -obj-$(CONFIG_ARCH_EXYNOS4) += setup-i2c0.o obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o obj-$(CONFIG_EXYNOS4_SETUP_I2C1) += setup-i2c1.o diff --git a/trunk/arch/arm/mach-exynos/clock-exynos4210.c b/trunk/arch/arm/mach-exynos/clock-exynos4210.c index a5823a7f249e..b9d5ef670eb4 100644 --- a/trunk/arch/arm/mach-exynos/clock-exynos4210.c +++ b/trunk/arch/arm/mach-exynos/clock-exynos4210.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -30,8 +31,6 @@ #include #include -#include "common.h" - static struct sleep_save exynos4210_clock_save[] = { SAVE_ITEM(S5P_CLKSRC_IMAGE), SAVE_ITEM(S5P_CLKSRC_LCD1), diff --git a/trunk/arch/arm/mach-exynos/clock-exynos4212.c b/trunk/arch/arm/mach-exynos/clock-exynos4212.c index 26a668b0d101..77d5decb34fd 100644 --- a/trunk/arch/arm/mach-exynos/clock-exynos4212.c +++ b/trunk/arch/arm/mach-exynos/clock-exynos4212.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -30,8 +31,6 @@ #include #include -#include "common.h" - static struct sleep_save exynos4212_clock_save[] = { SAVE_ITEM(S5P_CLKSRC_IMAGE), SAVE_ITEM(S5P_CLKDIV_IMAGE), diff --git a/trunk/arch/arm/mach-exynos/clock.c b/trunk/arch/arm/mach-exynos/clock.c index 83616a039b15..2894f0adef5c 100644 --- a/trunk/arch/arm/mach-exynos/clock.c +++ b/trunk/arch/arm/mach-exynos/clock.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -28,8 +29,6 @@ #include #include -#include "common.h" - static struct sleep_save exynos4_clock_save[] = { SAVE_ITEM(S5P_CLKDIV_LEFTBUS), SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS), diff --git a/trunk/arch/arm/mach-exynos/common.c b/trunk/arch/arm/mach-exynos/common.c deleted file mode 100644 index b6ac6ee658c0..000000000000 --- a/trunk/arch/arm/mach-exynos/common.c +++ /dev/null @@ -1,714 +0,0 @@ -/* - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Common Codes for EXYNOS - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" - -unsigned int gic_bank_offset __read_mostly; - -static const char name_exynos4210[] = "EXYNOS4210"; -static const char name_exynos4212[] = "EXYNOS4212"; -static const char name_exynos4412[] = "EXYNOS4412"; - -static struct cpu_table cpu_ids[] __initdata = { - { - .idcode = EXYNOS4210_CPU_ID, - .idmask = EXYNOS4_CPU_MASK, - .map_io = exynos4_map_io, - .init_clocks = exynos4_init_clocks, - .init_uarts = exynos4_init_uarts, - .init = exynos_init, - .name = name_exynos4210, - }, { - .idcode = EXYNOS4212_CPU_ID, - .idmask = EXYNOS4_CPU_MASK, - .map_io = exynos4_map_io, - .init_clocks = exynos4_init_clocks, - .init_uarts = exynos4_init_uarts, - .init = exynos_init, - .name = name_exynos4212, - }, { - .idcode = EXYNOS4412_CPU_ID, - .idmask = EXYNOS4_CPU_MASK, - .map_io = exynos4_map_io, - .init_clocks = exynos4_init_clocks, - .init_uarts = exynos4_init_uarts, - .init = exynos_init, - .name = name_exynos4412, - }, -}; - -/* Initial IO mappings */ - -static struct map_desc exynos_iodesc[] __initdata = { - { - .virtual = (unsigned long)S5P_VA_CHIPID, - .pfn = __phys_to_pfn(EXYNOS4_PA_CHIPID), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S3C_VA_SYS, - .pfn = __phys_to_pfn(EXYNOS4_PA_SYSCON), - .length = SZ_64K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S3C_VA_TIMER, - .pfn = __phys_to_pfn(EXYNOS4_PA_TIMER), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S3C_VA_WATCHDOG, - .pfn = __phys_to_pfn(EXYNOS4_PA_WATCHDOG), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_SROMC, - .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_SYSTIMER, - .pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_PMU, - .pfn = __phys_to_pfn(EXYNOS4_PA_PMU), - .length = SZ_64K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_COMBINER_BASE, - .pfn = __phys_to_pfn(EXYNOS4_PA_COMBINER), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_GIC_CPU, - .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_CPU), - .length = SZ_64K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_GIC_DIST, - .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_DIST), - .length = SZ_64K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S3C_VA_UART, - .pfn = __phys_to_pfn(EXYNOS4_PA_UART), - .length = SZ_512K, - .type = MT_DEVICE, - }, -}; - -static struct map_desc exynos4_iodesc[] __initdata = { - { - .virtual = (unsigned long)S5P_VA_CMU, - .pfn = __phys_to_pfn(EXYNOS4_PA_CMU), - .length = SZ_128K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_COREPERI_BASE, - .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI), - .length = SZ_8K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_L2CC, - .pfn = __phys_to_pfn(EXYNOS4_PA_L2CC), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_GPIO1, - .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO1), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_GPIO2, - .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO2), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_GPIO3, - .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO3), - .length = SZ_256, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_DMC0, - .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S3C_VA_USB_HSPHY, - .pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY), - .length = SZ_4K, - .type = MT_DEVICE, - }, -}; - -static struct map_desc exynos4_iodesc0[] __initdata = { - { - .virtual = (unsigned long)S5P_VA_SYSRAM, - .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM0), - .length = SZ_4K, - .type = MT_DEVICE, - }, -}; - -static struct map_desc exynos4_iodesc1[] __initdata = { - { - .virtual = (unsigned long)S5P_VA_SYSRAM, - .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM1), - .length = SZ_4K, - .type = MT_DEVICE, - }, -}; - -static void exynos_idle(void) -{ - if (!need_resched()) - cpu_do_idle(); - - local_irq_enable(); -} - -void exynos4_restart(char mode, const char *cmd) -{ - __raw_writel(0x1, S5P_SWRESET); -} - -/* - * exynos_map_io - * - * register the standard cpu IO areas - */ - -void __init exynos_init_io(struct map_desc *mach_desc, int size) -{ - /* initialize the io descriptors we need for initialization */ - iotable_init(exynos_iodesc, ARRAY_SIZE(exynos_iodesc)); - if (mach_desc) - iotable_init(mach_desc, size); - - /* detect cpu id and rev. */ - s5p_init_cpu(S5P_VA_CHIPID); - - s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids)); -} - -void __init exynos4_map_io(void) -{ - iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc)); - - if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0) - iotable_init(exynos4_iodesc0, ARRAY_SIZE(exynos4_iodesc0)); - else - iotable_init(exynos4_iodesc1, ARRAY_SIZE(exynos4_iodesc1)); - - /* initialize device information early */ - exynos4_default_sdhci0(); - exynos4_default_sdhci1(); - exynos4_default_sdhci2(); - exynos4_default_sdhci3(); - - s3c_adc_setname("samsung-adc-v3"); - - s3c_fimc_setname(0, "exynos4-fimc"); - s3c_fimc_setname(1, "exynos4-fimc"); - s3c_fimc_setname(2, "exynos4-fimc"); - s3c_fimc_setname(3, "exynos4-fimc"); - - /* The I2C bus controllers are directly compatible with s3c2440 */ - s3c_i2c0_setname("s3c2440-i2c"); - s3c_i2c1_setname("s3c2440-i2c"); - s3c_i2c2_setname("s3c2440-i2c"); - - s5p_fb_setname(0, "exynos4-fb"); - s5p_hdmi_setname("exynos4-hdmi"); -} - -void __init exynos4_init_clocks(int xtal) -{ - printk(KERN_DEBUG "%s: initializing clocks\n", __func__); - - s3c24xx_register_baseclocks(xtal); - s5p_register_clocks(xtal); - - if (soc_is_exynos4210()) - exynos4210_register_clocks(); - else if (soc_is_exynos4212() || soc_is_exynos4412()) - exynos4212_register_clocks(); - - exynos4_register_clocks(); - exynos4_setup_clocks(); -} - -#define COMBINER_ENABLE_SET 0x0 -#define COMBINER_ENABLE_CLEAR 0x4 -#define COMBINER_INT_STATUS 0xC - -static DEFINE_SPINLOCK(irq_controller_lock); - -struct combiner_chip_data { - unsigned int irq_offset; - unsigned int irq_mask; - void __iomem *base; -}; - -static struct combiner_chip_data combiner_data[MAX_COMBINER_NR]; - -static inline void __iomem *combiner_base(struct irq_data *data) -{ - struct combiner_chip_data *combiner_data = - irq_data_get_irq_chip_data(data); - - return combiner_data->base; -} - -static void combiner_mask_irq(struct irq_data *data) -{ - u32 mask = 1 << (data->irq % 32); - - __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR); -} - -static void combiner_unmask_irq(struct irq_data *data) -{ - u32 mask = 1 << (data->irq % 32); - - __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET); -} - -static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) -{ - struct combiner_chip_data *chip_data = irq_get_handler_data(irq); - struct irq_chip *chip = irq_get_chip(irq); - unsigned int cascade_irq, combiner_irq; - unsigned long status; - - chained_irq_enter(chip, desc); - - spin_lock(&irq_controller_lock); - status = __raw_readl(chip_data->base + COMBINER_INT_STATUS); - spin_unlock(&irq_controller_lock); - status &= chip_data->irq_mask; - - if (status == 0) - goto out; - - combiner_irq = __ffs(status); - - cascade_irq = combiner_irq + (chip_data->irq_offset & ~31); - if (unlikely(cascade_irq >= NR_IRQS)) - do_bad_IRQ(cascade_irq, desc); - else - generic_handle_irq(cascade_irq); - - out: - chained_irq_exit(chip, desc); -} - -static struct irq_chip combiner_chip = { - .name = "COMBINER", - .irq_mask = combiner_mask_irq, - .irq_unmask = combiner_unmask_irq, -}; - -static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq) -{ - if (combiner_nr >= MAX_COMBINER_NR) - BUG(); - if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0) - BUG(); - irq_set_chained_handler(irq, combiner_handle_cascade_irq); -} - -static void __init combiner_init(unsigned int combiner_nr, void __iomem *base, - unsigned int irq_start) -{ - unsigned int i; - - if (combiner_nr >= MAX_COMBINER_NR) - BUG(); - - combiner_data[combiner_nr].base = base; - combiner_data[combiner_nr].irq_offset = irq_start; - combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3); - - /* Disable all interrupts */ - - __raw_writel(combiner_data[combiner_nr].irq_mask, - base + COMBINER_ENABLE_CLEAR); - - /* Setup the Linux IRQ subsystem */ - - for (i = irq_start; i < combiner_data[combiner_nr].irq_offset - + MAX_IRQ_IN_COMBINER; i++) { - irq_set_chip_and_handler(i, &combiner_chip, handle_level_irq); - irq_set_chip_data(i, &combiner_data[combiner_nr]); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - } -} - -static void exynos4_gic_irq_fix_base(struct irq_data *d) -{ - struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); - - gic_data->cpu_base = S5P_VA_GIC_CPU + - (gic_bank_offset * smp_processor_id()); - - gic_data->dist_base = S5P_VA_GIC_DIST + - (gic_bank_offset * smp_processor_id()); -} - -void __init exynos4_init_irq(void) -{ - int irq; - - gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; - - gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); - gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base; - gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base; - gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base; - - for (irq = 0; irq < MAX_COMBINER_NR; irq++) { - - combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), - COMBINER_IRQ(irq, 0)); - combiner_cascade_irq(irq, IRQ_SPI(irq)); - } - - /* - * The parameters of s5p_init_irq() are for VIC init. - * Theses parameters should be NULL and 0 because EXYNOS4 - * uses GIC instead of VIC. - */ - s5p_init_irq(NULL, 0); -} - -struct bus_type exynos4_subsys = { - .name = "exynos4-core", - .dev_name = "exynos4-core", -}; - -static struct device exynos4_dev = { - .bus = &exynos4_subsys, -}; - -static int __init exynos4_core_init(void) -{ - return subsys_system_register(&exynos4_subsys, NULL); -} -core_initcall(exynos4_core_init); - -#ifdef CONFIG_CACHE_L2X0 -static int __init exynos4_l2x0_cache_init(void) -{ - /* TAG, Data Latency Control: 2cycle */ - __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); - - if (soc_is_exynos4210()) - __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); - else if (soc_is_exynos4212() || soc_is_exynos4412()) - __raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); - - /* L2X0 Prefetch Control */ - __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL); - - /* L2X0 Power Control */ - __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, - S5P_VA_L2CC + L2X0_POWER_CTRL); - - l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff); - - return 0; -} - -early_initcall(exynos4_l2x0_cache_init); -#endif - -int __init exynos_init(void) -{ - printk(KERN_INFO "EXYNOS: Initializing architecture\n"); - - /* set idle function */ - pm_idle = exynos_idle; - - return device_register(&exynos4_dev); -} - -static struct s3c24xx_uart_clksrc exynos4_serial_clocks[] = { - [0] = { - .name = "uclk1", - .divisor = 1, - .min_baud = 0, - .max_baud = 0, - }, -}; - -/* uart registration process */ - -void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no) -{ - struct s3c2410_uartcfg *tcfg = cfg; - u32 ucnt; - - for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { - if (!tcfg->clocks) { - tcfg->has_fracval = 1; - tcfg->clocks = exynos4_serial_clocks; - tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks); - } - tcfg->flags |= NO_NEED_CHECK_CLKSRC; - } - - s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); -} - -static DEFINE_SPINLOCK(eint_lock); - -static unsigned int eint0_15_data[16]; - -static unsigned int exynos4_get_irq_nr(unsigned int number) -{ - u32 ret = 0; - - switch (number) { - case 0 ... 3: - ret = (number + IRQ_EINT0); - break; - case 4 ... 7: - ret = (number + (IRQ_EINT4 - 4)); - break; - case 8 ... 15: - ret = (number + (IRQ_EINT8 - 8)); - break; - default: - printk(KERN_ERR "number available : %d\n", number); - } - - return ret; -} - -static inline void exynos4_irq_eint_mask(struct irq_data *data) -{ - u32 mask; - - spin_lock(&eint_lock); - mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); - mask |= eint_irq_to_bit(data->irq); - __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); - spin_unlock(&eint_lock); -} - -static void exynos4_irq_eint_unmask(struct irq_data *data) -{ - u32 mask; - - spin_lock(&eint_lock); - mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); - mask &= ~(eint_irq_to_bit(data->irq)); - __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); - spin_unlock(&eint_lock); -} - -static inline void exynos4_irq_eint_ack(struct irq_data *data) -{ - __raw_writel(eint_irq_to_bit(data->irq), - S5P_EINT_PEND(EINT_REG_NR(data->irq))); -} - -static void exynos4_irq_eint_maskack(struct irq_data *data) -{ - exynos4_irq_eint_mask(data); - exynos4_irq_eint_ack(data); -} - -static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type) -{ - int offs = EINT_OFFSET(data->irq); - int shift; - u32 ctrl, mask; - u32 newvalue = 0; - - switch (type) { - case IRQ_TYPE_EDGE_RISING: - newvalue = S5P_IRQ_TYPE_EDGE_RISING; - break; - - case IRQ_TYPE_EDGE_FALLING: - newvalue = S5P_IRQ_TYPE_EDGE_FALLING; - break; - - case IRQ_TYPE_EDGE_BOTH: - newvalue = S5P_IRQ_TYPE_EDGE_BOTH; - break; - - case IRQ_TYPE_LEVEL_LOW: - newvalue = S5P_IRQ_TYPE_LEVEL_LOW; - break; - - case IRQ_TYPE_LEVEL_HIGH: - newvalue = S5P_IRQ_TYPE_LEVEL_HIGH; - break; - - default: - printk(KERN_ERR "No such irq type %d", type); - return -EINVAL; - } - - shift = (offs & 0x7) * 4; - mask = 0x7 << shift; - - spin_lock(&eint_lock); - ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq))); - ctrl &= ~mask; - ctrl |= newvalue << shift; - __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq))); - spin_unlock(&eint_lock); - - switch (offs) { - case 0 ... 7: - s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE); - break; - case 8 ... 15: - s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE); - break; - case 16 ... 23: - s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE); - break; - case 24 ... 31: - s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE); - break; - default: - printk(KERN_ERR "No such irq number %d", offs); - } - - return 0; -} - -static struct irq_chip exynos4_irq_eint = { - .name = "exynos4-eint", - .irq_mask = exynos4_irq_eint_mask, - .irq_unmask = exynos4_irq_eint_unmask, - .irq_mask_ack = exynos4_irq_eint_maskack, - .irq_ack = exynos4_irq_eint_ack, - .irq_set_type = exynos4_irq_eint_set_type, -#ifdef CONFIG_PM - .irq_set_wake = s3c_irqext_wake, -#endif -}; - -/* - * exynos4_irq_demux_eint - * - * This function demuxes the IRQ from from EINTs 16 to 31. - * It is designed to be inlined into the specific handler - * s5p_irq_demux_eintX_Y. - * - * Each EINT pend/mask registers handle eight of them. - */ -static inline void exynos4_irq_demux_eint(unsigned int start) -{ - unsigned int irq; - - u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); - u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); - - status &= ~mask; - status &= 0xff; - - while (status) { - irq = fls(status) - 1; - generic_handle_irq(irq + start); - status &= ~(1 << irq); - } -} - -static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) -{ - struct irq_chip *chip = irq_get_chip(irq); - chained_irq_enter(chip, desc); - exynos4_irq_demux_eint(IRQ_EINT(16)); - exynos4_irq_demux_eint(IRQ_EINT(24)); - chained_irq_exit(chip, desc); -} - -static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc) -{ - u32 *irq_data = irq_get_handler_data(irq); - struct irq_chip *chip = irq_get_chip(irq); - - chained_irq_enter(chip, desc); - chip->irq_mask(&desc->irq_data); - - if (chip->irq_ack) - chip->irq_ack(&desc->irq_data); - - generic_handle_irq(*irq_data); - - chip->irq_unmask(&desc->irq_data); - chained_irq_exit(chip, desc); -} - -int __init exynos4_init_irq_eint(void) -{ - int irq; - - for (irq = 0 ; irq <= 31 ; irq++) { - irq_set_chip_and_handler(IRQ_EINT(irq), &exynos4_irq_eint, - handle_level_irq); - set_irq_flags(IRQ_EINT(irq), IRQF_VALID); - } - - irq_set_chained_handler(IRQ_EINT16_31, exynos4_irq_demux_eint16_31); - - for (irq = 0 ; irq <= 15 ; irq++) { - eint0_15_data[irq] = IRQ_EINT(irq); - - irq_set_handler_data(exynos4_get_irq_nr(irq), - &eint0_15_data[irq]); - irq_set_chained_handler(exynos4_get_irq_nr(irq), - exynos4_irq_eint0_15); - } - - return 0; -} -arch_initcall(exynos4_init_irq_eint); diff --git a/trunk/arch/arm/mach-exynos/common.h b/trunk/arch/arm/mach-exynos/common.h deleted file mode 100644 index 1ac49de0f398..000000000000 --- a/trunk/arch/arm/mach-exynos/common.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Common Header for EXYNOS machines - * - * 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. - */ - -#ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H -#define __ARCH_ARM_MACH_EXYNOS_COMMON_H - -void exynos_init_io(struct map_desc *mach_desc, int size); -void exynos4_init_irq(void); - -void exynos4_register_clocks(void); -void exynos4_setup_clocks(void); - -void exynos4210_register_clocks(void); -void exynos4212_register_clocks(void); - -void exynos4_restart(char mode, const char *cmd); - -extern struct sys_timer exynos4_timer; - -#ifdef CONFIG_ARCH_EXYNOS -extern int exynos_init(void); -extern void exynos4_map_io(void); -extern void exynos4_init_clocks(int xtal); -extern void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no); - -#else -#define exynos4_init_clocks NULL -#define exynos4_init_uarts NULL -#define exynos4_map_io NULL -#define exynos_init NULL -#endif - -#endif /* __ARCH_ARM_MACH_EXYNOS_COMMON_H */ diff --git a/trunk/arch/arm/mach-exynos/cpu.c b/trunk/arch/arm/mach-exynos/cpu.c new file mode 100644 index 000000000000..90ec247f3b37 --- /dev/null +++ b/trunk/arch/arm/mach-exynos/cpu.c @@ -0,0 +1,298 @@ +/* linux/arch/arm/mach-exynos/cpu.c + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * 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. +*/ + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +unsigned int gic_bank_offset __read_mostly; + +extern int combiner_init(unsigned int combiner_nr, void __iomem *base, + unsigned int irq_start); +extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq); + +/* Initial IO mappings */ +static struct map_desc exynos_iodesc[] __initdata = { + { + .virtual = (unsigned long)S5P_VA_SYSTIMER, + .pfn = __phys_to_pfn(EXYNOS_PA_SYSTIMER), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_PMU, + .pfn = __phys_to_pfn(EXYNOS_PA_PMU), + .length = SZ_64K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_COMBINER_BASE, + .pfn = __phys_to_pfn(EXYNOS_PA_COMBINER), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GIC_CPU, + .pfn = __phys_to_pfn(EXYNOS_PA_GIC_CPU), + .length = SZ_64K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GIC_DIST, + .pfn = __phys_to_pfn(EXYNOS_PA_GIC_DIST), + .length = SZ_64K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_UART, + .pfn = __phys_to_pfn(S3C_PA_UART), + .length = SZ_512K, + .type = MT_DEVICE, + }, +}; + +static struct map_desc exynos4_iodesc[] __initdata = { + { + .virtual = (unsigned long)S5P_VA_CMU, + .pfn = __phys_to_pfn(EXYNOS4_PA_CMU), + .length = SZ_128K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_COREPERI_BASE, + .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI), + .length = SZ_8K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_L2CC, + .pfn = __phys_to_pfn(EXYNOS4_PA_L2CC), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GPIO1, + .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO1), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GPIO2, + .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO2), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_GPIO3, + .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO3), + .length = SZ_256, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_DMC0, + .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_SROMC, + .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S3C_VA_USB_HSPHY, + .pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static struct map_desc exynos4_iodesc0[] __initdata = { + { + .virtual = (unsigned long)S5P_VA_SYSRAM, + .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM0), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static struct map_desc exynos4_iodesc1[] __initdata = { + { + .virtual = (unsigned long)S5P_VA_SYSRAM, + .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM1), + .length = SZ_4K, + .type = MT_DEVICE, + }, +}; + +static void exynos_idle(void) +{ + if (!need_resched()) + cpu_do_idle(); + + local_irq_enable(); +} + +static void exynos4_sw_reset(void) +{ + __raw_writel(0x1, S5P_SWRESET); +} + +/* + * exynos_map_io + * + * register the standard cpu IO areas + */ +void __init exynos4_map_io(void) +{ + iotable_init(exynos_iodesc, ARRAY_SIZE(exynos_iodesc)); + iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc)); + + if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0) + iotable_init(exynos4_iodesc0, ARRAY_SIZE(exynos4_iodesc0)); + else + iotable_init(exynos4_iodesc1, ARRAY_SIZE(exynos4_iodesc1)); + + /* initialize device information early */ + exynos4_default_sdhci0(); + exynos4_default_sdhci1(); + exynos4_default_sdhci2(); + exynos4_default_sdhci3(); + + s3c_adc_setname("samsung-adc-v3"); + + s3c_fimc_setname(0, "exynos4-fimc"); + s3c_fimc_setname(1, "exynos4-fimc"); + s3c_fimc_setname(2, "exynos4-fimc"); + s3c_fimc_setname(3, "exynos4-fimc"); + + /* The I2C bus controllers are directly compatible with s3c2440 */ + s3c_i2c0_setname("s3c2440-i2c"); + s3c_i2c1_setname("s3c2440-i2c"); + s3c_i2c2_setname("s3c2440-i2c"); + + s5p_fb_setname(0, "exynos4-fb"); + s5p_hdmi_setname("exynos4-hdmi"); +} + +void __init exynos4_init_clocks(int xtal) +{ + printk(KERN_DEBUG "%s: initializing clocks\n", __func__); + + s3c24xx_register_baseclocks(xtal); + s5p_register_clocks(xtal); + + if (soc_is_exynos4210()) + exynos4210_register_clocks(); + else if (soc_is_exynos4212() || soc_is_exynos4412()) + exynos4212_register_clocks(); + + exynos4_register_clocks(); + exynos4_setup_clocks(); +} + +static void exynos4_gic_irq_fix_base(struct irq_data *d) +{ + struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); + + gic_data->cpu_base = S5P_VA_GIC_CPU + + (gic_bank_offset * smp_processor_id()); + + gic_data->dist_base = S5P_VA_GIC_DIST + + (gic_bank_offset * smp_processor_id()); +} + +void __init exynos4_init_irq(void) +{ + int irq; + + gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; + + gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); + gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base; + gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base; + gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base; + + for (irq = 0; irq < MAX_COMBINER_NR; irq++) { + + combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), + COMBINER_IRQ(irq, 0)); + combiner_cascade_irq(irq, IRQ_SPI(irq)); + } + + /* The parameters of s5p_init_irq() are for VIC init. + * Theses parameters should be NULL and 0 because EXYNOS4 + * uses GIC instead of VIC. + */ + s5p_init_irq(NULL, 0); +} + +struct sysdev_class exynos4_sysclass = { + .name = "exynos4-core", +}; + +static struct sys_device exynos4_sysdev = { + .cls = &exynos4_sysclass, +}; + +static int __init exynos4_core_init(void) +{ + return sysdev_class_register(&exynos4_sysclass); +} +core_initcall(exynos4_core_init); + +#ifdef CONFIG_CACHE_L2X0 +static int __init exynos4_l2x0_cache_init(void) +{ + /* TAG, Data Latency Control: 2cycle */ + __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); + + if (soc_is_exynos4210()) + __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); + else if (soc_is_exynos4212() || soc_is_exynos4412()) + __raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); + + /* L2X0 Prefetch Control */ + __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL); + + /* L2X0 Power Control */ + __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, + S5P_VA_L2CC + L2X0_POWER_CTRL); + + l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff); + + return 0; +} + +early_initcall(exynos4_l2x0_cache_init); +#endif + +int __init exynos_init(void) +{ + printk(KERN_INFO "EXYNOS: Initializing architecture\n"); + + /* set idle function */ + pm_idle = exynos_idle; + + /* set sw_reset function */ + if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412()) + s5p_reset_hook = exynos4_sw_reset; + + return sysdev_register(&exynos4_sysdev); +} diff --git a/trunk/arch/arm/mach-exynos/include/mach/entry-macro.S b/trunk/arch/arm/mach-exynos/include/mach/entry-macro.S index 3ba4f547534b..f5e9fd8e37b4 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/entry-macro.S +++ b/trunk/arch/arm/mach-exynos/include/mach/entry-macro.S @@ -9,8 +9,83 @@ * warranty of any kind, whether express or implied. */ +#include +#include +#include + .macro disable_fiq .endm + .macro get_irqnr_preamble, base, tmp + mov \tmp, #0 + + mrc p15, 0, \base, c0, c0, 5 + and \base, \base, #3 + cmp \base, #0 + beq 1f + + ldr \tmp, =gic_bank_offset + ldr \tmp, [\tmp] + cmp \base, #1 + beq 1f + + cmp \base, #2 + addeq \tmp, \tmp, \tmp + addne \tmp, \tmp, \tmp, LSL #1 + +1: ldr \base, =gic_cpu_base_addr + ldr \base, [\base] + add \base, \base, \tmp + .endm + .macro arch_ret_to_user, tmp1, tmp2 .endm + + /* + * The interrupt numbering scheme is defined in the + * interrupt controller spec. To wit: + * + * Interrupts 0-15 are IPI + * 16-28 are reserved + * 29-31 are local. We allow 30 to be used for the watchdog. + * 32-1020 are global + * 1021-1022 are reserved + * 1023 is "spurious" (no interrupt) + * + * For now, we ignore all local interrupts so only return an interrupt if it's + * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs. + * + * A simple read from the controller will tell us the number of the highest + * priority enabled interrupt. We then just need to check whether it is in the + * valid range for an IRQ (30-1020 inclusive). + */ + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */ + + ldr \tmp, =1021 + + bic \irqnr, \irqstat, #0x1c00 + + cmp \irqnr, #15 + cmpcc \irqnr, \irqnr + cmpne \irqnr, \tmp + cmpcs \irqnr, \irqnr + addne \irqnr, \irqnr, #32 + + .endm + + /* We assume that irqstat (the raw value of the IRQ acknowledge + * register) is preserved from the macro above. + * If there is an IPI, we immediately signal end of interrupt on the + * controller, since this requires the original irqstat value which + * we won't easily be able to recreate later. + */ + + .macro test_for_ipi, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + cmp \irqnr, #16 + strcc \irqstat, [\base, #GIC_CPU_EOI] + cmpcs \irqnr, \irqnr + .endm diff --git a/trunk/arch/arm/mach-exynos/include/mach/map.h b/trunk/arch/arm/mach-exynos/include/mach/map.h index d1829860a0ec..058541d45af0 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/map.h +++ b/trunk/arch/arm/mach-exynos/include/mach/map.h @@ -149,6 +149,7 @@ #define S3C_PA_WDT EXYNOS4_PA_WATCHDOG #define S3C_PA_UART EXYNOS4_PA_UART +#define S5P_PA_CHIPID EXYNOS4_PA_CHIPID #define S5P_PA_EHCI EXYNOS4_PA_EHCI #define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0 #define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1 @@ -165,17 +166,26 @@ #define S5P_PA_ONENAND_DMA EXYNOS4_PA_ONENAND_DMA #define S5P_PA_SDO EXYNOS4_PA_SDO #define S5P_PA_SDRAM EXYNOS4_PA_SDRAM +#define S5P_PA_SROMC EXYNOS4_PA_SROMC +#define S5P_PA_SYSCON EXYNOS4_PA_SYSCON +#define S5P_PA_TIMER EXYNOS4_PA_TIMER #define S5P_PA_VP EXYNOS4_PA_VP #define SAMSUNG_PA_ADC EXYNOS4_PA_ADC #define SAMSUNG_PA_ADC1 EXYNOS4_PA_ADC1 #define SAMSUNG_PA_KEYPAD EXYNOS4_PA_KEYPAD +#define EXYNOS_PA_COMBINER EXYNOS4_PA_COMBINER +#define EXYNOS_PA_GIC_CPU EXYNOS4_PA_GIC_CPU +#define EXYNOS_PA_GIC_DIST EXYNOS4_PA_GIC_DIST +#define EXYNOS_PA_PMU EXYNOS4_PA_PMU +#define EXYNOS_PA_SYSTIMER EXYNOS4_PA_SYSTIMER + /* Compatibility UART */ #define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) -#define S5P_PA_UART(x) (EXYNOS4_PA_UART + ((x) * S3C_UART_OFFSET)) +#define S5P_PA_UART(x) (S3C_PA_UART + ((x) * S3C_UART_OFFSET)) #define S5P_PA_UART0 S5P_PA_UART(0) #define S5P_PA_UART1 S5P_PA_UART(1) #define S5P_PA_UART2 S5P_PA_UART(2) diff --git a/trunk/arch/arm/mach-exynos/include/mach/system.h b/trunk/arch/arm/mach-exynos/include/mach/system.h index 0063a6de3dc8..5e3220c18fc7 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/system.h +++ b/trunk/arch/arm/mach-exynos/include/mach/system.h @@ -13,6 +13,8 @@ #ifndef __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H __FILE__ +#include + static void arch_idle(void) { /* nothing here yet */ diff --git a/trunk/arch/arm/mach-exynos/include/mach/vmalloc.h b/trunk/arch/arm/mach-exynos/include/mach/vmalloc.h new file mode 100644 index 000000000000..284330e571d2 --- /dev/null +++ b/trunk/arch/arm/mach-exynos/include/mach/vmalloc.h @@ -0,0 +1,22 @@ +/* linux/arch/arm/mach-exynos4/include/mach/vmalloc.h + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Copyright 2010 Ben Dooks + * + * Based on arch/arm/mach-s5p6440/include/mach/vmalloc.h + * + * 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. + * + * EXYNOS4 vmalloc definition +*/ + +#ifndef __ASM_ARCH_VMALLOC_H +#define __ASM_ARCH_VMALLOC_H __FILE__ + +#define VMALLOC_END 0xF6000000UL + +#endif /* __ASM_ARCH_VMALLOC_H */ diff --git a/trunk/arch/arm/mach-exynos/init.c b/trunk/arch/arm/mach-exynos/init.c new file mode 100644 index 000000000000..a8a83e3881a4 --- /dev/null +++ b/trunk/arch/arm/mach-exynos/init.c @@ -0,0 +1,42 @@ +/* linux/arch/arm/mach-exynos4/init.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * 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. +*/ + +#include + +#include +#include +#include + +static struct s3c24xx_uart_clksrc exynos4_serial_clocks[] = { + [0] = { + .name = "uclk1", + .divisor = 1, + .min_baud = 0, + .max_baud = 0, + }, +}; + +/* uart registration process */ +void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) +{ + struct s3c2410_uartcfg *tcfg = cfg; + u32 ucnt; + + for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { + if (!tcfg->clocks) { + tcfg->has_fracval = 1; + tcfg->clocks = exynos4_serial_clocks; + tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks); + } + tcfg->flags |= NO_NEED_CHECK_CLKSRC; + } + + s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); +} diff --git a/trunk/arch/arm/mach-exynos/irq-combiner.c b/trunk/arch/arm/mach-exynos/irq-combiner.c new file mode 100644 index 000000000000..5a2758ab055e --- /dev/null +++ b/trunk/arch/arm/mach-exynos/irq-combiner.c @@ -0,0 +1,124 @@ +/* linux/arch/arm/mach-exynos4/irq-combiner.c + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Based on arch/arm/common/gic.c + * + * IRQ COMBINER support + * + * 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. +*/ + +#include + +#include + +#define COMBINER_ENABLE_SET 0x0 +#define COMBINER_ENABLE_CLEAR 0x4 +#define COMBINER_INT_STATUS 0xC + +static DEFINE_SPINLOCK(irq_controller_lock); + +struct combiner_chip_data { + unsigned int irq_offset; + unsigned int irq_mask; + void __iomem *base; +}; + +static struct combiner_chip_data combiner_data[MAX_COMBINER_NR]; + +static inline void __iomem *combiner_base(struct irq_data *data) +{ + struct combiner_chip_data *combiner_data = + irq_data_get_irq_chip_data(data); + + return combiner_data->base; +} + +static void combiner_mask_irq(struct irq_data *data) +{ + u32 mask = 1 << (data->irq % 32); + + __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR); +} + +static void combiner_unmask_irq(struct irq_data *data) +{ + u32 mask = 1 << (data->irq % 32); + + __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET); +} + +static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) +{ + struct combiner_chip_data *chip_data = irq_get_handler_data(irq); + struct irq_chip *chip = irq_get_chip(irq); + unsigned int cascade_irq, combiner_irq; + unsigned long status; + + chained_irq_enter(chip, desc); + + spin_lock(&irq_controller_lock); + status = __raw_readl(chip_data->base + COMBINER_INT_STATUS); + spin_unlock(&irq_controller_lock); + status &= chip_data->irq_mask; + + if (status == 0) + goto out; + + combiner_irq = __ffs(status); + + cascade_irq = combiner_irq + (chip_data->irq_offset & ~31); + if (unlikely(cascade_irq >= NR_IRQS)) + do_bad_IRQ(cascade_irq, desc); + else + generic_handle_irq(cascade_irq); + + out: + chained_irq_exit(chip, desc); +} + +static struct irq_chip combiner_chip = { + .name = "COMBINER", + .irq_mask = combiner_mask_irq, + .irq_unmask = combiner_unmask_irq, +}; + +void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq) +{ + if (combiner_nr >= MAX_COMBINER_NR) + BUG(); + if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0) + BUG(); + irq_set_chained_handler(irq, combiner_handle_cascade_irq); +} + +void __init combiner_init(unsigned int combiner_nr, void __iomem *base, + unsigned int irq_start) +{ + unsigned int i; + + if (combiner_nr >= MAX_COMBINER_NR) + BUG(); + + combiner_data[combiner_nr].base = base; + combiner_data[combiner_nr].irq_offset = irq_start; + combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3); + + /* Disable all interrupts */ + + __raw_writel(combiner_data[combiner_nr].irq_mask, + base + COMBINER_ENABLE_CLEAR); + + /* Setup the Linux IRQ subsystem */ + + for (i = irq_start; i < combiner_data[combiner_nr].irq_offset + + MAX_IRQ_IN_COMBINER; i++) { + irq_set_chip_and_handler(i, &combiner_chip, handle_level_irq); + irq_set_chip_data(i, &combiner_data[combiner_nr]); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } +} diff --git a/trunk/arch/arm/mach-exynos/irq-eint.c b/trunk/arch/arm/mach-exynos/irq-eint.c new file mode 100644 index 000000000000..badb8c66fc9b --- /dev/null +++ b/trunk/arch/arm/mach-exynos/irq-eint.c @@ -0,0 +1,237 @@ +/* linux/arch/arm/mach-exynos4/irq-eint.c + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * EXYNOS4 - IRQ EINT support + * + * 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. +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +static DEFINE_SPINLOCK(eint_lock); + +static unsigned int eint0_15_data[16]; + +static unsigned int exynos4_get_irq_nr(unsigned int number) +{ + u32 ret = 0; + + switch (number) { + case 0 ... 3: + ret = (number + IRQ_EINT0); + break; + case 4 ... 7: + ret = (number + (IRQ_EINT4 - 4)); + break; + case 8 ... 15: + ret = (number + (IRQ_EINT8 - 8)); + break; + default: + printk(KERN_ERR "number available : %d\n", number); + } + + return ret; +} + +static inline void exynos4_irq_eint_mask(struct irq_data *data) +{ + u32 mask; + + spin_lock(&eint_lock); + mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); + mask |= eint_irq_to_bit(data->irq); + __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); + spin_unlock(&eint_lock); +} + +static void exynos4_irq_eint_unmask(struct irq_data *data) +{ + u32 mask; + + spin_lock(&eint_lock); + mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); + mask &= ~(eint_irq_to_bit(data->irq)); + __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); + spin_unlock(&eint_lock); +} + +static inline void exynos4_irq_eint_ack(struct irq_data *data) +{ + __raw_writel(eint_irq_to_bit(data->irq), + S5P_EINT_PEND(EINT_REG_NR(data->irq))); +} + +static void exynos4_irq_eint_maskack(struct irq_data *data) +{ + exynos4_irq_eint_mask(data); + exynos4_irq_eint_ack(data); +} + +static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type) +{ + int offs = EINT_OFFSET(data->irq); + int shift; + u32 ctrl, mask; + u32 newvalue = 0; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + newvalue = S5P_IRQ_TYPE_EDGE_RISING; + break; + + case IRQ_TYPE_EDGE_FALLING: + newvalue = S5P_IRQ_TYPE_EDGE_FALLING; + break; + + case IRQ_TYPE_EDGE_BOTH: + newvalue = S5P_IRQ_TYPE_EDGE_BOTH; + break; + + case IRQ_TYPE_LEVEL_LOW: + newvalue = S5P_IRQ_TYPE_LEVEL_LOW; + break; + + case IRQ_TYPE_LEVEL_HIGH: + newvalue = S5P_IRQ_TYPE_LEVEL_HIGH; + break; + + default: + printk(KERN_ERR "No such irq type %d", type); + return -EINVAL; + } + + shift = (offs & 0x7) * 4; + mask = 0x7 << shift; + + spin_lock(&eint_lock); + ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq))); + ctrl &= ~mask; + ctrl |= newvalue << shift; + __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq))); + spin_unlock(&eint_lock); + + switch (offs) { + case 0 ... 7: + s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE); + break; + case 8 ... 15: + s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE); + break; + case 16 ... 23: + s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE); + break; + case 24 ... 31: + s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE); + break; + default: + printk(KERN_ERR "No such irq number %d", offs); + } + + return 0; +} + +static struct irq_chip exynos4_irq_eint = { + .name = "exynos4-eint", + .irq_mask = exynos4_irq_eint_mask, + .irq_unmask = exynos4_irq_eint_unmask, + .irq_mask_ack = exynos4_irq_eint_maskack, + .irq_ack = exynos4_irq_eint_ack, + .irq_set_type = exynos4_irq_eint_set_type, +#ifdef CONFIG_PM + .irq_set_wake = s3c_irqext_wake, +#endif +}; + +/* exynos4_irq_demux_eint + * + * This function demuxes the IRQ from from EINTs 16 to 31. + * It is designed to be inlined into the specific handler + * s5p_irq_demux_eintX_Y. + * + * Each EINT pend/mask registers handle eight of them. + */ +static inline void exynos4_irq_demux_eint(unsigned int start) +{ + unsigned int irq; + + u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); + u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); + + status &= ~mask; + status &= 0xff; + + while (status) { + irq = fls(status) - 1; + generic_handle_irq(irq + start); + status &= ~(1 << irq); + } +} + +static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) +{ + struct irq_chip *chip = irq_get_chip(irq); + chained_irq_enter(chip, desc); + exynos4_irq_demux_eint(IRQ_EINT(16)); + exynos4_irq_demux_eint(IRQ_EINT(24)); + chained_irq_exit(chip, desc); +} + +static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc) +{ + u32 *irq_data = irq_get_handler_data(irq); + struct irq_chip *chip = irq_get_chip(irq); + + chained_irq_enter(chip, desc); + chip->irq_mask(&desc->irq_data); + + if (chip->irq_ack) + chip->irq_ack(&desc->irq_data); + + generic_handle_irq(*irq_data); + + chip->irq_unmask(&desc->irq_data); + chained_irq_exit(chip, desc); +} + +int __init exynos4_init_irq_eint(void) +{ + int irq; + + for (irq = 0 ; irq <= 31 ; irq++) { + irq_set_chip_and_handler(IRQ_EINT(irq), &exynos4_irq_eint, + handle_level_irq); + set_irq_flags(IRQ_EINT(irq), IRQF_VALID); + } + + irq_set_chained_handler(IRQ_EINT16_31, exynos4_irq_demux_eint16_31); + + for (irq = 0 ; irq <= 15 ; irq++) { + eint0_15_data[irq] = IRQ_EINT(irq); + + irq_set_handler_data(exynos4_get_irq_nr(irq), + &eint0_15_data[irq]); + irq_set_chained_handler(exynos4_get_irq_nr(irq), + exynos4_irq_eint0_15); + } + + return 0; +} + +arch_initcall(exynos4_init_irq_eint); diff --git a/trunk/arch/arm/mach-exynos/mach-armlex4210.c b/trunk/arch/arm/mach-exynos/mach-armlex4210.c index d726fcd3acf9..f0ca6c157d29 100644 --- a/trunk/arch/arm/mach-exynos/mach-armlex4210.c +++ b/trunk/arch/arm/mach-exynos/mach-armlex4210.c @@ -16,11 +16,11 @@ #include #include -#include #include #include #include +#include #include #include #include @@ -28,8 +28,6 @@ #include -#include "common.h" - /* Following are default values for UCON, ULCON and UFCON UART registers */ #define ARMLEX4210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ S3C2410_UCON_RXILEVEL | \ @@ -189,7 +187,7 @@ static void __init armlex4210_smsc911x_init(void) static void __init armlex4210_map_io(void) { - exynos_init_io(NULL, 0); + s5p_init_io(NULL, 0, S5P_VA_CHIPID); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(armlex4210_uartcfgs, ARRAY_SIZE(armlex4210_uartcfgs)); @@ -212,8 +210,6 @@ MACHINE_START(ARMLEX4210, "ARMLEX4210") .atag_offset = 0x100, .init_irq = exynos4_init_irq, .map_io = armlex4210_map_io, - .handle_irq = gic_handle_irq, .init_machine = armlex4210_machine_init, .timer = &exynos4_timer, - .restart = exynos4_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-exynos/mach-nuri.c b/trunk/arch/arm/mach-exynos/mach-nuri.c index 635fb97e31ab..236bbe187163 100644 --- a/trunk/arch/arm/mach-exynos/mach-nuri.c +++ b/trunk/arch/arm/mach-exynos/mach-nuri.c @@ -32,12 +32,12 @@ #include #include -#include #include #include #include #include +#include #include #include #include @@ -54,8 +54,6 @@ #include -#include "common.h" - /* Following are default values for UCON, ULCON and UFCON UART registers */ #define NURI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ S3C2410_UCON_RXILEVEL | \ @@ -1285,7 +1283,7 @@ static struct platform_device *nuri_devices[] __initdata = { static void __init nuri_map_io(void) { - exynos_init_io(NULL, 0); + s5p_init_io(NULL, 0, S5P_VA_CHIPID); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs)); } @@ -1335,9 +1333,7 @@ MACHINE_START(NURI, "NURI") .atag_offset = 0x100, .init_irq = exynos4_init_irq, .map_io = nuri_map_io, - .handle_irq = gic_handle_irq, .init_machine = nuri_machine_init, .timer = &exynos4_timer, .reserve = &nuri_reserve, - .restart = exynos4_restart, MACHINE_END diff --git a/trunk/arch/arm/mach-exynos/mach-origen.c b/trunk/arch/arm/mach-exynos/mach-origen.c index 586eb995aa96..f80b563f2be7 100644 --- a/trunk/arch/arm/mach-exynos/mach-origen.c +++ b/trunk/arch/arm/mach-exynos/mach-origen.c @@ -22,13 +22,13 @@ #include #include -#include #include #include