diff --git a/[refs] b/[refs]
index af1be2fd40dc..022ad693d567 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: b35e7041186a9ace341665d404274d58a32b6e2c
+refs/heads/master: 5c1ad8b30587694590691d6a83b1e7adaa7ca6d0
diff --git a/trunk/.gitignore b/trunk/.gitignore
index 8d14531846b9..22fb8fa9bc3d 100644
--- a/trunk/.gitignore
+++ b/trunk/.gitignore
@@ -12,7 +12,6 @@
*.s
*.ko
*.so
-*.so.dbg
*.mod.c
*.i
*.lst
diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl
index aa38cc5692a0..d3290c46af51 100644
--- a/trunk/Documentation/DocBook/kernel-api.tmpl
+++ b/trunk/Documentation/DocBook/kernel-api.tmpl
@@ -46,7 +46,7 @@
Atomic and pointer manipulation
!Iinclude/asm-x86/atomic_32.h
-!Iinclude/asm-x86/unaligned.h
+!Iinclude/asm-x86/unaligned_32.h
Delaying, scheduling, and timer routines
diff --git a/trunk/Documentation/accounting/cgroupstats.txt b/trunk/Documentation/accounting/cgroupstats.txt
deleted file mode 100644
index eda40fd39cad..000000000000
--- a/trunk/Documentation/accounting/cgroupstats.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-Control Groupstats is inspired by the discussion at
-http://lkml.org/lkml/2007/4/11/187 and implements per cgroup statistics as
-suggested by Andrew Morton in http://lkml.org/lkml/2007/4/11/263.
-
-Per cgroup statistics infrastructure re-uses code from the taskstats
-interface. A new set of cgroup operations are registered with commands
-and attributes specific to cgroups. It should be very easy to
-extend per cgroup statistics, by adding members to the cgroupstats
-structure.
-
-The current model for cgroupstats is a pull, a push model (to post
-statistics on interesting events), should be very easy to add. Currently
-user space requests for statistics by passing the cgroup path.
-Statistics about the state of all the tasks in the cgroup is returned to
-user space.
-
-NOTE: We currently rely on delay accounting for extracting information
-about tasks blocked on I/O. If CONFIG_TASK_DELAY_ACCT is disabled, this
-information will not be available.
-
-To extract cgroup statistics a utility very similar to getdelays.c
-has been developed, the sample output of the utility is shown below
-
-~/balbir/cgroupstats # ./getdelays -C "/cgroup/a"
-sleeping 1, blocked 0, running 1, stopped 0, uninterruptible 0
-~/balbir/cgroupstats # ./getdelays -C "/cgroup"
-sleeping 155, blocked 0, running 1, stopped 0, uninterruptible 2
diff --git a/trunk/Documentation/cachetlb.txt b/trunk/Documentation/cachetlb.txt
index da42ab414c48..552cabac0608 100644
--- a/trunk/Documentation/cachetlb.txt
+++ b/trunk/Documentation/cachetlb.txt
@@ -87,7 +87,30 @@ changes occur:
This is used primarily during fault processing.
-5) void update_mmu_cache(struct vm_area_struct *vma,
+5) void flush_tlb_pgtables(struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+
+ The software page tables for address space 'mm' for virtual
+ addresses in the range 'start' to 'end-1' are being torn down.
+
+ Some platforms cache the lowest level of the software page tables
+ in a linear virtually mapped array, to make TLB miss processing
+ more efficient. On such platforms, since the TLB is caching the
+ software page table structure, it needs to be flushed when parts
+ of the software page table tree are unlinked/freed.
+
+ Sparc64 is one example of a platform which does this.
+
+ Usually, when munmap()'ing an area of user virtual address
+ space, the kernel leaves the page table parts around and just
+ marks the individual pte's as invalid. However, if very large
+ portions of the address space are unmapped, the kernel frees up
+ those portions of the software page tables to prevent potential
+ excessive kernel memory usage caused by erratic mmap/mmunmap
+ sequences. It is at these times that flush_tlb_pgtables will
+ be invoked.
+
+6) void update_mmu_cache(struct vm_area_struct *vma,
unsigned long address, pte_t pte)
At the end of every page fault, this routine is invoked to
@@ -100,7 +123,7 @@ changes occur:
translations for software managed TLB configurations.
The sparc64 port currently does this.
-6) void tlb_migrate_finish(struct mm_struct *mm)
+7) void tlb_migrate_finish(struct mm_struct *mm)
This interface is called at the end of an explicit
process migration. This interface provides a hook
diff --git a/trunk/Documentation/cgroups.txt b/trunk/Documentation/cgroups.txt
deleted file mode 100644
index 98a26f81fa75..000000000000
--- a/trunk/Documentation/cgroups.txt
+++ /dev/null
@@ -1,545 +0,0 @@
- CGROUPS
- -------
-
-Written by Paul Menage based on Documentation/cpusets.txt
-
-Original copyright statements from cpusets.txt:
-Portions Copyright (C) 2004 BULL SA.
-Portions Copyright (c) 2004-2006 Silicon Graphics, Inc.
-Modified by Paul Jackson
-Modified by Christoph Lameter
-
-CONTENTS:
-=========
-
-1. Control Groups
- 1.1 What are cgroups ?
- 1.2 Why are cgroups needed ?
- 1.3 How are cgroups implemented ?
- 1.4 What does notify_on_release do ?
- 1.5 How do I use cgroups ?
-2. Usage Examples and Syntax
- 2.1 Basic Usage
- 2.2 Attaching processes
-3. Kernel API
- 3.1 Overview
- 3.2 Synchronization
- 3.3 Subsystem API
-4. Questions
-
-1. Control Groups
-==========
-
-1.1 What are cgroups ?
-----------------------
-
-Control Groups provide a mechanism for aggregating/partitioning sets of
-tasks, and all their future children, into hierarchical groups with
-specialized behaviour.
-
-Definitions:
-
-A *cgroup* associates a set of tasks with a set of parameters for one
-or more subsystems.
-
-A *subsystem* is a module that makes use of the task grouping
-facilities provided by cgroups to treat groups of tasks in
-particular ways. A subsystem is typically a "resource controller" that
-schedules a resource or applies per-cgroup limits, but it may be
-anything that wants to act on a group of processes, e.g. a
-virtualization subsystem.
-
-A *hierarchy* is a set of cgroups arranged in a tree, such that
-every task in the system is in exactly one of the cgroups in the
-hierarchy, and a set of subsystems; each subsystem has system-specific
-state attached to each cgroup in the hierarchy. Each hierarchy has
-an instance of the cgroup virtual filesystem associated with it.
-
-At any one time there may be multiple active hierachies of task
-cgroups. Each hierarchy is a partition of all tasks in the system.
-
-User level code may create and destroy cgroups by name in an
-instance of the cgroup virtual file system, specify and query to
-which cgroup a task is assigned, and list the task pids assigned to
-a cgroup. Those creations and assignments only affect the hierarchy
-associated with that instance of the cgroup file system.
-
-On their own, the only use for cgroups is for simple job
-tracking. The intention is that other subsystems hook into the generic
-cgroup support to provide new attributes for cgroups, such as
-accounting/limiting the resources which processes in a cgroup can
-access. For example, cpusets (see Documentation/cpusets.txt) allows
-you to associate a set of CPUs and a set of memory nodes with the
-tasks in each cgroup.
-
-1.2 Why are cgroups needed ?
-----------------------------
-
-There are multiple efforts to provide process aggregations in the
-Linux kernel, mainly for resource tracking purposes. Such efforts
-include cpusets, CKRM/ResGroups, UserBeanCounters, and virtual server
-namespaces. These all require the basic notion of a
-grouping/partitioning of processes, with newly forked processes ending
-in the same group (cgroup) as their parent process.
-
-The kernel cgroup patch provides the minimum essential kernel
-mechanisms required to efficiently implement such groups. It has
-minimal impact on the system fast paths, and provides hooks for
-specific subsystems such as cpusets to provide additional behaviour as
-desired.
-
-Multiple hierarchy support is provided to allow for situations where
-the division of tasks into cgroups is distinctly different for
-different subsystems - having parallel hierarchies allows each
-hierarchy to be a natural division of tasks, without having to handle
-complex combinations of tasks that would be present if several
-unrelated subsystems needed to be forced into the same tree of
-cgroups.
-
-At one extreme, each resource controller or subsystem could be in a
-separate hierarchy; at the other extreme, all subsystems
-would be attached to the same hierarchy.
-
-As an example of a scenario (originally proposed by vatsa@in.ibm.com)
-that can benefit from multiple hierarchies, consider a large
-university server with various users - students, professors, system
-tasks etc. The resource planning for this server could be along the
-following lines:
-
- CPU : Top cpuset
- / \
- CPUSet1 CPUSet2
- | |
- (Profs) (Students)
-
- In addition (system tasks) are attached to topcpuset (so
- that they can run anywhere) with a limit of 20%
-
- Memory : Professors (50%), students (30%), system (20%)
-
- Disk : Prof (50%), students (30%), system (20%)
-
- Network : WWW browsing (20%), Network File System (60%), others (20%)
- / \
- Prof (15%) students (5%)
-
-Browsers like firefox/lynx go into the WWW network class, while (k)nfsd go
-into NFS network class.
-
-At the same time firefox/lynx will share an appropriate CPU/Memory class
-depending on who launched it (prof/student).
-
-With the ability to classify tasks differently for different resources
-(by putting those resource subsystems in different hierarchies) then
-the admin can easily set up a script which receives exec notifications
-and depending on who is launching the browser he can
-
- # echo browser_pid > /mnt///tasks
-
-With only a single hierarchy, he now would potentially have to create
-a separate cgroup for every browser launched and associate it with
-approp network and other resource class. This may lead to
-proliferation of such cgroups.
-
-Also lets say that the administrator would like to give enhanced network
-access temporarily to a student's browser (since it is night and the user
-wants to do online gaming :) OR give one of the students simulation
-apps enhanced CPU power,
-
-With ability to write pids directly to resource classes, its just a
-matter of :
-
- # echo pid > /mnt/network//tasks
- (after some time)
- # echo pid > /mnt/network//tasks
-
-Without this ability, he would have to split the cgroup into
-multiple separate ones and then associate the new cgroups with the
-new resource classes.
-
-
-
-1.3 How are cgroups implemented ?
----------------------------------
-
-Control Groups extends the kernel as follows:
-
- - Each task in the system has a reference-counted pointer to a
- css_set.
-
- - A css_set contains a set of reference-counted pointers to
- cgroup_subsys_state objects, one for each cgroup subsystem
- registered in the system. There is no direct link from a task to
- the cgroup of which it's a member in each hierarchy, but this
- can be determined by following pointers through the
- cgroup_subsys_state objects. This is because accessing the
- subsystem state is something that's expected to happen frequently
- and in performance-critical code, whereas operations that require a
- task's actual cgroup assignments (in particular, moving between
- cgroups) are less common. A linked list runs through the cg_list
- field of each task_struct using the css_set, anchored at
- css_set->tasks.
-
- - A cgroup hierarchy filesystem can be mounted for browsing and
- manipulation from user space.
-
- - You can list all the tasks (by pid) attached to any cgroup.
-
-The implementation of cgroups requires a few, simple hooks
-into the rest of the kernel, none in performance critical paths:
-
- - in init/main.c, to initialize the root cgroups and initial
- css_set at system boot.
-
- - in fork and exit, to attach and detach a task from its css_set.
-
-In addition a new file system, of type "cgroup" may be mounted, to
-enable browsing and modifying the cgroups presently known to the
-kernel. When mounting a cgroup hierarchy, you may specify a
-comma-separated list of subsystems to mount as the filesystem mount
-options. By default, mounting the cgroup filesystem attempts to
-mount a hierarchy containing all registered subsystems.
-
-If an active hierarchy with exactly the same set of subsystems already
-exists, it will be reused for the new mount. If no existing hierarchy
-matches, and any of the requested subsystems are in use in an existing
-hierarchy, the mount will fail with -EBUSY. Otherwise, a new hierarchy
-is activated, associated with the requested subsystems.
-
-It's not currently possible to bind a new subsystem to an active
-cgroup hierarchy, or to unbind a subsystem from an active cgroup
-hierarchy. This may be possible in future, but is fraught with nasty
-error-recovery issues.
-
-When a cgroup filesystem is unmounted, if there are any
-child cgroups created below the top-level cgroup, that hierarchy
-will remain active even though unmounted; if there are no
-child cgroups then the hierarchy will be deactivated.
-
-No new system calls are added for cgroups - all support for
-querying and modifying cgroups is via this cgroup file system.
-
-Each task under /proc has an added file named 'cgroup' displaying,
-for each active hierarchy, the subsystem names and the cgroup name
-as the path relative to the root of the cgroup file system.
-
-Each cgroup is represented by a directory in the cgroup file system
-containing the following files describing that cgroup:
-
- - tasks: list of tasks (by pid) attached to that cgroup
- - notify_on_release flag: run /sbin/cgroup_release_agent on exit?
-
-Other subsystems such as cpusets may add additional files in each
-cgroup dir
-
-New cgroups are created using the mkdir system call or shell
-command. The properties of a cgroup, such as its flags, are
-modified by writing to the appropriate file in that cgroups
-directory, as listed above.
-
-The named hierarchical structure of nested cgroups allows partitioning
-a large system into nested, dynamically changeable, "soft-partitions".
-
-The attachment of each task, automatically inherited at fork by any
-children of that task, to a cgroup allows organizing the work load
-on a system into related sets of tasks. A task may be re-attached to
-any other cgroup, if allowed by the permissions on the necessary
-cgroup file system directories.
-
-When a task is moved from one cgroup to another, it gets a new
-css_set pointer - if there's an already existing css_set with the
-desired collection of cgroups then that group is reused, else a new
-css_set is allocated. Note that the current implementation uses a
-linear search to locate an appropriate existing css_set, so isn't
-very efficient. A future version will use a hash table for better
-performance.
-
-To allow access from a cgroup to the css_sets (and hence tasks)
-that comprise it, a set of cg_cgroup_link objects form a lattice;
-each cg_cgroup_link is linked into a list of cg_cgroup_links for
-a single cgroup on its cont_link_list field, and a list of
-cg_cgroup_links for a single css_set on its cg_link_list.
-
-Thus the set of tasks in a cgroup can be listed by iterating over
-each css_set that references the cgroup, and sub-iterating over
-each css_set's task set.
-
-The use of a Linux virtual file system (vfs) to represent the
-cgroup hierarchy provides for a familiar permission and name space
-for cgroups, with a minimum of additional kernel code.
-
-1.4 What does notify_on_release do ?
-------------------------------------
-
-*** notify_on_release is disabled in the current patch set. It will be
-*** reactivated in a future patch in a less-intrusive manner
-
-If the notify_on_release flag is enabled (1) in a cgroup, then
-whenever the last task in the cgroup leaves (exits or attaches to
-some other cgroup) and the last child cgroup of that cgroup
-is removed, then the kernel runs the command specified by the contents
-of the "release_agent" file in that hierarchy's root directory,
-supplying the pathname (relative to the mount point of the cgroup
-file system) of the abandoned cgroup. This enables automatic
-removal of abandoned cgroups. The default value of
-notify_on_release in the root cgroup at system boot is disabled
-(0). The default value of other cgroups at creation is the current
-value of their parents notify_on_release setting. The default value of
-a cgroup hierarchy's release_agent path is empty.
-
-1.5 How do I use cgroups ?
---------------------------
-
-To start a new job that is to be contained within a cgroup, using
-the "cpuset" cgroup subsystem, the steps are something like:
-
- 1) mkdir /dev/cgroup
- 2) mount -t cgroup -ocpuset cpuset /dev/cgroup
- 3) Create the new cgroup by doing mkdir's and write's (or echo's) in
- the /dev/cgroup virtual file system.
- 4) Start a task that will be the "founding father" of the new job.
- 5) Attach that task to the new cgroup by writing its pid to the
- /dev/cgroup tasks file for that cgroup.
- 6) fork, exec or clone the job tasks from this founding father task.
-
-For example, the following sequence of commands will setup a cgroup
-named "Charlie", containing just CPUs 2 and 3, and Memory Node 1,
-and then start a subshell 'sh' in that cgroup:
-
- mount -t cgroup cpuset -ocpuset /dev/cgroup
- cd /dev/cgroup
- mkdir Charlie
- cd Charlie
- /bin/echo 2-3 > cpus
- /bin/echo 1 > mems
- /bin/echo $$ > tasks
- sh
- # The subshell 'sh' is now running in cgroup Charlie
- # The next line should display '/Charlie'
- cat /proc/self/cgroup
-
-2. Usage Examples and Syntax
-============================
-
-2.1 Basic Usage
----------------
-
-Creating, modifying, using the cgroups can be done through the cgroup
-virtual filesystem.
-
-To mount a cgroup hierarchy will all available subsystems, type:
-# mount -t cgroup xxx /dev/cgroup
-
-The "xxx" is not interpreted by the cgroup code, but will appear in
-/proc/mounts so may be any useful identifying string that you like.
-
-To mount a cgroup hierarchy with just the cpuset and numtasks
-subsystems, type:
-# mount -t cgroup -o cpuset,numtasks hier1 /dev/cgroup
-
-To change the set of subsystems bound to a mounted hierarchy, just
-remount with different options:
-
-# mount -o remount,cpuset,ns /dev/cgroup
-
-Note that changing the set of subsystems is currently only supported
-when the hierarchy consists of a single (root) cgroup. Supporting
-the ability to arbitrarily bind/unbind subsystems from an existing
-cgroup hierarchy is intended to be implemented in the future.
-
-Then under /dev/cgroup you can find a tree that corresponds to the
-tree of the cgroups in the system. For instance, /dev/cgroup
-is the cgroup that holds the whole system.
-
-If you want to create a new cgroup under /dev/cgroup:
-# cd /dev/cgroup
-# mkdir my_cgroup
-
-Now you want to do something with this cgroup.
-# cd my_cgroup
-
-In this directory you can find several files:
-# ls
-notify_on_release release_agent tasks
-(plus whatever files are added by the attached subsystems)
-
-Now attach your shell to this cgroup:
-# /bin/echo $$ > tasks
-
-You can also create cgroups inside your cgroup by using mkdir in this
-directory.
-# mkdir my_sub_cs
-
-To remove a cgroup, just use rmdir:
-# rmdir my_sub_cs
-
-This will fail if the cgroup is in use (has cgroups inside, or
-has processes attached, or is held alive by other subsystem-specific
-reference).
-
-2.2 Attaching processes
------------------------
-
-# /bin/echo PID > tasks
-
-Note that it is PID, not PIDs. You can only attach ONE task at a time.
-If you have several tasks to attach, you have to do it one after another:
-
-# /bin/echo PID1 > tasks
-# /bin/echo PID2 > tasks
- ...
-# /bin/echo PIDn > tasks
-
-3. Kernel API
-=============
-
-3.1 Overview
-------------
-
-Each kernel subsystem that wants to hook into the generic cgroup
-system needs to create a cgroup_subsys object. This contains
-various methods, which are callbacks from the cgroup system, along
-with a subsystem id which will be assigned by the cgroup system.
-
-Other fields in the cgroup_subsys object include:
-
-- subsys_id: a unique array index for the subsystem, indicating which
- entry in cgroup->subsys[] this subsystem should be
- managing. Initialized by cgroup_register_subsys(); prior to this
- it should be initialized to -1
-
-- hierarchy: an index indicating which hierarchy, if any, this
- subsystem is currently attached to. If this is -1, then the
- subsystem is not attached to any hierarchy, and all tasks should be
- considered to be members of the subsystem's top_cgroup. It should
- be initialized to -1.
-
-- name: should be initialized to a unique subsystem name prior to
- calling cgroup_register_subsystem. Should be no longer than
- MAX_CGROUP_TYPE_NAMELEN
-
-Each cgroup object created by the system has an array of pointers,
-indexed by subsystem id; this pointer is entirely managed by the
-subsystem; the generic cgroup code will never touch this pointer.
-
-3.2 Synchronization
--------------------
-
-There is a global mutex, cgroup_mutex, used by the cgroup
-system. This should be taken by anything that wants to modify a
-cgroup. It may also be taken to prevent cgroups from being
-modified, but more specific locks may be more appropriate in that
-situation.
-
-See kernel/cgroup.c for more details.
-
-Subsystems can take/release the cgroup_mutex via the functions
-cgroup_lock()/cgroup_unlock(), and can
-take/release the callback_mutex via the functions
-cgroup_lock()/cgroup_unlock().
-
-Accessing a task's cgroup pointer may be done in the following ways:
-- while holding cgroup_mutex
-- while holding the task's alloc_lock (via task_lock())
-- inside an rcu_read_lock() section via rcu_dereference()
-
-3.3 Subsystem API
---------------------------
-
-Each subsystem should:
-
-- add an entry in linux/cgroup_subsys.h
-- define a cgroup_subsys object called _subsys
-
-Each subsystem may export the following methods. The only mandatory
-methods are create/destroy. Any others that are null are presumed to
-be successful no-ops.
-
-struct cgroup_subsys_state *create(struct cgroup *cont)
-LL=cgroup_mutex
-
-Called to create a subsystem state object for a cgroup. The
-subsystem should allocate its subsystem state object for the passed
-cgroup, returning a pointer to the new object on success or a
-negative error code. On success, the subsystem pointer should point to
-a structure of type cgroup_subsys_state (typically embedded in a
-larger subsystem-specific object), which will be initialized by the
-cgroup system. Note that this will be called at initialization to
-create the root subsystem state for this subsystem; this case can be
-identified by the passed cgroup object having a NULL parent (since
-it's the root of the hierarchy) and may be an appropriate place for
-initialization code.
-
-void destroy(struct cgroup *cont)
-LL=cgroup_mutex
-
-The cgroup system is about to destroy the passed cgroup; the
-subsystem should do any necessary cleanup
-
-int can_attach(struct cgroup_subsys *ss, struct cgroup *cont,
- struct task_struct *task)
-LL=cgroup_mutex
-
-Called prior to moving a task into a cgroup; if the subsystem
-returns an error, this will abort the attach operation. If a NULL
-task is passed, then a successful result indicates that *any*
-unspecified task can be moved into the cgroup. Note that this isn't
-called on a fork. If this method returns 0 (success) then this should
-remain valid while the caller holds cgroup_mutex.
-
-void attach(struct cgroup_subsys *ss, struct cgroup *cont,
- struct cgroup *old_cont, struct task_struct *task)
-LL=cgroup_mutex
-
-
-Called after the task has been attached to the cgroup, to allow any
-post-attachment activity that requires memory allocations or blocking.
-
-void fork(struct cgroup_subsy *ss, struct task_struct *task)
-LL=callback_mutex, maybe read_lock(tasklist_lock)
-
-Called when a task is forked into a cgroup. Also called during
-registration for all existing tasks.
-
-void exit(struct cgroup_subsys *ss, struct task_struct *task)
-LL=callback_mutex
-
-Called during task exit
-
-int populate(struct cgroup_subsys *ss, struct cgroup *cont)
-LL=none
-
-Called after creation of a cgroup to allow a subsystem to populate
-the cgroup directory with file entries. The subsystem should make
-calls to cgroup_add_file() with objects of type cftype (see
-include/linux/cgroup.h for details). Note that although this
-method can return an error code, the error code is currently not
-always handled well.
-
-void post_clone(struct cgroup_subsys *ss, struct cgroup *cont)
-
-Called at the end of cgroup_clone() to do any paramater
-initialization which might be required before a task could attach. For
-example in cpusets, no task may attach before 'cpus' and 'mems' are set
-up.
-
-void bind(struct cgroup_subsys *ss, struct cgroup *root)
-LL=callback_mutex
-
-Called when a cgroup subsystem is rebound to a different hierarchy
-and root cgroup. Currently this will only involve movement between
-the default hierarchy (which never has sub-cgroups) and a hierarchy
-that is being created/destroyed (and hence has no sub-cgroups).
-
-4. Questions
-============
-
-Q: what's up with this '/bin/echo' ?
-A: bash's builtin 'echo' command does not check calls to write() against
- errors. If you use it in the cgroup file system, you won't be
- able to tell whether a command succeeded or failed.
-
-Q: When I attach processes, only the first of the line gets really attached !
-A: We can only return one error code per call to write(). So you should also
- put only ONE pid.
-
diff --git a/trunk/Documentation/cpu-hotplug.txt b/trunk/Documentation/cpu-hotplug.txt
index a741f658a3c9..b6d24c22274b 100644
--- a/trunk/Documentation/cpu-hotplug.txt
+++ b/trunk/Documentation/cpu-hotplug.txt
@@ -220,9 +220,7 @@ A: The following happen, listed in no particular order :-)
CPU_DOWN_PREPARE or CPU_DOWN_PREPARE_FROZEN, depending on whether or not the
CPU is being offlined while tasks are frozen due to a suspend operation in
progress
-- All processes are migrated away from this outgoing CPU to new CPUs.
- The new CPU is chosen from each process' current cpuset, which may be
- a subset of all online CPUs.
+- All process is migrated away from this outgoing CPU to a new CPU
- All interrupts targeted to this CPU is migrated to a new CPU
- timers/bottom half/task lets are also migrated to a new CPU
- Once all services are migrated, kernel calls an arch specific routine
diff --git a/trunk/Documentation/cpusets.txt b/trunk/Documentation/cpusets.txt
index 141bef1c8599..ec9de6917f01 100644
--- a/trunk/Documentation/cpusets.txt
+++ b/trunk/Documentation/cpusets.txt
@@ -7,7 +7,6 @@ Written by Simon.Derr@bull.net
Portions Copyright (c) 2004-2006 Silicon Graphics, Inc.
Modified by Paul Jackson
Modified by Christoph Lameter
-Modified by Paul Menage
CONTENTS:
=========
@@ -17,9 +16,9 @@ CONTENTS:
1.2 Why are cpusets needed ?
1.3 How are cpusets implemented ?
1.4 What are exclusive cpusets ?
- 1.5 What is memory_pressure ?
- 1.6 What is memory spread ?
- 1.7 What is sched_load_balance ?
+ 1.5 What does notify_on_release do ?
+ 1.6 What is memory_pressure ?
+ 1.7 What is memory spread ?
1.8 How do I use cpusets ?
2. Usage Examples and Syntax
2.1 Basic Usage
@@ -45,19 +44,18 @@ hierarchy visible in a virtual file system. These are the essential
hooks, beyond what is already present, required to manage dynamic
job placement on large systems.
-Cpusets use the generic cgroup subsystem described in
-Documentation/cgroup.txt.
-
-Requests by a task, using the sched_setaffinity(2) system call to
-include CPUs in its CPU affinity mask, and using the mbind(2) and
-set_mempolicy(2) system calls to include Memory Nodes in its memory
-policy, are both filtered through that tasks cpuset, filtering out any
-CPUs or Memory Nodes not in that cpuset. The scheduler will not
-schedule a task on a CPU that is not allowed in its cpus_allowed
-vector, and the kernel page allocator will not allocate a page on a
-node that is not allowed in the requesting tasks mems_allowed vector.
-
-User level code may create and destroy cpusets by name in the cgroup
+Each task has a pointer to a cpuset. Multiple tasks may reference
+the same cpuset. Requests by a task, using the sched_setaffinity(2)
+system call to include CPUs in its CPU affinity mask, and using the
+mbind(2) and set_mempolicy(2) system calls to include Memory Nodes
+in its memory policy, are both filtered through that tasks cpuset,
+filtering out any CPUs or Memory Nodes not in that cpuset. The
+scheduler will not schedule a task on a CPU that is not allowed in
+its cpus_allowed vector, and the kernel page allocator will not
+allocate a page on a node that is not allowed in the requesting tasks
+mems_allowed vector.
+
+User level code may create and destroy cpusets by name in the cpuset
virtual file system, manage the attributes and permissions of these
cpusets and which CPUs and Memory Nodes are assigned to each cpuset,
specify and query to which cpuset a task is assigned, and list the
@@ -117,7 +115,7 @@ Cpusets extends these two mechanisms as follows:
- Cpusets are sets of allowed CPUs and Memory Nodes, known to the
kernel.
- Each task in the system is attached to a cpuset, via a pointer
- in the task structure to a reference counted cgroup structure.
+ in the task structure to a reference counted cpuset structure.
- Calls to sched_setaffinity are filtered to just those CPUs
allowed in that tasks cpuset.
- Calls to mbind and set_mempolicy are filtered to just
@@ -147,10 +145,15 @@ into the rest of the kernel, none in performance critical paths:
- in page_alloc.c, to restrict memory to allowed nodes.
- in vmscan.c, to restrict page recovery to the current cpuset.
-You should mount the "cgroup" filesystem type in order to enable
-browsing and modifying the cpusets presently known to the kernel. No
-new system calls are added for cpusets - all support for querying and
-modifying cpusets is via this cpuset file system.
+In addition a new file system, of type "cpuset" may be mounted,
+typically at /dev/cpuset, to enable browsing and modifying the cpusets
+presently known to the kernel. No new system calls are added for
+cpusets - all support for querying and modifying cpusets is via
+this cpuset file system.
+
+Each task under /proc has an added file named 'cpuset', displaying
+the cpuset name, as the path relative to the root of the cpuset file
+system.
The /proc//status file for each task has two added lines,
displaying the tasks cpus_allowed (on which CPUs it may be scheduled)
@@ -160,15 +163,16 @@ in the format seen in the following example:
Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff
Mems_allowed: ffffffff,ffffffff
-Each cpuset is represented by a directory in the cgroup file system
-containing (on top of the standard cgroup files) the following
-files describing that cpuset:
+Each cpuset is represented by a directory in the cpuset file system
+containing the following files describing that cpuset:
- cpus: list of CPUs in that cpuset
- mems: list of Memory Nodes in that cpuset
- memory_migrate flag: if set, move pages to cpusets nodes
- cpu_exclusive flag: is cpu placement exclusive?
- mem_exclusive flag: is memory placement exclusive?
+ - tasks: list of tasks (by pid) attached to that cpuset
+ - notify_on_release flag: run /sbin/cpuset_release_agent on exit?
- memory_pressure: measure of how much paging pressure in cpuset
In addition, the root cpuset only has the following file:
@@ -233,7 +237,21 @@ such as requests from interrupt handlers, is allowed to be taken
outside even a mem_exclusive cpuset.
-1.5 What is memory_pressure ?
+1.5 What does notify_on_release do ?
+------------------------------------
+
+If the notify_on_release flag is enabled (1) in a cpuset, then whenever
+the last task in the cpuset leaves (exits or attaches to some other
+cpuset) and the last child cpuset of that cpuset is removed, then
+the kernel runs the command /sbin/cpuset_release_agent, supplying the
+pathname (relative to the mount point of the cpuset file system) of the
+abandoned cpuset. This enables automatic removal of abandoned cpusets.
+The default value of notify_on_release in the root cpuset at system
+boot is disabled (0). The default value of other cpusets at creation
+is the current value of their parents notify_on_release setting.
+
+
+1.6 What is memory_pressure ?
-----------------------------
The memory_pressure of a cpuset provides a simple per-cpuset metric
of the rate that the tasks in a cpuset are attempting to free up in
@@ -290,7 +308,7 @@ the tasks in the cpuset, in units of reclaims attempted per second,
times 1000.
-1.6 What is memory spread ?
+1.7 What is memory spread ?
---------------------------
There are two boolean flag files per cpuset that control where the
kernel allocates pages for the file system buffers and related in
@@ -360,142 +378,6 @@ policy, especially for jobs that might have one thread reading in the
data set, the memory allocation across the nodes in the jobs cpuset
can become very uneven.
-1.7 What is sched_load_balance ?
---------------------------------
-
-The kernel scheduler (kernel/sched.c) automatically load balances
-tasks. If one CPU is underutilized, kernel code running on that
-CPU will look for tasks on other more overloaded CPUs and move those
-tasks to itself, within the constraints of such placement mechanisms
-as cpusets and sched_setaffinity.
-
-The algorithmic cost of load balancing and its impact on key shared
-kernel data structures such as the task list increases more than
-linearly with the number of CPUs being balanced. So the scheduler
-has support to partition the systems CPUs into a number of sched
-domains such that it only load balances within each sched domain.
-Each sched domain covers some subset of the CPUs in the system;
-no two sched domains overlap; some CPUs might not be in any sched
-domain and hence won't be load balanced.
-
-Put simply, it costs less to balance between two smaller sched domains
-than one big one, but doing so means that overloads in one of the
-two domains won't be load balanced to the other one.
-
-By default, there is one sched domain covering all CPUs, except those
-marked isolated using the kernel boot time "isolcpus=" argument.
-
-This default load balancing across all CPUs is not well suited for
-the following two situations:
- 1) On large systems, load balancing across many CPUs is expensive.
- If the system is managed using cpusets to place independent jobs
- on separate sets of CPUs, full load balancing is unnecessary.
- 2) Systems supporting realtime on some CPUs need to minimize
- system overhead on those CPUs, including avoiding task load
- balancing if that is not needed.
-
-When the per-cpuset flag "sched_load_balance" is enabled (the default
-setting), it requests that all the CPUs in that cpusets allowed 'cpus'
-be contained in a single sched domain, ensuring that load balancing
-can move a task (not otherwised pinned, as by sched_setaffinity)
-from any CPU in that cpuset to any other.
-
-When the per-cpuset flag "sched_load_balance" is disabled, then the
-scheduler will avoid load balancing across the CPUs in that cpuset,
---except-- in so far as is necessary because some overlapping cpuset
-has "sched_load_balance" enabled.
-
-So, for example, if the top cpuset has the flag "sched_load_balance"
-enabled, then the scheduler will have one sched domain covering all
-CPUs, and the setting of the "sched_load_balance" flag in any other
-cpusets won't matter, as we're already fully load balancing.
-
-Therefore in the above two situations, the top cpuset flag
-"sched_load_balance" should be disabled, and only some of the smaller,
-child cpusets have this flag enabled.
-
-When doing this, you don't usually want to leave any unpinned tasks in
-the top cpuset that might use non-trivial amounts of CPU, as such tasks
-may be artificially constrained to some subset of CPUs, depending on
-the particulars of this flag setting in descendent cpusets. Even if
-such a task could use spare CPU cycles in some other CPUs, the kernel
-scheduler might not consider the possibility of load balancing that
-task to that underused CPU.
-
-Of course, tasks pinned to a particular CPU can be left in a cpuset
-that disables "sched_load_balance" as those tasks aren't going anywhere
-else anyway.
-
-There is an impedance mismatch here, between cpusets and sched domains.
-Cpusets are hierarchical and nest. Sched domains are flat; they don't
-overlap and each CPU is in at most one sched domain.
-
-It is necessary for sched domains to be flat because load balancing
-across partially overlapping sets of CPUs would risk unstable dynamics
-that would be beyond our understanding. So if each of two partially
-overlapping cpusets enables the flag 'sched_load_balance', then we
-form a single sched domain that is a superset of both. We won't move
-a task to a CPU outside it cpuset, but the scheduler load balancing
-code might waste some compute cycles considering that possibility.
-
-This mismatch is why there is not a simple one-to-one relation
-between which cpusets have the flag "sched_load_balance" enabled,
-and the sched domain configuration. If a cpuset enables the flag, it
-will get balancing across all its CPUs, but if it disables the flag,
-it will only be assured of no load balancing if no other overlapping
-cpuset enables the flag.
-
-If two cpusets have partially overlapping 'cpus' allowed, and only
-one of them has this flag enabled, then the other may find its
-tasks only partially load balanced, just on the overlapping CPUs.
-This is just the general case of the top_cpuset example given a few
-paragraphs above. In the general case, as in the top cpuset case,
-don't leave tasks that might use non-trivial amounts of CPU in
-such partially load balanced cpusets, as they may be artificially
-constrained to some subset of the CPUs allowed to them, for lack of
-load balancing to the other CPUs.
-
-1.7.1 sched_load_balance implementation details.
-------------------------------------------------
-
-The per-cpuset flag 'sched_load_balance' defaults to enabled (contrary
-to most cpuset flags.) When enabled for a cpuset, the kernel will
-ensure that it can load balance across all the CPUs in that cpuset
-(makes sure that all the CPUs in the cpus_allowed of that cpuset are
-in the same sched domain.)
-
-If two overlapping cpusets both have 'sched_load_balance' enabled,
-then they will be (must be) both in the same sched domain.
-
-If, as is the default, the top cpuset has 'sched_load_balance' enabled,
-then by the above that means there is a single sched domain covering
-the whole system, regardless of any other cpuset settings.
-
-The kernel commits to user space that it will avoid load balancing
-where it can. It will pick as fine a granularity partition of sched
-domains as it can while still providing load balancing for any set
-of CPUs allowed to a cpuset having 'sched_load_balance' enabled.
-
-The internal kernel cpuset to scheduler interface passes from the
-cpuset code to the scheduler code a partition of the load balanced
-CPUs in the system. This partition is a set of subsets (represented
-as an array of cpumask_t) of CPUs, pairwise disjoint, that cover all
-the CPUs that must be load balanced.
-
-Whenever the 'sched_load_balance' flag changes, or CPUs come or go
-from a cpuset with this flag enabled, or a cpuset with this flag
-enabled is removed, the cpuset code builds a new such partition and
-passes it to the scheduler sched domain setup code, to have the sched
-domains rebuilt as necessary.
-
-This partition exactly defines what sched domains the scheduler should
-setup - one sched domain for each element (cpumask_t) in the partition.
-
-The scheduler remembers the currently active sched domain partitions.
-When the scheduler routine partition_sched_domains() is invoked from
-the cpuset code to update these sched domains, it compares the new
-partition requested with the current, and updates its sched domains,
-removing the old and adding the new, for each change.
1.8 How do I use cpusets ?
--------------------------
@@ -587,7 +469,7 @@ than stress the kernel.
To start a new job that is to be contained within a cpuset, the steps are:
1) mkdir /dev/cpuset
- 2) mount -t cgroup -ocpuset cpuset /dev/cpuset
+ 2) mount -t cpuset none /dev/cpuset
3) Create the new cpuset by doing mkdir's and write's (or echo's) in
the /dev/cpuset virtual file system.
4) Start a task that will be the "founding father" of the new job.
@@ -599,7 +481,7 @@ For example, the following sequence of commands will setup a cpuset
named "Charlie", containing just CPUs 2 and 3, and Memory Node 1,
and then start a subshell 'sh' in that cpuset:
- mount -t cgroup -ocpuset cpuset /dev/cpuset
+ mount -t cpuset none /dev/cpuset
cd /dev/cpuset
mkdir Charlie
cd Charlie
@@ -631,7 +513,7 @@ Creating, modifying, using the cpusets can be done through the cpuset
virtual filesystem.
To mount it, type:
-# mount -t cgroup -o cpuset cpuset /dev/cpuset
+# mount -t cpuset none /dev/cpuset
Then under /dev/cpuset you can find a tree that corresponds to the
tree of the cpusets in the system. For instance, /dev/cpuset
@@ -674,18 +556,6 @@ To remove a cpuset, just use rmdir:
This will fail if the cpuset is in use (has cpusets inside, or has
processes attached).
-Note that for legacy reasons, the "cpuset" filesystem exists as a
-wrapper around the cgroup filesystem.
-
-The command
-
-mount -t cpuset X /dev/cpuset
-
-is equivalent to
-
-mount -t cgroup -ocpuset X /dev/cpuset
-echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent
-
2.2 Adding/removing cpus
------------------------
diff --git a/trunk/Documentation/device-mapper/dm-uevent.txt b/trunk/Documentation/device-mapper/dm-uevent.txt
deleted file mode 100644
index 07edbd85c714..000000000000
--- a/trunk/Documentation/device-mapper/dm-uevent.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-The device-mapper uevent code adds the capability to device-mapper to create
-and send kobject uevents (uevents). Previously device-mapper events were only
-available through the ioctl interface. The advantage of the uevents interface
-is the event contains environment attributes providing increased context for
-the event avoiding the need to query the state of the device-mapper device after
-the event is received.
-
-There are two functions currently for device-mapper events. The first function
-listed creates the event and the second function sends the event(s).
-
-void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
- const char *path, unsigned nr_valid_paths)
-
-void dm_send_uevents(struct list_head *events, struct kobject *kobj)
-
-
-The variables added to the uevent environment are:
-
-Variable Name: DM_TARGET
-Uevent Action(s): KOBJ_CHANGE
-Type: string
-Description:
-Value: Name of device-mapper target that generated the event.
-
-Variable Name: DM_ACTION
-Uevent Action(s): KOBJ_CHANGE
-Type: string
-Description:
-Value: Device-mapper specific action that caused the uevent action.
- PATH_FAILED - A path has failed.
- PATH_REINSTATED - A path has been reinstated.
-
-Variable Name: DM_SEQNUM
-Uevent Action(s): KOBJ_CHANGE
-Type: unsigned integer
-Description: A sequence number for this specific device-mapper device.
-Value: Valid unsigned integer range.
-
-Variable Name: DM_PATH
-Uevent Action(s): KOBJ_CHANGE
-Type: string
-Description: Major and minor number of the path device pertaining to this
-event.
-Value: Path name in the form of "Major:Minor"
-
-Variable Name: DM_NR_VALID_PATHS
-Uevent Action(s): KOBJ_CHANGE
-Type: unsigned integer
-Description:
-Value: Valid unsigned integer range.
-
-Variable Name: DM_NAME
-Uevent Action(s): KOBJ_CHANGE
-Type: string
-Description: Name of the device-mapper device.
-Value: Name
-
-Variable Name: DM_UUID
-Uevent Action(s): KOBJ_CHANGE
-Type: string
-Description: UUID of the device-mapper device.
-Value: UUID. (Empty string if there isn't one.)
-
-An example of the uevents generated as captured by udevmonitor is shown
-below.
-
-1.) Path failure.
-UEVENT[1192521009.711215] change@/block/dm-3
-ACTION=change
-DEVPATH=/block/dm-3
-SUBSYSTEM=block
-DM_TARGET=multipath
-DM_ACTION=PATH_FAILED
-DM_SEQNUM=1
-DM_PATH=8:32
-DM_NR_VALID_PATHS=0
-DM_NAME=mpath2
-DM_UUID=mpath-35333333000002328
-MINOR=3
-MAJOR=253
-SEQNUM=1130
-
-2.) Path reinstate.
-UEVENT[1192521132.989927] change@/block/dm-3
-ACTION=change
-DEVPATH=/block/dm-3
-SUBSYSTEM=block
-DM_TARGET=multipath
-DM_ACTION=PATH_REINSTATED
-DM_SEQNUM=2
-DM_PATH=8:32
-DM_NR_VALID_PATHS=1
-DM_NAME=mpath2
-DM_UUID=mpath-35333333000002328
-MINOR=3
-MAJOR=253
-SEQNUM=1131
diff --git a/trunk/Documentation/input/input-programming.txt b/trunk/Documentation/input/input-programming.txt
index 4d932dc66098..d9d523099bb7 100644
--- a/trunk/Documentation/input/input-programming.txt
+++ b/trunk/Documentation/input/input-programming.txt
@@ -42,8 +42,8 @@ static int __init button_init(void)
goto err_free_irq;
}
- button_dev->evbit[0] = BIT_MASK(EV_KEY);
- button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
+ button_dev->evbit[0] = BIT(EV_KEY);
+ button_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
error = input_register_device(button_dev);
if (error) {
@@ -217,15 +217,14 @@ If you don't need absfuzz and absflat, you can set them to zero, which mean
that the thing is precise and always returns to exactly the center position
(if it has any).
-1.4 BITS_TO_LONGS(), BIT_WORD(), BIT_MASK()
+1.4 NBITS(), LONG(), BIT()
~~~~~~~~~~~~~~~~~~~~~~~~~~
-These three macros from bitops.h help some bitfield computations:
+These three macros from input.h help some bitfield computations:
- BITS_TO_LONGS(x) - returns the length of a bitfield array in longs for
- x bits
- BIT_WORD(x) - returns the index in the array in longs for bit x
- BIT_MASK(x) - returns the index in a long for bit x
+ NBITS(x) - returns the length of a bitfield array in longs for x bits
+ LONG(x) - returns the index in the array in longs for bit x
+ BIT(x) - returns the index in a long for bit x
1.5 The id* and name fields
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/trunk/Documentation/kbuild/kconfig-language.txt b/trunk/Documentation/kbuild/kconfig-language.txt
index 616043a6da99..fe8b0c4892cf 100644
--- a/trunk/Documentation/kbuild/kconfig-language.txt
+++ b/trunk/Documentation/kbuild/kconfig-language.txt
@@ -77,12 +77,7 @@ applicable everywhere (see syntax).
Optionally, dependencies only for this default value can be added with
"if".
-- type definition + default value:
- "def_bool"/"def_tristate" ["if" ]
- This is a shorthand notation for a type definition plus a value.
- Optionally dependencies for this default value can be added with "if".
-
-- dependencies: "depends on"
+- dependencies: "depends on"/"requires"
This defines a dependency for this menu entry. If multiple
dependencies are defined, they are connected with '&&'. Dependencies
are applied to all other options within this menu entry (which also
@@ -294,10 +289,3 @@ source:
"source"
This reads the specified configuration file. This file is always parsed.
-
-mainmenu:
-
- "mainmenu"
-
-This sets the config program's title bar if the config program chooses
-to use it.
diff --git a/trunk/Documentation/kbuild/makefiles.txt b/trunk/Documentation/kbuild/makefiles.txt
index 6166e2d7da76..f099b814d383 100644
--- a/trunk/Documentation/kbuild/makefiles.txt
+++ b/trunk/Documentation/kbuild/makefiles.txt
@@ -518,28 +518,6 @@ more details, with real examples.
In this example for a specific GCC version the build will error out explaining
to the user why it stops.
- cc-cross-prefix
- cc-cross-prefix is used to check if there exist a $(CC) in path with
- one of the listed prefixes. The first prefix where there exist a
- prefix$(CC) in the PATH is returned - and if no prefix$(CC) is found
- then nothing is returned.
- Additional prefixes are separated by a single space in the
- call of cc-cross-prefix.
- This functionality is usefull for architecture Makefile that try
- to set CROSS_COMPILE to well know values but may have several
- values to select between.
- It is recommended only to try to set CROSS_COMPILE is it is a cross
- build (host arch is different from target arch). And is CROSS_COMPILE
- is already set then leave it with the old value.
-
- Example:
- #arch/m68k/Makefile
- ifneq ($(SUBARCH),$(ARCH))
- ifeq ($(CROSS_COMPILE),)
- CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu-)
- endif
- endif
-
=== 4 Host Program support
Kbuild supports building executables on the host for use during the
diff --git a/trunk/Documentation/kdump/kdump.txt b/trunk/Documentation/kdump/kdump.txt
index d0ac72cc19ff..1b37b28cc234 100644
--- a/trunk/Documentation/kdump/kdump.txt
+++ b/trunk/Documentation/kdump/kdump.txt
@@ -231,32 +231,6 @@ Dump-capture kernel config options (Arch Dependent, ia64)
any space below the alignment point will be wasted.
-Extended crashkernel syntax
-===========================
-
-While the "crashkernel=size[@offset]" syntax is sufficient for most
-configurations, sometimes it's handy to have the reserved memory dependent
-on the value of System RAM -- that's mostly for distributors that pre-setup
-the kernel command line to avoid a unbootable system after some memory has
-been removed from the machine.
-
-The syntax is:
-
- crashkernel=:[,:,...][@offset]
- range=start-[end]
-
-For example:
-
- crashkernel=512M-2G:64M,2G-:128M
-
-This would mean:
-
- 1) if the RAM is smaller than 512M, then don't reserve anything
- (this is the "rescue" case)
- 2) if the RAM size is between 512M and 2G, then reserve 64M
- 3) if the RAM size is larger than 2G, then reserve 128M
-
-
Boot into System Kernel
=======================
diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt
index 7bf6bd2f530b..189df0bcab99 100644
--- a/trunk/Documentation/kernel-parameters.txt
+++ b/trunk/Documentation/kernel-parameters.txt
@@ -431,10 +431,8 @@ and is between 256 and 4096 characters. It is defined in the file
over the 8254 in addition to over the IO-APIC. The
kernel tries to set a sensible default.
- hpet= [X86-32,HPET] option to control HPET usage
- Format: { enable (default) | disable | force }
- disable: disable HPET and use PIT instead
- force: allow force enabled of undocumented chips (ICH4, VIA)
+ hpet= [X86-32,HPET] option to disable HPET and use PIT.
+ Format: disable
com20020= [HW,NET] ARCnet - COM20020 chipset
Format:
@@ -499,13 +497,6 @@ and is between 256 and 4096 characters. It is defined in the file
[KNL] Reserve a chunk of physical memory to
hold a kernel to switch to with kexec on panic.
- crashkernel=range1:size1[,range2:size2,...][@offset]
- [KNL] Same as above, but depends on the memory
- in the running system. The syntax of range is
- start-[end] where start and end are both
- a memory unit (amount[KMG]). See also
- Documentation/kdump/kdump.txt for a example.
-
cs4232= [HW,OSS]
Format: ,,,,,
diff --git a/trunk/Documentation/markers.txt b/trunk/Documentation/markers.txt
deleted file mode 100644
index 295a71bc301e..000000000000
--- a/trunk/Documentation/markers.txt
+++ /dev/null
@@ -1,81 +0,0 @@
- Using the Linux Kernel Markers
-
- Mathieu Desnoyers
-
-
-This document introduces Linux Kernel Markers and their use. It provides
-examples of how to insert markers in the kernel and connect probe functions to
-them and provides some examples of probe functions.
-
-
-* Purpose of markers
-
-A marker placed in code provides a hook to call a function (probe) that you can
-provide at runtime. A marker can be "on" (a probe is connected to it) or "off"
-(no probe is attached). When a marker is "off" it has no effect, except for
-adding a tiny time penalty (checking a condition for a branch) and space
-penalty (adding a few bytes for the function call at the end of the
-instrumented function and adds a data structure in a separate section). When a
-marker is "on", the function you provide is called each time the marker is
-executed, in the execution context of the caller. When the function provided
-ends its execution, it returns to the caller (continuing from the marker site).
-
-You can put markers at important locations in the code. Markers are
-lightweight hooks that can pass an arbitrary number of parameters,
-described in a printk-like format string, to the attached probe function.
-
-They can be used for tracing and performance accounting.
-
-
-* Usage
-
-In order to use the macro trace_mark, you should include linux/marker.h.
-
-#include
-
-And,
-
-trace_mark(subsystem_event, "%d %s", someint, somestring);
-Where :
-- subsystem_event is an identifier unique to your event
- - subsystem is the name of your subsystem.
- - event is the name of the event to mark.
-- "%d %s" is the formatted string for the serializer.
-- someint is an integer.
-- somestring is a char pointer.
-
-Connecting a function (probe) to a marker is done by providing a probe (function
-to call) for the specific marker through marker_probe_register() and can be
-activated by calling marker_arm(). Marker deactivation can be done by calling
-marker_disarm() as many times as marker_arm() has been called. Removing a probe
-is done through marker_probe_unregister(); it will disarm the probe and make
-sure there is no caller left using the probe when it returns. Probe removal is
-preempt-safe because preemption is disabled around the probe call. See the
-"Probe example" section below for a sample probe module.
-
-The marker mechanism supports inserting multiple instances of the same marker.
-Markers can be put in inline functions, inlined static functions, and
-unrolled loops as well as regular functions.
-
-The naming scheme "subsystem_event" is suggested here as a convention intended
-to limit collisions. Marker names are global to the kernel: they are considered
-as being the same whether they are in the core kernel image or in modules.
-Conflicting format strings for markers with the same name will cause the markers
-to be detected to have a different format string not to be armed and will output
-a printk warning which identifies the inconsistency:
-
-"Format mismatch for probe probe_name (format), marker (format)"
-
-
-* Probe / marker example
-
-See the example provided in samples/markers/src
-
-Compile them with your kernel.
-
-Run, as root :
-modprobe marker-example (insmod order is not important)
-modprobe probe-example
-cat /proc/marker-example (returns an expected error)
-rmmod marker-example probe-example
-dmesg
diff --git a/trunk/Documentation/mips/00-INDEX b/trunk/Documentation/mips/00-INDEX
index 3f13bf8043d2..9df8a2eac7b4 100644
--- a/trunk/Documentation/mips/00-INDEX
+++ b/trunk/Documentation/mips/00-INDEX
@@ -4,3 +4,5 @@ AU1xxx_IDE.README
- README for MIPS AU1XXX IDE driver.
GT64120.README
- README for dir with info on MIPS boards using GT-64120 or GT-64120A.
+time.README
+ - README for MIPS time services.
diff --git a/trunk/Documentation/mips/time.README b/trunk/Documentation/mips/time.README
new file mode 100644
index 000000000000..a4ce603ed3b3
--- /dev/null
+++ b/trunk/Documentation/mips/time.README
@@ -0,0 +1,173 @@
+README for MIPS time services
+
+Jun Sun
+jsun@mvista.com or jsun@junsun.net
+
+
+ABOUT
+-----
+This file describes the new arch/mips/kernel/time.c, related files and the
+services they provide.
+
+If you are short in patience and just want to know how to use time.c for a
+new board or convert an existing board, go to the last section.
+
+
+FILES, COMPATABILITY AND CONFIGS
+---------------------------------
+
+The old arch/mips/kernel/time.c is renamed to old-time.c.
+
+A new time.c is put there, together with include/asm-mips/time.h.
+
+Two configs variables are introduced, CONFIG_OLD_TIME_C and CONFIG_NEW_TIME_C.
+So we allow boards using
+
+ 1) old time.c (CONFIG_OLD_TIME_C)
+ 2) new time.c (CONFIG_NEW_TIME_C)
+ 3) neither (their own private time.c)
+
+However, it is expected every board will move to the new time.c in the near
+future.
+
+
+WHAT THE NEW CODE PROVIDES?
+---------------------------
+
+The new time code provide the following services:
+
+ a) Implements functions required by Linux common code:
+ time_init
+
+ b) provides an abstraction of RTC and null RTC implementation as default.
+ extern unsigned long (*rtc_get_time)(void);
+ extern int (*rtc_set_time)(unsigned long);
+
+ c) high-level and low-level timer interrupt routines where the timer
+ interrupt source may or may not be the CPU timer. The high-level
+ routine is dispatched through do_IRQ() while the low-level is
+ dispatched in assemably code (usually int-handler.S)
+
+
+WHAT THE NEW CODE REQUIRES?
+---------------------------
+
+For the new code to work properly, each board implementation needs to supply
+the following functions or values:
+
+ a) board_time_init - a function pointer. Invoked at the beginnig of
+ time_init(). It is optional.
+ 1. (optional) set up RTC routines
+ 2. (optional) calibrate and set the mips_hpt_frequency
+
+ b) plat_timer_setup - a function pointer. Invoked at the end of time_init()
+ 1. (optional) over-ride any decisions made in time_init()
+ 2. set up the irqaction for timer interrupt.
+ 3. enable the timer interrupt
+
+ c) (optional) board-specific RTC routines.
+
+ d) (optional) mips_hpt_frequency - It must be definied if the board
+ is using CPU counter for timer interrupt.
+
+
+PORTING GUIDE
+-------------
+
+Step 1: decide how you like to implement the time services.
+
+ a) does this board have a RTC? If yes, implement the two RTC funcs.
+
+ b) does the CPU have counter/compare registers?
+
+ If the answer is no, you need a timer to provide the timer interrupt
+ at 100 HZ speed.
+
+ c) The following sub steps assume your CPU has counter register.
+ Do you plan to use the CPU counter register as the timer interrupt
+ or use an exnternal timer?
+
+ In order to use CPU counter register as the timer interrupt source, you
+ must know the counter speed (mips_hpt_frequency). It is usually the
+ same as the CPU speed or an integral divisor of it.
+
+ d) decide on whether you want to use high-level or low-level timer
+ interrupt routines. The low-level one is presumably faster, but should
+ not make too mcuh difference.
+
+
+Step 2: the machine setup() function
+
+ If you supply board_time_init(), set the function poointer.
+
+
+Step 3: implement rtc routines, board_time_init() and plat_timer_setup()
+ if needed.
+
+ board_time_init() -
+ a) (optional) set up RTC routines,
+ b) (optional) calibrate and set the mips_hpt_frequency
+ (only needed if you intended to use cpu counter as timer interrupt
+ source)
+
+ plat_timer_setup() -
+ a) (optional) over-write any choices made above by time_init().
+ b) machine specific code should setup the timer irqaction.
+ c) enable the timer interrupt
+
+
+ If the RTC chip is a common chip, I suggest the routines are put under
+ arch/mips/libs. For example, for DS1386 chip, one would create
+ rtc-ds1386.c under arch/mips/lib directory. Add the following line to
+ the arch/mips/lib/Makefile:
+
+ obj-$(CONFIG_DDB5476) += rtc-ds1386.o
+
+Step 4: if you are using low-level timer interrupt, change your interrupt
+ dispathcing code to check for timer interrupt and jump to
+ ll_timer_interrupt() directly if one is detected.
+
+Step 5: Modify arch/mips/config.in and add CONFIG_NEW_TIME_C to your machine.
+ Modify the appropriate defconfig if applicable.
+
+Final notes:
+
+For some tricky cases, you may need to add your own wrapper functions
+for some of the functions in time.c.
+
+For example, you may define your own timer interrupt routine, which does
+some of its own processing and then calls timer_interrupt().
+
+You can also over-ride any of the built-in functions (RTC routines
+and/or timer interrupt routine).
+
+
+PORTING NOTES FOR SMP
+----------------------
+
+If you have a SMP box, things are slightly more complicated.
+
+The time service running every jiffy is logically divided into two parts:
+
+ 1) the one for the whole system (defined in timer_interrupt())
+ 2) the one that should run for each CPU (defined in local_timer_interrupt())
+
+You need to decide on your timer interrupt sources.
+
+ case 1) - whole system has only one timer interrupt delivered to one CPU
+
+ In this case, you set up timer interrupt as in UP systems. In addtion,
+ you need to set emulate_local_timer_interrupt to 1 so that other
+ CPUs get to call local_timer_interrupt().
+
+ THIS IS CURRENTLY NOT IMPLEMNETED. However, it is rather easy to write
+ one should such a need arise. You simply make a IPI call.
+
+ case 2) - each CPU has a separate timer interrupt
+
+ In this case, you need to set up IRQ such that each of them will
+ call local_timer_interrupt(). In addition, you need to arrange
+ one and only one of them to call timer_interrupt().
+
+ You can also do the low-level version of those interrupt routines,
+ following similar dispatching routes described above.
diff --git a/trunk/Documentation/thinkpad-acpi.txt b/trunk/Documentation/thinkpad-acpi.txt
index 3b95bbacc775..60953d6c919d 100644
--- a/trunk/Documentation/thinkpad-acpi.txt
+++ b/trunk/Documentation/thinkpad-acpi.txt
@@ -105,15 +105,10 @@ The version of thinkpad-acpi's sysfs interface is exported by the driver
as a driver attribute (see below).
Sysfs driver attributes are on the driver's sysfs attribute space,
-for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and
-/sys/bus/platform/drivers/thinkpad_hwmon/
+for 2.6.20 this is /sys/bus/platform/drivers/thinkpad_acpi/.
-Sysfs device attributes are on the thinkpad_acpi device sysfs attribute
-space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/.
-
-Sysfs device attributes for the sensors and fan are on the
-thinkpad_hwmon device's sysfs attribute space, but you should locate it
-looking for a hwmon device with the name attribute of "thinkpad".
+Sysfs device attributes are on the driver's sysfs attribute space,
+for 2.6.20 this is /sys/devices/platform/thinkpad_acpi/.
Driver version
--------------
@@ -771,7 +766,7 @@ Temperature sensors
-------------------
procfs: /proc/acpi/ibm/thermal
-sysfs device attributes: (hwmon "thinkpad") temp*_input
+sysfs device attributes: (hwmon) temp*_input
Most ThinkPads include six or more separate temperature sensors but only
expose the CPU temperature through the standard ACPI methods. This
@@ -994,9 +989,7 @@ Fan control and monitoring: fan speed, fan enable/disable
---------------------------------------------------------
procfs: /proc/acpi/ibm/fan
-sysfs device attributes: (hwmon "thinkpad") fan1_input, pwm1,
- pwm1_enable
-sysfs hwmon driver attributes: fan_watchdog
+sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable
NOTE NOTE NOTE: fan control operations are disabled by default for
safety reasons. To enable them, the module parameter "fan_control=1"
@@ -1138,7 +1131,7 @@ hwmon device attribute fan1_input:
which can take up to two minutes. May return rubbish on older
ThinkPads.
-hwmon driver attribute fan_watchdog:
+driver attribute fan_watchdog:
Fan safety watchdog timer interval, in seconds. Minimum is
1 second, maximum is 120 seconds. 0 disables the watchdog.
@@ -1240,9 +1233,3 @@ Sysfs interface changelog:
layer, the radio switch generates input event EV_RADIO,
and the driver enables hot key handling by default in
the firmware.
-
-0x020000: ABI fix: added a separate hwmon platform device and
- driver, which must be located by name (thinkpad)
- and the hwmon class for libsensors4 (lm-sensors 3)
- compatibility. Moved all hwmon attributes to this
- new platform device.
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index 4ed41394e492..2534dc4aa95a 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -2178,7 +2178,7 @@ S: Maintained
KCONFIG
P: Roman Zippel
M: zippel@linux-m68k.org
-L: linux-kbuild@vger.kernel.org
+L: kbuild-devel@lists.sourceforge.net
S: Maintained
KDUMP
@@ -2207,7 +2207,6 @@ KERNEL BUILD (kbuild: Makefile, scripts/Makefile.*)
P: Sam Ravnborg
M: sam@ravnborg.org
T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
-L: linux-kbuild@vger.kernel.org
S: Maintained
KERNEL JANITORS
diff --git a/trunk/Makefile b/trunk/Makefile
index f9c264e243a2..529b9048d97e 100644
--- a/trunk/Makefile
+++ b/trunk/Makefile
@@ -773,9 +773,6 @@ endef
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) vmlinux.o FORCE
ifdef CONFIG_HEADERS_CHECK
$(Q)$(MAKE) -f $(srctree)/Makefile headers_check
-endif
-ifdef CONFIG_SAMPLES
- $(Q)$(MAKE) $(build)=samples
endif
$(call vmlinux-modpost)
$(call if_changed_rule,vmlinux__)
@@ -887,7 +884,10 @@ prepare2: prepare3 outputmakefile
prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \
include/asm include/config/auto.conf
- $(cmd_crmodverdir)
+ifneq ($(KBUILD_MODULES),)
+ $(Q)mkdir -p $(MODVERDIR)
+ $(Q)rm -f $(MODVERDIR)/*
+endif
archprepare: prepare1 scripts_basic
@@ -903,24 +903,14 @@ prepare: prepare0
export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
-# The asm symlink changes when $(ARCH) changes.
-# Detect this and ask user to run make mrproper
-
-include/asm: FORCE
- $(Q)set -e; asmlink=`readlink include/asm | cut -d '-' -f 2`; \
- if [ -L include/asm ]; then \
- if [ "$$asmlink" != "$(SRCARCH)" ]; then \
- echo "ERROR: the symlink $@ points to asm-$$asmlink but asm-$(SRCARCH) was expected"; \
- echo " set ARCH or save .config and run 'make mrproper' to fix it"; \
- exit 1; \
- fi; \
- else \
- echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \
- if [ ! -d include ]; then \
- mkdir -p include; \
- fi; \
- ln -fsn asm-$(SRCARCH) $@; \
- fi
+# FIXME: The asm symlink changes when $(ARCH) changes. That's
+# hard to detect, but I suppose "make mrproper" is a good idea
+# before switching between archs anyway.
+
+include/asm:
+ @echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'
+ $(Q)if [ ! -d include ]; then mkdir -p include; fi;
+ @ln -fsn asm-$(SRCARCH) $@
# Generate some files
# ---------------------------------------------------------------------------
@@ -1030,12 +1020,19 @@ _modinst_:
fi
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
-# This depmod is only for convenience to give the initial
+# If System.map exists, run depmod. This deliberately does not have a
+# dependency on System.map since that would run the dependency tree on
+# vmlinux. This depmod is only for convenience to give the initial
# boot a modules.dep even before / is mounted read-write. However the
# boot script depmod is the master version.
+ifeq "$(strip $(INSTALL_MOD_PATH))" ""
+depmod_opts :=
+else
+depmod_opts := -b $(INSTALL_MOD_PATH) -r
+endif
PHONY += _modinst_post
_modinst_post: _modinst_
- $(call cmd,depmod)
+ if [ -r System.map -a -x $(DEPMOD) ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi
else # CONFIG_MODULES
@@ -1223,7 +1220,8 @@ else # KBUILD_EXTMOD
KBUILD_MODULES := 1
PHONY += crmodverdir
crmodverdir:
- $(cmd_crmodverdir)
+ $(Q)mkdir -p $(MODVERDIR)
+ $(Q)rm -f $(MODVERDIR)/*
PHONY += $(objtree)/Module.symvers
$(objtree)/Module.symvers:
@@ -1251,6 +1249,15 @@ _emodinst_:
$(Q)mkdir -p $(MODLIB)/$(install-dir)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
+# Run depmod only is we have System.map and depmod is executable
+quiet_cmd_depmod = DEPMOD $(KERNELRELEASE)
+ cmd_depmod = if [ -r System.map -a -x $(DEPMOD) ]; then \
+ $(DEPMOD) -ae -F System.map \
+ $(if $(strip $(INSTALL_MOD_PATH)), \
+ -b $(INSTALL_MOD_PATH) -r) \
+ $(KERNELRELEASE); \
+ fi
+
PHONY += _emodinst_post
_emodinst_post: _emodinst_
$(call cmd,depmod)
@@ -1334,7 +1341,7 @@ define find-sources
find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
-name $1 -print; \
find $(__srctree) $(RCS_FIND_IGNORE) \
- \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \
+ \( -name include -o -name arch \) -prune -o \
-name $1 -print; \
)
endef
@@ -1483,11 +1490,9 @@ endif
# Modules
/ %/: prepare scripts FORCE
- $(cmd_crmodverdir)
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
$(build)=$(build-dir)
%.ko: prepare scripts FORCE
- $(cmd_crmodverdir)
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
$(build)=$(build-dir) $(@:.ko=.o)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
@@ -1501,19 +1506,6 @@ quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN $(wildcard $(rm-dirs)))
quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files)))
cmd_rmfiles = rm -f $(rm-files)
-# Run depmod only is we have System.map and depmod is executable
-# and we build for the host arch
-quiet_cmd_depmod = DEPMOD $(KERNELRELEASE)
- cmd_depmod = \
- if [ -r System.map -a -x $(DEPMOD) -a "$(SUBARCH)" == "$(ARCH)" ]; then \
- $(DEPMOD) -ae -F System.map \
- $(if $(strip $(INSTALL_MOD_PATH)), -b $(INSTALL_MOD_PATH) -r) \
- $(KERNELRELEASE); \
- fi
-
-# Create temporary dir for module support files
-cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR); rm -f $(MODVERDIR)/*
-
a_flags = -Wp,-MD,$(depfile) $(KBUILD_AFLAGS) $(AFLAGS_KERNEL) \
$(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig
index 4c002ba37e50..2a85dc33907c 100644
--- a/trunk/arch/alpha/Kconfig
+++ b/trunk/arch/alpha/Kconfig
@@ -654,7 +654,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
+source "arch/alpha/oprofile/Kconfig"
source "arch/alpha/Kconfig.debug"
diff --git a/trunk/arch/alpha/kernel/semaphore.c b/trunk/arch/alpha/kernel/semaphore.c
index 8d2982aa1b8d..8c8aaa205eae 100644
--- a/trunk/arch/alpha/kernel/semaphore.c
+++ b/trunk/arch/alpha/kernel/semaphore.c
@@ -69,7 +69,7 @@ __down_failed(struct semaphore *sem)
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down failed(%p)\n",
- tsk->comm, task_pid_nr(tsk), sem);
+ tsk->comm, tsk->pid, sem);
#endif
tsk->state = TASK_UNINTERRUPTIBLE;
@@ -98,7 +98,7 @@ __down_failed(struct semaphore *sem)
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down acquired(%p)\n",
- tsk->comm, task_pid_nr(tsk), sem);
+ tsk->comm, tsk->pid, sem);
#endif
}
@@ -111,7 +111,7 @@ __down_failed_interruptible(struct semaphore *sem)
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down failed(%p)\n",
- tsk->comm, task_pid_nr(tsk), sem);
+ tsk->comm, tsk->pid, sem);
#endif
tsk->state = TASK_INTERRUPTIBLE;
@@ -139,7 +139,7 @@ __down_failed_interruptible(struct semaphore *sem)
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down %s(%p)\n",
- current->comm, task_pid_nr(current),
+ current->comm, current->pid,
(ret < 0 ? "interrupted" : "acquired"), sem);
#endif
return ret;
@@ -168,7 +168,7 @@ down(struct semaphore *sem)
#endif
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down(%p) from %p\n",
- current->comm, task_pid_nr(current), sem,
+ current->comm, current->pid, sem,
atomic_read(&sem->count), __builtin_return_address(0));
#endif
__down(sem);
@@ -182,7 +182,7 @@ down_interruptible(struct semaphore *sem)
#endif
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down(%p) from %p\n",
- current->comm, task_pid_nr(current), sem,
+ current->comm, current->pid, sem,
atomic_read(&sem->count), __builtin_return_address(0));
#endif
return __down_interruptible(sem);
@@ -201,7 +201,7 @@ down_trylock(struct semaphore *sem)
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down_trylock %s from %p\n",
- current->comm, task_pid_nr(current),
+ current->comm, current->pid,
ret ? "failed" : "acquired",
__builtin_return_address(0));
#endif
@@ -217,7 +217,7 @@ up(struct semaphore *sem)
#endif
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): up(%p) from %p\n",
- current->comm, task_pid_nr(current), sem,
+ current->comm, current->pid, sem,
atomic_read(&sem->count), __builtin_return_address(0));
#endif
__up(sem);
diff --git a/trunk/arch/alpha/kernel/traps.c b/trunk/arch/alpha/kernel/traps.c
index 2dc7f9fed213..ec0f05e0d8ff 100644
--- a/trunk/arch/alpha/kernel/traps.c
+++ b/trunk/arch/alpha/kernel/traps.c
@@ -182,7 +182,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
#ifdef CONFIG_SMP
printk("CPU %d ", hard_smp_processor_id());
#endif
- printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err);
+ printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
dik_show_regs(regs, r9_15);
add_taint(TAINT_DIE);
dik_show_trace((unsigned long *)(regs+1));
@@ -646,7 +646,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
lock_kernel();
printk("%s(%d): unhandled unaligned exception\n",
- current->comm, task_pid_nr(current));
+ current->comm, current->pid);
printk("pc = [<%016lx>] ra = [<%016lx>] ps = %04lx\n",
pc, una_reg(26), regs->ps);
@@ -786,7 +786,7 @@ do_entUnaUser(void __user * va, unsigned long opcode,
}
if (++cnt < 5) {
printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",
- current->comm, task_pid_nr(current),
+ current->comm, current->pid,
regs->pc - 4, va, opcode, reg);
}
last_time = jiffies;
diff --git a/trunk/arch/alpha/lib/fls.c b/trunk/arch/alpha/lib/fls.c
index 32afaa3fa686..7ad84ea0acf8 100644
--- a/trunk/arch/alpha/lib/fls.c
+++ b/trunk/arch/alpha/lib/fls.c
@@ -3,7 +3,7 @@
*/
#include
-#include
+#include
/* This is fls(x)-1, except zero is held to zero. This allows most
efficent input into extbl, plus it allows easy handling of fls(0)=0. */
diff --git a/trunk/arch/alpha/mm/fault.c b/trunk/arch/alpha/mm/fault.c
index 4829f96585b1..25154df3055a 100644
--- a/trunk/arch/alpha/mm/fault.c
+++ b/trunk/arch/alpha/mm/fault.c
@@ -188,13 +188,13 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
/* We ran out of memory, or some other thing happened to us that
made us unable to handle the page fault gracefully. */
out_of_memory:
- if (is_global_init(current)) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
}
printk(KERN_ALERT "VM: killing process %s(%d)\n",
- current->comm, task_pid_nr(current));
+ current->comm, current->pid);
if (!user_mode(regs))
goto no_context;
do_group_exit(SIGKILL);
diff --git a/trunk/arch/alpha/oprofile/Kconfig b/trunk/arch/alpha/oprofile/Kconfig
new file mode 100644
index 000000000000..5ade19801b97
--- /dev/null
+++ b/trunk/arch/alpha/oprofile/Kconfig
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+ depends on EXPERIMENTAL
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+endmenu
+
diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig
index 4cee938df01e..0a0c88d0039c 100644
--- a/trunk/arch/arm/Kconfig
+++ b/trunk/arch/arm/Kconfig
@@ -1068,7 +1068,7 @@ endmenu
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
+source "arch/arm/oprofile/Kconfig"
source "arch/arm/Kconfig.debug"
diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c
index 4f1a03124a74..93b7f8e22dcc 100644
--- a/trunk/arch/arm/kernel/process.c
+++ b/trunk/arch/arm/kernel/process.c
@@ -265,7 +265,7 @@ void __show_regs(struct pt_regs *regs)
void show_regs(struct pt_regs * regs)
{
printk("\n");
- printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm);
+ printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
__show_regs(regs);
__backtrace();
}
diff --git a/trunk/arch/arm/kernel/ptrace.c b/trunk/arch/arm/kernel/ptrace.c
index 4b05dc5c1023..5feee722ea98 100644
--- a/trunk/arch/arm/kernel/ptrace.c
+++ b/trunk/arch/arm/kernel/ptrace.c
@@ -382,16 +382,16 @@ static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp)
if (ret != 2 || old_insn.thumb != BREAKINST_THUMB)
printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at "
- "0x%08lx (0x%04x)\n", task->comm,
- task_pid_nr(task), addr, old_insn.thumb);
+ "0x%08lx (0x%04x)\n", task->comm, task->pid,
+ addr, old_insn.thumb);
} else {
ret = swap_insn(task, addr & ~3, &old_insn.arm,
&bp->insn.arm, 4);
if (ret != 4 || old_insn.arm != BREAKINST_ARM)
printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at "
- "0x%08lx (0x%08x)\n", task->comm,
- task_pid_nr(task), addr, old_insn.arm);
+ "0x%08lx (0x%08x)\n", task->comm, task->pid,
+ addr, old_insn.arm);
}
}
diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c
index 4764bd9ccee8..8ad47619c079 100644
--- a/trunk/arch/arm/kernel/traps.c
+++ b/trunk/arch/arm/kernel/traps.c
@@ -223,7 +223,7 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p
print_modules();
__show_regs(regs);
printk("Process %s (pid: %d, stack limit = 0x%p)\n",
- tsk->comm, task_pid_nr(tsk), thread + 1);
+ tsk->comm, tsk->pid, thread + 1);
if (!user_mode(regs) || in_interrupt()) {
dump_mem("Stack: ", regs->ARM_sp,
@@ -337,7 +337,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
#ifdef CONFIG_DEBUG_USER
if (user_debug & UDBG_UNDEFINED) {
printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
- current->comm, task_pid_nr(current), pc);
+ current->comm, current->pid, pc);
dump_instr(regs);
}
#endif
@@ -388,7 +388,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
#ifdef CONFIG_DEBUG_USER
if (user_debug & UDBG_SYSCALL) {
printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
- task_pid_nr(current), current->comm, n);
+ current->pid, current->comm, n);
dump_instr(regs);
}
#endif
@@ -565,7 +565,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
*/
if (user_debug & UDBG_SYSCALL) {
printk("[%d] %s: arm syscall %d\n",
- task_pid_nr(current), current->comm, no);
+ current->pid, current->comm, no);
dump_instr(regs);
if (user_mode(regs)) {
__show_regs(regs);
@@ -642,7 +642,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
#ifdef CONFIG_DEBUG_USER
if (user_debug & UDBG_BADABORT) {
printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
- task_pid_nr(current), current->comm, code, instr);
+ current->pid, current->comm, code, instr);
dump_instr(regs);
show_pte(current->mm, addr);
}
diff --git a/trunk/arch/arm/mm/alignment.c b/trunk/arch/arm/mm/alignment.c
index e162cca5917f..074b7cb07743 100644
--- a/trunk/arch/arm/mm/alignment.c
+++ b/trunk/arch/arm/mm/alignment.c
@@ -757,7 +757,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (ai_usermode & 1)
printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx "
"Address=0x%08lx FSR 0x%03x\n", current->comm,
- task_pid_nr(current), instrptr,
+ current->pid, instrptr,
thumb_mode(regs) ? 4 : 8,
thumb_mode(regs) ? tinstr : instr,
addr, fsr);
diff --git a/trunk/arch/arm/mm/fault.c b/trunk/arch/arm/mm/fault.c
index a8a7dab757eb..59ed1d05b71b 100644
--- a/trunk/arch/arm/mm/fault.c
+++ b/trunk/arch/arm/mm/fault.c
@@ -197,7 +197,7 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
return fault;
out_of_memory:
- if (!is_global_init(tsk))
+ if (!is_init(tsk))
goto out;
/*
diff --git a/trunk/arch/arm/oprofile/Kconfig b/trunk/arch/arm/oprofile/Kconfig
new file mode 100644
index 000000000000..afd93ad02feb
--- /dev/null
+++ b/trunk/arch/arm/oprofile/Kconfig
@@ -0,0 +1,42 @@
+
+menu "Profiling support"
+ depends on EXPERIMENTAL
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+if OPROFILE
+
+config OPROFILE_ARMV6
+ bool
+ depends on CPU_V6 && !SMP
+ default y
+ select OPROFILE_ARM11_CORE
+
+config OPROFILE_MPCORE
+ bool
+ depends on CPU_V6 && SMP
+ default y
+ select OPROFILE_ARM11_CORE
+
+config OPROFILE_ARM11_CORE
+ bool
+
+endif
+
+endmenu
+
diff --git a/trunk/arch/avr32/kernel/traps.c b/trunk/arch/avr32/kernel/traps.c
index 8a7caf8e7b45..9a73ce7eb50f 100644
--- a/trunk/arch/avr32/kernel/traps.c
+++ b/trunk/arch/avr32/kernel/traps.c
@@ -89,7 +89,7 @@ void _exception(long signr, struct pt_regs *regs, int code,
* generate the same exception over and over again and we get
* nowhere. Better to kill it and let the kernel panic.
*/
- if (is_global_init(current)) {
+ if (is_init(current)) {
__sighandler_t handler;
spin_lock_irq(¤t->sighand->siglock);
diff --git a/trunk/arch/avr32/mm/fault.c b/trunk/arch/avr32/mm/fault.c
index 6560cb18b4e3..11472f8701bd 100644
--- a/trunk/arch/avr32/mm/fault.c
+++ b/trunk/arch/avr32/mm/fault.c
@@ -160,7 +160,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
if (exception_trace && printk_ratelimit())
printk("%s%s[%d]: segfault at %08lx pc %08lx "
"sp %08lx ecr %lu\n",
- is_global_init(tsk) ? KERN_EMERG : KERN_INFO,
+ is_init(tsk) ? KERN_EMERG : KERN_INFO,
tsk->comm, tsk->pid, address, regs->pc,
regs->sp, ecr);
_exception(SIGSEGV, regs, code, address);
@@ -209,7 +209,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_global_init(current)) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
@@ -231,7 +231,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
if (exception_trace)
printk("%s%s[%d]: bus error at %08lx pc %08lx "
"sp %08lx ecr %lu\n",
- is_global_init(tsk) ? KERN_EMERG : KERN_INFO,
+ is_init(tsk) ? KERN_EMERG : KERN_INFO,
tsk->comm, tsk->pid, address, regs->pc,
regs->sp, ecr);
diff --git a/trunk/arch/blackfin/Kconfig b/trunk/arch/blackfin/Kconfig
index 4c5ca9d5e40f..aa9db3073312 100644
--- a/trunk/arch/blackfin/Kconfig
+++ b/trunk/arch/blackfin/Kconfig
@@ -1012,7 +1012,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
+source "arch/blackfin/oprofile/Kconfig"
menu "Kernel hacking"
diff --git a/trunk/arch/blackfin/oprofile/Kconfig b/trunk/arch/blackfin/oprofile/Kconfig
new file mode 100644
index 000000000000..0a2fd999c941
--- /dev/null
+++ b/trunk/arch/blackfin/oprofile/Kconfig
@@ -0,0 +1,29 @@
+menu "Profiling support"
+depends on EXPERIMENTAL
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+config HARDWARE_PM
+ tristate "Hardware Performance Monitor Profiling"
+ depends on PROFILING
+ help
+ take use of hardware performance monitor to profiling the kernel
+ and application.
+
+ If unsure, say N.
+
+endmenu
diff --git a/trunk/arch/cris/Kconfig b/trunk/arch/cris/Kconfig
index 21900a9378bb..6b4d026a00a1 100644
--- a/trunk/arch/cris/Kconfig
+++ b/trunk/arch/cris/Kconfig
@@ -196,8 +196,6 @@ source "sound/Kconfig"
source "drivers/usb/Kconfig"
-source "kernel/Kconfig.instrumentation"
-
source "arch/cris/Kconfig.debug"
source "security/Kconfig"
diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig
index 43153e767bb1..74eef7111f2b 100644
--- a/trunk/arch/frv/Kconfig
+++ b/trunk/arch/frv/Kconfig
@@ -375,8 +375,6 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
-
source "arch/frv/Kconfig.debug"
source "security/Kconfig"
diff --git a/trunk/arch/frv/kernel/irq-mb93091.c b/trunk/arch/frv/kernel/irq-mb93091.c
index 9e38f99bbab8..ad753c1e9b8f 100644
--- a/trunk/arch/frv/kernel/irq-mb93091.c
+++ b/trunk/arch/frv/kernel/irq-mb93091.c
@@ -17,10 +17,10 @@
#include
#include
#include
-#include
#include
#include
+#include
#include
#include
#include
diff --git a/trunk/arch/frv/kernel/irq-mb93093.c b/trunk/arch/frv/kernel/irq-mb93093.c
index 3c2752ca9775..e0983f6926ed 100644
--- a/trunk/arch/frv/kernel/irq-mb93093.c
+++ b/trunk/arch/frv/kernel/irq-mb93093.c
@@ -17,10 +17,10 @@
#include
#include
#include
-#include
#include
#include
+#include
#include
#include
#include
diff --git a/trunk/arch/frv/kernel/irq-mb93493.c b/trunk/arch/frv/kernel/irq-mb93493.c
index 7754c7338e4b..c157eeff871d 100644
--- a/trunk/arch/frv/kernel/irq-mb93493.c
+++ b/trunk/arch/frv/kernel/irq-mb93493.c
@@ -17,10 +17,10 @@
#include
#include
#include
-#include
#include
#include
+#include
#include
#include
#include
diff --git a/trunk/arch/frv/kernel/irq.c b/trunk/arch/frv/kernel/irq.c
index 7ddb69089ed4..c7e59dcadee4 100644
--- a/trunk/arch/frv/kernel/irq.c
+++ b/trunk/arch/frv/kernel/irq.c
@@ -24,12 +24,12 @@
#include
#include
#include
-#include
#include
#include
#include
#include
+#include
#include
#include
#include
diff --git a/trunk/arch/h8300/Kconfig b/trunk/arch/h8300/Kconfig
index e2e9f57abe2e..e35f74e6e505 100644
--- a/trunk/arch/h8300/Kconfig
+++ b/trunk/arch/h8300/Kconfig
@@ -223,8 +223,6 @@ endmenu
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
-
source "arch/h8300/Kconfig.debug"
source "security/Kconfig"
diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig
index d1bedbf9deb8..b84d5050e92e 100644
--- a/trunk/arch/i386/Kconfig
+++ b/trunk/arch/i386/Kconfig
@@ -1080,9 +1080,7 @@ config APM_REAL_MODE_POWER_OFF
endif # APM
-source "arch/x86/kernel/cpu/cpufreq/Kconfig_32"
-
-source "drivers/cpuidle/Kconfig"
+source "arch/x86/kernel/cpu/cpufreq/Kconfig"
endmenu
@@ -1258,6 +1256,31 @@ source "drivers/Kconfig"
source "fs/Kconfig"
+menuconfig INSTRUMENTATION
+ bool "Instrumentation Support"
+ default y
+ ---help---
+ Say Y here to get to see options related to performance measurement,
+ debugging, and testing. This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
+
+if INSTRUMENTATION
+
+source "arch/x86/oprofile/Kconfig"
+
+config KPROBES
+ bool "Kprobes"
+ depends on KALLSYMS && MODULES
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+
+endif # INSTRUMENTATION
+
source "arch/i386/Kconfig.debug"
source "security/Kconfig"
diff --git a/trunk/arch/i386/Makefile b/trunk/arch/i386/Makefile
index b88e47ca3032..f036d2dee3de 100644
--- a/trunk/arch/i386/Makefile
+++ b/trunk/arch/i386/Makefile
@@ -102,7 +102,7 @@ core-$(CONFIG_XEN) += arch/x86/xen/
# default subarch .h files
mflags-y += -Iinclude/asm-x86/mach-default
-head-y := arch/x86/kernel/head_32.o arch/x86/kernel/init_task.o
+head-y := arch/x86/kernel/head_32.o arch/x86/kernel/init_task_32.o
libs-y += arch/x86/lib/
core-y += arch/x86/kernel/ \
@@ -131,9 +131,9 @@ all: bzImage
zImage zlilo zdisk: KBUILD_IMAGE := arch/x86/boot/zImage
zImage bzImage: vmlinux
- $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
$(Q)mkdir -p $(objtree)/arch/i386/boot
- $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/i386/boot/bzImage
+ $(Q)ln -fsn $(objtree)/arch/x86/boot/bzImage $(objtree)/arch/i386/boot/bzImage
+ $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
compressed: zImage
diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig
index c89108e9770d..c60532d93c54 100644
--- a/trunk/arch/ia64/Kconfig
+++ b/trunk/arch/ia64/Kconfig
@@ -592,7 +592,20 @@ config IRQ_PER_CPU
source "arch/ia64/hp/sim/Kconfig"
-source "kernel/Kconfig.instrumentation"
+menu "Instrumentation Support"
+
+source "arch/ia64/oprofile/Kconfig"
+
+config KPROBES
+ bool "Kprobes"
+ depends on KALLSYMS && MODULES
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+endmenu
source "arch/ia64/Kconfig.debug"
diff --git a/trunk/arch/ia64/configs/sn2_defconfig b/trunk/arch/ia64/configs/sn2_defconfig
index 75fd90dc76a3..449d3e75bfc2 100644
--- a/trunk/arch/ia64/configs/sn2_defconfig
+++ b/trunk/arch/ia64/configs/sn2_defconfig
@@ -26,7 +26,6 @@ CONFIG_TASK_IO_ACCOUNTING=y
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=20
-CONFIG_CGROUPS=y
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
diff --git a/trunk/arch/ia64/ia32/sys_ia32.c b/trunk/arch/ia64/ia32/sys_ia32.c
index d025a22eb225..a3405b3c1eef 100644
--- a/trunk/arch/ia64/ia32/sys_ia32.c
+++ b/trunk/arch/ia64/ia32/sys_ia32.c
@@ -773,7 +773,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro
if (flags & MAP_SHARED)
printk(KERN_INFO
"%s(%d): emulate_mmap() can't share head (addr=0x%lx)\n",
- current->comm, task_pid_nr(current), start);
+ current->comm, current->pid, start);
ret = mmap_subpage(file, start, min(PAGE_ALIGN(start), end), prot, flags,
off);
if (IS_ERR((void *) ret))
@@ -786,7 +786,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro
if (flags & MAP_SHARED)
printk(KERN_INFO
"%s(%d): emulate_mmap() can't share tail (end=0x%lx)\n",
- current->comm, task_pid_nr(current), end);
+ current->comm, current->pid, end);
ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags,
(off + len) - offset_in_page(end));
if (IS_ERR((void *) ret))
@@ -816,7 +816,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro
if ((flags & MAP_SHARED) && !is_congruent)
printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap "
- "(addr=0x%lx,off=0x%llx)\n", current->comm, task_pid_nr(current), start, off);
+ "(addr=0x%lx,off=0x%llx)\n", current->comm, current->pid, start, off);
DBG("mmap_body: mapping [0x%lx-0x%lx) %s with poff 0x%llx\n", pstart, pend,
is_congruent ? "congruent" : "not congruent", poff);
diff --git a/trunk/arch/ia64/kernel/efi.c b/trunk/arch/ia64/kernel/efi.c
index 8e4894b205e2..73ca86d03810 100644
--- a/trunk/arch/ia64/kernel/efi.c
+++ b/trunk/arch/ia64/kernel/efi.c
@@ -967,7 +967,7 @@ find_memmap_space (void)
* to use. We can allocate partial granules only if the unavailable
* parts exist, and are WB.
*/
-unsigned long
+void
efi_memmap_init(unsigned long *s, unsigned long *e)
{
struct kern_memdesc *k, *prev = NULL;
@@ -1084,8 +1084,6 @@ efi_memmap_init(unsigned long *s, unsigned long *e)
/* reserve the memory we are using for kern_memmap */
*s = (u64)kern_memmap;
*e = (u64)++k;
-
- return total_mem;
}
void
diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c
index 59169bf7145f..f55fa07849c4 100644
--- a/trunk/arch/ia64/kernel/perfmon.c
+++ b/trunk/arch/ia64/kernel/perfmon.c
@@ -158,14 +158,14 @@
*/
#define PROTECT_CTX(c, f) \
do { \
- DPRINT(("spinlock_irq_save ctx %p by [%d]\n", c, task_pid_nr(current))); \
+ DPRINT(("spinlock_irq_save ctx %p by [%d]\n", c, current->pid)); \
spin_lock_irqsave(&(c)->ctx_lock, f); \
- DPRINT(("spinlocked ctx %p by [%d]\n", c, task_pid_nr(current))); \
+ DPRINT(("spinlocked ctx %p by [%d]\n", c, current->pid)); \
} while(0)
#define UNPROTECT_CTX(c, f) \
do { \
- DPRINT(("spinlock_irq_restore ctx %p by [%d]\n", c, task_pid_nr(current))); \
+ DPRINT(("spinlock_irq_restore ctx %p by [%d]\n", c, current->pid)); \
spin_unlock_irqrestore(&(c)->ctx_lock, f); \
} while(0)
@@ -227,12 +227,12 @@
#ifdef PFM_DEBUGGING
#define DPRINT(a) \
do { \
- if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
+ if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \
} while (0)
#define DPRINT_ovfl(a) \
do { \
- if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
+ if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \
} while (0)
#endif
@@ -913,7 +913,7 @@ pfm_mask_monitoring(struct task_struct *task)
unsigned long mask, val, ovfl_mask;
int i;
- DPRINT_ovfl(("masking monitoring for [%d]\n", task_pid_nr(task)));
+ DPRINT_ovfl(("masking monitoring for [%d]\n", task->pid));
ovfl_mask = pmu_conf->ovfl_val;
/*
@@ -992,12 +992,12 @@ pfm_restore_monitoring(struct task_struct *task)
ovfl_mask = pmu_conf->ovfl_val;
if (task != current) {
- printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task_pid_nr(task), task_pid_nr(current));
+ printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task->pid, current->pid);
return;
}
if (ctx->ctx_state != PFM_CTX_MASKED) {
printk(KERN_ERR "perfmon.%d: task[%d] current[%d] invalid state=%d\n", __LINE__,
- task_pid_nr(task), task_pid_nr(current), ctx->ctx_state);
+ task->pid, current->pid, ctx->ctx_state);
return;
}
psr = pfm_get_psr();
@@ -1051,8 +1051,7 @@ pfm_restore_monitoring(struct task_struct *task)
if ((mask & 0x1) == 0UL) continue;
ctx->th_pmcs[i] = ctx->ctx_pmcs[i];
ia64_set_pmc(i, ctx->th_pmcs[i]);
- DPRINT(("[%d] pmc[%d]=0x%lx\n",
- task_pid_nr(task), i, ctx->th_pmcs[i]));
+ DPRINT(("[%d] pmc[%d]=0x%lx\n", task->pid, i, ctx->th_pmcs[i]));
}
ia64_srlz_d();
@@ -1371,7 +1370,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
error_conflict:
DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n",
- task_pid_nr(pfm_sessions.pfs_sys_session[cpu]),
+ pfm_sessions.pfs_sys_session[cpu]->pid,
cpu));
abort:
UNLOCK_PFS(flags);
@@ -1443,7 +1442,7 @@ pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long siz
/* sanity checks */
if (task->mm == NULL || size == 0UL || vaddr == NULL) {
- printk(KERN_ERR "perfmon: pfm_remove_smpl_mapping [%d] invalid context mm=%p\n", task_pid_nr(task), task->mm);
+ printk(KERN_ERR "perfmon: pfm_remove_smpl_mapping [%d] invalid context mm=%p\n", task->pid, task->mm);
return -EINVAL;
}
@@ -1460,7 +1459,7 @@ pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long siz
up_write(&task->mm->mmap_sem);
if (r !=0) {
- printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size);
+ printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task->pid, vaddr, size);
}
DPRINT(("do_unmap(%p, %lu)=%d\n", vaddr, size, r));
@@ -1502,7 +1501,7 @@ pfm_free_smpl_buffer(pfm_context_t *ctx)
return 0;
invalid_free:
- printk(KERN_ERR "perfmon: pfm_free_smpl_buffer [%d] no buffer\n", task_pid_nr(current));
+ printk(KERN_ERR "perfmon: pfm_free_smpl_buffer [%d] no buffer\n", current->pid);
return -EINVAL;
}
#endif
@@ -1548,13 +1547,13 @@ pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
unsigned long flags;
DECLARE_WAITQUEUE(wait, current);
if (PFM_IS_FILE(filp) == 0) {
- printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current));
+ printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid);
return -EINVAL;
}
ctx = (pfm_context_t *)filp->private_data;
if (ctx == NULL) {
- printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", task_pid_nr(current));
+ printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", current->pid);
return -EINVAL;
}
@@ -1608,7 +1607,7 @@ pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
PROTECT_CTX(ctx, flags);
}
- DPRINT(("[%d] back to running ret=%ld\n", task_pid_nr(current), ret));
+ DPRINT(("[%d] back to running ret=%ld\n", current->pid, ret));
set_current_state(TASK_RUNNING);
remove_wait_queue(&ctx->ctx_msgq_wait, &wait);
@@ -1617,7 +1616,7 @@ pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
ret = -EINVAL;
msg = pfm_get_next_msg(ctx);
if (msg == NULL) {
- printk(KERN_ERR "perfmon: pfm_read no msg for ctx=%p [%d]\n", ctx, task_pid_nr(current));
+ printk(KERN_ERR "perfmon: pfm_read no msg for ctx=%p [%d]\n", ctx, current->pid);
goto abort_locked;
}
@@ -1648,13 +1647,13 @@ pfm_poll(struct file *filp, poll_table * wait)
unsigned int mask = 0;
if (PFM_IS_FILE(filp) == 0) {
- printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current));
+ printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid);
return 0;
}
ctx = (pfm_context_t *)filp->private_data;
if (ctx == NULL) {
- printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", task_pid_nr(current));
+ printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", current->pid);
return 0;
}
@@ -1693,7 +1692,7 @@ pfm_do_fasync(int fd, struct file *filp, pfm_context_t *ctx, int on)
ret = fasync_helper (fd, filp, on, &ctx->ctx_async_queue);
DPRINT(("pfm_fasync called by [%d] on ctx_fd=%d on=%d async_queue=%p ret=%d\n",
- task_pid_nr(current),
+ current->pid,
fd,
on,
ctx->ctx_async_queue, ret));
@@ -1708,13 +1707,13 @@ pfm_fasync(int fd, struct file *filp, int on)
int ret;
if (PFM_IS_FILE(filp) == 0) {
- printk(KERN_ERR "perfmon: pfm_fasync bad magic [%d]\n", task_pid_nr(current));
+ printk(KERN_ERR "perfmon: pfm_fasync bad magic [%d]\n", current->pid);
return -EBADF;
}
ctx = (pfm_context_t *)filp->private_data;
if (ctx == NULL) {
- printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", task_pid_nr(current));
+ printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", current->pid);
return -EBADF;
}
/*
@@ -1760,7 +1759,7 @@ pfm_syswide_force_stop(void *info)
if (owner != ctx->ctx_task) {
printk(KERN_ERR "perfmon: pfm_syswide_force_stop CPU%d unexpected owner [%d] instead of [%d]\n",
smp_processor_id(),
- task_pid_nr(owner), task_pid_nr(ctx->ctx_task));
+ owner->pid, ctx->ctx_task->pid);
return;
}
if (GET_PMU_CTX() != ctx) {
@@ -1770,7 +1769,7 @@ pfm_syswide_force_stop(void *info)
return;
}
- DPRINT(("on CPU%d forcing system wide stop for [%d]\n", smp_processor_id(), task_pid_nr(ctx->ctx_task)));
+ DPRINT(("on CPU%d forcing system wide stop for [%d]\n", smp_processor_id(), ctx->ctx_task->pid));
/*
* the context is already protected in pfm_close(), we simply
* need to mask interrupts to avoid a PMU interrupt race on
@@ -1822,7 +1821,7 @@ pfm_flush(struct file *filp, fl_owner_t id)
ctx = (pfm_context_t *)filp->private_data;
if (ctx == NULL) {
- printk(KERN_ERR "perfmon: pfm_flush: NULL ctx [%d]\n", task_pid_nr(current));
+ printk(KERN_ERR "perfmon: pfm_flush: NULL ctx [%d]\n", current->pid);
return -EBADF;
}
@@ -1970,7 +1969,7 @@ pfm_close(struct inode *inode, struct file *filp)
ctx = (pfm_context_t *)filp->private_data;
if (ctx == NULL) {
- printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", task_pid_nr(current));
+ printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", current->pid);
return -EBADF;
}
@@ -2067,7 +2066,7 @@ pfm_close(struct inode *inode, struct file *filp)
*/
ctx->ctx_state = PFM_CTX_ZOMBIE;
- DPRINT(("zombie ctx for [%d]\n", task_pid_nr(task)));
+ DPRINT(("zombie ctx for [%d]\n", task->pid));
/*
* cannot free the context on the spot. deferred until
* the task notices the ZOMBIE state
@@ -2473,7 +2472,7 @@ pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t
/* invoke and lock buffer format, if found */
fmt = pfm_find_buffer_fmt(arg->ctx_smpl_buf_id);
if (fmt == NULL) {
- DPRINT(("[%d] cannot find buffer format\n", task_pid_nr(task)));
+ DPRINT(("[%d] cannot find buffer format\n", task->pid));
return -EINVAL;
}
@@ -2484,7 +2483,7 @@ pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t
ret = pfm_buf_fmt_validate(fmt, task, ctx_flags, cpu, fmt_arg);
- DPRINT(("[%d] after validate(0x%x,%d,%p)=%d\n", task_pid_nr(task), ctx_flags, cpu, fmt_arg, ret));
+ DPRINT(("[%d] after validate(0x%x,%d,%p)=%d\n", task->pid, ctx_flags, cpu, fmt_arg, ret));
if (ret) goto error;
@@ -2606,23 +2605,23 @@ pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task)
* no kernel task or task not owner by caller
*/
if (task->mm == NULL) {
- DPRINT(("task [%d] has not memory context (kernel thread)\n", task_pid_nr(task)));
+ DPRINT(("task [%d] has not memory context (kernel thread)\n", task->pid));
return -EPERM;
}
if (pfm_bad_permissions(task)) {
- DPRINT(("no permission to attach to [%d]\n", task_pid_nr(task)));
+ DPRINT(("no permission to attach to [%d]\n", task->pid));
return -EPERM;
}
/*
* cannot block in self-monitoring mode
*/
if (CTX_OVFL_NOBLOCK(ctx) == 0 && task == current) {
- DPRINT(("cannot load a blocking context on self for [%d]\n", task_pid_nr(task)));
+ DPRINT(("cannot load a blocking context on self for [%d]\n", task->pid));
return -EINVAL;
}
if (task->exit_state == EXIT_ZOMBIE) {
- DPRINT(("cannot attach to zombie task [%d]\n", task_pid_nr(task)));
+ DPRINT(("cannot attach to zombie task [%d]\n", task->pid));
return -EBUSY;
}
@@ -2632,7 +2631,7 @@ pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task)
if (task == current) return 0;
if ((task->state != TASK_STOPPED) && (task->state != TASK_TRACED)) {
- DPRINT(("cannot attach to non-stopped task [%d] state=%ld\n", task_pid_nr(task), task->state));
+ DPRINT(("cannot attach to non-stopped task [%d] state=%ld\n", task->pid, task->state));
return -EBUSY;
}
/*
@@ -3513,7 +3512,7 @@ pfm_use_debug_registers(struct task_struct *task)
if (pmu_conf->use_rr_dbregs == 0) return 0;
- DPRINT(("called for [%d]\n", task_pid_nr(task)));
+ DPRINT(("called for [%d]\n", task->pid));
/*
* do it only once
@@ -3544,7 +3543,7 @@ pfm_use_debug_registers(struct task_struct *task)
DPRINT(("ptrace_use_dbregs=%u sys_use_dbregs=%u by [%d] ret = %d\n",
pfm_sessions.pfs_ptrace_use_dbregs,
pfm_sessions.pfs_sys_use_dbregs,
- task_pid_nr(task), ret));
+ task->pid, ret));
UNLOCK_PFS(flags);
@@ -3569,7 +3568,7 @@ pfm_release_debug_registers(struct task_struct *task)
LOCK_PFS(flags);
if (pfm_sessions.pfs_ptrace_use_dbregs == 0) {
- printk(KERN_ERR "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task_pid_nr(task));
+ printk(KERN_ERR "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task->pid);
ret = -1;
} else {
pfm_sessions.pfs_ptrace_use_dbregs--;
@@ -3621,7 +3620,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
/* sanity check */
if (unlikely(task == NULL)) {
- printk(KERN_ERR "perfmon: [%d] pfm_restart no task\n", task_pid_nr(current));
+ printk(KERN_ERR "perfmon: [%d] pfm_restart no task\n", current->pid);
return -EINVAL;
}
@@ -3630,7 +3629,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
fmt = ctx->ctx_buf_fmt;
DPRINT(("restarting self %d ovfl=0x%lx\n",
- task_pid_nr(task),
+ task->pid,
ctx->ctx_ovfl_regs[0]));
if (CTX_HAS_SMPL(ctx)) {
@@ -3654,11 +3653,11 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_PMD_LONG_RESET);
if (rst_ctrl.bits.mask_monitoring == 0) {
- DPRINT(("resuming monitoring for [%d]\n", task_pid_nr(task)));
+ DPRINT(("resuming monitoring for [%d]\n", task->pid));
if (state == PFM_CTX_MASKED) pfm_restore_monitoring(task);
} else {
- DPRINT(("keeping monitoring stopped for [%d]\n", task_pid_nr(task)));
+ DPRINT(("keeping monitoring stopped for [%d]\n", task->pid));
// cannot use pfm_stop_monitoring(task, regs);
}
@@ -3715,10 +3714,10 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
* "self-monitoring".
*/
if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) {
- DPRINT(("unblocking [%d] \n", task_pid_nr(task)));
+ DPRINT(("unblocking [%d] \n", task->pid));
complete(&ctx->ctx_restart_done);
} else {
- DPRINT(("[%d] armed exit trap\n", task_pid_nr(task)));
+ DPRINT(("[%d] armed exit trap\n", task->pid));
ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_RESET;
@@ -3806,7 +3805,7 @@ pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_
* don't bother if we are loaded and task is being debugged
*/
if (is_loaded && (thread->flags & IA64_THREAD_DBG_VALID) != 0) {
- DPRINT(("debug registers already in use for [%d]\n", task_pid_nr(task)));
+ DPRINT(("debug registers already in use for [%d]\n", task->pid));
return -EBUSY;
}
@@ -3847,7 +3846,7 @@ pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_
* is shared by all processes running on it
*/
if (first_time && can_access_pmu) {
- DPRINT(("[%d] clearing ibrs, dbrs\n", task_pid_nr(task)));
+ DPRINT(("[%d] clearing ibrs, dbrs\n", task->pid));
for (i=0; i < pmu_conf->num_ibrs; i++) {
ia64_set_ibr(i, 0UL);
ia64_dv_serialize_instruction();
@@ -4036,7 +4035,7 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
return -EBUSY;
}
DPRINT(("task [%d] ctx_state=%d is_system=%d\n",
- task_pid_nr(PFM_CTX_TASK(ctx)),
+ PFM_CTX_TASK(ctx)->pid,
state,
is_system));
/*
@@ -4094,7 +4093,7 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
* monitoring disabled in kernel at next reschedule
*/
ctx->ctx_saved_psr_up = 0;
- DPRINT(("task=[%d]\n", task_pid_nr(task)));
+ DPRINT(("task=[%d]\n", task->pid));
}
return 0;
}
@@ -4299,12 +4298,11 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
if (is_system) {
if (pfm_sessions.pfs_ptrace_use_dbregs) {
- DPRINT(("cannot load [%d] dbregs in use\n",
- task_pid_nr(task)));
+ DPRINT(("cannot load [%d] dbregs in use\n", task->pid));
ret = -EBUSY;
} else {
pfm_sessions.pfs_sys_use_dbregs++;
- DPRINT(("load [%d] increased sys_use_dbreg=%u\n", task_pid_nr(task), pfm_sessions.pfs_sys_use_dbregs));
+ DPRINT(("load [%d] increased sys_use_dbreg=%u\n", task->pid, pfm_sessions.pfs_sys_use_dbregs));
set_dbregs = 1;
}
}
@@ -4396,7 +4394,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
/* allow user level control */
ia64_psr(regs)->sp = 0;
- DPRINT(("clearing psr.sp for [%d]\n", task_pid_nr(task)));
+ DPRINT(("clearing psr.sp for [%d]\n", task->pid));
SET_LAST_CPU(ctx, smp_processor_id());
INC_ACTIVATION();
@@ -4431,7 +4429,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
*/
SET_PMU_OWNER(task, ctx);
- DPRINT(("context loaded on PMU for [%d]\n", task_pid_nr(task)));
+ DPRINT(("context loaded on PMU for [%d]\n", task->pid));
} else {
/*
* when not current, task MUST be stopped, so this is safe
@@ -4495,7 +4493,7 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
int prev_state, is_system;
int ret;
- DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task_pid_nr(task) : -1));
+ DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1));
prev_state = ctx->ctx_state;
is_system = ctx->ctx_fl_system;
@@ -4570,7 +4568,7 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
*/
ia64_psr(regs)->sp = 1;
- DPRINT(("setting psr.sp for [%d]\n", task_pid_nr(task)));
+ DPRINT(("setting psr.sp for [%d]\n", task->pid));
}
/*
* save PMDs to context
@@ -4610,7 +4608,7 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
ctx->ctx_fl_can_restart = 0;
ctx->ctx_fl_going_zombie = 0;
- DPRINT(("disconnected [%d] from context\n", task_pid_nr(task)));
+ DPRINT(("disconnected [%d] from context\n", task->pid));
return 0;
}
@@ -4633,7 +4631,7 @@ pfm_exit_thread(struct task_struct *task)
PROTECT_CTX(ctx, flags);
- DPRINT(("state=%d task [%d]\n", ctx->ctx_state, task_pid_nr(task)));
+ DPRINT(("state=%d task [%d]\n", ctx->ctx_state, task->pid));
state = ctx->ctx_state;
switch(state) {
@@ -4642,13 +4640,13 @@ pfm_exit_thread(struct task_struct *task)
* only comes to this function if pfm_context is not NULL, i.e., cannot
* be in unloaded state
*/
- printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task_pid_nr(task));
+ printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task->pid);
break;
case PFM_CTX_LOADED:
case PFM_CTX_MASKED:
ret = pfm_context_unload(ctx, NULL, 0, regs);
if (ret) {
- printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret);
+ printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, state, ret);
}
DPRINT(("ctx unloaded for current state was %d\n", state));
@@ -4657,12 +4655,12 @@ pfm_exit_thread(struct task_struct *task)
case PFM_CTX_ZOMBIE:
ret = pfm_context_unload(ctx, NULL, 0, regs);
if (ret) {
- printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret);
+ printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, state, ret);
}
free_ok = 1;
break;
default:
- printk(KERN_ERR "perfmon: pfm_exit_thread [%d] unexpected state=%d\n", task_pid_nr(task), state);
+ printk(KERN_ERR "perfmon: pfm_exit_thread [%d] unexpected state=%d\n", task->pid, state);
break;
}
UNPROTECT_CTX(ctx, flags);
@@ -4746,7 +4744,7 @@ pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags)
DPRINT(("context %d state=%d [%d] task_state=%ld must_stop=%d\n",
ctx->ctx_fd,
state,
- task_pid_nr(task),
+ task->pid,
task->state, PFM_CMD_STOPPED(cmd)));
/*
@@ -4793,7 +4791,7 @@ pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags)
*/
if (PFM_CMD_STOPPED(cmd)) {
if ((task->state != TASK_STOPPED) && (task->state != TASK_TRACED)) {
- DPRINT(("[%d] task not in stopped state\n", task_pid_nr(task)));
+ DPRINT(("[%d] task not in stopped state\n", task->pid));
return -EBUSY;
}
/*
@@ -4886,7 +4884,7 @@ sys_perfmonctl (int fd, int cmd, void __user *arg, int count)
* limit abuse to min page size
*/
if (unlikely(sz > PFM_MAX_ARGSIZE)) {
- printk(KERN_ERR "perfmon: [%d] argument too big %lu\n", task_pid_nr(current), sz);
+ printk(KERN_ERR "perfmon: [%d] argument too big %lu\n", current->pid, sz);
return -E2BIG;
}
@@ -5033,11 +5031,11 @@ pfm_context_force_terminate(pfm_context_t *ctx, struct pt_regs *regs)
{
int ret;
- DPRINT(("entering for [%d]\n", task_pid_nr(current)));
+ DPRINT(("entering for [%d]\n", current->pid));
ret = pfm_context_unload(ctx, NULL, 0, regs);
if (ret) {
- printk(KERN_ERR "pfm_context_force_terminate: [%d] unloaded failed with %d\n", task_pid_nr(current), ret);
+ printk(KERN_ERR "pfm_context_force_terminate: [%d] unloaded failed with %d\n", current->pid, ret);
}
/*
@@ -5074,7 +5072,7 @@ pfm_handle_work(void)
ctx = PFM_GET_CTX(current);
if (ctx == NULL) {
- printk(KERN_ERR "perfmon: [%d] has no PFM context\n", task_pid_nr(current));
+ printk(KERN_ERR "perfmon: [%d] has no PFM context\n", current->pid);
return;
}
@@ -5271,7 +5269,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
DPRINT_ovfl(("pmc0=0x%lx pid=%d iip=0x%lx, %s "
"used_pmds=0x%lx\n",
pmc0,
- task ? task_pid_nr(task): -1,
+ task ? task->pid: -1,
(regs ? regs->cr_iip : 0),
CTX_OVFL_NOBLOCK(ctx) ? "nonblocking" : "blocking",
ctx->ctx_used_pmds[0]));
@@ -5460,7 +5458,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
}
DPRINT_ovfl(("owner [%d] pending=%ld reason=%u ovfl_pmds=0x%lx ovfl_notify=0x%lx masked=%d\n",
- GET_PMU_OWNER() ? task_pid_nr(GET_PMU_OWNER()) : -1,
+ GET_PMU_OWNER() ? GET_PMU_OWNER()->pid : -1,
PFM_GET_WORK_PENDING(task),
ctx->ctx_fl_trap_reason,
ovfl_pmds,
@@ -5485,7 +5483,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
sanity_check:
printk(KERN_ERR "perfmon: CPU%d overflow handler [%d] pmc0=0x%lx\n",
smp_processor_id(),
- task ? task_pid_nr(task) : -1,
+ task ? task->pid : -1,
pmc0);
return;
@@ -5518,7 +5516,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
*
* Overall pretty hairy stuff....
*/
- DPRINT(("ctx is zombie for [%d], converted to spurious\n", task ? task_pid_nr(task): -1));
+ DPRINT(("ctx is zombie for [%d], converted to spurious\n", task ? task->pid: -1));
pfm_clear_psr_up();
ia64_psr(regs)->up = 0;
ia64_psr(regs)->sp = 1;
@@ -5579,13 +5577,13 @@ pfm_do_interrupt_handler(int irq, void *arg, struct pt_regs *regs)
report_spurious1:
printk(KERN_INFO "perfmon: spurious overflow interrupt on CPU%d: process %d has no PFM context\n",
- this_cpu, task_pid_nr(task));
+ this_cpu, task->pid);
pfm_unfreeze_pmu();
return -1;
report_spurious2:
printk(KERN_INFO "perfmon: spurious overflow interrupt on CPU%d: process %d, invalid flag\n",
this_cpu,
- task_pid_nr(task));
+ task->pid);
pfm_unfreeze_pmu();
return -1;
}
@@ -5872,8 +5870,7 @@ pfm_force_cleanup(pfm_context_t *ctx, struct pt_regs *regs)
ia64_psr(regs)->sp = 1;
if (GET_PMU_OWNER() == task) {
- DPRINT(("cleared ownership for [%d]\n",
- task_pid_nr(ctx->ctx_task)));
+ DPRINT(("cleared ownership for [%d]\n", ctx->ctx_task->pid));
SET_PMU_OWNER(NULL, NULL);
}
@@ -5885,7 +5882,7 @@ pfm_force_cleanup(pfm_context_t *ctx, struct pt_regs *regs)
task->thread.pfm_context = NULL;
task->thread.flags &= ~IA64_THREAD_PM_VALID;
- DPRINT(("force cleanup for [%d]\n", task_pid_nr(task)));
+ DPRINT(("force cleanup for [%d]\n", task->pid));
}
@@ -6429,7 +6426,7 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx)
if (PMD_IS_COUNTING(i)) {
DPRINT(("[%d] pmd[%d] ctx_pmd=0x%lx hw_pmd=0x%lx\n",
- task_pid_nr(task),
+ task->pid,
i,
ctx->ctx_pmds[i].val,
val & ovfl_val));
@@ -6451,11 +6448,11 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx)
*/
if (pmc0 & (1UL << i)) {
val += 1 + ovfl_val;
- DPRINT(("[%d] pmd[%d] overflowed\n", task_pid_nr(task), i));
+ DPRINT(("[%d] pmd[%d] overflowed\n", task->pid, i));
}
}
- DPRINT(("[%d] ctx_pmd[%d]=0x%lx pmd_val=0x%lx\n", task_pid_nr(task), i, val, pmd_val));
+ DPRINT(("[%d] ctx_pmd[%d]=0x%lx pmd_val=0x%lx\n", task->pid, i, val, pmd_val));
if (is_self) ctx->th_pmds[i] = pmd_val;
@@ -6796,14 +6793,14 @@ dump_pmu_state(const char *from)
printk("CPU%d from %s() current [%d] iip=0x%lx %s\n",
this_cpu,
from,
- task_pid_nr(current),
+ current->pid,
regs->cr_iip,
current->comm);
task = GET_PMU_OWNER();
ctx = GET_PMU_CTX();
- printk("->CPU%d owner [%d] ctx=%p\n", this_cpu, task ? task_pid_nr(task) : -1, ctx);
+ printk("->CPU%d owner [%d] ctx=%p\n", this_cpu, task ? task->pid : -1, ctx);
psr = pfm_get_psr();
@@ -6851,7 +6848,7 @@ pfm_inherit(struct task_struct *task, struct pt_regs *regs)
{
struct thread_struct *thread;
- DPRINT(("perfmon: pfm_inherit clearing state for [%d]\n", task_pid_nr(task)));
+ DPRINT(("perfmon: pfm_inherit clearing state for [%d]\n", task->pid));
thread = &task->thread;
diff --git a/trunk/arch/ia64/kernel/perfmon_default_smpl.c b/trunk/arch/ia64/kernel/perfmon_default_smpl.c
index a7af1cb419f9..ff80eab83b38 100644
--- a/trunk/arch/ia64/kernel/perfmon_default_smpl.c
+++ b/trunk/arch/ia64/kernel/perfmon_default_smpl.c
@@ -44,11 +44,11 @@ default_validate(struct task_struct *task, unsigned int flags, int cpu, void *da
int ret = 0;
if (data == NULL) {
- DPRINT(("[%d] no argument passed\n", task_pid_nr(task)));
+ DPRINT(("[%d] no argument passed\n", task->pid));
return -EINVAL;
}
- DPRINT(("[%d] validate flags=0x%x CPU%d\n", task_pid_nr(task), flags, cpu));
+ DPRINT(("[%d] validate flags=0x%x CPU%d\n", task->pid, flags, cpu));
/*
* must hold at least the buffer header + one minimally sized entry
@@ -88,7 +88,7 @@ default_init(struct task_struct *task, void *buf, unsigned int flags, int cpu, v
hdr->hdr_count = 0UL;
DPRINT(("[%d] buffer=%p buf_size=%lu hdr_size=%lu hdr_version=%u cur_offs=%lu\n",
- task_pid_nr(task),
+ task->pid,
buf,
hdr->hdr_buf_size,
sizeof(*hdr),
@@ -245,7 +245,7 @@ default_restart(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, stru
static int
default_exit(struct task_struct *task, void *buf, struct pt_regs *regs)
{
- DPRINT(("[%d] exit(%p)\n", task_pid_nr(task), buf));
+ DPRINT(("[%d] exit(%p)\n", task->pid, buf));
return 0;
}
diff --git a/trunk/arch/ia64/kernel/process.c b/trunk/arch/ia64/kernel/process.c
index 2418289ee5ca..c613fc0e91cc 100644
--- a/trunk/arch/ia64/kernel/process.c
+++ b/trunk/arch/ia64/kernel/process.c
@@ -105,8 +105,7 @@ show_regs (struct pt_regs *regs)
unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
print_modules();
- printk("\nPid: %d, CPU %d, comm: %20s\n", task_pid_nr(current),
- smp_processor_id(), current->comm);
+ printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm);
printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s\n",
regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
print_symbol("ip is at %s\n", ip);
diff --git a/trunk/arch/ia64/kernel/setup.c b/trunk/arch/ia64/kernel/setup.c
index cbf67f1aa291..c5cfcfa4c87c 100644
--- a/trunk/arch/ia64/kernel/setup.c
+++ b/trunk/arch/ia64/kernel/setup.c
@@ -208,48 +208,6 @@ static int __init register_memory(void)
__initcall(register_memory);
-
-#ifdef CONFIG_KEXEC
-static void __init setup_crashkernel(unsigned long total, int *n)
-{
- unsigned long long base = 0, size = 0;
- int ret;
-
- ret = parse_crashkernel(boot_command_line, total,
- &size, &base);
- if (ret == 0 && size > 0) {
- if (!base) {
- sort_regions(rsvd_region, *n);
- base = kdump_find_rsvd_region(size,
- rsvd_region, *n);
- }
- if (base != ~0UL) {
- printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
- "for crashkernel (System RAM: %ldMB)\n",
- (unsigned long)(size >> 20),
- (unsigned long)(base >> 20),
- (unsigned long)(total >> 20));
- rsvd_region[*n].start =
- (unsigned long)__va(base);
- rsvd_region[*n].end =
- (unsigned long)__va(base + size);
- (*n)++;
- crashk_res.start = base;
- crashk_res.end = base + size - 1;
- }
- }
- efi_memmap_res.start = ia64_boot_param->efi_memmap;
- efi_memmap_res.end = efi_memmap_res.start +
- ia64_boot_param->efi_memmap_size;
- boot_param_res.start = __pa(ia64_boot_param);
- boot_param_res.end = boot_param_res.start +
- sizeof(*ia64_boot_param);
-}
-#else
-static inline void __init setup_crashkernel(unsigned long total, int *n)
-{}
-#endif
-
/**
* reserve_memory - setup reserved memory areas
*
@@ -261,7 +219,6 @@ void __init
reserve_memory (void)
{
int n = 0;
- unsigned long total_memory;
/*
* none of the entries in this table overlap
@@ -297,11 +254,50 @@ reserve_memory (void)
n++;
#endif
- total_memory = efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
+ efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
n++;
- setup_crashkernel(total_memory, &n);
-
+#ifdef CONFIG_KEXEC
+ /* crashkernel=size@offset specifies the size to reserve for a crash
+ * kernel. If offset is 0, then it is determined automatically.
+ * By reserving this memory we guarantee that linux never set's it
+ * up as a DMA target.Useful for holding code to do something
+ * appropriate after a kernel panic.
+ */
+ {
+ char *from = strstr(boot_command_line, "crashkernel=");
+ unsigned long base, size;
+ if (from) {
+ size = memparse(from + 12, &from);
+ if (*from == '@')
+ base = memparse(from+1, &from);
+ else
+ base = 0;
+ if (size) {
+ if (!base) {
+ sort_regions(rsvd_region, n);
+ base = kdump_find_rsvd_region(size,
+ rsvd_region, n);
+ }
+ if (base != ~0UL) {
+ rsvd_region[n].start =
+ (unsigned long)__va(base);
+ rsvd_region[n].end =
+ (unsigned long)__va(base + size);
+ n++;
+ crashk_res.start = base;
+ crashk_res.end = base + size - 1;
+ }
+ }
+ }
+ efi_memmap_res.start = ia64_boot_param->efi_memmap;
+ efi_memmap_res.end = efi_memmap_res.start +
+ ia64_boot_param->efi_memmap_size;
+ boot_param_res.start = __pa(ia64_boot_param);
+ boot_param_res.end = boot_param_res.start +
+ sizeof(*ia64_boot_param);
+ }
+#endif
/* end of memory marker */
rsvd_region[n].start = ~0UL;
rsvd_region[n].end = ~0UL;
diff --git a/trunk/arch/ia64/kernel/signal.c b/trunk/arch/ia64/kernel/signal.c
index cdb64cc4d9c8..aeec8184e862 100644
--- a/trunk/arch/ia64/kernel/signal.c
+++ b/trunk/arch/ia64/kernel/signal.c
@@ -227,7 +227,7 @@ ia64_rt_sigreturn (struct sigscratch *scr)
si.si_signo = SIGSEGV;
si.si_errno = 0;
si.si_code = SI_KERNEL;
- si.si_pid = task_pid_vnr(current);
+ si.si_pid = current->pid;
si.si_uid = current->uid;
si.si_addr = sc;
force_sig_info(SIGSEGV, &si, current);
@@ -332,7 +332,7 @@ force_sigsegv_info (int sig, void __user *addr)
si.si_signo = SIGSEGV;
si.si_errno = 0;
si.si_code = SI_KERNEL;
- si.si_pid = task_pid_vnr(current);
+ si.si_pid = current->pid;
si.si_uid = current->uid;
si.si_addr = addr;
force_sig_info(SIGSEGV, &si, current);
diff --git a/trunk/arch/ia64/kernel/traps.c b/trunk/arch/ia64/kernel/traps.c
index 78d65cb947d2..3aeaf15e468b 100644
--- a/trunk/arch/ia64/kernel/traps.c
+++ b/trunk/arch/ia64/kernel/traps.c
@@ -61,7 +61,7 @@ die (const char *str, struct pt_regs *regs, long err)
if (++die.lock_owner_depth < 3) {
printk("%s[%d]: %s %ld [%d]\n",
- current->comm, task_pid_nr(current), str, err, ++die_counter);
+ current->comm, current->pid, str, err, ++die_counter);
(void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
show_regs(regs);
} else
@@ -315,7 +315,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
last.time = current_jiffies + 5 * HZ;
printk(KERN_WARNING
"%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
- current->comm, task_pid_nr(current), regs->cr_iip + ia64_psr(regs)->ri, isr);
+ current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
}
}
}
@@ -453,7 +453,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
if (code == 8) {
# ifdef CONFIG_IA64_PRINT_HAZARDS
printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
- current->comm, task_pid_nr(current),
+ current->comm, current->pid,
regs.cr_iip + ia64_psr(®s)->ri, regs.pr);
# endif
return;
diff --git a/trunk/arch/ia64/kernel/unaligned.c b/trunk/arch/ia64/kernel/unaligned.c
index 2173de9fe917..fe6aa5a9f8fa 100644
--- a/trunk/arch/ia64/kernel/unaligned.c
+++ b/trunk/arch/ia64/kernel/unaligned.c
@@ -1340,8 +1340,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
size_t len;
len = sprintf(buf, "%s(%d): unaligned access to 0x%016lx, "
- "ip=0x%016lx\n\r", current->comm,
- task_pid_nr(current),
+ "ip=0x%016lx\n\r", current->comm, current->pid,
ifa, regs->cr_iip + ipsr->ri);
/*
* Don't call tty_write_message() if we're in the kernel; we might
@@ -1364,7 +1363,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
"administrator\n"
"echo 0 > /proc/sys/kernel/ignore-"
"unaligned-usertrap to re-enable\n",
- current->comm, task_pid_nr(current));
+ current->comm, current->pid);
}
}
} else {
diff --git a/trunk/arch/ia64/mm/fault.c b/trunk/arch/ia64/mm/fault.c
index 7571076a16a1..32f26253c4e8 100644
--- a/trunk/arch/ia64/mm/fault.c
+++ b/trunk/arch/ia64/mm/fault.c
@@ -274,7 +274,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_global_init(current)) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c
index c6c19bf11bec..3e10152abbf0 100644
--- a/trunk/arch/ia64/mm/init.c
+++ b/trunk/arch/ia64/mm/init.c
@@ -127,8 +127,8 @@ ia64_init_addr_space (void)
vma->vm_mm = current->mm;
vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
vma->vm_end = vma->vm_start + PAGE_SIZE;
+ vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7];
vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
- vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
down_write(¤t->mm->mmap_sem);
if (insert_vm_struct(current->mm, vma)) {
up_write(¤t->mm->mmap_sem);
diff --git a/trunk/arch/ia64/oprofile/Kconfig b/trunk/arch/ia64/oprofile/Kconfig
new file mode 100644
index 000000000000..97271ab484dc
--- /dev/null
+++ b/trunk/arch/ia64/oprofile/Kconfig
@@ -0,0 +1,20 @@
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ Due to firmware bugs, you may need to use the "nohalt" boot
+ option if you're using OProfile with the hardware performance
+ counters.
+
+ If unsure, say N.
+
diff --git a/trunk/arch/m32r/Kconfig b/trunk/arch/m32r/Kconfig
index ab9a264cb194..bd5fe76401f1 100644
--- a/trunk/arch/m32r/Kconfig
+++ b/trunk/arch/m32r/Kconfig
@@ -426,7 +426,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
+source "arch/m32r/oprofile/Kconfig"
source "arch/m32r/Kconfig.debug"
diff --git a/trunk/arch/m32r/kernel/traps.c b/trunk/arch/m32r/kernel/traps.c
index 89ba4a0b5d51..97e0b1c0830e 100644
--- a/trunk/arch/m32r/kernel/traps.c
+++ b/trunk/arch/m32r/kernel/traps.c
@@ -196,7 +196,7 @@ static void show_registers(struct pt_regs *regs)
printk("SPI: %08lx\n", sp);
}
printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
- current->comm, task_pid_nr(current), 0xffff & i, 4096+(unsigned long)current);
+ current->comm, current->pid, 0xffff & i, 4096+(unsigned long)current);
/*
* When in-kernel, we also print out the stack and code at the
diff --git a/trunk/arch/m32r/mm/fault.c b/trunk/arch/m32r/mm/fault.c
index 4a71df4c1b30..70a766aad3e0 100644
--- a/trunk/arch/m32r/mm/fault.c
+++ b/trunk/arch/m32r/mm/fault.c
@@ -271,7 +271,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_global_init(tsk)) {
+ if (is_init(tsk)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/trunk/arch/m32r/oprofile/Kconfig b/trunk/arch/m32r/oprofile/Kconfig
new file mode 100644
index 000000000000..19d37730b664
--- /dev/null
+++ b/trunk/arch/m32r/oprofile/Kconfig
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+ depends on EXPERIMENTAL
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+endmenu
+
diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig
index 01dee84f840a..20a9c08e59c3 100644
--- a/trunk/arch/m68k/Kconfig
+++ b/trunk/arch/m68k/Kconfig
@@ -683,8 +683,6 @@ endmenu
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
-
source "arch/m68k/Kconfig.debug"
source "security/Kconfig"
diff --git a/trunk/arch/m68k/kernel/traps.c b/trunk/arch/m68k/kernel/traps.c
index 97f556fa4932..4e2752a0e89b 100644
--- a/trunk/arch/m68k/kernel/traps.c
+++ b/trunk/arch/m68k/kernel/traps.c
@@ -900,7 +900,7 @@ void show_registers(struct pt_regs *regs)
regs->d4, regs->d5, regs->a0, regs->a1);
printk("Process %s (pid: %d, task=%p)\n",
- current->comm, task_pid_nr(current), current);
+ current->comm, current->pid, current);
addr = (unsigned long)&fp->un;
printk("Frame format=%X ", regs->format);
switch (regs->format) {
@@ -1038,7 +1038,7 @@ void bad_super_trap (struct frame *fp)
fp->un.fmtb.daddr, space_names[ssw & DFC],
fp->ptregs.pc);
}
- printk ("Current process id is %d\n", task_pid_nr(current));
+ printk ("Current process id is %d\n", current->pid);
die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
}
diff --git a/trunk/arch/m68k/mm/fault.c b/trunk/arch/m68k/mm/fault.c
index f493f03231d5..eaa618681159 100644
--- a/trunk/arch/m68k/mm/fault.c
+++ b/trunk/arch/m68k/mm/fault.c
@@ -180,7 +180,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_global_init(current)) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/trunk/arch/m68knommu/Kconfig b/trunk/arch/m68knommu/Kconfig
index f52c627bdadd..185906b54cb0 100644
--- a/trunk/arch/m68knommu/Kconfig
+++ b/trunk/arch/m68knommu/Kconfig
@@ -696,8 +696,6 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
-
source "arch/m68knommu/Kconfig.debug"
source "security/Kconfig"
diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig
index 4dc142d394a3..cb027580cd1d 100644
--- a/trunk/arch/mips/Kconfig
+++ b/trunk/arch/mips/Kconfig
@@ -2005,7 +2005,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
+source "arch/mips/oprofile/Kconfig"
source "arch/mips/Kconfig.debug"
diff --git a/trunk/arch/mips/au1000/pb1200/irqmap.c b/trunk/arch/mips/au1000/pb1200/irqmap.c
index bdf00e2a35e4..5f48b0603796 100644
--- a/trunk/arch/mips/au1000/pb1200/irqmap.c
+++ b/trunk/arch/mips/au1000/pb1200/irqmap.c
@@ -36,8 +36,8 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/trunk/arch/mips/basler/excite/excite_irq.c b/trunk/arch/mips/basler/excite/excite_irq.c
index 4903e067916b..1ecab6350421 100644
--- a/trunk/arch/mips/basler/excite/excite_irq.c
+++ b/trunk/arch/mips/basler/excite/excite_irq.c
@@ -29,7 +29,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/trunk/arch/mips/bcm47xx/time.c b/trunk/arch/mips/bcm47xx/time.c
index 0c6f47b3fd94..0ab4676c8bd3 100644
--- a/trunk/arch/mips/bcm47xx/time.c
+++ b/trunk/arch/mips/bcm47xx/time.c
@@ -46,3 +46,10 @@ void __init plat_time_init(void)
/* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
mips_hpt_frequency = hz;
}
+
+void __init
+plat_timer_setup(struct irqaction *irq)
+{
+ /* Enable the timer interrupt */
+ setup_irq(7, irq);
+}
diff --git a/trunk/arch/mips/configs/ip27_defconfig b/trunk/arch/mips/configs/ip27_defconfig
index 892d4c38fd0d..49bcc58929ba 100644
--- a/trunk/arch/mips/configs/ip27_defconfig
+++ b/trunk/arch/mips/configs/ip27_defconfig
@@ -175,7 +175,6 @@ CONFIG_POSIX_MQUEUE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=15
-CONFIG_CGROUPS=y
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
diff --git a/trunk/arch/mips/configs/mipssim_defconfig b/trunk/arch/mips/configs/mipssim_defconfig
index 61b72f5a953e..86dcb7464353 100644
--- a/trunk/arch/mips/configs/mipssim_defconfig
+++ b/trunk/arch/mips/configs/mipssim_defconfig
@@ -1,68 +1,71 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.23
-# Thu Oct 18 22:45:52 2007
+# Linux kernel version: 2.6.20
+# Tue Feb 20 21:47:35 2007
#
CONFIG_MIPS=y
#
# Machine selection
#
-# CONFIG_MACH_ALCHEMY is not set
+CONFIG_ZONE_DMA=y
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
# CONFIG_BASLER_EXCITE is not set
-# CONFIG_BCM47XX is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
-# CONFIG_LEMOTE_FULONG is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
+# CONFIG_WR_PPMC is not set
CONFIG_MIPS_SIM=y
-# CONFIG_MARKEINS is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_MIPS_XXS1500 is not set
# CONFIG_PNX8550_JBS is not set
# CONFIG_PNX8550_STB810 is not set
-# CONFIG_PMC_MSP is not set
+# CONFIG_MACH_VR41XX is not set
# CONFIG_PMC_YOSEMITE is not set
# CONFIG_QEMU is not set
+# CONFIG_MARKEINS is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_BIGSUR is not set
# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
# CONFIG_SIBYTE_PTSWARM is not set
-# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SNI_RM is not set
# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
# CONFIG_TOSHIBA_RBTX4938 is not set
-# CONFIG_WR_PPMC is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_TIME=y
-CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
-CONFIG_BOOT_RAW=y
-CONFIG_CEVT_R4K=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-# CONFIG_HOTPLUG_CPU is not set
-# CONFIG_NO_IOPORT is not set
# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
@@ -73,11 +76,6 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_TICK_ONESHOT is not set
-# CONFIG_NO_HZ is not set
-# CONFIG_HIGH_RES_TIMERS is not set
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-# CONFIG_CPU_LOONGSON2 is not set
CONFIG_CPU_MIPS32_R1=y
# CONFIG_CPU_MIPS32_R2 is not set
# CONFIG_CPU_MIPS64_R1 is not set
@@ -117,8 +115,8 @@ CONFIG_CPU_HAS_PREFETCH=y
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
-CONFIG_SYS_SUPPORTS_MULTITHREADING=y
# CONFIG_MIPS_VPE_LOADER is not set
+# CONFIG_64BIT_PHYS_ADDR is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_GENERIC_HARDIRQS=y
@@ -132,52 +130,50 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=0
-CONFIG_VIRT_TO_BUS=y
+CONFIG_ZONE_DMA_FLAG=1
# CONFIG_HZ_48 is not set
-CONFIG_HZ_100=y
+# CONFIG_HZ_100 is not set
# CONFIG_HZ_128 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_256 is not set
-# CONFIG_HZ_1000 is not set
+CONFIG_HZ_1000=y
# CONFIG_HZ_1024 is not set
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=100
+CONFIG_HZ=1000
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
# CONFIG_KEXEC is not set
-# CONFIG_SECCOMP is not set
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# General setup
+# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
-# CONFIG_SWAP is not set
+CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
+# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
-# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
@@ -191,29 +187,31 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
+CONFIG_VM_EVENT_COUNTERS=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_KMOD=y
+
+#
+# Block layer
+#
CONFIG_BLOCK=y
# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
-# CONFIG_BLK_DEV_BSG is not set
#
# IO Schedulers
@@ -231,10 +229,17 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
#
-# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
# CONFIG_PCCARD is not set
+#
+# PCI Hotplug Support
+#
+
#
# Executable file formats
#
@@ -245,8 +250,9 @@ CONFIG_TRAD_SIGNALS=y
#
# Power management options
#
-# CONFIG_PM is not set
-CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
#
# Networking
@@ -256,50 +262,75 @@ CONFIG_NET=y
#
# Networking options
#
+# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_ASK_IP_FIB_HASH=y
# CONFIG_IP_FIB_TRIE is not set
CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_MULTIPLE_TABLES is not set
-# CONFIG_IP_ROUTE_MULTIPATH is not set
-# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
+CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
+CONFIG_SYN_COOKIES=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
+CONFIG_TCP_MD5SIG=y
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
-# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETWORK_SECMARK=y
# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -316,7 +347,44 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
#
# QoS and/or fair queueing
#
-# CONFIG_NET_SCHED is not set
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FIFO=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+# CONFIG_NET_CLS_FW is not set
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+# CONFIG_NET_CLS_POLICE is not set
+CONFIG_NET_ESTIMATOR=y
#
# Network testing
@@ -325,17 +393,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
-# CONFIG_RFKILL is not set
-# CONFIG_NET_9P is not set
+CONFIG_FIB_RULES=y
#
# Device Drivers
@@ -344,25 +403,52 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
#
# Generic Driver Options
#
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
CONFIG_BLK_DEV_NBD=y
# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
-# CONFIG_MISC_DEVICES is not set
+
+#
+# Misc devices
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
# CONFIG_IDE is not set
#
@@ -370,29 +456,48 @@ CONFIG_BLK_DEV_NBD=y
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
-# CONFIG_SCSI_DMA is not set
# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
-# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_VETH is not set
# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
-# CONFIG_AX88796 is not set
CONFIG_MIPS_SIM_NET=y
# CONFIG_DM9000 is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_B44 is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
@@ -408,18 +513,49 @@ CONFIG_MIPS_SIM_NET=y
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
# CONFIG_PHONE is not set
#
# Input device support
#
-# CONFIG_INPUT is not set
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
#
# Hardware I/O ports
#
-# CONFIG_SERIO is not set
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
# CONFIG_GAMEPORT is not set
#
@@ -445,13 +581,31 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
# CONFIG_I2C is not set
#
@@ -459,60 +613,118 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
#
-# Sonics Silicon Backplane
+# Dallas's 1-wire bus
#
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB is not set
+# CONFIG_W1 is not set
#
-# Multifunction device drivers
+# Hardware Monitoring support
#
-# CONFIG_MFD_SM501 is not set
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_DAB is not set
#
-# Graphics support
+# Digital Video Broadcasting Devices
#
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DVB is not set
#
-# Display device support
+# Graphics support
#
-# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB is not set
#
# Sound
#
# CONFIG_SOUND is not set
-# CONFIG_USB_SUPPORT is not set
+
+#
+# HID Devices
+#
+# CONFIG_HID is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
# CONFIG_MMC is not set
+
+#
+# LED devices
+#
# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
# CONFIG_RTC_CLASS is not set
#
-# Userspace I/O
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
#
-# CONFIG_UIO is not set
#
# File systems
#
-# CONFIG_EXT2_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_EXT4DEV_FS is not set
# CONFIG_REISERFS_FS is not set
@@ -520,7 +732,6 @@ CONFIG_RTC_LIB=y
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=y
# CONFIG_INOTIFY is not set
@@ -549,11 +760,10 @@ CONFIG_ROMFS_FS=y
CONFIG_PROC_FS=y
# CONFIG_PROC_KCORE is not set
CONFIG_PROC_SYSCTL=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_SYSFS is not set
+# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_RAMFS=y
#
# Miscellaneous filesystems
@@ -571,7 +781,10 @@ CONFIG_TMPFS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-CONFIG_NETWORK_FILESYSTEMS=y
+
+#
+# Network File Systems
+#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
@@ -583,7 +796,6 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -591,14 +803,22 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
# CONFIG_NLS is not set
-# CONFIG_DLM is not set
+
+#
+# Distributed Lock Manager
+#
#
# Profiling support
@@ -613,22 +833,20 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DETECT_SOFTLOCKUP is not set
-# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_MUTEXES is not set
+CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
-# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
@@ -636,9 +854,7 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
CONFIG_FORCED_INLINING=y
-# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_FAULT_INJECTION is not set
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
# CONFIG_DEBUG_STACK_USAGE is not set
@@ -649,20 +865,60 @@ CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
# Security options
#
# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
+# CONFIG_CRYPTO_DES is not set
+CONFIG_CRYPTO_FCRYPT=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CAMELLIA=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
#
# Library routines
#
+CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_ITU_T is not set
-# CONFIG_CRC32 is not set
-# CONFIG_CRC7 is not set
+CONFIG_CRC16=y
+CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
diff --git a/trunk/arch/mips/configs/sb1250-swarm_defconfig b/trunk/arch/mips/configs/sb1250-swarm_defconfig
index 49dfcef2518c..3ed991ae0ebe 100644
--- a/trunk/arch/mips/configs/sb1250-swarm_defconfig
+++ b/trunk/arch/mips/configs/sb1250-swarm_defconfig
@@ -196,7 +196,6 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
-CONFIG_CGROUPS=y
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
diff --git a/trunk/arch/mips/emma2rh/markeins/setup.c b/trunk/arch/mips/emma2rh/markeins/setup.c
index 82f9e9013e70..5e1da53b04a7 100644
--- a/trunk/arch/mips/emma2rh/markeins/setup.c
+++ b/trunk/arch/mips/emma2rh/markeins/setup.c
@@ -104,6 +104,12 @@ void __init plat_time_init(void)
mips_hpt_frequency = (bus_frequency * (4 + reg)) / 4 / 2;
}
+void __init plat_timer_setup(struct irqaction *irq)
+{
+ /* we are using the cpu counter for timer interrupts */
+ setup_irq(CPU_IRQ_BASE + 7, irq);
+}
+
static void markeins_board_init(void);
extern void markeins_irq_setup(void);
diff --git a/trunk/arch/mips/kernel/cevt-r4k.c b/trunk/arch/mips/kernel/cevt-r4k.c
index a915e5693421..08b84d476c87 100644
--- a/trunk/arch/mips/kernel/cevt-r4k.c
+++ b/trunk/arch/mips/kernel/cevt-r4k.c
@@ -10,7 +10,6 @@
#include
#include
-#include
#include
static int mips_next_event(unsigned long delta,
diff --git a/trunk/arch/mips/kernel/irixelf.c b/trunk/arch/mips/kernel/irixelf.c
index 7852c7cdf29e..b997af713eb3 100644
--- a/trunk/arch/mips/kernel/irixelf.c
+++ b/trunk/arch/mips/kernel/irixelf.c
@@ -1172,8 +1172,8 @@ static int irix_core_dump(long signr, struct pt_regs *regs, struct file *file, u
prstatus.pr_sighold = current->blocked.sig[0];
psinfo.pr_pid = prstatus.pr_pid = current->pid;
psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid;
- psinfo.pr_pgrp = prstatus.pr_pgrp = task_pgrp_nr(current);
- psinfo.pr_sid = prstatus.pr_sid = task_session_nr(current);
+ psinfo.pr_pgrp = prstatus.pr_pgrp = process_group(current);
+ psinfo.pr_sid = prstatus.pr_sid = process_session(current);
if (current->pid == current->tgid) {
/*
* This is the record for the group leader. Add in the
diff --git a/trunk/arch/mips/kernel/irixsig.c b/trunk/arch/mips/kernel/irixsig.c
index a0a91056fda7..85c2e389edd6 100644
--- a/trunk/arch/mips/kernel/irixsig.c
+++ b/trunk/arch/mips/kernel/irixsig.c
@@ -609,7 +609,7 @@ asmlinkage int irix_waitsys(int type, int pid,
p = list_entry(_p, struct task_struct, sibling);
if ((type == IRIX_P_PID) && p->pid != pid)
continue;
- if ((type == IRIX_P_PGID) && task_pgrp_nr(p) != pid)
+ if ((type == IRIX_P_PGID) && process_group(p) != pid)
continue;
if ((p->exit_signal != SIGCHLD))
continue;
diff --git a/trunk/arch/mips/kernel/sysirix.c b/trunk/arch/mips/kernel/sysirix.c
index 4c477c7ff74a..ee7790d9debe 100644
--- a/trunk/arch/mips/kernel/sysirix.c
+++ b/trunk/arch/mips/kernel/sysirix.c
@@ -763,11 +763,11 @@ asmlinkage int irix_setpgrp(int flags)
printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);
#endif
if(!flags)
- error = task_pgrp_nr(current);
+ error = process_group(current);
else
error = sys_setsid();
#ifdef DEBUG_PROCGRPS
- printk("returning %d\n", task_pgrp_nr(current));
+ printk("returning %d\n", process_group(current));
#endif
return error;
diff --git a/trunk/arch/mips/kernel/time.c b/trunk/arch/mips/kernel/time.c
index c4e6866d5cbc..ea7cfe766a8e 100644
--- a/trunk/arch/mips/kernel/time.c
+++ b/trunk/arch/mips/kernel/time.c
@@ -39,6 +39,17 @@
#include
+/*
+ * The integer part of the number of usecs per jiffy is taken from tick,
+ * but the fractional part is not recorded, so we calculate it using the
+ * initial value of HZ. This aids systems where tick isn't really an
+ * integer (e.g. for HZ = 128).
+ */
+#define USECS_PER_JIFFY TICK_SIZE
+#define USECS_PER_JIFFY_FRAC ((unsigned long)(u32)((1000000ULL << 32) / HZ))
+
+#define TICK_SIZE (tick_nsec / 1000)
+
/*
* forward reference
*/
@@ -171,59 +182,84 @@ struct clocksource clocksource_mips = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
+static void __init init_mips_clocksource(void)
{
u64 temp;
u32 shift;
+ if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read)
+ return;
+
+ /* Calclate a somewhat reasonable rating value */
+ clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
/* Find a shift value */
for (shift = 32; shift > 0; shift--) {
temp = (u64) NSEC_PER_SEC << shift;
- do_div(temp, clock);
+ do_div(temp, mips_hpt_frequency);
if ((temp >> 32) == 0)
break;
}
- cs->shift = shift;
- cs->mult = (u32) temp;
+ clocksource_mips.shift = shift;
+ clocksource_mips.mult = (u32)temp;
+
+ clocksource_register(&clocksource_mips);
}
-void __cpuinit clockevent_set_clock(struct clock_event_device *cd,
- unsigned int clock)
+void __init __weak plat_time_init(void)
{
- u64 temp;
- u32 shift;
-
- /* Find a shift value */
- for (shift = 32; shift > 0; shift--) {
- temp = (u64) NSEC_PER_SEC << shift;
- do_div(temp, clock);
- if ((temp >> 32) == 0)
- break;
- }
- cd->shift = shift;
- cd->mult = (u32) temp;
}
-static void __init init_mips_clocksource(void)
+void __init __weak plat_timer_setup(struct irqaction *irq)
{
- if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read)
- return;
-
- /* Calclate a somewhat reasonable rating value */
- clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
+}
- clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
+#ifdef CONFIG_MIPS_MT_SMTC
+DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device);
- clocksource_register(&clocksource_mips);
+static void smtc_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
}
-void __init __weak plat_time_init(void)
+static void mips_broadcast(cpumask_t mask)
{
+ unsigned int cpu;
+
+ for_each_cpu_mask(cpu, mask)
+ smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0);
}
-void __init __weak plat_timer_setup(struct irqaction *irq)
+static void setup_smtc_dummy_clockevent_device(void)
{
+ //uint64_t mips_freq = mips_hpt_^frequency;
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd;
+
+ cd = &per_cpu(smtc_dummy_clockevent_device, cpu);
+
+ cd->name = "SMTC";
+ cd->features = CLOCK_EVT_FEAT_DUMMY;
+
+ /* Calculate the min / max delta */
+ cd->mult = 0; //div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
+ cd->shift = 0; //32;
+ cd->max_delta_ns = 0; //clockevent_delta2ns(0x7fffffff, cd);
+ cd->min_delta_ns = 0; //clockevent_delta2ns(0x30, cd);
+
+ cd->rating = 200;
+ cd->irq = 17; //-1;
+// if (cpu)
+// cd->cpumask = CPU_MASK_ALL; // cpumask_of_cpu(cpu);
+// else
+ cd->cpumask = cpumask_of_cpu(cpu);
+
+ cd->set_mode = smtc_set_mode;
+
+ cd->broadcast = mips_broadcast;
+
+ clockevents_register_device(cd);
}
+#endif
void __init time_init(void)
{
diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c
index fa500787152d..7b78d137259f 100644
--- a/trunk/arch/mips/kernel/traps.c
+++ b/trunk/arch/mips/kernel/traps.c
@@ -314,7 +314,7 @@ void show_registers(const struct pt_regs *regs)
__show_regs(regs);
print_modules();
printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
- current->comm, task_pid_nr(current), current_thread_info(), current);
+ current->comm, current->pid, current_thread_info(), current);
show_stacktrace(current, regs);
show_code((unsigned int __user *) regs->cp0_epc);
printk("\n");
diff --git a/trunk/arch/mips/lemote/lm2e/setup.c b/trunk/arch/mips/lemote/lm2e/setup.c
index 2cc6745991ab..09314a20f9fb 100644
--- a/trunk/arch/mips/lemote/lm2e/setup.c
+++ b/trunk/arch/mips/lemote/lm2e/setup.c
@@ -53,6 +53,11 @@ unsigned long bus_clock;
unsigned int memsize;
unsigned int highmemsize = 0;
+void __init plat_timer_setup(struct irqaction *irq)
+{
+ setup_irq(MIPS_CPU_IRQ_BASE + 7, irq);
+}
+
void __init plat_time_init(void)
{
/* setup mips r4k timer */
diff --git a/trunk/arch/mips/mm/fault.c b/trunk/arch/mips/mm/fault.c
index fa636fc6b7b9..5699c7713e2f 100644
--- a/trunk/arch/mips/mm/fault.c
+++ b/trunk/arch/mips/mm/fault.c
@@ -173,7 +173,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_global_init(tsk)) {
+ if (is_init(tsk)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/trunk/arch/mips/oprofile/Kconfig b/trunk/arch/mips/oprofile/Kconfig
new file mode 100644
index 000000000000..fb6f235348b0
--- /dev/null
+++ b/trunk/arch/mips/oprofile/Kconfig
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+ depends on EXPERIMENTAL
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING && !MIPS_MT_SMTC && EXPERIMENTAL
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+endmenu
+
diff --git a/trunk/arch/mips/pmc-sierra/msp71xx/msp_time.c b/trunk/arch/mips/pmc-sierra/msp71xx/msp_time.c
index 7cfeda5a651b..f221d4763625 100644
--- a/trunk/arch/mips/pmc-sierra/msp71xx/msp_time.c
+++ b/trunk/arch/mips/pmc-sierra/msp71xx/msp_time.c
@@ -86,5 +86,8 @@ void __init plat_timer_setup(struct irqaction *irq)
#ifdef CONFIG_IRQ_MSP_CIC
/* we are using the vpe0 counter for timer interrupts */
setup_irq(MSP_INT_VPE0_TIMER, irq);
+#else
+ /* we are using the mips counter for timer interrupts */
+ setup_irq(MSP_INT_TIMER, irq);
#endif
}
diff --git a/trunk/arch/mips/pmc-sierra/yosemite/setup.c b/trunk/arch/mips/pmc-sierra/yosemite/setup.c
index 855977ca51cd..015fcc363dc0 100644
--- a/trunk/arch/mips/pmc-sierra/yosemite/setup.c
+++ b/trunk/arch/mips/pmc-sierra/yosemite/setup.c
@@ -137,6 +137,11 @@ int rtc_mips_set_time(unsigned long tim)
return 0;
}
+void __init plat_timer_setup(struct irqaction *irq)
+{
+ setup_irq(7, irq);
+}
+
void __init plat_time_init(void)
{
mips_hpt_frequency = cpu_clock_freq / 2;
diff --git a/trunk/arch/mips/sibyte/bcm1480/smp.c b/trunk/arch/mips/sibyte/bcm1480/smp.c
index 02b266a31c46..6eac36d1b8c8 100644
--- a/trunk/arch/mips/sibyte/bcm1480/smp.c
+++ b/trunk/arch/mips/sibyte/bcm1480/smp.c
@@ -69,9 +69,8 @@ void bcm1480_smp_init(void)
void bcm1480_smp_finish(void)
{
- extern void sb1480_clockevent_init(void);
-
- sb1480_clockevent_init();
+ extern void bcm1480_time_init(void);
+ bcm1480_time_init();
local_irq_enable();
}
diff --git a/trunk/arch/mips/sibyte/bcm1480/time.c b/trunk/arch/mips/sibyte/bcm1480/time.c
index c730744aa474..5b4bfbbb5a24 100644
--- a/trunk/arch/mips/sibyte/bcm1480/time.c
+++ b/trunk/arch/mips/sibyte/bcm1480/time.c
@@ -27,8 +27,9 @@
*/
#include
#include
-#include
+#include
#include
+#include
#include
#include
@@ -100,36 +101,25 @@ static void sibyte_set_mode(enum clock_event_mode mode,
break;
case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
- case CLOCK_EVT_MODE_RESUME:
;
}
}
-static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
-{
- unsigned int cpu = smp_processor_id();
- void __iomem *timer_init;
- unsigned int cnt;
- int res;
-
- timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
- cnt = __raw_readq(timer_init);
- cnt += delta;
- __raw_writeq(cnt, timer_init);
- res = ((long)(__raw_readq(timer_init) - cnt ) > 0) ? -ETIME : 0;
-
- return res;
-}
-
-static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
+struct clock_event_device sibyte_hpt_clockevent = {
+ .name = "bcm1480-counter",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .set_mode = sibyte_set_mode,
+ .shift = 32,
+ .irq = 0,
+};
static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
{
+ struct clock_event_device *cd = &sibyte_hpt_clockevent;
unsigned int cpu = smp_processor_id();
- struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
/* Reset the timer */
- __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+ __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
cd->event_handler(cd);
@@ -150,23 +140,26 @@ static struct irqaction sibyte_counter_irqaction = {
* called directly from irq_handler.S when IP[4] is set during an
* interrupt
*/
-void __cpuinit sb1480_clockevent_init(void)
+static void __init sb1480_clockevent_init(void)
{
unsigned int cpu = smp_processor_id();
unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu;
- struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
-
- cd->name = "bcm1480-counter";
- cd->features = CLOCK_EVT_FEAT_PERIODIC |
- CLOCK_EVT_MODE_ONESHOT;
- cd->set_next_event = sibyte_next_event;
- cd->set_mode = sibyte_set_mode;
- cd->irq = irq;
- clockevent_set_clock(cd, BCM1480_HPT_VALUE);
setup_irq(irq, &sibyte_counter_irqaction);
}
+void bcm1480_timer_interrupt(void)
+{
+ int cpu = smp_processor_id();
+ int irq = K_BCM1480_INT_TIMER_0 + cpu;
+
+ /* Reset the timer */
+ __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+
+ ll_timer_interrupt(irq);
+}
+
static cycle_t bcm1480_hpt_read(void)
{
/* We assume this function is called xtime_lock held. */
@@ -175,26 +168,9 @@ static cycle_t bcm1480_hpt_read(void)
return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count;
}
-struct clocksource bcm1480_clocksource = {
- .name = "MIPS",
- .rating = 200,
- .read = bcm1480_hpt_read,
- .mask = CLOCKSOURCE_MASK(32),
- .shift = 32,
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-void __init sb1480_clocksource_init(void)
-{
- struct clocksource *cs = &bcm1480_clocksource;
-
- clocksource_set_clock(cs, BCM1480_HPT_VALUE);
- clocksource_register(cs);
-}
-
void __init bcm1480_hpt_setup(void)
{
+ clocksource_mips.read = bcm1480_hpt_read;
mips_hpt_frequency = BCM1480_HPT_VALUE;
- sb1480_clocksource_init();
sb1480_clockevent_init();
}
diff --git a/trunk/arch/mips/sibyte/sb1250/irq.c b/trunk/arch/mips/sibyte/sb1250/irq.c
index 500d17e84c09..7659174819c6 100644
--- a/trunk/arch/mips/sibyte/sb1250/irq.c
+++ b/trunk/arch/mips/sibyte/sb1250/irq.c
@@ -400,11 +400,43 @@ static void sb1250_kgdb_interrupt(void)
#endif /* CONFIG_KGDB */
+static inline void sb1250_timer_interrupt(void)
+{
+ int cpu = smp_processor_id();
+ int irq = K_INT_TIMER_0 + cpu;
+
+ irq_enter();
+ kstat_this_cpu.irqs[irq]++;
+
+ write_seqlock(&xtime_lock);
+
+ /* ACK interrupt */
+ ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+
+ /*
+ * call the generic timer interrupt handling
+ */
+ do_timer(1);
+
+ write_sequnlock(&xtime_lock);
+
+ /*
+ * In UP mode, we call local_timer_interrupt() to do profiling
+ * and process accouting.
+ *
+ * In SMP mode, local_timer_interrupt() is invoked by appropriate
+ * low-level local timer interrupt handler.
+ */
+ local_timer_interrupt(irq);
+
+ irq_exit();
+}
+
extern void sb1250_mailbox_interrupt(void);
asmlinkage void plat_irq_dispatch(void)
{
- unsigned int cpu = smp_processor_id();
unsigned int pending;
/*
@@ -422,7 +454,7 @@ asmlinkage void plat_irq_dispatch(void)
if (pending & CAUSEF_IP7) /* CPU performance counter interrupt */
do_IRQ(MIPS_CPU_IRQ_BASE + 7);
else if (pending & CAUSEF_IP4)
- do_IRQ(K_INT_TIMER_0 + cpu); /* sb1250_timer_interrupt() */
+ sb1250_timer_interrupt();
#ifdef CONFIG_SMP
else if (pending & CAUSEF_IP3)
diff --git a/trunk/arch/mips/sibyte/sb1250/smp.c b/trunk/arch/mips/sibyte/sb1250/smp.c
index aaa4f30dda79..c38e1f34460d 100644
--- a/trunk/arch/mips/sibyte/sb1250/smp.c
+++ b/trunk/arch/mips/sibyte/sb1250/smp.c
@@ -57,9 +57,8 @@ void sb1250_smp_init(void)
void sb1250_smp_finish(void)
{
- extern void sb1250_clockevent_init(void);
-
- sb1250_clockevent_init();
+ extern void sb1250_time_init(void);
+ sb1250_time_init();
local_irq_enable();
}
diff --git a/trunk/arch/mips/sibyte/sb1250/time.c b/trunk/arch/mips/sibyte/sb1250/time.c
index 9ef54628bc9c..fe11fed8e0d7 100644
--- a/trunk/arch/mips/sibyte/sb1250/time.c
+++ b/trunk/arch/mips/sibyte/sb1250/time.c
@@ -100,7 +100,6 @@ static void sibyte_set_mode(enum clock_event_mode mode,
break;
case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
- case CLOCK_EVT_MODE_RESUME:
;
}
}
@@ -145,7 +144,79 @@ static struct irqaction sibyte_irqaction = {
.name = "timer",
};
-void __cpuinit sb1250_clockevent_init(void)
+/*
+ * The general purpose timer ticks at 1 Mhz independent if
+ * the rest of the system
+ */
+static void sibyte_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned int cpu = smp_processor_id();
+ void __iomem *timer_cfg, *timer_init;
+
+ timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
+ timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ __raw_writeq(0, timer_cfg);
+ __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init);
+ __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+ timer_cfg);
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* Stop the timer until we actually program a shot */
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ __raw_writeq(0, timer_cfg);
+ break;
+
+ case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
+ ;
+ }
+}
+
+static int
+sibyte_next_event(unsigned long delta, struct clock_event_device *evt)
+{
+ unsigned int cpu = smp_processor_id();
+ void __iomem *timer_cfg, *timer_init;
+
+ timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
+ timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
+
+ __raw_writeq(0, timer_cfg);
+ __raw_writeq(delta, timer_init);
+ __raw_writeq(M_SCD_TIMER_ENABLE, timer_cfg);
+
+ return 0;
+}
+
+struct clock_event_device sibyte_hpt_clockevent = {
+ .name = "sb1250-counter",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .set_mode = sibyte_set_mode,
+ .set_next_event = sibyte_next_event,
+ .shift = 32,
+ .irq = 0,
+};
+
+static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
+{
+ struct clock_event_device *cd = &sibyte_hpt_clockevent;
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction sibyte_irqaction = {
+ .handler = sibyte_counter_handler,
+ .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .name = "timer",
+};
+
+static void __init sb1250_clockevent_init(void)
{
struct clock_event_device *cd = &sibyte_hpt_clockevent;
unsigned int cpu = smp_processor_id();
@@ -178,6 +249,12 @@ void __cpuinit sb1250_clockevent_init(void)
clockevents_register_device(cd);
}
+void __init plat_time_init(void)
+{
+ sb1250_clocksource_init();
+ sb1250_clockevent_init();
+}
+
/*
* The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over
* again.
@@ -190,26 +267,3 @@ static cycle_t sb1250_hpt_read(void)
return SB1250_HPT_VALUE - count;
}
-
-struct clocksource bcm1250_clocksource = {
- .name = "MIPS",
- .rating = 200,
- .read = sb1250_hpt_read,
- .mask = CLOCKSOURCE_MASK(32),
- .shift = 32,
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-void __init sb1250_clocksource_init(void)
-{
- struct clocksource *cs = &bcm1250_clocksource;
-
- clocksource_set_clock(cs, V_SCD_TIMER_FREQ);
- clocksource_register(cs);
-}
-
-void __init plat_time_init(void)
-{
- sb1250_clocksource_init();
- sb1250_clockevent_init();
-}
diff --git a/trunk/arch/mips/sibyte/swarm/setup.c b/trunk/arch/mips/sibyte/swarm/setup.c
index 080c966263b7..8b3ef0e4cd55 100644
--- a/trunk/arch/mips/sibyte/swarm/setup.c
+++ b/trunk/arch/mips/sibyte/swarm/setup.c
@@ -69,6 +69,31 @@ const char *get_system_type(void)
return "SiByte " SIBYTE_BOARD_NAME;
}
+void __init plat_time_init(void)
+{
+#if defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+ /* Setup HPT */
+ sb1250_hpt_setup();
+#endif
+}
+
+void __init plat_timer_setup(struct irqaction *irq)
+{
+ /*
+ * we don't set up irqaction, because we will deliver timer
+ * interrupts through low-level (direct) meachanism.
+ */
+
+ /* We only need to setup the generic timer */
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ bcm1480_time_init();
+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+ sb1250_time_init();
+#else
+#error invalid SiByte board configuration
+#endif
+}
+
int swarm_be_handler(struct pt_regs *regs, int is_fixup)
{
if (!is_fixup && (regs->cp0_cause & 4)) {
diff --git a/trunk/arch/mips/sni/time.c b/trunk/arch/mips/sni/time.c
index 0910b35cb71f..b80877349d38 100644
--- a/trunk/arch/mips/sni/time.c
+++ b/trunk/arch/mips/sni/time.c
@@ -121,6 +121,15 @@ void __init plat_time_init(void)
setup_pit_timer();
}
+/*
+ * R4k counter based timer interrupt. Works on RM200-225 and possibly
+ * others but not on RM400
+ */
+static void __init sni_cpu_timer_setup(struct irqaction *irq)
+{
+ setup_irq(SNI_MIPS_IRQ_CPU_TIMER, irq);
+}
+
void __init plat_timer_setup(struct irqaction *irq)
{
switch (sni_brd_type) {
@@ -130,6 +139,15 @@ void __init plat_timer_setup(struct irqaction *irq)
case SNI_BRD_MINITOWER:
sni_a20r_timer_setup(irq);
break;
+
+ case SNI_BRD_PCI_TOWER:
+ case SNI_BRD_RM200:
+ case SNI_BRD_PCI_MTOWER:
+ case SNI_BRD_PCI_DESKTOP:
+ case SNI_BRD_PCI_TOWER_CPLUS:
+ case SNI_BRD_PCI_MTOWER_CPLUS:
+ sni_cpu_timer_setup(irq);
+ break;
}
}
diff --git a/trunk/arch/mips/tx4927/common/tx4927_setup.c b/trunk/arch/mips/tx4927/common/tx4927_setup.c
index 36c5f200eb3d..8ce0989671d8 100644
--- a/trunk/arch/mips/tx4927/common/tx4927_setup.c
+++ b/trunk/arch/mips/tx4927/common/tx4927_setup.c
@@ -72,6 +72,22 @@ void __init plat_time_init(void)
#endif
}
+void __init plat_timer_setup(struct irqaction *irq)
+{
+ setup_irq(TX4927_IRQ_CPU_TIMER, irq);
+
+#ifdef CONFIG_TOSHIBA_RBTX4927
+ {
+ extern void toshiba_rbtx4927_timer_setup(struct irqaction
+ *irq);
+ toshiba_rbtx4927_timer_setup(irq);
+ }
+#endif
+
+ return;
+}
+
+
#ifdef DEBUG
void print_cp0(char *key, int num, char *name, u32 val)
{
diff --git a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index c7470fba6180..b97102a1c635 100644
--- a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -94,6 +94,7 @@
#define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 )
#define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 )
#define TOSHIBA_RBTX4927_SETUP_TIME_INIT ( 1 << 5 )
+#define TOSHIBA_RBTX4927_SETUP_TIMER_SETUP ( 1 << 6 )
#define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 )
#define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 )
#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 )
@@ -107,6 +108,7 @@ static const u32 toshiba_rbtx4927_setup_debug_flag =
(TOSHIBA_RBTX4927_SETUP_NONE | TOSHIBA_RBTX4927_SETUP_INFO |
TOSHIBA_RBTX4927_SETUP_WARN | TOSHIBA_RBTX4927_SETUP_EROR |
TOSHIBA_RBTX4927_SETUP_EFWFU | TOSHIBA_RBTX4927_SETUP_SETUP |
+ TOSHIBA_RBTX4927_SETUP_TIME_INIT | TOSHIBA_RBTX4927_SETUP_TIMER_SETUP
| TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 |
TOSHIBA_RBTX4927_SETUP_PCI2 | TOSHIBA_RBTX4927_SETUP_PCI66);
#endif
@@ -945,6 +947,14 @@ toshiba_rbtx4927_time_init(void)
}
+void __init toshiba_rbtx4927_timer_setup(struct irqaction *irq)
+{
+ TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP,
+ "-\n");
+ TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP,
+ "+\n");
+}
+
static int __init toshiba_rbtx4927_rtc_init(void)
{
static struct resource __initdata res = {
diff --git a/trunk/arch/mips/tx4938/common/setup.c b/trunk/arch/mips/tx4938/common/setup.c
index 3ba4101d141e..ab4082267553 100644
--- a/trunk/arch/mips/tx4938/common/setup.c
+++ b/trunk/arch/mips/tx4938/common/setup.c
@@ -24,7 +24,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -43,3 +43,8 @@ plat_mem_setup(void)
{
toshiba_rbtx4938_setup();
}
+
+void __init plat_timer_setup(struct irqaction *irq)
+{
+ setup_irq(TX4938_IRQ_CPU_TIMER, irq);
+}
diff --git a/trunk/arch/mips/vr41xx/common/init.c b/trunk/arch/mips/vr41xx/common/init.c
index 8d760df686c4..407cec203b29 100644
--- a/trunk/arch/mips/vr41xx/common/init.c
+++ b/trunk/arch/mips/vr41xx/common/init.c
@@ -48,6 +48,11 @@ void __init plat_time_init(void)
mips_hpt_frequency = tclock / 4;
}
+void __init plat_timer_setup(struct irqaction *irq)
+{
+ setup_irq(TIMER_IRQ, irq);
+}
+
void __init plat_mem_setup(void)
{
vr41xx_calculate_clock_frequency();
diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig
index b8ef1787a191..3d73545e8c48 100644
--- a/trunk/arch/parisc/Kconfig
+++ b/trunk/arch/parisc/Kconfig
@@ -267,7 +267,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
+source "arch/parisc/oprofile/Kconfig"
source "arch/parisc/Kconfig.debug"
diff --git a/trunk/arch/parisc/kernel/signal.c b/trunk/arch/parisc/kernel/signal.c
index 2ce3806f02e1..fb35ebc0c4da 100644
--- a/trunk/arch/parisc/kernel/signal.c
+++ b/trunk/arch/parisc/kernel/signal.c
@@ -181,7 +181,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
si.si_signo = SIGSEGV;
si.si_errno = 0;
si.si_code = SI_KERNEL;
- si.si_pid = task_pid_vnr(current);
+ si.si_pid = current->pid;
si.si_uid = current->uid;
si.si_addr = &frame->uc;
force_sig_info(SIGSEGV, &si, current);
diff --git a/trunk/arch/parisc/kernel/traps.c b/trunk/arch/parisc/kernel/traps.c
index 99fd56939afa..bbf029a184ac 100644
--- a/trunk/arch/parisc/kernel/traps.c
+++ b/trunk/arch/parisc/kernel/traps.c
@@ -219,7 +219,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
return; /* STFU */
printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
- current->comm, task_pid_nr(current), str, err, regs->iaoq[0]);
+ current->comm, current->pid, str, err, regs->iaoq[0]);
#ifdef PRINT_USER_FAULTS
/* XXX for debugging only */
show_regs(regs);
@@ -252,7 +252,7 @@ KERN_CRIT " || ||\n");
if (err)
printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
- current->comm, task_pid_nr(current), str, err);
+ current->comm, current->pid, str, err);
/* Wot's wrong wif bein' racy? */
if (current->thread.flags & PARISC_KERNEL_DEATH) {
@@ -317,7 +317,7 @@ static void handle_break(struct pt_regs *regs)
if (unlikely(iir != GDB_BREAK_INSN)) {
printk(KERN_DEBUG "break %d,%d: pid=%d command='%s'\n",
iir & 31, (iir>>13) & ((1<<13)-1),
- task_pid_nr(current), current->comm);
+ current->pid, current->comm);
show_regs(regs);
}
#endif
@@ -747,7 +747,7 @@ void handle_interruption(int code, struct pt_regs *regs)
if (user_mode(regs)) {
#ifdef PRINT_USER_FAULTS
printk(KERN_DEBUG "\nhandle_interruption() pid=%d command='%s'\n",
- task_pid_nr(current), current->comm);
+ current->pid, current->comm);
show_regs(regs);
#endif
/* SIGBUS, for lack of a better one. */
@@ -772,7 +772,7 @@ void handle_interruption(int code, struct pt_regs *regs)
else
printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ",
code);
- printk("pid=%d command='%s'\n", task_pid_nr(current), current->comm);
+ printk("pid=%d command='%s'\n", current->pid, current->comm);
show_regs(regs);
#endif
si.si_signo = SIGSEGV;
diff --git a/trunk/arch/parisc/kernel/unaligned.c b/trunk/arch/parisc/kernel/unaligned.c
index aebf3c168871..347bb922e6d0 100644
--- a/trunk/arch/parisc/kernel/unaligned.c
+++ b/trunk/arch/parisc/kernel/unaligned.c
@@ -469,7 +469,7 @@ void handle_unaligned(struct pt_regs *regs)
&& ++unaligned_count < 5) {
char buf[256];
sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
- current->comm, task_pid_nr(current), regs->ior, regs->iaoq[0]);
+ current->comm, current->pid, regs->ior, regs->iaoq[0]);
printk(KERN_WARNING "%s", buf);
#ifdef DEBUG_UNALIGNED
show_regs(regs);
diff --git a/trunk/arch/parisc/mm/fault.c b/trunk/arch/parisc/mm/fault.c
index b2e3e9a8cece..1c091b415cd9 100644
--- a/trunk/arch/parisc/mm/fault.c
+++ b/trunk/arch/parisc/mm/fault.c
@@ -211,7 +211,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
#ifdef PRINT_USER_FAULTS
printk(KERN_DEBUG "\n");
printk(KERN_DEBUG "do_page_fault() pid=%d command='%s' type=%lu address=0x%08lx\n",
- task_pid_nr(tsk), tsk->comm, code, address);
+ tsk->pid, tsk->comm, code, address);
if (vma) {
printk(KERN_DEBUG "vm_start = 0x%08lx, vm_end = 0x%08lx\n",
vma->vm_start, vma->vm_end);
diff --git a/trunk/arch/parisc/oprofile/Kconfig b/trunk/arch/parisc/oprofile/Kconfig
new file mode 100644
index 000000000000..5ade19801b97
--- /dev/null
+++ b/trunk/arch/parisc/oprofile/Kconfig
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+ depends on EXPERIMENTAL
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+endmenu
+
diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig
index 18f397ca05ef..3763f681ce4c 100644
--- a/trunk/arch/powerpc/Kconfig
+++ b/trunk/arch/powerpc/Kconfig
@@ -669,7 +669,20 @@ source "arch/powerpc/sysdev/qe_lib/Kconfig"
source "lib/Kconfig"
-source "kernel/Kconfig.instrumentation"
+menu "Instrumentation Support"
+
+source "arch/powerpc/oprofile/Kconfig"
+
+config KPROBES
+ bool "Kprobes"
+ depends on !BOOKE && !4xx && KALLSYMS && MODULES
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+endmenu
source "arch/powerpc/Kconfig.debug"
diff --git a/trunk/arch/powerpc/configs/cell_defconfig b/trunk/arch/powerpc/configs/cell_defconfig
index dcd7c02727c2..8b47c846421c 100644
--- a/trunk/arch/powerpc/configs/cell_defconfig
+++ b/trunk/arch/powerpc/configs/cell_defconfig
@@ -68,7 +68,6 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=15
-CONFIG_CGROUPS=y
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
diff --git a/trunk/arch/powerpc/configs/ppc64_defconfig b/trunk/arch/powerpc/configs/ppc64_defconfig
index 05582af50c5b..bb8d4e46f0c5 100644
--- a/trunk/arch/powerpc/configs/ppc64_defconfig
+++ b/trunk/arch/powerpc/configs/ppc64_defconfig
@@ -71,7 +71,6 @@ CONFIG_TASK_DELAY_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
-CONFIG_CGROUPS=y
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
diff --git a/trunk/arch/powerpc/configs/pseries_defconfig b/trunk/arch/powerpc/configs/pseries_defconfig
index 62a38406b62f..c09eb8cfbe71 100644
--- a/trunk/arch/powerpc/configs/pseries_defconfig
+++ b/trunk/arch/powerpc/configs/pseries_defconfig
@@ -71,7 +71,6 @@ CONFIG_AUDITSYSCALL=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
-CONFIG_CGROUPS=y
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
diff --git a/trunk/arch/powerpc/kernel/machine_kexec.c b/trunk/arch/powerpc/kernel/machine_kexec.c
index c0c8e8c3ced9..e60a0c544d63 100644
--- a/trunk/arch/powerpc/kernel/machine_kexec.c
+++ b/trunk/arch/powerpc/kernel/machine_kexec.c
@@ -61,39 +61,45 @@ NORET_TYPE void machine_kexec(struct kimage *image)
for(;;);
}
+static int __init early_parse_crashk(char *p)
+{
+ unsigned long size;
+
+ if (!p)
+ return 1;
+
+ size = memparse(p, &p);
+
+ if (*p == '@')
+ crashk_res.start = memparse(p + 1, &p);
+ else
+ crashk_res.start = KDUMP_KERNELBASE;
+
+ crashk_res.end = crashk_res.start + size - 1;
+
+ return 0;
+}
+early_param("crashkernel", early_parse_crashk);
+
void __init reserve_crashkernel(void)
{
- unsigned long long crash_size, crash_base;
- int ret;
-
- /* this is necessary because of lmb_phys_mem_size() */
- lmb_analyze();
-
- /* use common parsing */
- ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(),
- &crash_size, &crash_base);
- if (ret == 0 && crash_size > 0) {
- if (crash_base == 0)
- crash_base = KDUMP_KERNELBASE;
- crashk_res.start = crash_base;
- } else {
- /* handle the device tree */
- crash_size = crashk_res.end - crashk_res.start + 1;
- }
+ unsigned long size;
- if (crash_size == 0)
+ if (crashk_res.start == 0)
return;
/* We might have got these values via the command line or the
* device tree, either way sanitise them now. */
+ size = crashk_res.end - crashk_res.start + 1;
+
if (crashk_res.start != KDUMP_KERNELBASE)
printk("Crash kernel location must be 0x%x\n",
KDUMP_KERNELBASE);
crashk_res.start = KDUMP_KERNELBASE;
- crash_size = PAGE_ALIGN(crash_size);
- crashk_res.end = crashk_res.start + crash_size - 1;
+ size = PAGE_ALIGN(size);
+ crashk_res.end = crashk_res.start + size - 1;
/* Crash kernel trumps memory limit */
if (memory_limit && memory_limit <= crashk_res.end) {
@@ -102,13 +108,7 @@ void __init reserve_crashkernel(void)
memory_limit);
}
- printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
- "for crashkernel (System RAM: %ldMB)\n",
- (unsigned long)(crash_size >> 20),
- (unsigned long)(crashk_res.start >> 20),
- (unsigned long)(lmb_phys_mem_size() >> 20));
-
- lmb_reserve(crashk_res.start, crash_size);
+ lmb_reserve(crashk_res.start, size);
}
int overlaps_crashkernel(unsigned long start, unsigned long size)
diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c
index b9d88374f14f..ea6ad7a2a7e3 100644
--- a/trunk/arch/powerpc/kernel/process.c
+++ b/trunk/arch/powerpc/kernel/process.c
@@ -459,7 +459,7 @@ void show_regs(struct pt_regs * regs)
printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
#endif
printk("TASK = %p[%d] '%s' THREAD: %p",
- current, task_pid_nr(current), current->comm, task_thread_info(current));
+ current, current->pid, current->comm, task_thread_info(current));
#ifdef CONFIG_SMP
printk(" CPU: %d", smp_processor_id());
diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c
index 59c464e26f38..bf9e39c6e296 100644
--- a/trunk/arch/powerpc/kernel/traps.c
+++ b/trunk/arch/powerpc/kernel/traps.c
@@ -201,7 +201,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
* generate the same exception over and over again and we get
* nowhere. Better to kill it and let the kernel panic.
*/
- if (is_global_init(current)) {
+ if (is_init(current)) {
__sighandler_t handler;
spin_lock_irq(¤t->sighand->siglock);
@@ -881,7 +881,7 @@ void nonrecoverable_exception(struct pt_regs *regs)
void trace_syscall(struct pt_regs *regs)
{
printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
- current, task_pid_nr(current), regs->nip, regs->link, regs->gpr[0],
+ current, current->pid, regs->nip, regs->link, regs->gpr[0],
regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
}
diff --git a/trunk/arch/powerpc/mm/fault.c b/trunk/arch/powerpc/mm/fault.c
index a18fda361cc0..ab3546c5ac3a 100644
--- a/trunk/arch/powerpc/mm/fault.c
+++ b/trunk/arch/powerpc/mm/fault.c
@@ -375,7 +375,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_global_init(current)) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/trunk/arch/powerpc/oprofile/Kconfig b/trunk/arch/powerpc/oprofile/Kconfig
new file mode 100644
index 000000000000..7089e79689b9
--- /dev/null
+++ b/trunk/arch/powerpc/oprofile/Kconfig
@@ -0,0 +1,24 @@
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+config OPROFILE_CELL
+ bool "OProfile for Cell Broadband Engine"
+ depends on (SPU_FS = y && OPROFILE = m) || (SPU_FS = y && OPROFILE = y) || (SPU_FS = m && OPROFILE = m)
+ default y
+ help
+ Profiling of Cell BE SPUs requires special support enabled
+ by this option.
diff --git a/trunk/arch/powerpc/platforms/maple/setup.c b/trunk/arch/powerpc/platforms/maple/setup.c
index 144177d77cf1..354c05861629 100644
--- a/trunk/arch/powerpc/platforms/maple/setup.c
+++ b/trunk/arch/powerpc/platforms/maple/setup.c
@@ -41,13 +41,13 @@
#include
#include
#include
-#include
#include
#include
#include
#include
#include
+#include
#include
#include
#include
diff --git a/trunk/arch/powerpc/platforms/pseries/ras.c b/trunk/arch/powerpc/platforms/pseries/ras.c
index a1ab25c7082f..3a393c7f390e 100644
--- a/trunk/arch/powerpc/platforms/pseries/ras.c
+++ b/trunk/arch/powerpc/platforms/pseries/ras.c
@@ -332,7 +332,7 @@ static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err)
err->disposition == RTAS_DISP_NOT_RECOVERED &&
err->target == RTAS_TARGET_MEMORY &&
err->type == RTAS_TYPE_ECC_UNCORR &&
- !(current->pid == 0 || is_global_init(current))) {
+ !(current->pid == 0 || is_init(current))) {
/* Kill off a user process with an ECC error */
printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n",
current->pid);
diff --git a/trunk/arch/ppc/Kconfig b/trunk/arch/ppc/Kconfig
index 6473fa7cb4b9..607925c8a99e 100644
--- a/trunk/arch/ppc/Kconfig
+++ b/trunk/arch/ppc/Kconfig
@@ -1317,7 +1317,7 @@ endmenu
source "lib/Kconfig"
-source "kernel/Kconfig.instrumentation"
+source "arch/powerpc/oprofile/Kconfig"
source "arch/ppc/Kconfig.debug"
diff --git a/trunk/arch/ppc/kernel/traps.c b/trunk/arch/ppc/kernel/traps.c
index c78568905c3b..3f3b292eb773 100644
--- a/trunk/arch/ppc/kernel/traps.c
+++ b/trunk/arch/ppc/kernel/traps.c
@@ -121,7 +121,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
* generate the same exception over and over again and we get
* nowhere. Better to kill it and let the kernel panic.
*/
- if (is_global_init(current)) {
+ if (is_init(current)) {
__sighandler_t handler;
spin_lock_irq(¤t->sighand->siglock);
diff --git a/trunk/arch/ppc/mm/fault.c b/trunk/arch/ppc/mm/fault.c
index 254c23b755e6..94913ddcf76e 100644
--- a/trunk/arch/ppc/mm/fault.c
+++ b/trunk/arch/ppc/mm/fault.c
@@ -290,7 +290,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_global_init(current)) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/trunk/arch/ppc/platforms/chestnut.c b/trunk/arch/ppc/platforms/chestnut.c
index dcd6070b85eb..248684f50dd9 100644
--- a/trunk/arch/ppc/platforms/chestnut.c
+++ b/trunk/arch/ppc/platforms/chestnut.c
@@ -49,6 +49,7 @@ extern void gen550_progress(char *, unsigned short);
extern void gen550_init(int, struct uart_port *);
extern void mv64360_pcibios_fixup(mv64x60_handle_t *bh);
+#define BIT(x) (1<cpu, print_tainted());
printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
- current->comm, task_pid_nr(current), (void *) tsk,
+ current->comm, current->pid, (void *) tsk,
(void *) tsk->thread.ksp);
show_registers(regs);
diff --git a/trunk/arch/s390/lib/uaccess_pt.c b/trunk/arch/s390/lib/uaccess_pt.c
index b159a9d65680..60604b2819b2 100644
--- a/trunk/arch/s390/lib/uaccess_pt.c
+++ b/trunk/arch/s390/lib/uaccess_pt.c
@@ -64,7 +64,7 @@ static int __handle_fault(struct mm_struct *mm, unsigned long address,
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_global_init(current)) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c
index 2456b52ed068..14c241ccdd4d 100644
--- a/trunk/arch/s390/mm/fault.c
+++ b/trunk/arch/s390/mm/fault.c
@@ -211,7 +211,7 @@ static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code,
struct mm_struct *mm = tsk->mm;
up_read(&mm->mmap_sem);
- if (is_global_init(tsk)) {
+ if (is_init(tsk)) {
yield();
down_read(&mm->mmap_sem);
return 1;
diff --git a/trunk/arch/s390/oprofile/Kconfig b/trunk/arch/s390/oprofile/Kconfig
new file mode 100644
index 000000000000..208220a5f23f
--- /dev/null
+++ b/trunk/arch/s390/oprofile/Kconfig
@@ -0,0 +1,22 @@
+
+menu "Profiling support"
+
+config PROFILING
+ bool "Profiling support"
+ help
+ Say Y here to enable profiling support mechanisms used by
+ profilers such as readprofile or OProfile.
+
+
+config OPROFILE
+ tristate "OProfile system profiling"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+endmenu
+
diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig
index 247f8a65e733..44982c1dfa23 100644
--- a/trunk/arch/sh/Kconfig
+++ b/trunk/arch/sh/Kconfig
@@ -758,7 +758,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
+source "arch/sh/oprofile/Kconfig"
source "arch/sh/Kconfig.debug"
diff --git a/trunk/arch/sh/kernel/machine_kexec.c b/trunk/arch/sh/kernel/machine_kexec.c
index 5c17de51987e..790ed69b8666 100644
--- a/trunk/arch/sh/kernel/machine_kexec.c
+++ b/trunk/arch/sh/kernel/machine_kexec.c
@@ -104,3 +104,24 @@ NORET_TYPE void machine_kexec(struct kimage *image)
(*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg);
}
+/* crashkernel=size@addr specifies the location to reserve for
+ * a crash kernel. By reserving this memory we guarantee
+ * that linux never sets it up as a DMA target.
+ * Useful for holding code to do something appropriate
+ * after a kernel panic.
+ */
+static int __init parse_crashkernel(char *arg)
+{
+ unsigned long size, base;
+ size = memparse(arg, &arg);
+ if (*arg == '@') {
+ base = memparse(arg+1, &arg);
+ /* FIXME: Do I want a sanity check
+ * to validate the memory range?
+ */
+ crashk_res.start = base;
+ crashk_res.end = base + size - 1;
+ }
+ return 0;
+}
+early_param("crashkernel", parse_crashkernel);
diff --git a/trunk/arch/sh/kernel/process.c b/trunk/arch/sh/kernel/process.c
index 6d7f2b07e491..b4469992d6b2 100644
--- a/trunk/arch/sh/kernel/process.c
+++ b/trunk/arch/sh/kernel/process.c
@@ -121,7 +121,7 @@ void machine_power_off(void)
void show_regs(struct pt_regs * regs)
{
printk("\n");
- printk("Pid : %d, Comm: %20s\n", task_pid_nr(current), current->comm);
+ printk("Pid : %d, Comm: %20s\n", current->pid, current->comm);
print_symbol("PC is at %s\n", instruction_pointer(regs));
printk("PC : %08lx SP : %08lx SR : %08lx ",
regs->pc, regs->regs[15], regs->sr);
diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c
index b749403f6b38..b3027a6775b9 100644
--- a/trunk/arch/sh/kernel/setup.c
+++ b/trunk/arch/sh/kernel/setup.c
@@ -128,37 +128,6 @@ static void __init register_bootmem_low_pages(void)
free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
}
-#ifdef CONFIG_KEXEC
-static void __init reserve_crashkernel(void)
-{
- unsigned long long free_mem;
- unsigned long long crash_size, crash_base;
- int ret;
-
- free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
-
- ret = parse_crashkernel(boot_command_line, free_mem,
- &crash_size, &crash_base);
- if (ret == 0 && crash_size) {
- if (crash_base > 0) {
- printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
- "for crashkernel (System RAM: %ldMB)\n",
- (unsigned long)(crash_size >> 20),
- (unsigned long)(crash_base >> 20),
- (unsigned long)(free_mem >> 20));
- crashk_res.start = crash_base;
- crashk_res.end = crash_base + crash_size - 1;
- reserve_bootmem(crash_base, crash_size);
- } else
- printk(KERN_INFO "crashkernel reservation failed - "
- "you have to specify a base address\n");
- }
-}
-#else
-static inline void __init reserve_crashkernel(void)
-{}
-#endif
-
void __init setup_bootmem_allocator(unsigned long free_pfn)
{
unsigned long bootmap_size;
@@ -220,8 +189,11 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
}
}
#endif
-
- reserve_crashkernel();
+#ifdef CONFIG_KEXEC
+ if (crashk_res.start != crashk_res.end)
+ reserve_bootmem(crashk_res.start,
+ crashk_res.end - crashk_res.start + 1);
+#endif
}
#ifndef CONFIG_NEED_MULTIPLE_NODES
diff --git a/trunk/arch/sh/kernel/signal.c b/trunk/arch/sh/kernel/signal.c
index ca754fd42437..2f42442cf164 100644
--- a/trunk/arch/sh/kernel/signal.c
+++ b/trunk/arch/sh/kernel/signal.c
@@ -382,7 +382,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
set_fs(USER_DS);
pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
- current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
+ current->comm, current->pid, frame, regs->pc, regs->pr);
flush_cache_sigtramp(regs->pr);
@@ -462,7 +462,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
set_fs(USER_DS);
pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
- current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
+ current->comm, current->pid, frame, regs->pc, regs->pr);
flush_cache_sigtramp(regs->pr);
diff --git a/trunk/arch/sh/kernel/traps.c b/trunk/arch/sh/kernel/traps.c
index cf99111cb33f..dcb46e71da1c 100644
--- a/trunk/arch/sh/kernel/traps.c
+++ b/trunk/arch/sh/kernel/traps.c
@@ -95,8 +95,8 @@ void die(const char * str, struct pt_regs * regs, long err)
print_modules();
show_regs(regs);
- printk("Process: %s (pid: %d, stack limit = %p)\n", current->comm,
- task_pid_nr(current), task_stack_page(current) + 1);
+ printk("Process: %s (pid: %d, stack limit = %p)\n",
+ current->comm, current->pid, task_stack_page(current) + 1);
if (!user_mode(regs) || in_interrupt())
dump_mem("Stack: ", regs->regs[15], THREAD_SIZE +
@@ -386,8 +386,7 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
printk(KERN_NOTICE "Fixing up unaligned userspace access "
"in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
- current->comm, task_pid_nr(current),
- (u16 *)regs->pc, instruction);
+ current->comm,current->pid,(u16*)regs->pc,instruction);
}
ret = -EFAULT;
diff --git a/trunk/arch/sh/mm/fault.c b/trunk/arch/sh/mm/fault.c
index f33cedb353fc..4729668ce5bf 100644
--- a/trunk/arch/sh/mm/fault.c
+++ b/trunk/arch/sh/mm/fault.c
@@ -207,7 +207,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_global_init(current)) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/trunk/arch/sh/oprofile/Kconfig b/trunk/arch/sh/oprofile/Kconfig
new file mode 100644
index 000000000000..5ade19801b97
--- /dev/null
+++ b/trunk/arch/sh/oprofile/Kconfig
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+ depends on EXPERIMENTAL
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+endmenu
+
diff --git a/trunk/arch/sh64/Kconfig b/trunk/arch/sh64/Kconfig
index ba204bac49df..b3327ce8e82f 100644
--- a/trunk/arch/sh64/Kconfig
+++ b/trunk/arch/sh64/Kconfig
@@ -284,7 +284,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
+source "arch/sh64/oprofile/Kconfig"
source "arch/sh64/Kconfig.debug"
diff --git a/trunk/arch/sh64/kernel/traps.c b/trunk/arch/sh64/kernel/traps.c
index c03101fab467..9d0d58fb29fa 100644
--- a/trunk/arch/sh64/kernel/traps.c
+++ b/trunk/arch/sh64/kernel/traps.c
@@ -764,7 +764,7 @@ static int misaligned_fixup(struct pt_regs *regs)
--user_mode_unaligned_fixup_count;
/* Only do 'count' worth of these reports, to remove a potential DoS against syslog */
printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n",
- current->comm, task_pid_nr(current), (__u32)regs->pc, opcode);
+ current->comm, current->pid, (__u32)regs->pc, opcode);
} else
#endif
if (!user_mode(regs) && (kernel_mode_unaligned_fixup_count > 0)) {
@@ -774,7 +774,7 @@ static int misaligned_fixup(struct pt_regs *regs)
(__u32)regs->pc, opcode);
} else {
printk("Fixing up unaligned kernelspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n",
- current->comm, task_pid_nr(current), (__u32)regs->pc, opcode);
+ current->comm, current->pid, (__u32)regs->pc, opcode);
}
}
diff --git a/trunk/arch/sh64/mm/fault.c b/trunk/arch/sh64/mm/fault.c
index 7c79a1ba8059..dd81c669c79b 100644
--- a/trunk/arch/sh64/mm/fault.c
+++ b/trunk/arch/sh64/mm/fault.c
@@ -81,7 +81,7 @@ static inline void print_vma(struct vm_area_struct *vma)
static inline void print_task(struct task_struct *tsk)
{
- printk("Task pid %d\n", task_pid_nr(tsk));
+ printk("Task pid %d\n", tsk->pid);
}
static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address)
@@ -272,13 +272,13 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
* usermode, so only need a few */
count++;
printk("user mode bad_area address=%08lx pid=%d (%s) pc=%08lx\n",
- address, task_pid_nr(current), current->comm,
+ address, current->pid, current->comm,
(unsigned long) regs->pc);
#if 0
show_regs(regs);
#endif
}
- if (is_global_init(tsk)) {
+ if (is_init(tsk)) {
panic("INIT had user mode bad_area\n");
}
tsk->thread.address = address;
@@ -320,14 +320,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- if (is_global_init(current)) {
+ if (is_init(current)) {
panic("INIT out of memory\n");
yield();
goto survive;
}
printk("fault:Out of memory\n");
up_read(&mm->mmap_sem);
- if (is_global_init(current)) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/trunk/arch/sh64/oprofile/Kconfig b/trunk/arch/sh64/oprofile/Kconfig
new file mode 100644
index 000000000000..19d37730b664
--- /dev/null
+++ b/trunk/arch/sh64/oprofile/Kconfig
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+ depends on EXPERIMENTAL
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+endmenu
+
diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig
index 527adc808ad6..c0f4ba109daa 100644
--- a/trunk/arch/sparc/Kconfig
+++ b/trunk/arch/sparc/Kconfig
@@ -320,7 +320,11 @@ endmenu
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
+menu "Instrumentation Support"
+
+source "arch/sparc/oprofile/Kconfig"
+
+endmenu
source "arch/sparc/Kconfig.debug"
diff --git a/trunk/arch/sparc/kernel/ptrace.c b/trunk/arch/sparc/kernel/ptrace.c
index fe562db475e9..003f8eed32f4 100644
--- a/trunk/arch/sparc/kernel/ptrace.c
+++ b/trunk/arch/sparc/kernel/ptrace.c
@@ -155,7 +155,7 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
/* Rest of them are completely unsupported. */
default:
printk("%s [%d]: Wants to read user offset %ld\n",
- current->comm, task_pid_nr(current), offset);
+ current->comm, current->pid, offset);
pt_error_return(regs, EIO);
return;
}
@@ -222,7 +222,7 @@ static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset,
/* Rest of them are completely unsupported or "no-touch". */
default:
printk("%s [%d]: Wants to write user offset %ld\n",
- current->comm, task_pid_nr(current), offset);
+ current->comm, current->pid, offset);
goto failure;
}
success:
diff --git a/trunk/arch/sparc/kernel/sys_sparc.c b/trunk/arch/sparc/kernel/sys_sparc.c
index 42bf09db9a81..6c0221e9a9f5 100644
--- a/trunk/arch/sparc/kernel/sys_sparc.c
+++ b/trunk/arch/sparc/kernel/sys_sparc.c
@@ -357,7 +357,7 @@ c_sys_nis_syscall (struct pt_regs *regs)
if (count++ > 5)
return -ENOSYS;
printk ("%s[%d]: Unimplemented SPARC system call %d\n",
- current->comm, task_pid_nr(current), (int)regs->u_regs[1]);
+ current->comm, current->pid, (int)regs->u_regs[1]);
#ifdef DEBUG_UNIMP_SYSCALL
show_regs (regs);
#endif
diff --git a/trunk/arch/sparc/kernel/sys_sunos.c b/trunk/arch/sparc/kernel/sys_sunos.c
index 28c187c5d9fd..f807172cab0e 100644
--- a/trunk/arch/sparc/kernel/sys_sunos.c
+++ b/trunk/arch/sparc/kernel/sys_sunos.c
@@ -866,7 +866,7 @@ asmlinkage int sunos_killpg(int pgrp, int sig)
rcu_read_lock();
ret = -EINVAL;
if (pgrp > 0)
- ret = kill_pgrp(find_vpid(pgrp), sig, 0);
+ ret = kill_pgrp(find_pid(pgrp), sig, 0);
rcu_read_unlock();
return ret;
diff --git a/trunk/arch/sparc/kernel/traps.c b/trunk/arch/sparc/kernel/traps.c
index d404e7994527..3bc3bff51e08 100644
--- a/trunk/arch/sparc/kernel/traps.c
+++ b/trunk/arch/sparc/kernel/traps.c
@@ -38,7 +38,7 @@ struct trap_trace_entry trapbuf[1024];
void syscall_trace_entry(struct pt_regs *regs)
{
- printk("%s[%d]: ", current->comm, task_pid_nr(current));
+ printk("%s[%d]: ", current->comm, current->pid);
printk("scall<%d> (could be %d)\n", (int) regs->u_regs[UREG_G1],
(int) regs->u_regs[UREG_I0]);
}
@@ -99,7 +99,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
" /_| \\__/ |_\\\n"
" \\__U_/\n");
- printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter);
+ printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
show_regs(regs);
add_taint(TAINT_DIE);
diff --git a/trunk/arch/sparc/oprofile/Kconfig b/trunk/arch/sparc/oprofile/Kconfig
new file mode 100644
index 000000000000..d8a84088471a
--- /dev/null
+++ b/trunk/arch/sparc/oprofile/Kconfig
@@ -0,0 +1,17 @@
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
diff --git a/trunk/arch/sparc64/Kconfig b/trunk/arch/sparc64/Kconfig
index c7a74e376985..59c4d752d286 100644
--- a/trunk/arch/sparc64/Kconfig
+++ b/trunk/arch/sparc64/Kconfig
@@ -460,7 +460,20 @@ source "drivers/fc4/Kconfig"
source "fs/Kconfig"
-source "kernel/Kconfig.instrumentation"
+menu "Instrumentation Support"
+
+source "arch/sparc64/oprofile/Kconfig"
+
+config KPROBES
+ bool "Kprobes (EXPERIMENTAL)"
+ depends on KALLSYMS && EXPERIMENTAL && MODULES
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+endmenu
source "arch/sparc64/Kconfig.debug"
diff --git a/trunk/arch/sparc64/kernel/sys_sunos32.c b/trunk/arch/sparc64/kernel/sys_sunos32.c
index 170d6ca8de6f..8f7a06e2c7e7 100644
--- a/trunk/arch/sparc64/kernel/sys_sunos32.c
+++ b/trunk/arch/sparc64/kernel/sys_sunos32.c
@@ -831,7 +831,7 @@ asmlinkage int sunos_killpg(int pgrp, int sig)
rcu_read_lock();
ret = -EINVAL;
if (pgrp > 0)
- ret = kill_pgrp(find_vpid(pgrp), sig, 0);
+ ret = kill_pgrp(find_pid(pgrp), sig, 0);
rcu_read_unlock();
return ret;
diff --git a/trunk/arch/sparc64/kernel/traps.c b/trunk/arch/sparc64/kernel/traps.c
index e9c7e4f07abf..34573a55b6e5 100644
--- a/trunk/arch/sparc64/kernel/traps.c
+++ b/trunk/arch/sparc64/kernel/traps.c
@@ -2225,7 +2225,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
" /_| \\__/ |_\\\n"
" \\__U_/\n");
- printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter);
+ printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV);
__asm__ __volatile__("flushw");
__show_regs(regs);
diff --git a/trunk/arch/sparc64/oprofile/Kconfig b/trunk/arch/sparc64/oprofile/Kconfig
new file mode 100644
index 000000000000..d8a84088471a
--- /dev/null
+++ b/trunk/arch/sparc64/oprofile/Kconfig
@@ -0,0 +1,17 @@
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
diff --git a/trunk/arch/sparc64/solaris/misc.c b/trunk/arch/sparc64/solaris/misc.c
index c86cb3091a8e..3b67de7455f1 100644
--- a/trunk/arch/sparc64/solaris/misc.c
+++ b/trunk/arch/sparc64/solaris/misc.c
@@ -415,7 +415,7 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
switch (cmd) {
case 0: /* getpgrp */
- return task_pgrp_nr(current);
+ return process_group(current);
case 1: /* setpgrp */
{
int (*sys_setpgid)(pid_t,pid_t) =
@@ -426,7 +426,7 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
ret = sys_setpgid(0, 0);
if (ret) return ret;
proc_clear_tty(current);
- return task_pgrp_nr(current);
+ return process_group(current);
}
case 2: /* getsid */
{
diff --git a/trunk/arch/um/Kconfig b/trunk/arch/um/Kconfig
index d8925d285573..740d8a922e48 100644
--- a/trunk/arch/um/Kconfig
+++ b/trunk/arch/um/Kconfig
@@ -289,6 +289,4 @@ config INPUT
bool
default n
-source "kernel/Kconfig.instrumentation"
-
source "arch/um/Kconfig.debug"
diff --git a/trunk/arch/um/kernel/trap.c b/trunk/arch/um/kernel/trap.c
index cb3321f8e0a9..bd060551e619 100644
--- a/trunk/arch/um/kernel/trap.c
+++ b/trunk/arch/um/kernel/trap.c
@@ -108,7 +108,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- if (is_global_init(current)) {
+ if (is_init(current)) {
up_read(&mm->mmap_sem);
yield();
down_read(&mm->mmap_sem);
diff --git a/trunk/arch/um/sys-x86_64/sysrq.c b/trunk/arch/um/sys-x86_64/sysrq.c
index 765444031819..ce3e07fcf283 100644
--- a/trunk/arch/um/sys-x86_64/sysrq.c
+++ b/trunk/arch/um/sys-x86_64/sysrq.c
@@ -15,8 +15,8 @@ void __show_regs(struct pt_regs * regs)
{
printk("\n");
print_modules();
- printk("Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current),
- current->comm, print_tainted(), init_utsname()->release);
+ printk("Pid: %d, comm: %.20s %s %s\n",
+ current->pid, current->comm, print_tainted(), init_utsname()->release);
printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff,
PT_REGS_RIP(regs));
printk("\nRSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs),
diff --git a/trunk/arch/v850/Kconfig b/trunk/arch/v850/Kconfig
index b6a50b8b38de..ace479ab273f 100644
--- a/trunk/arch/v850/Kconfig
+++ b/trunk/arch/v850/Kconfig
@@ -331,8 +331,6 @@ source "sound/Kconfig"
source "drivers/usb/Kconfig"
-source "kernel/Kconfig.instrumentation"
-
source "arch/v850/Kconfig.debug"
source "security/Kconfig"
diff --git a/trunk/arch/x86/ia32/ia32_binfmt.c b/trunk/arch/x86/ia32/ia32_binfmt.c
index 55822d2cf053..5027650eb273 100644
--- a/trunk/arch/x86/ia32/ia32_binfmt.c
+++ b/trunk/arch/x86/ia32/ia32_binfmt.c
@@ -5,6 +5,10 @@
* This tricks binfmt_elf.c into loading 32bit binaries using lots
* of ugly preprocessor tricks. Talk about very very poor man's inheritance.
*/
+#define __ASM_X86_64_ELF_H 1
+
+#undef ELF_CLASS
+#define ELF_CLASS ELFCLASS32
#include
#include
@@ -15,7 +19,6 @@
#include
#include
#include
-#include
#include
#include
@@ -28,20 +31,6 @@
#include
#include
-#undef ELF_ARCH
-#undef ELF_CLASS
-#define ELF_CLASS ELFCLASS32
-#define ELF_ARCH EM_386
-
-#undef elfhdr
-#undef elf_phdr
-#undef elf_note
-#undef elf_addr_t
-#define elfhdr elf32_hdr
-#define elf_phdr elf32_phdr
-#define elf_note elf32_note
-#define elf_addr_t Elf32_Off
-
#define ELF_NAME "elf/i386"
#define AT_SYSINFO 32
@@ -59,20 +48,74 @@ int sysctl_vsyscall32 = 1;
} while(0)
struct file;
+struct elf_phdr;
#define IA32_EMULATOR 1
-#undef ELF_ET_DYN_BASE
-
#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
+#undef ELF_ARCH
+#define ELF_ARCH EM_386
+
+#define ELF_DATA ELFDATA2LSB
+
+#define USE_ELF_CORE_DUMP 1
+
+/* Override elfcore.h */
+#define _LINUX_ELFCORE_H 1
+typedef unsigned int elf_greg_t;
+
+#define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+struct elf_siginfo
+{
+ int si_signo; /* signal number */
+ int si_code; /* extra code */
+ int si_errno; /* errno */
+};
+
#define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
+struct elf_prstatus
+{
+ struct elf_siginfo pr_info; /* Info associated with signal */
+ short pr_cursig; /* Current signal */
+ unsigned int pr_sigpend; /* Set of pending signals */
+ unsigned int pr_sighold; /* Set of held signals */
+ pid_t pr_pid;
+ pid_t pr_ppid;
+ pid_t pr_pgrp;
+ pid_t pr_sid;
+ struct compat_timeval pr_utime; /* User time */
+ struct compat_timeval pr_stime; /* System time */
+ struct compat_timeval pr_cutime; /* Cumulative user time */
+ struct compat_timeval pr_cstime; /* Cumulative system time */
+ elf_gregset_t pr_reg; /* GP registers */
+ int pr_fpvalid; /* True if math co-processor being used. */
+};
+
+#define ELF_PRARGSZ (80) /* Number of chars for args */
+
+struct elf_prpsinfo
+{
+ char pr_state; /* numeric process state */
+ char pr_sname; /* char for pr_state */
+ char pr_zomb; /* zombie */
+ char pr_nice; /* nice val */
+ unsigned int pr_flag; /* flags */
+ __u16 pr_uid;
+ __u16 pr_gid;
+ pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* filename of executable */
+ char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
+};
+
#define _GET_SEG(x) \
({ __u32 seg; asm("movl %%" __stringify(x) ",%0" : "=r"(seg)); seg; })
/* Assumes current==process to be dumped */
-#undef ELF_CORE_COPY_REGS
#define ELF_CORE_COPY_REGS(pr_reg, regs) \
pr_reg[0] = regs->rbx; \
pr_reg[1] = regs->rcx; \
@@ -92,41 +135,36 @@ struct file;
pr_reg[15] = regs->rsp; \
pr_reg[16] = regs->ss;
-
-#define elf_prstatus compat_elf_prstatus
-#define elf_prpsinfo compat_elf_prpsinfo
-#define elf_fpregset_t struct user_i387_ia32_struct
-#define elf_fpxregset_t struct user32_fxsr_struct
-#define user user32
+#define user user32
#undef elf_read_implies_exec
#define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X)
+//#include
+#include
+
+typedef struct user_i387_ia32_struct elf_fpregset_t;
+typedef struct user32_fxsr_struct elf_fpxregset_t;
+
-#define elf_core_copy_regs elf32_core_copy_regs
-static inline void elf32_core_copy_regs(compat_elf_gregset_t *elfregs,
- struct pt_regs *regs)
+static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *regs)
{
- ELF_CORE_COPY_REGS((&elfregs->ebx), regs)
+ ELF_CORE_COPY_REGS((*elfregs), regs)
}
-#define elf_core_copy_task_regs elf32_core_copy_task_regs
-static inline int elf32_core_copy_task_regs(struct task_struct *t,
- compat_elf_gregset_t* elfregs)
+static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
{
struct pt_regs *pp = task_pt_regs(t);
- ELF_CORE_COPY_REGS((&elfregs->ebx), pp);
+ ELF_CORE_COPY_REGS((*elfregs), pp);
/* fix wrong segments */
- elfregs->ds = t->thread.ds;
- elfregs->fs = t->thread.fsindex;
- elfregs->gs = t->thread.gsindex;
- elfregs->es = t->thread.es;
+ (*elfregs)[7] = t->thread.ds;
+ (*elfregs)[9] = t->thread.fsindex;
+ (*elfregs)[10] = t->thread.gsindex;
+ (*elfregs)[8] = t->thread.es;
return 1;
}
-#define elf_core_copy_task_fpregs elf32_core_copy_task_fpregs
static inline int
-elf32_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs,
- elf_fpregset_t *fpu)
+elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu)
{
struct _fpstate_ia32 *fpstate = (void*)fpu;
mm_segment_t oldfs = get_fs();
@@ -148,9 +186,8 @@ elf32_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs,
#define ELF_CORE_COPY_XFPREGS 1
#define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
-#define elf_core_copy_task_xfpregs elf32_core_copy_task_xfpregs
static inline int
-elf32_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
+elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
{
struct pt_regs *regs = task_pt_regs(t);
if (!tsk_used_math(t))
@@ -169,10 +206,6 @@ elf32_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
extern int force_personality32;
-#undef ELF_EXEC_PAGESIZE
-#undef ELF_HWCAP
-#undef ELF_PLATFORM
-#undef SET_PERSONALITY
#define ELF_EXEC_PAGESIZE PAGE_SIZE
#define ELF_HWCAP (boot_cpu_data.x86_capability[0])
#define ELF_PLATFORM ("i686")
@@ -198,7 +231,6 @@ do { \
#define load_elf_binary load_elf32_binary
-#undef ELF_PLAT_INIT
#define ELF_PLAT_INIT(r, load_addr) elf32_init(r)
#undef start_thread
diff --git a/trunk/arch/x86/kernel/Makefile_32 b/trunk/arch/x86/kernel/Makefile_32
index ccea590bbb92..a3fa11f8f460 100644
--- a/trunk/arch/x86/kernel/Makefile_32
+++ b/trunk/arch/x86/kernel/Makefile_32
@@ -2,7 +2,7 @@
# Makefile for the linux kernel.
#
-extra-y := head_32.o init_task.o vmlinux.lds
+extra-y := head_32.o init_task_32.o vmlinux.lds
obj-y := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
@@ -17,7 +17,6 @@ obj-$(CONFIG_MCA) += mca_32.o
obj-$(CONFIG_X86_MSR) += msr.o
obj-$(CONFIG_X86_CPUID) += cpuid.o
obj-$(CONFIG_MICROCODE) += microcode.o
-obj-$(CONFIG_PCI) += early-quirks.o
obj-$(CONFIG_APM) += apm_32.o
obj-$(CONFIG_X86_SMP) += smp_32.o smpboot_32.o tsc_sync.o
obj-$(CONFIG_SMP) += smpcommon_32.o
diff --git a/trunk/arch/x86/kernel/Makefile_64 b/trunk/arch/x86/kernel/Makefile_64
index dec06e769281..43da66213a47 100644
--- a/trunk/arch/x86/kernel/Makefile_64
+++ b/trunk/arch/x86/kernel/Makefile_64
@@ -2,7 +2,7 @@
# Makefile for the linux kernel.
#
-extra-y := head_64.o head64.o init_task.o vmlinux.lds
+extra-y := head_64.o head64.o init_task_64.o vmlinux.lds
EXTRA_AFLAGS := -traditional
obj-y := process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \
ptrace_64.o time_64.o ioport_64.o ldt_64.o setup_64.o i8259_64.o sys_x86_64.o \
@@ -39,7 +39,7 @@ obj-$(CONFIG_K8_NB) += k8.o
obj-$(CONFIG_AUDIT) += audit_64.o
obj-$(CONFIG_MODULES) += module_64.o
-obj-$(CONFIG_PCI) += early-quirks.o
+obj-$(CONFIG_PCI) += early-quirks_64.o
obj-y += topology.o
obj-y += intel_cacheinfo.o
diff --git a/trunk/arch/x86/kernel/acpi/Makefile_32 b/trunk/arch/x86/kernel/acpi/Makefile_32
index 045dd54b33e0..a4852a2e9190 100644
--- a/trunk/arch/x86/kernel/acpi/Makefile_32
+++ b/trunk/arch/x86/kernel/acpi/Makefile_32
@@ -1,4 +1,7 @@
obj-$(CONFIG_ACPI) += boot.o
+ifneq ($(CONFIG_PCI),)
+obj-$(CONFIG_X86_IO_APIC) += earlyquirk_32.o
+endif
obj-$(CONFIG_ACPI_SLEEP) += sleep_32.o wakeup_32.o
ifneq ($(CONFIG_ACPI_PROCESSOR),)
diff --git a/trunk/arch/x86/kernel/acpi/boot.c b/trunk/arch/x86/kernel/acpi/boot.c
index f28b2e251b1d..afd2afe9102d 100644
--- a/trunk/arch/x86/kernel/acpi/boot.c
+++ b/trunk/arch/x86/kernel/acpi/boot.c
@@ -555,7 +555,7 @@ EXPORT_SYMBOL(acpi_map_lsapic);
int acpi_unmap_lsapic(int cpu)
{
- per_cpu(x86_cpu_to_apicid, cpu) = -1;
+ x86_cpu_to_apicid[cpu] = -1;
cpu_clear(cpu, cpu_present_map);
num_processors--;
diff --git a/trunk/arch/x86/kernel/acpi/cstate.c b/trunk/arch/x86/kernel/acpi/cstate.c
index 10b67170b133..2d39f55d29a8 100644
--- a/trunk/arch/x86/kernel/acpi/cstate.c
+++ b/trunk/arch/x86/kernel/acpi/cstate.c
@@ -29,7 +29,7 @@
void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
unsigned int cpu)
{
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = cpu_data + cpu;
flags->bm_check = 0;
if (num_online_cpus() == 1)
@@ -72,7 +72,7 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
struct acpi_processor_cx *cx, struct acpi_power_register *reg)
{
struct cstate_entry *percpu_entry;
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = cpu_data + cpu;
cpumask_t saved_mask;
int retval;
diff --git a/trunk/arch/x86/kernel/acpi/earlyquirk_32.c b/trunk/arch/x86/kernel/acpi/earlyquirk_32.c
new file mode 100644
index 000000000000..23f78efc577d
--- /dev/null
+++ b/trunk/arch/x86/kernel/acpi/earlyquirk_32.c
@@ -0,0 +1,84 @@
+/*
+ * Do early PCI probing for bug detection when the main PCI subsystem is
+ * not up yet.
+ */
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#ifdef CONFIG_ACPI
+
+static int __init nvidia_hpet_check(struct acpi_table_header *header)
+{
+ return 0;
+}
+#endif
+
+static int __init check_bridge(int vendor, int device)
+{
+#ifdef CONFIG_ACPI
+ static int warned;
+ /* According to Nvidia all timer overrides are bogus unless HPET
+ is enabled. */
+ if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) {
+ if (!warned && acpi_table_parse(ACPI_SIG_HPET,
+ nvidia_hpet_check)) {
+ warned = 1;
+ acpi_skip_timer_override = 1;
+ printk(KERN_INFO "Nvidia board "
+ "detected. Ignoring ACPI "
+ "timer override.\n");
+ printk(KERN_INFO "If you got timer trouble "
+ "try acpi_use_timer_override\n");
+
+ }
+ }
+#endif
+ if (vendor == PCI_VENDOR_ID_ATI && timer_over_8254 == 1) {
+ timer_over_8254 = 0;
+ printk(KERN_INFO "ATI board detected. Disabling timer routing "
+ "over 8254.\n");
+ }
+ return 0;
+}
+
+void __init check_acpi_pci(void)
+{
+ int num, slot, func;
+
+ /* Assume the machine supports type 1. If not it will
+ always read ffffffff and should not have any side effect.
+ Actually a few buggy systems can machine check. Allow the user
+ to disable it by command line option at least -AK */
+ if (!early_pci_allowed())
+ return;
+
+ /* Poor man's PCI discovery */
+ for (num = 0; num < 32; num++) {
+ for (slot = 0; slot < 32; slot++) {
+ for (func = 0; func < 8; func++) {
+ u32 class;
+ u32 vendor;
+ class = read_pci_config(num, slot, func,
+ PCI_CLASS_REVISION);
+ if (class == 0xffffffff)
+ break;
+
+ if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
+ continue;
+
+ vendor = read_pci_config(num, slot, func,
+ PCI_VENDOR_ID);
+
+ if (check_bridge(vendor & 0xffff, vendor >> 16))
+ return;
+ }
+
+ }
+ }
+}
diff --git a/trunk/arch/x86/kernel/acpi/processor.c b/trunk/arch/x86/kernel/acpi/processor.c
index 2ed0a4ce62f0..b54fded49834 100644
--- a/trunk/arch/x86/kernel/acpi/processor.c
+++ b/trunk/arch/x86/kernel/acpi/processor.c
@@ -63,7 +63,7 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
{
unsigned int cpu = pr->id;
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = cpu_data + cpu;
pr->pdc = NULL;
if (c->x86_vendor == X86_VENDOR_INTEL)
diff --git a/trunk/arch/x86/kernel/alternative.c b/trunk/arch/x86/kernel/alternative.c
index d6405e0842b5..3bd2688bd443 100644
--- a/trunk/arch/x86/kernel/alternative.c
+++ b/trunk/arch/x86/kernel/alternative.c
@@ -357,14 +357,14 @@ void alternatives_smp_switch(int smp)
if (smp) {
printk(KERN_INFO "SMP alternatives: switching to SMP code\n");
clear_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
- clear_bit(X86_FEATURE_UP, cpu_data(0).x86_capability);
+ clear_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
list_for_each_entry(mod, &smp_alt_modules, next)
alternatives_smp_lock(mod->locks, mod->locks_end,
mod->text, mod->text_end);
} else {
printk(KERN_INFO "SMP alternatives: switching to UP code\n");
set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
- set_bit(X86_FEATURE_UP, cpu_data(0).x86_capability);
+ set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
list_for_each_entry(mod, &smp_alt_modules, next)
alternatives_smp_unlock(mod->locks, mod->locks_end,
mod->text, mod->text_end);
@@ -432,7 +432,7 @@ void __init alternative_instructions(void)
if (1 == num_possible_cpus()) {
printk(KERN_INFO "SMP alternatives: switching to UP code\n");
set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
- set_bit(X86_FEATURE_UP, cpu_data(0).x86_capability);
+ set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
alternatives_smp_unlock(__smp_locks, __smp_locks_end,
_text, _etext);
}
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig_32 b/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig
similarity index 100%
rename from trunk/arch/x86/kernel/cpu/cpufreq/Kconfig_32
rename to trunk/arch/x86/kernel/cpu/cpufreq/Kconfig
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index fea0af0476b9..2ca43ba32bc0 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -77,7 +77,7 @@ static unsigned int acpi_pstate_strict;
static int check_est_cpu(unsigned int cpuid)
{
- struct cpuinfo_x86 *cpu = &cpu_data(cpuid);
+ struct cpuinfo_x86 *cpu = &cpu_data[cpuid];
if (cpu->x86_vendor != X86_VENDOR_INTEL ||
!cpu_has(cpu, X86_FEATURE_EST))
@@ -560,7 +560,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
unsigned int cpu = policy->cpu;
struct acpi_cpufreq_data *data;
unsigned int result = 0;
- struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
+ struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
struct acpi_processor_performance *perf;
dprintk("acpi_cpufreq_cpu_init\n");
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
index 326a4c81f684..c11baaf9f2b4 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
@@ -305,7 +305,7 @@ static struct cpufreq_driver eps_driver = {
static int __init eps_init(void)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = cpu_data;
/* This driver will work only on Centaur C7 processors with
* Enhanced SpeedStep/PowerSaver registers */
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/elanfreq.c b/trunk/arch/x86/kernel/cpu/cpufreq/elanfreq.c
index 94619c22f563..1e7ae7dafcf6 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/elanfreq.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/elanfreq.c
@@ -199,7 +199,7 @@ static int elanfreq_target (struct cpufreq_policy *policy,
static int elanfreq_cpu_init(struct cpufreq_policy *policy)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = cpu_data;
unsigned int i;
int result;
@@ -280,7 +280,7 @@ static struct cpufreq_driver elanfreq_driver = {
static int __init elanfreq_init(void)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = cpu_data;
/* Test if we have the right hardware */
if ((c->x86_vendor != X86_VENDOR_AMD) ||
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/longhaul.c b/trunk/arch/x86/kernel/cpu/cpufreq/longhaul.c
index 749d00cb2ebd..5045f5d583c8 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/longhaul.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/longhaul.c
@@ -780,7 +780,7 @@ static int longhaul_setup_southbridge(void)
static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = cpu_data;
char *cpuname=NULL;
int ret;
u32 lo, hi;
@@ -959,7 +959,7 @@ static struct cpufreq_driver longhaul_driver = {
static int __init longhaul_init(void)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = cpu_data;
if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
return -ENODEV;
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/longrun.c b/trunk/arch/x86/kernel/cpu/cpufreq/longrun.c
index af4a867a097c..b2689514295a 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/longrun.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/longrun.c
@@ -172,7 +172,7 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq,
u32 save_lo, save_hi;
u32 eax, ebx, ecx, edx;
u32 try_hi;
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = cpu_data;
if (!low_freq || !high_freq)
return -EINVAL;
@@ -298,7 +298,7 @@ static struct cpufreq_driver longrun_driver = {
*/
static int __init longrun_init(void)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = cpu_data;
if (c->x86_vendor != X86_VENDOR_TRANSMETA ||
!cpu_has(c, X86_FEATURE_LONGRUN))
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/trunk/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
index 14791ec55cfd..793eae854f4f 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
@@ -195,7 +195,7 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
{
- struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
+ struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
int cpuid = 0;
unsigned int i;
@@ -279,7 +279,7 @@ static struct cpufreq_driver p4clockmod_driver = {
static int __init cpufreq_p4_init(void)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = cpu_data;
int ret;
/*
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
index 42405b4e34ed..6d0285339317 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
@@ -215,7 +215,7 @@ static struct cpufreq_driver powernow_k6_driver = {
*/
static int __init powernow_k6_init(void)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = cpu_data;
if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
((c->x86_model != 12) && (c->x86_model != 13)))
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
index b5a9863d6cdc..f3686a5f2308 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
@@ -114,7 +114,7 @@ static int check_fsb(unsigned int fsbspeed)
static int check_powernow(void)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = cpu_data;
unsigned int maxei, eax, ebx, ecx, edx;
if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 !=6)) {
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/sc520_freq.c b/trunk/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
index 42da9bd677d6..d9f3e90a7ae0 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
@@ -102,7 +102,7 @@ static int sc520_freq_target (struct cpufreq_policy *policy,
static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = cpu_data;
int result;
/* capability check */
@@ -151,7 +151,7 @@ static struct cpufreq_driver sc520_freq_driver = {
static int __init sc520_freq_init(void)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = cpu_data;
int err;
/* Test if we have the right hardware */
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
index 3031f1196192..811d47438546 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -230,7 +230,7 @@ static struct cpu_model models[] =
static int centrino_cpu_init_table(struct cpufreq_policy *policy)
{
- struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
+ struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
struct cpu_model *model;
for(model = models; model->cpu_id != NULL; model++)
@@ -340,7 +340,7 @@ static unsigned int get_cur_freq(unsigned int cpu)
static int centrino_cpu_init(struct cpufreq_policy *policy)
{
- struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
+ struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
unsigned freq;
unsigned l, h;
int ret;
@@ -612,7 +612,7 @@ static struct cpufreq_driver centrino_driver = {
*/
static int __init centrino_init(void)
{
- struct cpuinfo_x86 *cpu = &cpu_data(0);
+ struct cpuinfo_x86 *cpu = cpu_data;
if (!cpu_has(cpu, X86_FEATURE_EST))
return -ENODEV;
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c b/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
index 76c3ab0da468..b1acc8ce3167 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
+++ b/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
@@ -228,7 +228,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_processor_frequency);
unsigned int speedstep_detect_processor (void)
{
- struct cpuinfo_x86 *c = &cpu_data(0);
+ struct cpuinfo_x86 *c = cpu_data;
u32 ebx, msr_lo, msr_hi;
dprintk("x86: %x, model: %x\n", c->x86, c->x86_model);
diff --git a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c
index 9921b01fe199..297a24116949 100644
--- a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -295,7 +295,7 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
#ifdef CONFIG_X86_HT
- unsigned int cpu = c->cpu_index;
+ unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data);
#endif
if (c->cpuid_level > 3) {
@@ -417,14 +417,14 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
if (new_l2) {
l2 = new_l2;
#ifdef CONFIG_X86_HT
- per_cpu(cpu_llc_id, cpu) = l2_id;
+ cpu_llc_id[cpu] = l2_id;
#endif
}
if (new_l3) {
l3 = new_l3;
#ifdef CONFIG_X86_HT
- per_cpu(cpu_llc_id, cpu) = l3_id;
+ cpu_llc_id[cpu] = l3_id;
#endif
}
@@ -459,7 +459,7 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
struct _cpuid4_info *this_leaf, *sibling_leaf;
unsigned long num_threads_sharing;
int index_msb, i;
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = cpu_data;
this_leaf = CPUID4_INFO_IDX(cpu, index);
num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
@@ -470,8 +470,8 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
index_msb = get_count_order(num_threads_sharing);
for_each_online_cpu(i) {
- if (cpu_data(i).apicid >> index_msb ==
- c->apicid >> index_msb) {
+ if (c[i].apicid >> index_msb ==
+ c[cpu].apicid >> index_msb) {
cpu_set(i, this_leaf->shared_cpu_map);
if (i != cpu && cpuid4_info[i]) {
sibling_leaf = CPUID4_INFO_IDX(i, index);
diff --git a/trunk/arch/x86/kernel/cpu/perfctr-watchdog.c b/trunk/arch/x86/kernel/cpu/perfctr-watchdog.c
index c02541e6e653..54cdbf1a40f1 100644
--- a/trunk/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/trunk/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -120,9 +120,7 @@ int reserve_perfctr_nmi(unsigned int msr)
unsigned int counter;
counter = nmi_perfctr_msr_to_bit(msr);
- /* register not managed by the allocator? */
- if (counter > NMI_MAX_COUNTER_BITS)
- return 1;
+ BUG_ON(counter > NMI_MAX_COUNTER_BITS);
if (!test_and_set_bit(counter, perfctr_nmi_owner))
return 1;
@@ -134,9 +132,7 @@ void release_perfctr_nmi(unsigned int msr)
unsigned int counter;
counter = nmi_perfctr_msr_to_bit(msr);
- /* register not managed by the allocator? */
- if (counter > NMI_MAX_COUNTER_BITS)
- return;
+ BUG_ON(counter > NMI_MAX_COUNTER_BITS);
clear_bit(counter, perfctr_nmi_owner);
}
@@ -146,9 +142,7 @@ int reserve_evntsel_nmi(unsigned int msr)
unsigned int counter;
counter = nmi_evntsel_msr_to_bit(msr);
- /* register not managed by the allocator? */
- if (counter > NMI_MAX_COUNTER_BITS)
- return 1;
+ BUG_ON(counter > NMI_MAX_COUNTER_BITS);
if (!test_and_set_bit(counter, evntsel_nmi_owner))
return 1;
@@ -160,9 +154,7 @@ void release_evntsel_nmi(unsigned int msr)
unsigned int counter;
counter = nmi_evntsel_msr_to_bit(msr);
- /* register not managed by the allocator? */
- if (counter > NMI_MAX_COUNTER_BITS)
- return;
+ BUG_ON(counter > NMI_MAX_COUNTER_BITS);
clear_bit(counter, evntsel_nmi_owner);
}
diff --git a/trunk/arch/x86/kernel/cpu/proc.c b/trunk/arch/x86/kernel/cpu/proc.c
index 2d42b414b777..879a0f789b1e 100644
--- a/trunk/arch/x86/kernel/cpu/proc.c
+++ b/trunk/arch/x86/kernel/cpu/proc.c
@@ -85,13 +85,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
/* nothing */
};
struct cpuinfo_x86 *c = v;
- int i, n = 0;
+ int i, n = c - cpu_data;
int fpu_exception;
#ifdef CONFIG_SMP
if (!cpu_online(n))
return 0;
- n = c->cpu_index;
#endif
seq_printf(m, "processor\t: %d\n"
"vendor_id\t: %s\n"
@@ -176,15 +175,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
static void *c_start(struct seq_file *m, loff_t *pos)
{
- if (*pos == 0) /* just in case, cpu 0 is not the first */
- *pos = first_cpu(cpu_possible_map);
- if ((*pos) < NR_CPUS && cpu_possible(*pos))
- return &cpu_data(*pos);
- return NULL;
+ return *pos < NR_CPUS ? cpu_data + *pos : NULL;
}
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
{
- *pos = next_cpu(*pos, cpu_possible_map);
+ ++*pos;
return c_start(m, pos);
}
static void c_stop(struct seq_file *m, void *v)
diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig_64 b/trunk/arch/x86/kernel/cpufreq/Kconfig
similarity index 97%
rename from trunk/arch/x86/kernel/cpu/cpufreq/Kconfig_64
rename to trunk/arch/x86/kernel/cpufreq/Kconfig
index 9c9699fdcf52..a3fd51926cbd 100644
--- a/trunk/arch/x86/kernel/cpu/cpufreq/Kconfig_64
+++ b/trunk/arch/x86/kernel/cpufreq/Kconfig
@@ -19,7 +19,7 @@ config X86_POWERNOW_K8
To compile this driver as a module, choose M here: the
module will be called powernow-k8.
- For details, take a look at .
+ For details, take a look at .
If in doubt, say N.
diff --git a/trunk/arch/x86/kernel/cpuid.c b/trunk/arch/x86/kernel/cpuid.c
index 05c9936a16cc..70dcf912d9fb 100644
--- a/trunk/arch/x86/kernel/cpuid.c
+++ b/trunk/arch/x86/kernel/cpuid.c
@@ -114,7 +114,7 @@ static ssize_t cpuid_read(struct file *file, char __user *buf,
static int cpuid_open(struct inode *inode, struct file *file)
{
unsigned int cpu = iminor(file->f_path.dentry->d_inode);
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = &(cpu_data)[cpu];
if (cpu >= NR_CPUS || !cpu_online(cpu))
return -ENXIO; /* No such CPU */
@@ -134,18 +134,15 @@ static const struct file_operations cpuid_fops = {
.open = cpuid_open,
};
-static __cpuinit int cpuid_device_create(int cpu)
+static int __cpuinit cpuid_device_create(int i)
{
+ int err = 0;
struct device *dev;
- dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu),
- "cpu%d", cpu);
- return IS_ERR(dev) ? PTR_ERR(dev) : 0;
-}
-
-static void cpuid_device_destroy(int cpu)
-{
- device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
+ dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), "cpu%d",i);
+ if (IS_ERR(dev))
+ err = PTR_ERR(dev);
+ return err;
}
static int __cpuinit cpuid_class_cpu_callback(struct notifier_block *nfb,
@@ -153,21 +150,18 @@ static int __cpuinit cpuid_class_cpu_callback(struct notifier_block *nfb,
void *hcpu)
{
unsigned int cpu = (unsigned long)hcpu;
- int err = 0;
switch (action) {
- case CPU_UP_PREPARE:
- case CPU_UP_PREPARE_FROZEN:
- err = cpuid_device_create(cpu);
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+ cpuid_device_create(cpu);
break;
- case CPU_UP_CANCELED:
- case CPU_UP_CANCELED_FROZEN:
case CPU_DEAD:
case CPU_DEAD_FROZEN:
- cpuid_device_destroy(cpu);
+ device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
break;
}
- return err ? NOTIFY_BAD : NOTIFY_OK;
+ return NOTIFY_OK;
}
static struct notifier_block __cpuinitdata cpuid_class_cpu_notifier =
@@ -204,7 +198,7 @@ static int __init cpuid_init(void)
out_class:
i = 0;
for_each_online_cpu(i) {
- cpuid_device_destroy(i);
+ device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i));
}
class_destroy(cpuid_class);
out_chrdev:
@@ -218,7 +212,7 @@ static void __exit cpuid_exit(void)
int cpu = 0;
for_each_online_cpu(cpu)
- cpuid_device_destroy(cpu);
+ device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
class_destroy(cpuid_class);
unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
diff --git a/trunk/arch/x86/kernel/crash_dump_32.c b/trunk/arch/x86/kernel/crash_dump_32.c
index 72d0c56c1b48..32e75d0731a9 100644
--- a/trunk/arch/x86/kernel/crash_dump_32.c
+++ b/trunk/arch/x86/kernel/crash_dump_32.c
@@ -47,7 +47,6 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
if (!kdump_buf_page) {
printk(KERN_WARNING "Kdump: Kdump buffer page not"
" allocated\n");
- kunmap_atomic(vaddr, KM_PTE0);
return -EFAULT;
}
copy_page(kdump_buf_page, vaddr);
diff --git a/trunk/arch/x86/kernel/e820_32.c b/trunk/arch/x86/kernel/e820_32.c
index d58039e8de74..3c86b979a40a 100644
--- a/trunk/arch/x86/kernel/e820_32.c
+++ b/trunk/arch/x86/kernel/e820_32.c
@@ -288,8 +288,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
request_resource(res, code_resource);
request_resource(res, data_resource);
#ifdef CONFIG_KEXEC
- if (crashk_res.start != crashk_res.end)
- request_resource(res, &crashk_res);
+ request_resource(res, &crashk_res);
#endif
}
}
diff --git a/trunk/arch/x86/kernel/e820_64.c b/trunk/arch/x86/kernel/e820_64.c
index 57616865d8a0..e422b8159f69 100644
--- a/trunk/arch/x86/kernel/e820_64.c
+++ b/trunk/arch/x86/kernel/e820_64.c
@@ -226,8 +226,7 @@ void __init e820_reserve_resources(void)
request_resource(res, &code_resource);
request_resource(res, &data_resource);
#ifdef CONFIG_KEXEC
- if (crashk_res.start != crashk_res.end)
- request_resource(res, &crashk_res);
+ request_resource(res, &crashk_res);
#endif
}
}
diff --git a/trunk/arch/x86/kernel/early-quirks.c b/trunk/arch/x86/kernel/early-quirks_64.c
similarity index 88%
rename from trunk/arch/x86/kernel/early-quirks.c
rename to trunk/arch/x86/kernel/early-quirks_64.c
index dc34acbd54aa..13aa4fd728f3 100644
--- a/trunk/arch/x86/kernel/early-quirks.c
+++ b/trunk/arch/x86/kernel/early-quirks_64.c
@@ -13,13 +13,9 @@
#include
#include
#include
-#include
-#include
-#include
-
-#ifdef CONFIG_IOMMU
+#include
#include
-#endif
+#include
static void __init via_bugs(void)
{
@@ -27,8 +23,7 @@ static void __init via_bugs(void)
if ((end_pfn > MAX_DMA32_PFN || force_iommu) &&
!iommu_aperture_allowed) {
printk(KERN_INFO
- "Looks like a VIA chipset. Disabling IOMMU."
- " Override with iommu=allowed\n");
+ "Looks like a VIA chipset. Disabling IOMMU. Override with iommu=allowed\n");
iommu_aperture_disabled = 1;
}
#endif
@@ -45,7 +40,6 @@ static int __init nvidia_hpet_check(struct acpi_table_header *header)
static void __init nvidia_bugs(void)
{
#ifdef CONFIG_ACPI
-#ifdef CONFIG_X86_IO_APIC
/*
* All timer overrides on Nvidia are
* wrong unless HPET is enabled.
@@ -64,7 +58,6 @@ static void __init nvidia_bugs(void)
printk(KERN_INFO "If you got timer trouble "
"try acpi_use_timer_override\n");
}
-#endif
#endif
/* RED-PEN skip them on mptables too? */
@@ -72,13 +65,11 @@ static void __init nvidia_bugs(void)
static void __init ati_bugs(void)
{
-#ifdef CONFIG_X86_IO_APIC
if (timer_over_8254 == 1) {
timer_over_8254 = 0;
printk(KERN_INFO
- "ATI board detected. Disabling timer routing over 8254.\n");
+ "ATI board detected. Disabling timer routing over 8254.\n");
}
-#endif
}
struct chipset {
@@ -113,7 +104,7 @@ void __init early_quirks(void)
if (class == 0xffffffff)
break;
- if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
+ if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
continue;
vendor = read_pci_config(num, slot, func,
diff --git a/trunk/arch/x86/kernel/genapic_64.c b/trunk/arch/x86/kernel/genapic_64.c
index ce703e21c912..4ae03e3e8294 100644
--- a/trunk/arch/x86/kernel/genapic_64.c
+++ b/trunk/arch/x86/kernel/genapic_64.c
@@ -24,19 +24,10 @@
#include
#endif
-/*
- * which logical CPU number maps to which CPU (physical APIC ID)
- *
- * The following static array is used during kernel startup
- * and the x86_cpu_to_apicid_ptr contains the address of the
- * array during this time. Is it zeroed when the per_cpu
- * data area is removed.
- */
-u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata
+/* which logical CPU number maps to which CPU (physical APIC ID) */
+u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly
= { [0 ... NR_CPUS-1] = BAD_APICID };
-void *x86_cpu_to_apicid_ptr;
-DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
-EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
+EXPORT_SYMBOL(x86_cpu_to_apicid);
struct genapic __read_mostly *genapic = &apic_flat;
diff --git a/trunk/arch/x86/kernel/genapic_flat_64.c b/trunk/arch/x86/kernel/genapic_flat_64.c
index 07352b74bda6..91c7526768ee 100644
--- a/trunk/arch/x86/kernel/genapic_flat_64.c
+++ b/trunk/arch/x86/kernel/genapic_flat_64.c
@@ -172,7 +172,7 @@ static unsigned int physflat_cpu_mask_to_apicid(cpumask_t cpumask)
*/
cpu = first_cpu(cpumask);
if ((unsigned)cpu < NR_CPUS)
- return per_cpu(x86_cpu_to_apicid, cpu);
+ return x86_cpu_to_apicid[cpu];
else
return BAD_APICID;
}
diff --git a/trunk/arch/x86/kernel/head64.c b/trunk/arch/x86/kernel/head64.c
index 6b3469311e42..a7eee0a4751d 100644
--- a/trunk/arch/x86/kernel/head64.c
+++ b/trunk/arch/x86/kernel/head64.c
@@ -58,7 +58,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
for (i = 0; i < IDT_ENTRIES; i++)
set_intr_gate(i, early_idt_handler);
- load_idt((const struct desc_ptr *)&idt_descr);
+ asm volatile("lidt %0" :: "m" (idt_descr));
early_printk("Kernel alive\n");
diff --git a/trunk/arch/x86/kernel/hpet.c b/trunk/arch/x86/kernel/hpet.c
index 22d8f00c80dc..f8367074da0d 100644
--- a/trunk/arch/x86/kernel/hpet.c
+++ b/trunk/arch/x86/kernel/hpet.c
@@ -69,15 +69,12 @@ static inline void hpet_clear_mapping(void)
* HPET command line enable / disable
*/
static int boot_hpet_disable;
-int hpet_force_user;
static int __init hpet_setup(char* str)
{
if (str) {
if (!strncmp("disable", str, 7))
boot_hpet_disable = 1;
- if (!strncmp("force", str, 5))
- hpet_force_user = 1;
}
return 1;
}
diff --git a/trunk/arch/x86/kernel/i8259_32.c b/trunk/arch/x86/kernel/i8259_32.c
index f634fc715c99..d34a10cc13a7 100644
--- a/trunk/arch/x86/kernel/i8259_32.c
+++ b/trunk/arch/x86/kernel/i8259_32.c
@@ -403,8 +403,7 @@ void __init native_init_IRQ(void)
int vector = FIRST_EXTERNAL_VECTOR + i;
if (i >= NR_IRQS)
break;
- /* SYSCALL_VECTOR was reserved in trap_init. */
- if (!test_bit(vector, used_vectors))
+ if (vector != SYSCALL_VECTOR)
set_intr_gate(vector, interrupt[i]);
}
diff --git a/trunk/arch/x86/kernel/init_task.c b/trunk/arch/x86/kernel/init_task_32.c
similarity index 79%
rename from trunk/arch/x86/kernel/init_task.c
rename to trunk/arch/x86/kernel/init_task_32.c
index 468c9c437842..d26fc063a760 100644
--- a/trunk/arch/x86/kernel/init_task.c
+++ b/trunk/arch/x86/kernel/init_task_32.c
@@ -15,6 +15,7 @@ static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct mm_struct init_mm = INIT_MM(init_mm);
+
EXPORT_SYMBOL(init_mm);
/*
@@ -24,7 +25,7 @@ EXPORT_SYMBOL(init_mm);
* way process stacks are handled. This is done by having a special
* "init_task" linker map entry..
*/
-union thread_union init_thread_union
+union thread_union init_thread_union
__attribute__((__section__(".data.init_task"))) =
{ INIT_THREAD_INFO(init_task) };
@@ -34,14 +35,12 @@ union thread_union init_thread_union
* All other task structs will be allocated on slabs in fork.c
*/
struct task_struct init_task = INIT_TASK(init_task);
+
EXPORT_SYMBOL(init_task);
/*
* per-CPU TSS segments. Threads are completely 'soft' on Linux,
- * no more per-task TSS's. The TSS size is kept cacheline-aligned
- * so they are allowed to end up in the .data.cacheline_aligned
- * section. Since TSS's are completely CPU-local, we want them
- * on exact cacheline boundaries, to eliminate cacheline ping-pong.
- */
+ * no more per-task TSS's.
+ */
DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
diff --git a/trunk/arch/x86/kernel/init_task_64.c b/trunk/arch/x86/kernel/init_task_64.c
new file mode 100644
index 000000000000..4ff33d4f8551
--- /dev/null
+++ b/trunk/arch/x86/kernel/init_task_64.c
@@ -0,0 +1,54 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+EXPORT_SYMBOL(init_mm);
+
+/*
+ * Initial task structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by having a special
+ * "init_task" linker map entry..
+ */
+union thread_union init_thread_union
+ __attribute__((__section__(".data.init_task"))) =
+ { INIT_THREAD_INFO(init_task) };
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+
+EXPORT_SYMBOL(init_task);
+/*
+ * per-CPU TSS segments. Threads are completely 'soft' on Linux,
+ * no more per-task TSS's. The TSS size is kept cacheline-aligned
+ * so they are allowed to end up in the .data.cacheline_aligned
+ * section. Since TSS's are completely CPU-local, we want them
+ * on exact cacheline boundaries, to eliminate cacheline ping-pong.
+ */
+DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
+
+/* Copies of the original ist values from the tss are only accessed during
+ * debugging, no special alignment required.
+ */
+DEFINE_PER_CPU(struct orig_ist, orig_ist);
+
+#define ALIGN_TO_4K __attribute__((section(".data.init_task")))
diff --git a/trunk/arch/x86/kernel/io_apic_32.c b/trunk/arch/x86/kernel/io_apic_32.c
index 0c55e9d86f69..5f10c7189534 100644
--- a/trunk/arch/x86/kernel/io_apic_32.c
+++ b/trunk/arch/x86/kernel/io_apic_32.c
@@ -1198,7 +1198,7 @@ static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }
static int __assign_irq_vector(int irq)
{
static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
- int vector, offset;
+ int vector, offset, i;
BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
@@ -1215,8 +1215,11 @@ static int __assign_irq_vector(int irq)
}
if (vector == current_vector)
return -ENOSPC;
- if (test_and_set_bit(vector, used_vectors))
+ if (vector == SYSCALL_VECTOR)
goto next;
+ for (i = 0; i < NR_IRQ_VECTORS; i++)
+ if (irq_vector[i] == vector)
+ goto next;
current_vector = vector;
current_offset = offset;
@@ -2292,12 +2295,6 @@ static inline void __init check_timer(void)
void __init setup_IO_APIC(void)
{
- int i;
-
- /* Reserve all the system vectors. */
- for (i = FIRST_SYSTEM_VECTOR; i < NR_VECTORS; i++)
- set_bit(i, used_vectors);
-
enable_IO_APIC();
if (acpi_ioapic)
diff --git a/trunk/arch/x86/kernel/machine_kexec_32.c b/trunk/arch/x86/kernel/machine_kexec_32.c
index 11b935f4f886..8459ca64bc2f 100644
--- a/trunk/arch/x86/kernel/machine_kexec_32.c
+++ b/trunk/arch/x86/kernel/machine_kexec_32.c
@@ -149,6 +149,28 @@ NORET_TYPE void machine_kexec(struct kimage *image)
image->start, cpu_has_pae);
}
+/* crashkernel=size@addr specifies the location to reserve for
+ * a crash kernel. By reserving this memory we guarantee
+ * that linux never sets it up as a DMA target.
+ * Useful for holding code to do something appropriate
+ * after a kernel panic.
+ */
+static int __init parse_crashkernel(char *arg)
+{
+ unsigned long size, base;
+ size = memparse(arg, &arg);
+ if (*arg == '@') {
+ base = memparse(arg+1, &arg);
+ /* FIXME: Do I want a sanity check
+ * to validate the memory range?
+ */
+ crashk_res.start = base;
+ crashk_res.end = base + size - 1;
+ }
+ return 0;
+}
+early_param("crashkernel", parse_crashkernel);
+
void arch_crash_save_vmcoreinfo(void)
{
#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
diff --git a/trunk/arch/x86/kernel/machine_kexec_64.c b/trunk/arch/x86/kernel/machine_kexec_64.c
index 0d8577f05422..7450b69710b5 100644
--- a/trunk/arch/x86/kernel/machine_kexec_64.c
+++ b/trunk/arch/x86/kernel/machine_kexec_64.c
@@ -231,6 +231,33 @@ NORET_TYPE void machine_kexec(struct kimage *image)
image->start);
}
+/* crashkernel=size@addr specifies the location to reserve for
+ * a crash kernel. By reserving this memory we guarantee
+ * that linux never set's it up as a DMA target.
+ * Useful for holding code to do something appropriate
+ * after a kernel panic.
+ */
+static int __init setup_crashkernel(char *arg)
+{
+ unsigned long size, base;
+ char *p;
+ if (!arg)
+ return -EINVAL;
+ size = memparse(arg, &p);
+ if (arg == p)
+ return -EINVAL;
+ if (*p == '@') {
+ base = memparse(p+1, &p);
+ /* FIXME: Do I want a sanity check to validate the
+ * memory range? Yes you do, but it's too early for
+ * e820 -AK */
+ crashk_res.start = base;
+ crashk_res.end = base + size - 1;
+ }
+ return 0;
+}
+early_param("crashkernel", setup_crashkernel);
+
void arch_crash_save_vmcoreinfo(void)
{
#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
diff --git a/trunk/arch/x86/kernel/mce_64.c b/trunk/arch/x86/kernel/mce_64.c
index 2cf20de5beca..66e6b797b2cb 100644
--- a/trunk/arch/x86/kernel/mce_64.c
+++ b/trunk/arch/x86/kernel/mce_64.c
@@ -799,8 +799,7 @@ static __cpuinit int mce_create_device(unsigned int cpu)
{
int err;
int i;
-
- if (!mce_available(&cpu_data(cpu)))
+ if (!mce_available(&cpu_data[cpu]))
return -EIO;
memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject));
diff --git a/trunk/arch/x86/kernel/mce_amd_64.c b/trunk/arch/x86/kernel/mce_amd_64.c
index 752fb16a817d..0d2afd96aca4 100644
--- a/trunk/arch/x86/kernel/mce_amd_64.c
+++ b/trunk/arch/x86/kernel/mce_amd_64.c
@@ -472,11 +472,11 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
sprintf(name, "threshold_bank%i", bank);
#ifdef CONFIG_SMP
- if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) { /* symlink */
+ if (cpu_data[cpu].cpu_core_id && shared_bank[bank]) { /* symlink */
i = first_cpu(per_cpu(cpu_core_map, cpu));
/* first core not up yet */
- if (cpu_data(i).cpu_core_id)
+ if (cpu_data[i].cpu_core_id)
goto out;
/* already linked */
diff --git a/trunk/arch/x86/kernel/microcode.c b/trunk/arch/x86/kernel/microcode.c
index 09c315214a5e..09cf78110358 100644
--- a/trunk/arch/x86/kernel/microcode.c
+++ b/trunk/arch/x86/kernel/microcode.c
@@ -132,7 +132,7 @@ static struct ucode_cpu_info {
static void collect_cpu_info(int cpu_num)
{
- struct cpuinfo_x86 *c = &cpu_data(cpu_num);
+ struct cpuinfo_x86 *c = cpu_data + cpu_num;
struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
unsigned int val[2];
@@ -522,7 +522,7 @@ static struct platform_device *microcode_pdev;
static int cpu_request_microcode(int cpu)
{
char name[30];
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = cpu_data + cpu;
const struct firmware *firmware;
void *buf;
unsigned long size;
@@ -570,7 +570,7 @@ static int cpu_request_microcode(int cpu)
static int apply_microcode_check_cpu(int cpu)
{
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = cpu_data + cpu;
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
cpumask_t old;
unsigned int val[2];
diff --git a/trunk/arch/x86/kernel/mpparse_64.c b/trunk/arch/x86/kernel/mpparse_64.c
index ef4aab123581..8bf0ca03ac8e 100644
--- a/trunk/arch/x86/kernel/mpparse_64.c
+++ b/trunk/arch/x86/kernel/mpparse_64.c
@@ -57,8 +57,6 @@ unsigned long mp_lapic_addr = 0;
/* Processor that is doing the boot up */
unsigned int boot_cpu_id = -1U;
-EXPORT_SYMBOL(boot_cpu_id);
-
/* Internal processor count */
unsigned int num_processors __cpuinitdata = 0;
@@ -88,7 +86,7 @@ static int __init mpf_checksum(unsigned char *mp, int len)
return sum & 0xFF;
}
-static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
+static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
{
int cpu;
cpumask_t tmp_map;
@@ -125,18 +123,7 @@ static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
cpu = 0;
}
bios_cpu_apicid[cpu] = m->mpc_apicid;
- /*
- * We get called early in the the start_kernel initialization
- * process when the per_cpu data area is not yet setup, so we
- * use a static array that is removed after the per_cpu data
- * area is created.
- */
- if (x86_cpu_to_apicid_ptr) {
- u8 *x86_cpu_to_apicid = (u8 *)x86_cpu_to_apicid_ptr;
- x86_cpu_to_apicid[cpu] = m->mpc_apicid;
- } else {
- per_cpu(x86_cpu_to_apicid, cpu) = m->mpc_apicid;
- }
+ x86_cpu_to_apicid[cpu] = m->mpc_apicid;
cpu_set(cpu, cpu_possible_map);
cpu_set(cpu, cpu_present_map);
diff --git a/trunk/arch/x86/kernel/msr.c b/trunk/arch/x86/kernel/msr.c
index ee6eba4ecfea..e18e516cf549 100644
--- a/trunk/arch/x86/kernel/msr.c
+++ b/trunk/arch/x86/kernel/msr.c
@@ -112,7 +112,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
static int msr_open(struct inode *inode, struct file *file)
{
unsigned int cpu = iminor(file->f_path.dentry->d_inode);
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = &(cpu_data)[cpu];
if (cpu >= NR_CPUS || !cpu_online(cpu))
return -ENXIO; /* No such CPU */
diff --git a/trunk/arch/x86/kernel/pci-dma_64.c b/trunk/arch/x86/kernel/pci-dma_64.c
index afaf9f12c032..b2b42bdb0a15 100644
--- a/trunk/arch/x86/kernel/pci-dma_64.c
+++ b/trunk/arch/x86/kernel/pci-dma_64.c
@@ -11,7 +11,7 @@
#include
#include
-int iommu_merge __read_mostly = 1;
+int iommu_merge __read_mostly = 0;
EXPORT_SYMBOL(iommu_merge);
dma_addr_t bad_dma_address __read_mostly;
diff --git a/trunk/arch/x86/kernel/process_32.c b/trunk/arch/x86/kernel/process_32.c
index 7b899584d290..097aeafce5ff 100644
--- a/trunk/arch/x86/kernel/process_32.c
+++ b/trunk/arch/x86/kernel/process_32.c
@@ -295,52 +295,34 @@ static int __init idle_setup(char *str)
}
early_param("idle", idle_setup);
-void __show_registers(struct pt_regs *regs, int all)
+void show_regs(struct pt_regs * regs)
{
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
unsigned long d0, d1, d2, d3, d6, d7;
- unsigned long esp;
- unsigned short ss, gs;
-
- if (user_mode_vm(regs)) {
- esp = regs->esp;
- ss = regs->xss & 0xffff;
- savesegment(gs, gs);
- } else {
- esp = (unsigned long) (®s->esp);
- savesegment(ss, ss);
- savesegment(gs, gs);
- }
printk("\n");
- printk("Pid: %d, comm: %s %s (%s %.*s)\n",
- task_pid_nr(current), current->comm,
- print_tainted(), init_utsname()->release,
- (int)strcspn(init_utsname()->version, " "),
- init_utsname()->version);
-
- printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
- 0xffff & regs->xcs, regs->eip, regs->eflags,
- smp_processor_id());
+ printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
+ printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
print_symbol("EIP is at %s\n", regs->eip);
+ if (user_mode_vm(regs))
+ printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
+ printk(" EFLAGS: %08lx %s (%s %.*s)\n",
+ regs->eflags, print_tainted(), init_utsname()->release,
+ (int)strcspn(init_utsname()->version, " "),
+ init_utsname()->version);
printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
- regs->eax, regs->ebx, regs->ecx, regs->edx);
- printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
- regs->esi, regs->edi, regs->ebp, esp);
- printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
- regs->xds & 0xffff, regs->xes & 0xffff,
- regs->xfs & 0xffff, gs, ss);
-
- if (!all)
- return;
+ regs->eax,regs->ebx,regs->ecx,regs->edx);
+ printk("ESI: %08lx EDI: %08lx EBP: %08lx",
+ regs->esi, regs->edi, regs->ebp);
+ printk(" DS: %04x ES: %04x FS: %04x\n",
+ 0xffff & regs->xds,0xffff & regs->xes, 0xffff & regs->xfs);
cr0 = read_cr0();
cr2 = read_cr2();
cr3 = read_cr3();
cr4 = read_cr4_safe();
- printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
- cr0, cr2, cr3, cr4);
+ printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
get_debugreg(d0, 0);
get_debugreg(d1, 1);
@@ -348,16 +330,10 @@ void __show_registers(struct pt_regs *regs, int all)
get_debugreg(d3, 3);
printk("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
d0, d1, d2, d3);
-
get_debugreg(d6, 6);
get_debugreg(d7, 7);
- printk("DR6: %08lx DR7: %08lx\n",
- d6, d7);
-}
+ printk("DR6: %08lx DR7: %08lx\n", d6, d7);
-void show_regs(struct pt_regs *regs)
-{
- __show_registers(regs, 1);
show_trace(NULL, regs, ®s->esp);
}
diff --git a/trunk/arch/x86/kernel/quirks.c b/trunk/arch/x86/kernel/quirks.c
index a4ce1911efdf..d769e204f942 100644
--- a/trunk/arch/x86/kernel/quirks.c
+++ b/trunk/arch/x86/kernel/quirks.c
@@ -45,12 +45,9 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
if (!(config & 0x2))
pci_write_config_byte(dev, 0xf4, config);
}
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH,
- quirk_intel_irqbalance);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH,
- quirk_intel_irqbalance);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH,
- quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance);
#endif
#if defined(CONFIG_HPET_TIMER)
@@ -59,8 +56,7 @@ unsigned long force_hpet_address;
static enum {
NONE_FORCE_HPET_RESUME,
OLD_ICH_FORCE_HPET_RESUME,
- ICH_FORCE_HPET_RESUME,
- VT8237_FORCE_HPET_RESUME
+ ICH_FORCE_HPET_RESUME
} force_hpet_resume_type;
static void __iomem *rcba_base;
@@ -150,17 +146,17 @@ static void ich_force_enable_hpet(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0,
- ich_force_enable_hpet);
+ ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,
- ich_force_enable_hpet);
+ ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,
- ich_force_enable_hpet);
+ ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,
- ich_force_enable_hpet);
+ ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31,
- ich_force_enable_hpet);
+ ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1,
- ich_force_enable_hpet);
+ ich_force_enable_hpet);
static struct pci_dev *cached_dev;
@@ -236,91 +232,10 @@ static void old_ich_force_enable_hpet(struct pci_dev *dev)
printk(KERN_DEBUG "Failed to force enable HPET\n");
}
-/*
- * Undocumented chipset features. Make sure that the user enforced
- * this.
- */
-static void old_ich_force_enable_hpet_user(struct pci_dev *dev)
-{
- if (hpet_force_user)
- old_ich_force_enable_hpet(dev);
-}
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
- old_ich_force_enable_hpet_user);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,
- old_ich_force_enable_hpet_user);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
- old_ich_force_enable_hpet_user);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,
- old_ich_force_enable_hpet_user);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
- old_ich_force_enable_hpet);
+ old_ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12,
- old_ich_force_enable_hpet);
-
-
-static void vt8237_force_hpet_resume(void)
-{
- u32 val;
-
- if (!force_hpet_address || !cached_dev)
- return;
-
- val = 0xfed00000 | 0x80;
- pci_write_config_dword(cached_dev, 0x68, val);
-
- pci_read_config_dword(cached_dev, 0x68, &val);
- if (val & 0x80)
- printk(KERN_DEBUG "Force enabled HPET at resume\n");
- else
- BUG();
-}
-
-static void vt8237_force_enable_hpet(struct pci_dev *dev)
-{
- u32 uninitialized_var(val);
-
- if (!hpet_force_user || hpet_address || force_hpet_address)
- return;
-
- pci_read_config_dword(dev, 0x68, &val);
- /*
- * Bit 7 is HPET enable bit.
- * Bit 31:10 is HPET base address (contrary to what datasheet claims)
- */
- if (val & 0x80) {
- force_hpet_address = (val & ~0x3ff);
- printk(KERN_DEBUG "HPET at base address 0x%lx\n",
- force_hpet_address);
- return;
- }
-
- /*
- * HPET is disabled. Trying enabling at FED00000 and check
- * whether it sticks
- */
- val = 0xfed00000 | 0x80;
- pci_write_config_dword(dev, 0x68, val);
-
- pci_read_config_dword(dev, 0x68, &val);
- if (val & 0x80) {
- force_hpet_address = (val & ~0x3ff);
- printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
- force_hpet_address);
- cached_dev = dev;
- force_hpet_resume_type = VT8237_FORCE_HPET_RESUME;
- return;
- }
-
- printk(KERN_DEBUG "Failed to force enable HPET\n");
-}
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
- vt8237_force_enable_hpet);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
- vt8237_force_enable_hpet);
-
+ old_ich_force_enable_hpet);
void force_hpet_resume(void)
{
@@ -331,9 +246,6 @@ void force_hpet_resume(void)
case OLD_ICH_FORCE_HPET_RESUME:
return old_ich_force_hpet_resume();
- case VT8237_FORCE_HPET_RESUME:
- return vt8237_force_hpet_resume();
-
default:
break;
}
diff --git a/trunk/arch/x86/kernel/reboot_64.c b/trunk/arch/x86/kernel/reboot_64.c
index 776eb06b6512..368db2b9c5ac 100644
--- a/trunk/arch/x86/kernel/reboot_64.c
+++ b/trunk/arch/x86/kernel/reboot_64.c
@@ -11,7 +11,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -137,7 +136,7 @@ void machine_emergency_restart(void)
}
case BOOT_TRIPLE:
- load_idt((const struct desc_ptr *)&no_idt);
+ __asm__ __volatile__("lidt (%0)": :"r" (&no_idt));
__asm__ __volatile__("int3");
reboot_type = BOOT_KBD;
diff --git a/trunk/arch/x86/kernel/reboot_fixups_32.c b/trunk/arch/x86/kernel/reboot_fixups_32.c
index 1a07bbea7be3..8b30b26ad069 100644
--- a/trunk/arch/x86/kernel/reboot_fixups_32.c
+++ b/trunk/arch/x86/kernel/reboot_fixups_32.c
@@ -12,7 +12,6 @@
#include
#include
#include
-#include
static void cs5530a_warm_reset(struct pci_dev *dev)
{
@@ -25,8 +24,11 @@ static void cs5530a_warm_reset(struct pci_dev *dev)
static void cs5536_warm_reset(struct pci_dev *dev)
{
- /* writing 1 to the LSB of this MSR causes a hard reset */
- wrmsrl(MSR_DIVIL_SOFT_RESET, 1ULL);
+ /*
+ * 6.6.2.12 Soft Reset (DIVIL_SOFT_RESET)
+ * writing 1 to the LSB of this MSR causes a hard reset.
+ */
+ wrmsrl(0x51400017, 1ULL);
udelay(50); /* shouldn't get here but be safe and spin a while */
}
diff --git a/trunk/arch/x86/kernel/setup64.c b/trunk/arch/x86/kernel/setup64.c
index 3558ac78c926..ba9188235057 100644
--- a/trunk/arch/x86/kernel/setup64.c
+++ b/trunk/arch/x86/kernel/setup64.c
@@ -184,12 +184,6 @@ void __cpuinit check_efer(void)
unsigned long kernel_eflags;
-/*
- * Copies of the original ist values from the tss are only accessed during
- * debugging, no special alignment required.
- */
-DEFINE_PER_CPU(struct orig_ist, orig_ist);
-
/*
* cpu_init() initializes state that is per-CPU. Some data is already
* initialized (naturally) in the bootstrap process, such as the GDT
@@ -230,8 +224,8 @@ void __cpuinit cpu_init (void)
memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
cpu_gdt_descr[cpu].size = GDT_SIZE;
- load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
- load_idt((const struct desc_ptr *)&idt_descr);
+ asm volatile("lgdt %0" :: "m" (cpu_gdt_descr[cpu]));
+ asm volatile("lidt %0" :: "m" (idt_descr));
memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
syscall_init();
diff --git a/trunk/arch/x86/kernel/setup_32.c b/trunk/arch/x86/kernel/setup_32.c
index e4f199124761..b87a6fd5ba48 100644
--- a/trunk/arch/x86/kernel/setup_32.c
+++ b/trunk/arch/x86/kernel/setup_32.c
@@ -378,49 +378,6 @@ extern unsigned long __init setup_memory(void);
extern void zone_sizes_init(void);
#endif /* !CONFIG_NEED_MULTIPLE_NODES */
-static inline unsigned long long get_total_mem(void)
-{
- unsigned long long total;
-
- total = max_low_pfn - min_low_pfn;
-#ifdef CONFIG_HIGHMEM
- total += highend_pfn - highstart_pfn;
-#endif
-
- return total << PAGE_SHIFT;
-}
-
-#ifdef CONFIG_KEXEC
-static void __init reserve_crashkernel(void)
-{
- unsigned long long total_mem;
- unsigned long long crash_size, crash_base;
- int ret;
-
- total_mem = get_total_mem();
-
- ret = parse_crashkernel(boot_command_line, total_mem,
- &crash_size, &crash_base);
- if (ret == 0 && crash_size > 0) {
- if (crash_base > 0) {
- printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
- "for crashkernel (System RAM: %ldMB)\n",
- (unsigned long)(crash_size >> 20),
- (unsigned long)(crash_base >> 20),
- (unsigned long)(total_mem >> 20));
- crashk_res.start = crash_base;
- crashk_res.end = crash_base + crash_size - 1;
- reserve_bootmem(crash_base, crash_size);
- } else
- printk(KERN_INFO "crashkernel reservation failed - "
- "you have to specify a base address\n");
- }
-}
-#else
-static inline void __init reserve_crashkernel(void)
-{}
-#endif
-
void __init setup_bootmem_allocator(void)
{
unsigned long bootmap_size;
@@ -496,7 +453,11 @@ void __init setup_bootmem_allocator(void)
}
}
#endif
- reserve_crashkernel();
+#ifdef CONFIG_KEXEC
+ if (crashk_res.start != crashk_res.end)
+ reserve_bootmem(crashk_res.start,
+ crashk_res.end - crashk_res.start + 1);
+#endif
}
/*
@@ -661,7 +622,9 @@ void __init setup_arch(char **cmdline_p)
#endif
#ifdef CONFIG_PCI
- early_quirks();
+#ifdef CONFIG_X86_IO_APIC
+ check_acpi_pci(); /* Checks more than just ACPI actually */
+#endif
#endif
#ifdef CONFIG_ACPI
diff --git a/trunk/arch/x86/kernel/setup_64.c b/trunk/arch/x86/kernel/setup_64.c
index 31322d42eaae..5a19f0cc5b67 100644
--- a/trunk/arch/x86/kernel/setup_64.c
+++ b/trunk/arch/x86/kernel/setup_64.c
@@ -191,37 +191,6 @@ static inline void copy_edd(void)
}
#endif
-#ifdef CONFIG_KEXEC
-static void __init reserve_crashkernel(void)
-{
- unsigned long long free_mem;
- unsigned long long crash_size, crash_base;
- int ret;
-
- free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
-
- ret = parse_crashkernel(boot_command_line, free_mem,
- &crash_size, &crash_base);
- if (ret == 0 && crash_size) {
- if (crash_base > 0) {
- printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
- "for crashkernel (System RAM: %ldMB)\n",
- (unsigned long)(crash_size >> 20),
- (unsigned long)(crash_base >> 20),
- (unsigned long)(free_mem >> 20));
- crashk_res.start = crash_base;
- crashk_res.end = crash_base + crash_size - 1;
- reserve_bootmem(crash_base, crash_size);
- } else
- printk(KERN_INFO "crashkernel reservation failed - "
- "you have to specify a base address\n");
- }
-}
-#else
-static inline void __init reserve_crashkernel(void)
-{}
-#endif
-
#define EBDA_ADDR_POINTER 0x40E
unsigned __initdata ebda_addr;
@@ -302,11 +271,6 @@ void __init setup_arch(char **cmdline_p)
dmi_scan_machine();
-#ifdef CONFIG_SMP
- /* setup to use the static apicid table during kernel startup */
- x86_cpu_to_apicid_ptr = (void *)&x86_cpu_to_apicid_init;
-#endif
-
#ifdef CONFIG_ACPI
/*
* Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
@@ -393,7 +357,13 @@ void __init setup_arch(char **cmdline_p)
}
}
#endif
- reserve_crashkernel();
+#ifdef CONFIG_KEXEC
+ if (crashk_res.start != crashk_res.end) {
+ reserve_bootmem_generic(crashk_res.start,
+ crashk_res.end - crashk_res.start + 1);
+ }
+#endif
+
paging_init();
#ifdef CONFIG_PCI
@@ -559,7 +529,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
but in the same order as the HT nodeids.
If that doesn't result in a usable node fall back to the
path for the previous case. */
- int ht_nodeid = apicid - (cpu_data(0).phys_proc_id << bits);
+ int ht_nodeid = apicid - (cpu_data[0].phys_proc_id << bits);
if (ht_nodeid >= 0 &&
apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
node = apicid_to_node[ht_nodeid];
@@ -883,7 +853,6 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
#ifdef CONFIG_SMP
c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff;
- c->cpu_index = 0;
#endif
}
@@ -990,7 +959,6 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
static int show_cpuinfo(struct seq_file *m, void *v)
{
struct cpuinfo_x86 *c = v;
- int cpu = 0;
/*
* These flag bits must match the definitions in .
@@ -1069,9 +1037,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
#ifdef CONFIG_SMP
- if (!cpu_online(c->cpu_index))
+ if (!cpu_online(c-cpu_data))
return 0;
- cpu = c->cpu_index;
#endif
seq_printf(m,"processor\t: %u\n"
@@ -1079,7 +1046,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
"cpu family\t: %d\n"
"model\t\t: %d\n"
"model name\t: %s\n",
- (unsigned)cpu,
+ (unsigned)(c-cpu_data),
c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
c->x86,
(int)c->x86_model,
@@ -1091,7 +1058,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "stepping\t: unknown\n");
if (cpu_has(c,X86_FEATURE_TSC)) {
- unsigned int freq = cpufreq_quick_get((unsigned)cpu);
+ unsigned int freq = cpufreq_quick_get((unsigned)(c-cpu_data));
if (!freq)
freq = cpu_khz;
seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
@@ -1104,6 +1071,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
#ifdef CONFIG_SMP
if (smp_num_siblings * c->x86_max_cores > 1) {
+ int cpu = c - cpu_data;
seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
seq_printf(m, "siblings\t: %d\n",
cpus_weight(per_cpu(cpu_core_map, cpu)));
@@ -1161,16 +1129,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
static void *c_start(struct seq_file *m, loff_t *pos)
{
- if (*pos == 0) /* just in case, cpu 0 is not the first */
- *pos = first_cpu(cpu_possible_map);
- if ((*pos) < NR_CPUS && cpu_possible(*pos))
- return &cpu_data(*pos);
- return NULL;
+ return *pos < NR_CPUS ? cpu_data + *pos : NULL;
}
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
{
- *pos = next_cpu(*pos, cpu_possible_map);
+ ++*pos;
return c_start(m, pos);
}
diff --git a/trunk/arch/x86/kernel/signal_32.c b/trunk/arch/x86/kernel/signal_32.c
index 6dc394b87255..0d79df3c5631 100644
--- a/trunk/arch/x86/kernel/signal_32.c
+++ b/trunk/arch/x86/kernel/signal_32.c
@@ -200,8 +200,8 @@ asmlinkage int sys_sigreturn(unsigned long __unused)
if (show_unhandled_signals && printk_ratelimit())
printk("%s%s[%d] bad frame in sigreturn frame:%p eip:%lx"
" esp:%lx oeax:%lx\n",
- task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
- current->comm, task_pid_nr(current), frame, regs->eip,
+ current->pid > 1 ? KERN_INFO : KERN_EMERG,
+ current->comm, current->pid, frame, regs->eip,
regs->esp, regs->orig_eax);
force_sig(SIGSEGV, current);
diff --git a/trunk/arch/x86/kernel/smp_32.c b/trunk/arch/x86/kernel/smp_32.c
index 2621ca3b2e4d..791d9f8036ae 100644
--- a/trunk/arch/x86/kernel/smp_32.c
+++ b/trunk/arch/x86/kernel/smp_32.c
@@ -610,7 +610,7 @@ static void stop_this_cpu (void * dummy)
*/
cpu_clear(smp_processor_id(), cpu_online_map);
disable_local_APIC();
- if (cpu_data(smp_processor_id()).hlt_works_ok)
+ if (cpu_data[smp_processor_id()].hlt_works_ok)
for(;;) halt();
for (;;);
}
@@ -676,7 +676,7 @@ static int convert_apicid_to_cpu(int apic_id)
int i;
for (i = 0; i < NR_CPUS; i++) {
- if (per_cpu(x86_cpu_to_apicid, i) == apic_id)
+ if (x86_cpu_to_apicid[i] == apic_id)
return i;
}
return -1;
diff --git a/trunk/arch/x86/kernel/smp_64.c b/trunk/arch/x86/kernel/smp_64.c
index 03fa6ed559c6..5c2964727d19 100644
--- a/trunk/arch/x86/kernel/smp_64.c
+++ b/trunk/arch/x86/kernel/smp_64.c
@@ -322,27 +322,17 @@ void unlock_ipi_call_lock(void)
}
/*
- * this function sends a 'generic call function' IPI to all other CPU
- * of the system defined in the mask.
+ * this function sends a 'generic call function' IPI to one other CPU
+ * in the system.
+ *
+ * cpu is a standard Linux logical CPU number.
*/
-
-static int
-__smp_call_function_mask(cpumask_t mask,
- void (*func)(void *), void *info,
- int wait)
+static void
+__smp_call_function_single(int cpu, void (*func) (void *info), void *info,
+ int nonatomic, int wait)
{
struct call_data_struct data;
- cpumask_t allbutself;
- int cpus;
-
- allbutself = cpu_online_map;
- cpu_clear(smp_processor_id(), allbutself);
-
- cpus_and(mask, mask, allbutself);
- cpus = cpus_weight(mask);
-
- if (!cpus)
- return 0;
+ int cpus = 1;
data.func = func;
data.info = info;
@@ -353,55 +343,19 @@ __smp_call_function_mask(cpumask_t mask,
call_data = &data;
wmb();
-
- /* Send a message to other CPUs */
- if (cpus_equal(mask, allbutself))
- send_IPI_allbutself(CALL_FUNCTION_VECTOR);
- else
- send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
+ /* Send a message to all other CPUs and wait for them to respond */
+ send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR);
/* Wait for response */
while (atomic_read(&data.started) != cpus)
cpu_relax();
if (!wait)
- return 0;
+ return;
while (atomic_read(&data.finished) != cpus)
cpu_relax();
-
- return 0;
-}
-/**
- * smp_call_function_mask(): Run a function on a set of other CPUs.
- * @mask: The set of cpus to run on. Must not include the current cpu.
- * @func: The function to run. This must be fast and non-blocking.
- * @info: An arbitrary pointer to pass to the function.
- * @wait: If true, wait (atomically) until function has completed on other CPUs.
- *
- * Returns 0 on success, else a negative status code.
- *
- * If @wait is true, then returns once @func has returned; otherwise
- * it returns just before the target cpu calls @func.
- *
- * You must not call this function with disabled interrupts or from a
- * hardware interrupt handler or from a bottom half handler.
- */
-int smp_call_function_mask(cpumask_t mask,
- void (*func)(void *), void *info,
- int wait)
-{
- int ret;
-
- /* Can deadlock when called with interrupts disabled */
- WARN_ON(irqs_disabled());
-
- spin_lock(&call_lock);
- ret = __smp_call_function_mask(mask, func, info, wait);
- spin_unlock(&call_lock);
- return ret;
}
-EXPORT_SYMBOL(smp_call_function_mask);
/*
* smp_call_function_single - Run a function on a specific CPU
@@ -420,7 +374,6 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
int nonatomic, int wait)
{
/* prevent preemption and reschedule on another processor */
- int ret;
int me = get_cpu();
/* Can deadlock when called with interrupts disabled */
@@ -434,13 +387,50 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
return 0;
}
- ret = smp_call_function_mask(cpumask_of_cpu(cpu), func, info, wait);
-
+ spin_lock(&call_lock);
+ __smp_call_function_single(cpu, func, info, nonatomic, wait);
+ spin_unlock(&call_lock);
put_cpu();
- return ret;
+ return 0;
}
EXPORT_SYMBOL(smp_call_function_single);
+/*
+ * this function sends a 'generic call function' IPI to all other CPUs
+ * in the system.
+ */
+static void __smp_call_function (void (*func) (void *info), void *info,
+ int nonatomic, int wait)
+{
+ struct call_data_struct data;
+ int cpus = num_online_cpus()-1;
+
+ if (!cpus)
+ return;
+
+ data.func = func;
+ data.info = info;
+ atomic_set(&data.started, 0);
+ data.wait = wait;
+ if (wait)
+ atomic_set(&data.finished, 0);
+
+ call_data = &data;
+ wmb();
+ /* Send a message to all other CPUs and wait for them to respond */
+ send_IPI_allbutself(CALL_FUNCTION_VECTOR);
+
+ /* Wait for response */
+ while (atomic_read(&data.started) != cpus)
+ cpu_relax();
+
+ if (!wait)
+ return;
+
+ while (atomic_read(&data.finished) != cpus)
+ cpu_relax();
+}
+
/*
* smp_call_function - run a function on all other CPUs.
* @func: The function to run. This must be fast and non-blocking.
@@ -459,7 +449,10 @@ EXPORT_SYMBOL(smp_call_function_single);
int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
int wait)
{
- return smp_call_function_mask(cpu_online_map, func, info, wait);
+ spin_lock(&call_lock);
+ __smp_call_function(func,info,nonatomic,wait);
+ spin_unlock(&call_lock);
+ return 0;
}
EXPORT_SYMBOL(smp_call_function);
@@ -486,7 +479,7 @@ void smp_send_stop(void)
/* Don't deadlock on the call lock in panic */
nolock = !spin_trylock(&call_lock);
local_irq_save(flags);
- __smp_call_function_mask(cpu_online_map, stop_this_cpu, NULL, 0);
+ __smp_call_function(stop_this_cpu, NULL, 0, 0);
if (!nolock)
spin_unlock(&call_lock);
disable_local_APIC();
diff --git a/trunk/arch/x86/kernel/smpboot_32.c b/trunk/arch/x86/kernel/smpboot_32.c
index 7b8fdfa169dd..be3faac04719 100644
--- a/trunk/arch/x86/kernel/smpboot_32.c
+++ b/trunk/arch/x86/kernel/smpboot_32.c
@@ -67,7 +67,7 @@ int smp_num_siblings = 1;
EXPORT_SYMBOL(smp_num_siblings);
/* Last level cache ID of each logical CPU */
-DEFINE_PER_CPU(u8, cpu_llc_id) = BAD_APICID;
+int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
/* representing HT siblings of each logical CPU */
DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
@@ -89,20 +89,12 @@ EXPORT_SYMBOL(cpu_possible_map);
static cpumask_t smp_commenced_mask;
/* Per CPU bogomips and other parameters */
-DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
-EXPORT_PER_CPU_SYMBOL(cpu_info);
+struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
+EXPORT_SYMBOL(cpu_data);
-/*
- * The following static array is used during kernel startup
- * and the x86_cpu_to_apicid_ptr contains the address of the
- * array during this time. Is it zeroed when the per_cpu
- * data area is removed.
- */
-u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata =
- { [0 ... NR_CPUS-1] = BAD_APICID };
-void *x86_cpu_to_apicid_ptr;
-DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
-EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
+u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
+ { [0 ... NR_CPUS-1] = 0xff };
+EXPORT_SYMBOL(x86_cpu_to_apicid);
u8 apicid_2_node[MAX_APICID];
@@ -158,10 +150,9 @@ void __init smp_alloc_memory(void)
void __cpuinit smp_store_cpu_info(int id)
{
- struct cpuinfo_x86 *c = &cpu_data(id);
+ struct cpuinfo_x86 *c = cpu_data + id;
*c = boot_cpu_data;
- c->cpu_index = id;
if (id!=0)
identify_secondary_cpu(c);
/*
@@ -303,7 +294,7 @@ static int cpucount;
/* maps the cpu to the sched domain representing multi-core */
cpumask_t cpu_coregroup_map(int cpu)
{
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = cpu_data + cpu;
/*
* For perf, we return last level cache shared map.
* And for power savings, we return cpu_core_map
@@ -320,41 +311,41 @@ static cpumask_t cpu_sibling_setup_map;
void __cpuinit set_cpu_sibling_map(int cpu)
{
int i;
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = cpu_data;
cpu_set(cpu, cpu_sibling_setup_map);
if (smp_num_siblings > 1) {
for_each_cpu_mask(i, cpu_sibling_setup_map) {
- if (c->phys_proc_id == cpu_data(i).phys_proc_id &&
- c->cpu_core_id == cpu_data(i).cpu_core_id) {
+ if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
+ c[cpu].cpu_core_id == c[i].cpu_core_id) {
cpu_set(i, per_cpu(cpu_sibling_map, cpu));
cpu_set(cpu, per_cpu(cpu_sibling_map, i));
cpu_set(i, per_cpu(cpu_core_map, cpu));
cpu_set(cpu, per_cpu(cpu_core_map, i));
- cpu_set(i, c->llc_shared_map);
- cpu_set(cpu, cpu_data(i).llc_shared_map);
+ cpu_set(i, c[cpu].llc_shared_map);
+ cpu_set(cpu, c[i].llc_shared_map);
}
}
} else {
cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
}
- cpu_set(cpu, c->llc_shared_map);
+ cpu_set(cpu, c[cpu].llc_shared_map);
if (current_cpu_data.x86_max_cores == 1) {
per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
- c->booted_cores = 1;
+ c[cpu].booted_cores = 1;
return;
}
for_each_cpu_mask(i, cpu_sibling_setup_map) {
- if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
- per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
- cpu_set(i, c->llc_shared_map);
- cpu_set(cpu, cpu_data(i).llc_shared_map);
+ if (cpu_llc_id[cpu] != BAD_APICID &&
+ cpu_llc_id[cpu] == cpu_llc_id[i]) {
+ cpu_set(i, c[cpu].llc_shared_map);
+ cpu_set(cpu, c[i].llc_shared_map);
}
- if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
+ if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
cpu_set(i, per_cpu(cpu_core_map, cpu));
cpu_set(cpu, per_cpu(cpu_core_map, i));
/*
@@ -366,15 +357,15 @@ void __cpuinit set_cpu_sibling_map(int cpu)
* the booted_cores for this new cpu
*/
if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
- c->booted_cores++;
+ c[cpu].booted_cores++;
/*
* increment the core count for all
* the other cpus in this package
*/
if (i != cpu)
- cpu_data(i).booted_cores++;
- } else if (i != cpu && !c->booted_cores)
- c->booted_cores = cpu_data(i).booted_cores;
+ c[i].booted_cores++;
+ } else if (i != cpu && !c[cpu].booted_cores)
+ c[cpu].booted_cores = c[i].booted_cores;
}
}
}
@@ -813,7 +804,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
irq_ctx_init(cpu);
- per_cpu(x86_cpu_to_apicid, cpu) = apicid;
+ x86_cpu_to_apicid[cpu] = apicid;
/*
* This grunge runs the startup process for
* the targeted processor.
@@ -853,7 +844,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
/* number CPUs logically, starting from 1 (BSP is 0) */
Dprintk("OK.\n");
printk("CPU%d: ", cpu);
- print_cpu_info(&cpu_data(cpu));
+ print_cpu_info(&cpu_data[cpu]);
Dprintk("CPU has booted.\n");
} else {
boot_error= 1;
@@ -875,7 +866,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
cpucount--;
} else {
- per_cpu(x86_cpu_to_apicid, cpu) = apicid;
+ x86_cpu_to_apicid[cpu] = apicid;
cpu_set(cpu, cpu_present_map);
}
@@ -924,7 +915,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu)
struct warm_boot_cpu_info info;
int apicid, ret;
- apicid = per_cpu(x86_cpu_to_apicid, cpu);
+ apicid = x86_cpu_to_apicid[cpu];
if (apicid == BAD_APICID) {
ret = -ENODEV;
goto exit;
@@ -970,11 +961,11 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
*/
smp_store_cpu_info(0); /* Final full version of the data */
printk("CPU%d: ", 0);
- print_cpu_info(&cpu_data(0));
+ print_cpu_info(&cpu_data[0]);
boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
boot_cpu_logical_apicid = logical_smp_processor_id();
- per_cpu(x86_cpu_to_apicid, 0) = boot_cpu_physical_apicid;
+ x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
current_thread_info()->cpu = 0;
@@ -1017,7 +1008,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
- map_cpu_to_logical_apicid();
cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, per_cpu(cpu_core_map, 0));
return;
@@ -1039,7 +1029,6 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
}
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
- map_cpu_to_logical_apicid();
cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, per_cpu(cpu_core_map, 0));
return;
@@ -1093,7 +1082,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
Dprintk("Before bogomips.\n");
for (cpu = 0; cpu < NR_CPUS; cpu++)
if (cpu_isset(cpu, cpu_callout_map))
- bogosum += cpu_data(cpu).loops_per_jiffy;
+ bogosum += cpu_data[cpu].loops_per_jiffy;
printk(KERN_INFO
"Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
cpucount+1,
@@ -1163,7 +1152,7 @@ void __init native_smp_prepare_boot_cpu(void)
void remove_siblinginfo(int cpu)
{
int sibling;
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = cpu_data;
for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
@@ -1171,15 +1160,15 @@ void remove_siblinginfo(int cpu)
* last thread sibling in this cpu core going down
*/
if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
- cpu_data(sibling).booted_cores--;
+ c[sibling].booted_cores--;
}
for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
cpus_clear(per_cpu(cpu_sibling_map, cpu));
cpus_clear(per_cpu(cpu_core_map, cpu));
- c->phys_proc_id = 0;
- c->cpu_core_id = 0;
+ c[cpu].phys_proc_id = 0;
+ c[cpu].cpu_core_id = 0;
cpu_clear(cpu, cpu_sibling_setup_map);
}
diff --git a/trunk/arch/x86/kernel/smpboot_64.c b/trunk/arch/x86/kernel/smpboot_64.c
index fd1fff6a35a2..e351ac4ab5b1 100644
--- a/trunk/arch/x86/kernel/smpboot_64.c
+++ b/trunk/arch/x86/kernel/smpboot_64.c
@@ -65,7 +65,7 @@ int smp_num_siblings = 1;
EXPORT_SYMBOL(smp_num_siblings);
/* Last level cache ID of each logical CPU */
-DEFINE_PER_CPU(u8, cpu_llc_id) = BAD_APICID;
+u8 cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
/* Bitmask of currently online CPUs */
cpumask_t cpu_online_map __read_mostly;
@@ -84,8 +84,8 @@ cpumask_t cpu_possible_map;
EXPORT_SYMBOL(cpu_possible_map);
/* Per CPU bogomips and other parameters */
-DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
-EXPORT_PER_CPU_SYMBOL(cpu_info);
+struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
+EXPORT_SYMBOL(cpu_data);
/* Set when the idlers are all forked */
int smp_threads_ready;
@@ -138,10 +138,9 @@ static unsigned long __cpuinit setup_trampoline(void)
static void __cpuinit smp_store_cpu_info(int id)
{
- struct cpuinfo_x86 *c = &cpu_data(id);
+ struct cpuinfo_x86 *c = cpu_data + id;
*c = boot_cpu_data;
- c->cpu_index = id;
identify_cpu(c);
print_cpu_info(c);
}
@@ -238,7 +237,7 @@ void __cpuinit smp_callin(void)
/* maps the cpu to the sched domain representing multi-core */
cpumask_t cpu_coregroup_map(int cpu)
{
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = cpu_data + cpu;
/*
* For perf, we return last level cache shared map.
* And for power savings, we return cpu_core_map
@@ -255,41 +254,41 @@ static cpumask_t cpu_sibling_setup_map;
static inline void set_cpu_sibling_map(int cpu)
{
int i;
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = cpu_data;
cpu_set(cpu, cpu_sibling_setup_map);
if (smp_num_siblings > 1) {
for_each_cpu_mask(i, cpu_sibling_setup_map) {
- if (c->phys_proc_id == cpu_data(i).phys_proc_id &&
- c->cpu_core_id == cpu_data(i).cpu_core_id) {
+ if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
+ c[cpu].cpu_core_id == c[i].cpu_core_id) {
cpu_set(i, per_cpu(cpu_sibling_map, cpu));
cpu_set(cpu, per_cpu(cpu_sibling_map, i));
cpu_set(i, per_cpu(cpu_core_map, cpu));
cpu_set(cpu, per_cpu(cpu_core_map, i));
- cpu_set(i, c->llc_shared_map);
- cpu_set(cpu, cpu_data(i).llc_shared_map);
+ cpu_set(i, c[cpu].llc_shared_map);
+ cpu_set(cpu, c[i].llc_shared_map);
}
}
} else {
cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
}
- cpu_set(cpu, c->llc_shared_map);
+ cpu_set(cpu, c[cpu].llc_shared_map);
if (current_cpu_data.x86_max_cores == 1) {
per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
- c->booted_cores = 1;
+ c[cpu].booted_cores = 1;
return;
}
for_each_cpu_mask(i, cpu_sibling_setup_map) {
- if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
- per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
- cpu_set(i, c->llc_shared_map);
- cpu_set(cpu, cpu_data(i).llc_shared_map);
+ if (cpu_llc_id[cpu] != BAD_APICID &&
+ cpu_llc_id[cpu] == cpu_llc_id[i]) {
+ cpu_set(i, c[cpu].llc_shared_map);
+ cpu_set(cpu, c[i].llc_shared_map);
}
- if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
+ if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
cpu_set(i, per_cpu(cpu_core_map, cpu));
cpu_set(cpu, per_cpu(cpu_core_map, i));
/*
@@ -301,15 +300,15 @@ static inline void set_cpu_sibling_map(int cpu)
* the booted_cores for this new cpu
*/
if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
- c->booted_cores++;
+ c[cpu].booted_cores++;
/*
* increment the core count for all
* the other cpus in this package
*/
if (i != cpu)
- cpu_data(i).booted_cores++;
- } else if (i != cpu && !c->booted_cores)
- c->booted_cores = cpu_data(i).booted_cores;
+ c[i].booted_cores++;
+ } else if (i != cpu && !c[cpu].booted_cores)
+ c[cpu].booted_cores = c[i].booted_cores;
}
}
}
@@ -695,7 +694,7 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
clear_node_cpumask(cpu); /* was set by numa_add_cpu */
cpu_clear(cpu, cpu_present_map);
cpu_clear(cpu, cpu_possible_map);
- per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
+ x86_cpu_to_apicid[cpu] = BAD_APICID;
return -EIO;
}
@@ -841,26 +840,6 @@ static int __init smp_sanity_check(unsigned max_cpus)
return 0;
}
-/*
- * Copy apicid's found by MP_processor_info from initial array to the per cpu
- * data area. The x86_cpu_to_apicid_init array is then expendable and the
- * x86_cpu_to_apicid_ptr is zeroed indicating that the static array is no
- * longer available.
- */
-void __init smp_set_apicids(void)
-{
- int cpu;
-
- for_each_cpu_mask(cpu, cpu_possible_map) {
- if (per_cpu_offset(cpu))
- per_cpu(x86_cpu_to_apicid, cpu) =
- x86_cpu_to_apicid_init[cpu];
- }
-
- /* indicate the static array will be going away soon */
- x86_cpu_to_apicid_ptr = NULL;
-}
-
/*
* Prepare for SMP bootup. The MP table or ACPI has been read
* earlier. Just do some sanity checking here and enable APIC mode.
@@ -870,7 +849,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
nmi_watchdog_default();
current_cpu_data = boot_cpu_data;
current_thread_info()->cpu = 0; /* needed? */
- smp_set_apicids();
set_cpu_sibling_map(0);
if (smp_sanity_check(max_cpus) < 0) {
@@ -990,7 +968,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
static void remove_siblinginfo(int cpu)
{
int sibling;
- struct cpuinfo_x86 *c = &cpu_data(cpu);
+ struct cpuinfo_x86 *c = cpu_data;
for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
@@ -998,15 +976,15 @@ static void remove_siblinginfo(int cpu)
* last thread sibling in this cpu core going down
*/
if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
- cpu_data(sibling).booted_cores--;
+ c[sibling].booted_cores--;
}
for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
cpus_clear(per_cpu(cpu_sibling_map, cpu));
cpus_clear(per_cpu(cpu_core_map, cpu));
- c->phys_proc_id = 0;
- c->cpu_core_id = 0;
+ c[cpu].phys_proc_id = 0;
+ c[cpu].cpu_core_id = 0;
cpu_clear(cpu, cpu_sibling_setup_map);
}
diff --git a/trunk/arch/x86/kernel/suspend_64.c b/trunk/arch/x86/kernel/suspend_64.c
index 622bb0268284..f8fafe527ff1 100644
--- a/trunk/arch/x86/kernel/suspend_64.c
+++ b/trunk/arch/x86/kernel/suspend_64.c
@@ -32,9 +32,9 @@ void __save_processor_state(struct saved_context *ctxt)
/*
* descriptor tables
*/
- store_gdt((struct desc_ptr *)&ctxt->gdt_limit);
- store_idt((struct desc_ptr *)&ctxt->idt_limit);
- store_tr(ctxt->tr);
+ asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit));
+ asm volatile ("sidt %0" : "=m" (ctxt->idt_limit));
+ asm volatile ("str %0" : "=m" (ctxt->tr));
/* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
/*
@@ -91,9 +91,8 @@ void __restore_processor_state(struct saved_context *ctxt)
* now restore the descriptor tables to their proper values
* ltr is done i fix_processor_context().
*/
- load_gdt((const struct desc_ptr *)&ctxt->gdt_limit);
- load_idt((const struct desc_ptr *)&ctxt->idt_limit);
-
+ asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
+ asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
/*
* segment registers
diff --git a/trunk/arch/x86/kernel/traps_32.c b/trunk/arch/x86/kernel/traps_32.c
index cc9acace7e23..b132d3957dfc 100644
--- a/trunk/arch/x86/kernel/traps_32.c
+++ b/trunk/arch/x86/kernel/traps_32.c
@@ -63,9 +63,6 @@
int panic_on_unrecovered_nmi;
-DECLARE_BITMAP(used_vectors, NR_VECTORS);
-EXPORT_SYMBOL_GPL(used_vectors);
-
asmlinkage int system_call(void);
/* Do we ignore FPU interrupts ? */
@@ -291,24 +288,48 @@ EXPORT_SYMBOL(dump_stack);
void show_registers(struct pt_regs *regs)
{
int i;
-
+ int in_kernel = 1;
+ unsigned long esp;
+ unsigned short ss, gs;
+
+ esp = (unsigned long) (®s->esp);
+ savesegment(ss, ss);
+ savesegment(gs, gs);
+ if (user_mode_vm(regs)) {
+ in_kernel = 0;
+ esp = regs->esp;
+ ss = regs->xss & 0xffff;
+ }
print_modules();
- __show_registers(regs, 0);
+ printk(KERN_EMERG "CPU: %d\n"
+ KERN_EMERG "EIP: %04x:[<%08lx>] %s VLI\n"
+ KERN_EMERG "EFLAGS: %08lx (%s %.*s)\n",
+ smp_processor_id(), 0xffff & regs->xcs, regs->eip,
+ print_tainted(), regs->eflags, init_utsname()->release,
+ (int)strcspn(init_utsname()->version, " "),
+ init_utsname()->version);
+ print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip);
+ printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
+ regs->eax, regs->ebx, regs->ecx, regs->edx);
+ printk(KERN_EMERG "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
+ regs->esi, regs->edi, regs->ebp, esp);
+ printk(KERN_EMERG "ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n",
+ regs->xds & 0xffff, regs->xes & 0xffff, regs->xfs & 0xffff, gs, ss);
printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)",
- TASK_COMM_LEN, current->comm, task_pid_nr(current),
+ TASK_COMM_LEN, current->comm, current->pid,
current_thread_info(), current, task_thread_info(current));
/*
* When in-kernel, we also print out the stack and code at the
* time of the fault..
*/
- if (!user_mode_vm(regs)) {
+ if (in_kernel) {
u8 *eip;
unsigned int code_prologue = code_bytes * 43 / 64;
unsigned int code_len = code_bytes;
unsigned char c;
printk("\n" KERN_EMERG "Stack: ");
- show_stack_log_lvl(NULL, regs, ®s->esp, KERN_EMERG);
+ show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
printk(KERN_EMERG "Code: ");
@@ -353,11 +374,11 @@ int is_valid_bugaddr(unsigned long eip)
void die(const char * str, struct pt_regs * regs, long err)
{
static struct {
- raw_spinlock_t lock;
+ spinlock_t lock;
u32 lock_owner;
int lock_owner_depth;
} die = {
- .lock = __RAW_SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(die.lock),
.lock_owner = -1,
.lock_owner_depth = 0
};
@@ -368,14 +389,13 @@ void die(const char * str, struct pt_regs * regs, long err)
if (die.lock_owner != raw_smp_processor_id()) {
console_verbose();
- __raw_spin_lock(&die.lock);
- raw_local_save_flags(flags);
+ spin_lock_irqsave(&die.lock, flags);
die.lock_owner = smp_processor_id();
die.lock_owner_depth = 0;
bust_spinlocks(1);
}
else
- raw_local_save_flags(flags);
+ local_save_flags(flags);
if (++die.lock_owner_depth < 3) {
unsigned long esp;
@@ -419,8 +439,7 @@ void die(const char * str, struct pt_regs * regs, long err)
bust_spinlocks(0);
die.lock_owner = -1;
add_taint(TAINT_DIE);
- __raw_spin_unlock(&die.lock);
- raw_local_irq_restore(flags);
+ spin_unlock_irqrestore(&die.lock, flags);
if (!regs)
return;
@@ -603,7 +622,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
printk_ratelimit())
printk(KERN_INFO
"%s[%d] general protection eip:%lx esp:%lx error:%lx\n",
- current->comm, task_pid_nr(current),
+ current->comm, current->pid,
regs->eip, regs->esp, error_code);
force_sig(SIGSEGV, current);
@@ -1123,8 +1142,6 @@ static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
void __init trap_init(void)
{
- int i;
-
#ifdef CONFIG_EISA
void __iomem *p = ioremap(0x0FFFD9, 4);
if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) {
@@ -1184,11 +1201,6 @@ void __init trap_init(void)
set_system_gate(SYSCALL_VECTOR,&system_call);
- /* Reserve all the builtin and the syscall vector. */
- for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
- set_bit(i, used_vectors);
- set_bit(SYSCALL_VECTOR, used_vectors);
-
/*
* Should be a barrier for any external CPU state.
*/
diff --git a/trunk/arch/x86/kernel/traps_64.c b/trunk/arch/x86/kernel/traps_64.c
index df690c3fa458..b4a9b3db1994 100644
--- a/trunk/arch/x86/kernel/traps_64.c
+++ b/trunk/arch/x86/kernel/traps_64.c
@@ -462,7 +462,7 @@ void out_of_line_bug(void)
EXPORT_SYMBOL(out_of_line_bug);
#endif
-static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(die_lock);
static int die_owner = -1;
static unsigned int die_nest_count;
@@ -474,13 +474,13 @@ unsigned __kprobes long oops_begin(void)
oops_enter();
/* racy, but better than risking deadlock. */
- raw_local_irq_save(flags);
+ local_irq_save(flags);
cpu = smp_processor_id();
- if (!__raw_spin_trylock(&die_lock)) {
+ if (!spin_trylock(&die_lock)) {
if (cpu == die_owner)
/* nested oops. should stop eventually */;
else
- __raw_spin_lock(&die_lock);
+ spin_lock(&die_lock);
}
die_nest_count++;
die_owner = cpu;
@@ -494,10 +494,12 @@ void __kprobes oops_end(unsigned long flags)
die_owner = -1;
bust_spinlocks(0);
die_nest_count--;
- if (!die_nest_count)
+ if (die_nest_count)
+ /* We still own the lock */
+ local_irq_restore(flags);
+ else
/* Nest count reaches zero, release the lock. */
- __raw_spin_unlock(&die_lock);
- raw_local_irq_restore(flags);
+ spin_unlock_irqrestore(&die_lock, flags);
if (panic_on_oops)
panic("Fatal exception");
oops_exit();
diff --git a/trunk/arch/x86/kernel/tsc_32.c b/trunk/arch/x86/kernel/tsc_32.c
index b8a7cf671432..e87a3939ed40 100644
--- a/trunk/arch/x86/kernel/tsc_32.c
+++ b/trunk/arch/x86/kernel/tsc_32.c
@@ -181,8 +181,8 @@ int recalibrate_cpu_khz(void)
if (cpu_has_tsc) {
cpu_khz = calculate_cpu_khz();
tsc_khz = cpu_khz;
- cpu_data(0).loops_per_jiffy =
- cpufreq_scale(cpu_data(0).loops_per_jiffy,
+ cpu_data[0].loops_per_jiffy =
+ cpufreq_scale(cpu_data[0].loops_per_jiffy,
cpu_khz_old, cpu_khz);
return 0;
} else
@@ -215,7 +215,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
return 0;
}
ref_freq = freq->old;
- loops_per_jiffy_ref = cpu_data(freq->cpu).loops_per_jiffy;
+ loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy;
cpu_khz_ref = cpu_khz;
}
@@ -223,7 +223,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
(val == CPUFREQ_POSTCHANGE && freq->old > freq->new) ||
(val == CPUFREQ_RESUMECHANGE)) {
if (!(freq->flags & CPUFREQ_CONST_LOOPS))
- cpu_data(freq->cpu).loops_per_jiffy =
+ cpu_data[freq->cpu].loops_per_jiffy =
cpufreq_scale(loops_per_jiffy_ref,
ref_freq, freq->new);
diff --git a/trunk/arch/x86/kernel/tsc_64.c b/trunk/arch/x86/kernel/tsc_64.c
index 9c70af45b42b..9f22e542c374 100644
--- a/trunk/arch/x86/kernel/tsc_64.c
+++ b/trunk/arch/x86/kernel/tsc_64.c
@@ -73,13 +73,13 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
struct cpufreq_freqs *freq = data;
unsigned long *lpj, dummy;
- if (cpu_has(&cpu_data(freq->cpu), X86_FEATURE_CONSTANT_TSC))
+ if (cpu_has(&cpu_data[freq->cpu], X86_FEATURE_CONSTANT_TSC))
return 0;
lpj = &dummy;
if (!(freq->flags & CPUFREQ_CONST_LOOPS))
#ifdef CONFIG_SMP
- lpj = &cpu_data(freq->cpu).loops_per_jiffy;
+ lpj = &cpu_data[freq->cpu].loops_per_jiffy;
#else
lpj = &boot_cpu_data.loops_per_jiffy;
#endif
diff --git a/trunk/arch/x86/kernel/vsyscall_64.c b/trunk/arch/x86/kernel/vsyscall_64.c
index 78f2250963ae..585541ca1a7e 100644
--- a/trunk/arch/x86/kernel/vsyscall_64.c
+++ b/trunk/arch/x86/kernel/vsyscall_64.c
@@ -48,7 +48,7 @@
({unsigned long v; \
extern char __vsyscall_0; \
asm("" : "=r" (v) : "0" (x)); \
- ((v - VSYSCALL_START) + __pa_symbol(&__vsyscall_0)); })
+ ((v - VSYSCALL_FIRST_PAGE) + __pa_symbol(&__vsyscall_0)); })
/*
* vsyscall_gtod_data contains data that is :
@@ -291,7 +291,7 @@ static void __cpuinit vsyscall_set_cpu(int cpu)
#ifdef CONFIG_NUMA
node = cpu_to_node(cpu);
#endif
- if (cpu_has(&cpu_data(cpu), X86_FEATURE_RDTSCP))
+ if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP))
write_rdtscp_aux((node << 12) | cpu);
/* Store cpu number in limit so that it can be loaded quickly
diff --git a/trunk/arch/x86/lib/delay_32.c b/trunk/arch/x86/lib/delay_32.c
index 952e7a89c2ac..f6edb11364df 100644
--- a/trunk/arch/x86/lib/delay_32.c
+++ b/trunk/arch/x86/lib/delay_32.c
@@ -82,7 +82,7 @@ inline void __const_udelay(unsigned long xloops)
__asm__("mull %0"
:"=d" (xloops), "=&a" (d0)
:"1" (xloops), "0"
- (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4)));
+ (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4)));
__delay(++xloops);
}
diff --git a/trunk/arch/x86/lib/delay_64.c b/trunk/arch/x86/lib/delay_64.c
index 0ebbfb9e7c7f..2dbebd308347 100644
--- a/trunk/arch/x86/lib/delay_64.c
+++ b/trunk/arch/x86/lib/delay_64.c
@@ -40,8 +40,7 @@ EXPORT_SYMBOL(__delay);
inline void __const_udelay(unsigned long xloops)
{
- __delay(((xloops * HZ *
- cpu_data(raw_smp_processor_id()).loops_per_jiffy) >> 32) + 1);
+ __delay(((xloops * HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32) + 1);
}
EXPORT_SYMBOL(__const_udelay);
diff --git a/trunk/arch/x86/lib/usercopy_32.c b/trunk/arch/x86/lib/usercopy_32.c
index 8bab2b2efaff..9f38b12b4af1 100644
--- a/trunk/arch/x86/lib/usercopy_32.c
+++ b/trunk/arch/x86/lib/usercopy_32.c
@@ -748,7 +748,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from,
retval = get_user_pages(current, current->mm,
(unsigned long )to, 1, 1, 0, &pg, NULL);
- if (retval == -ENOMEM && is_global_init(current)) {
+ if (retval == -ENOMEM && is_init(current)) {
up_read(¤t->mm->mmap_sem);
congestion_wait(WRITE, HZ/50);
goto survive;
diff --git a/trunk/arch/x86/mach-voyager/voyager_smp.c b/trunk/arch/x86/mach-voyager/voyager_smp.c
index f93a730b44d0..e4928aa6bdfb 100644
--- a/trunk/arch/x86/mach-voyager/voyager_smp.c
+++ b/trunk/arch/x86/mach-voyager/voyager_smp.c
@@ -36,8 +36,8 @@ static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned = { [0 ... NR
/* per CPU data structure (for /proc/cpuinfo et al), visible externally
* indexed physically */
-DEFINE_PER_CPU(cpuinfo_x86, cpu_info) __cacheline_aligned;
-EXPORT_PER_CPU_SYMBOL(cpu_info);
+struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
+EXPORT_SYMBOL(cpu_data);
/* physical ID of the CPU used to boot the system */
unsigned char boot_cpu_id;
@@ -430,7 +430,7 @@ find_smp_config(void)
void __init
smp_store_cpu_info(int id)
{
- struct cpuinfo_x86 *c = &cpu_data(id);
+ struct cpuinfo_x86 *c=&cpu_data[id];
*c = boot_cpu_data;
@@ -634,7 +634,7 @@ do_boot_cpu(__u8 cpu)
cpu, smp_processor_id()));
printk("CPU%d: ", cpu);
- print_cpu_info(&cpu_data(cpu));
+ print_cpu_info(&cpu_data[cpu]);
wmb();
cpu_set(cpu, cpu_callout_map);
cpu_set(cpu, cpu_present_map);
@@ -683,7 +683,7 @@ smp_boot_cpus(void)
*/
smp_store_cpu_info(boot_cpu_id);
printk("CPU%d: ", boot_cpu_id);
- print_cpu_info(&cpu_data(boot_cpu_id));
+ print_cpu_info(&cpu_data[boot_cpu_id]);
if(is_cpu_quad()) {
/* booting on a Quad CPU */
@@ -714,7 +714,7 @@ smp_boot_cpus(void)
unsigned long bogosum = 0;
for (i = 0; i < NR_CPUS; i++)
if (cpu_isset(i, cpu_online_map))
- bogosum += cpu_data(i).loops_per_jiffy;
+ bogosum += cpu_data[i].loops_per_jiffy;
printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
cpucount+1,
bogosum/(500000/HZ),
diff --git a/trunk/arch/x86/mm/fault_32.c b/trunk/arch/x86/mm/fault_32.c
index b695d70e998c..6555c3d14371 100644
--- a/trunk/arch/x86/mm/fault_32.c
+++ b/trunk/arch/x86/mm/fault_32.c
@@ -471,8 +471,8 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
printk_ratelimit()) {
printk("%s%s[%d]: segfault at %08lx eip %08lx "
"esp %08lx error %lx\n",
- task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
- tsk->comm, task_pid_nr(tsk), address, regs->eip,
+ tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
+ tsk->comm, tsk->pid, address, regs->eip,
regs->esp, error_code);
}
tsk->thread.cr2 = address;
@@ -564,8 +564,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
* it's allocated already.
*/
if ((page >> PAGE_SHIFT) < max_low_pfn
- && (page & _PAGE_PRESENT)
- && !(page & _PAGE_PSE)) {
+ && (page & _PAGE_PRESENT)) {
page &= PAGE_MASK;
page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
& (PTRS_PER_PTE - 1)];
@@ -588,7 +587,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_global_init(tsk)) {
+ if (is_init(tsk)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/trunk/arch/x86/mm/fault_64.c b/trunk/arch/x86/mm/fault_64.c
index 00be7f0a71b2..5e0e54906c48 100644
--- a/trunk/arch/x86/mm/fault_64.c
+++ b/trunk/arch/x86/mm/fault_64.c
@@ -169,7 +169,7 @@ void dump_pagetable(unsigned long address)
pmd = pmd_offset(pud, address);
if (bad_address(pmd)) goto bad;
printk("PMD %lx ", pmd_val(*pmd));
- if (!pmd_present(*pmd) || pmd_large(*pmd)) goto ret;
+ if (!pmd_present(*pmd)) goto ret;
pte = pte_offset_kernel(pmd, address);
if (bad_address(pte)) goto bad;
@@ -285,6 +285,7 @@ static int vmalloc_fault(unsigned long address)
return 0;
}
+static int page_fault_trace;
int show_unhandled_signals = 1;
/*
@@ -353,6 +354,10 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
if (likely(regs->eflags & X86_EFLAGS_IF))
local_irq_enable();
+ if (unlikely(page_fault_trace))
+ printk("pagefault rip:%lx rsp:%lx cs:%lu ss:%lu address %lx error %lx\n",
+ regs->rip,regs->rsp,regs->cs,regs->ss,address,error_code);
+
if (unlikely(error_code & PF_RSVD))
pgtable_bad(address, regs, error_code);
@@ -483,7 +488,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
printk_ratelimit()) {
printk(
- "%s%s[%d]: segfault at %lx rip %lx rsp %lx error %lx\n",
+ "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
tsk->comm, tsk->pid, address, regs->rip,
regs->rsp, error_code);
@@ -549,7 +554,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_global_init(current)) {
+ if (is_init(current)) {
yield();
goto again;
}
@@ -616,3 +621,10 @@ void vmalloc_sync_all(void)
BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) ==
(__START_KERNEL & PGDIR_MASK)));
}
+
+static int __init enable_pagefaulttrace(char *str)
+{
+ page_fault_trace = 1;
+ return 1;
+}
+__setup("pagefaulttrace", enable_pagefaulttrace);
diff --git a/trunk/arch/x86/mm/numa_64.c b/trunk/arch/x86/mm/numa_64.c
index 3d6926ba8995..5eec5e56d07f 100644
--- a/trunk/arch/x86/mm/numa_64.c
+++ b/trunk/arch/x86/mm/numa_64.c
@@ -612,7 +612,7 @@ void __init init_cpu_to_node(void)
{
int i;
for (i = 0; i < NR_CPUS; i++) {
- u8 apicid = x86_cpu_to_apicid_init[i];
+ u8 apicid = x86_cpu_to_apicid[i];
if (apicid == BAD_APICID)
continue;
if (apicid_to_node[apicid] == NUMA_NO_NODE)
diff --git a/trunk/arch/x86/mm/pageattr_64.c b/trunk/arch/x86/mm/pageattr_64.c
index c7b7dfe1d405..8a4f65bf956e 100644
--- a/trunk/arch/x86/mm/pageattr_64.c
+++ b/trunk/arch/x86/mm/pageattr_64.c
@@ -230,14 +230,9 @@ void global_flush_tlb(void)
struct page *pg, *next;
struct list_head l;
- /*
- * Write-protect the semaphore, to exclude two contexts
- * doing a list_replace_init() call in parallel and to
- * exclude new additions to the deferred_pages list:
- */
- down_write(&init_mm.mmap_sem);
+ down_read(&init_mm.mmap_sem);
list_replace_init(&deferred_pages, &l);
- up_write(&init_mm.mmap_sem);
+ up_read(&init_mm.mmap_sem);
flush_map(&l);
diff --git a/trunk/arch/x86/oprofile/backtrace.c b/trunk/arch/x86/oprofile/backtrace.c
index 0ed046a187f7..c049ce414f01 100644
--- a/trunk/arch/x86/oprofile/backtrace.c
+++ b/trunk/arch/x86/oprofile/backtrace.c
@@ -13,45 +13,25 @@
#include
#include
#include
-#include
-static void backtrace_warning_symbol(void *data, char *msg,
- unsigned long symbol)
-{
- /* Ignore warnings */
-}
-
-static void backtrace_warning(void *data, char *msg)
-{
- /* Ignore warnings */
-}
+struct frame_head {
+ struct frame_head * ebp;
+ unsigned long ret;
+} __attribute__((packed));
-static int backtrace_stack(void *data, char *name)
+static struct frame_head *
+dump_kernel_backtrace(struct frame_head * head)
{
- /* Yes, we want all stacks */
- return 0;
-}
+ oprofile_add_trace(head->ret);
-static void backtrace_address(void *data, unsigned long addr)
-{
- unsigned int *depth = data;
+ /* frame pointers should strictly progress back up the stack
+ * (towards higher addresses) */
+ if (head >= head->ebp)
+ return NULL;
- if ((*depth)--)
- oprofile_add_trace(addr);
+ return head->ebp;
}
-static struct stacktrace_ops backtrace_ops = {
- .warning = backtrace_warning,
- .warning_symbol = backtrace_warning_symbol,
- .stack = backtrace_stack,
- .address = backtrace_address,
-};
-
-struct frame_head {
- struct frame_head *ebp;
- unsigned long ret;
-} __attribute__((packed));
-
static struct frame_head *
dump_user_backtrace(struct frame_head * head)
{
@@ -73,16 +53,72 @@ dump_user_backtrace(struct frame_head * head)
return bufhead[0].ebp;
}
+/*
+ * | | /\ Higher addresses
+ * | |
+ * --------------- stack base (address of current_thread_info)
+ * | thread info |
+ * . .
+ * | stack |
+ * --------------- saved regs->ebp value if valid (frame_head address)
+ * . .
+ * --------------- saved regs->rsp value if x86_64
+ * | |
+ * --------------- struct pt_regs * stored on stack if 32-bit
+ * | |
+ * . .
+ * | |
+ * --------------- %esp
+ * | |
+ * | | \/ Lower addresses
+ *
+ * Thus, regs (or regs->rsp for x86_64) <-> stack base restricts the
+ * valid(ish) ebp values. Note: (1) for x86_64, NMI and several other
+ * exceptions use special stacks, maintained by the interrupt stack table
+ * (IST). These stacks are set up in trap_init() in
+ * arch/x86_64/kernel/traps.c. Thus, for x86_64, regs now does not point
+ * to the kernel stack; instead, it points to some location on the NMI
+ * stack. On the other hand, regs->rsp is the stack pointer saved when the
+ * NMI occurred. (2) For 32-bit, regs->esp is not valid because the
+ * processor does not save %esp on the kernel stack when interrupts occur
+ * in the kernel mode.
+ */
+#ifdef CONFIG_FRAME_POINTER
+static int valid_kernel_stack(struct frame_head * head, struct pt_regs * regs)
+{
+ unsigned long headaddr = (unsigned long)head;
+#ifdef CONFIG_X86_64
+ unsigned long stack = (unsigned long)regs->rsp;
+#else
+ unsigned long stack = (unsigned long)regs;
+#endif
+ unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
+
+ return headaddr > stack && headaddr < stack_base;
+}
+#else
+/* without fp, it's just junk */
+static int valid_kernel_stack(struct frame_head * head, struct pt_regs * regs)
+{
+ return 0;
+}
+#endif
+
+
void
x86_backtrace(struct pt_regs * const regs, unsigned int depth)
{
- struct frame_head *head = (struct frame_head *)frame_pointer(regs);
- unsigned long stack = stack_pointer(regs);
+ struct frame_head *head;
+
+#ifdef CONFIG_X86_64
+ head = (struct frame_head *)regs->rbp;
+#else
+ head = (struct frame_head *)regs->ebp;
+#endif
if (!user_mode_vm(regs)) {
- if (depth)
- dump_trace(NULL, regs, (unsigned long *)stack,
- &backtrace_ops, &depth);
+ while (depth-- && valid_kernel_stack(head, regs))
+ head = dump_kernel_backtrace(head);
return;
}
diff --git a/trunk/arch/x86_64/.gitignore b/trunk/arch/x86_64/.gitignore
deleted file mode 100644
index 36ef4c374d25..000000000000
--- a/trunk/arch/x86_64/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-boot
diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig
index aab25f3ba3ce..78cb68f2ebbd 100644
--- a/trunk/arch/x86_64/Kconfig
+++ b/trunk/arch/x86_64/Kconfig
@@ -723,9 +723,7 @@ config ARCH_HIBERNATION_HEADER
source "drivers/acpi/Kconfig"
-source "arch/x86/kernel/cpu/cpufreq/Kconfig_64"
-
-source "drivers/cpuidle/Kconfig"
+source "arch/x86/kernel/cpufreq/Kconfig"
endmenu
@@ -768,9 +766,9 @@ source "fs/Kconfig.binfmt"
config IA32_EMULATION
bool "IA32 Emulation"
help
- Include code to run 32-bit programs under a 64-bit kernel. You should
- likely turn this on, unless you're 100% sure that you don't have any
- 32-bit programs left.
+ Include code to run 32-bit programs under a 64-bit kernel. You should likely
+ turn this on, unless you're 100% sure that you don't have any 32-bit programs
+ left.
config IA32_AOUT
tristate "IA32 a.out support"
@@ -801,6 +799,21 @@ source "drivers/firmware/Kconfig"
source fs/Kconfig
+menu "Instrumentation Support"
+
+source "arch/x86/oprofile/Kconfig"
+
+config KPROBES
+ bool "Kprobes"
+ depends on KALLSYMS && MODULES
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+endmenu
+
source "arch/x86_64/Kconfig.debug"
source "security/Kconfig"
diff --git a/trunk/arch/x86_64/Makefile b/trunk/arch/x86_64/Makefile
index 6d89ab762ffc..03e1ede27b85 100644
--- a/trunk/arch/x86_64/Makefile
+++ b/trunk/arch/x86_64/Makefile
@@ -74,7 +74,7 @@ KBUILD_CFLAGS += $(cflags-y)
CFLAGS_KERNEL += $(cflags-kernel-y)
KBUILD_AFLAGS += -m64
-head-y := arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/init_task.o
+head-y := arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/init_task_64.o
libs-y += arch/x86/lib/
core-y += arch/x86/kernel/ \
@@ -97,9 +97,9 @@ BOOTIMAGE := arch/x86/boot/bzImage
KBUILD_IMAGE := $(BOOTIMAGE)
bzImage: vmlinux
- $(Q)$(MAKE) $(build)=$(boot) $(BOOTIMAGE)
$(Q)mkdir -p $(objtree)/arch/x86_64/boot
- $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/x86_64/boot/bzImage
+ $(Q)ln -fsn $(objtree)/arch/x86/boot/bzImage $(objtree)/arch/x86_64/boot/bzImage
+ $(Q)$(MAKE) $(build)=$(boot) $(BOOTIMAGE)
bzlilo: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zlilo
diff --git a/trunk/arch/xtensa/Kconfig b/trunk/arch/xtensa/Kconfig
index 85ffbb491490..7fbb44bea37f 100644
--- a/trunk/arch/xtensa/Kconfig
+++ b/trunk/arch/xtensa/Kconfig
@@ -251,8 +251,6 @@ config EMBEDDED_RAMDISK_IMAGE
provide one yourself.
endmenu
-source "kernel/Kconfig.instrumentation"
-
source "arch/xtensa/Kconfig.debug"
source "security/Kconfig"
diff --git a/trunk/arch/xtensa/kernel/traps.c b/trunk/arch/xtensa/kernel/traps.c
index 397bcd6ad08d..8be99c777d9d 100644
--- a/trunk/arch/xtensa/kernel/traps.c
+++ b/trunk/arch/xtensa/kernel/traps.c
@@ -176,7 +176,7 @@ void do_unhandled(struct pt_regs *regs, unsigned long exccause)
printk("Caught unhandled exception in '%s' "
"(pid = %d, pc = %#010lx) - should not happen\n"
"\tEXCCAUSE is %ld\n",
- current->comm, task_pid_nr(current), regs->pc, exccause);
+ current->comm, current->pid, regs->pc, exccause);
force_sig(SIGILL, current);
}
@@ -228,7 +228,7 @@ do_illegal_instruction(struct pt_regs *regs)
/* If in user mode, send SIGILL signal to current process. */
printk("Illegal Instruction in '%s' (pid = %d, pc = %#010lx)\n",
- current->comm, task_pid_nr(current), regs->pc);
+ current->comm, current->pid, regs->pc);
force_sig(SIGILL, current);
}
@@ -254,7 +254,7 @@ do_unaligned_user (struct pt_regs *regs)
current->thread.error_code = -3;
printk("Unaligned memory access to %08lx in '%s' "
"(pid = %d, pc = %#010lx)\n",
- regs->excvaddr, current->comm, task_pid_nr(current), regs->pc);
+ regs->excvaddr, current->comm, current->pid, regs->pc);
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRALN;
diff --git a/trunk/arch/xtensa/mm/fault.c b/trunk/arch/xtensa/mm/fault.c
index 33f366be323f..2f842859948f 100644
--- a/trunk/arch/xtensa/mm/fault.c
+++ b/trunk/arch/xtensa/mm/fault.c
@@ -145,7 +145,7 @@ void do_page_fault(struct pt_regs *regs)
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_global_init(current)) {
+ if (is_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c
index 8025d646ab30..3935469e3662 100644
--- a/trunk/block/ll_rw_blk.c
+++ b/trunk/block/ll_rw_blk.c
@@ -3367,7 +3367,7 @@ void submit_bio(int rw, struct bio *bio)
if (unlikely(block_dump)) {
char b[BDEVNAME_SIZE];
printk(KERN_DEBUG "%s(%d): %s block %Lu on %s\n",
- current->comm, task_pid_nr(current),
+ current->comm, current->pid,
(rw & WRITE) ? "WRITE" : "READ",
(unsigned long long)bio->bi_sector,
bdevname(bio->bi_bdev,b));
@@ -3739,7 +3739,7 @@ EXPORT_SYMBOL(end_dequeued_request);
/**
* end_request - end I/O on the current segment of the request
- * @req: the request being processed
+ * @rq: the request being processed
* @uptodate: error value or 0/1 uptodate flag
*
* Description:
diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile
index cfe38ffff28a..d2dc01cc73e7 100644
--- a/trunk/drivers/Makefile
+++ b/trunk/drivers/Makefile
@@ -76,7 +76,6 @@ obj-$(CONFIG_MCA) += mca/
obj-$(CONFIG_EISA) += eisa/
obj-$(CONFIG_LGUEST_GUEST) += lguest/
obj-$(CONFIG_CPU_FREQ) += cpufreq/
-obj-$(CONFIG_CPU_IDLE) += cpuidle/
obj-$(CONFIG_MMC) += mmc/
obj-$(CONFIG_NEW_LEDS) += leds/
obj-$(CONFIG_INFINIBAND) += infiniband/
diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig
index b83389145f28..4875f0149eb4 100644
--- a/trunk/drivers/acpi/Kconfig
+++ b/trunk/drivers/acpi/Kconfig
@@ -88,7 +88,7 @@ config ACPI_PROC_EVENT
config ACPI_AC
tristate "AC Adapter"
- depends on X86 && POWER_SUPPLY
+ depends on X86
default y
help
This driver adds support for the AC Adapter object, which indicates
@@ -97,7 +97,7 @@ config ACPI_AC
config ACPI_BATTERY
tristate "Battery"
- depends on X86 && POWER_SUPPLY
+ depends on X86
default y
help
This driver adds support for battery information through
@@ -117,7 +117,6 @@ config ACPI_BUTTON
config ACPI_VIDEO
tristate "Video"
depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL
- depends on INPUT
help
This driver implement the ACPI Extensions For Display Adapters
for integrated graphics devices on motherboard, as specified in
@@ -350,11 +349,12 @@ config ACPI_HOTPLUG_MEMORY
$>modprobe acpi_memhotplug
config ACPI_SBS
- tristate "Smart Battery System"
+ tristate "Smart Battery System (EXPERIMENTAL)"
depends on X86
- depends on POWER_SUPPLY
+ depends on EXPERIMENTAL
help
- This driver adds support for the Smart Battery System, another
- type of access to battery information, found on some laptops.
+ This driver adds support for the Smart Battery System.
+ A "Smart Battery" is quite old and quite rare compared
+ to today's ACPI "Control Method" battery.
endif # ACPI
diff --git a/trunk/drivers/acpi/Makefile b/trunk/drivers/acpi/Makefile
index 54e3ab0e5fc0..d4336f1730e9 100644
--- a/trunk/drivers/acpi/Makefile
+++ b/trunk/drivers/acpi/Makefile
@@ -60,4 +60,3 @@ obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
obj-y += cm_sbs.o
obj-$(CONFIG_ACPI_SBS) += sbs.o
-obj-$(CONFIG_ACPI_SBS) += sbshc.o
diff --git a/trunk/drivers/acpi/ac.c b/trunk/drivers/acpi/ac.c
index e03de37a750d..26d70702b313 100644
--- a/trunk/drivers/acpi/ac.c
+++ b/trunk/drivers/acpi/ac.c
@@ -29,7 +29,6 @@
#include
#include
#include
-#include
#include
#include
@@ -73,37 +72,16 @@ static struct acpi_driver acpi_ac_driver = {
};
struct acpi_ac {
- struct power_supply charger;
struct acpi_device * device;
unsigned long state;
};
-#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger);
-
static const struct file_operations acpi_ac_fops = {
.open = acpi_ac_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static int get_ac_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct acpi_ac *ac = to_acpi_ac(psy);
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = ac->state;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static enum power_supply_property ac_props[] = {
- POWER_SUPPLY_PROP_ONLINE,
-};
/* --------------------------------------------------------------------------
AC Adapter Management
@@ -230,7 +208,6 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
acpi_bus_generate_netlink_event(device->pnp.device_class,
device->dev.bus_id, event,
(u32) ac->state);
- kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -267,12 +244,7 @@ static int acpi_ac_add(struct acpi_device *device)
result = acpi_ac_add_fs(device);
if (result)
goto end;
- ac->charger.name = acpi_device_bid(device);
- ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
- ac->charger.properties = ac_props;
- ac->charger.num_properties = ARRAY_SIZE(ac_props);
- ac->charger.get_property = get_ac_property;
- power_supply_register(&ac->device->dev, &ac->charger);
+
status = acpi_install_notify_handler(device->handle,
ACPI_ALL_NOTIFY, acpi_ac_notify,
ac);
@@ -307,8 +279,7 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
status = acpi_remove_notify_handler(device->handle,
ACPI_ALL_NOTIFY, acpi_ac_notify);
- if (ac->charger.dev)
- power_supply_unregister(&ac->charger);
+
acpi_ac_remove_fs(device);
kfree(ac);
diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c
index 681e26b56b11..9b2c0f74f869 100644
--- a/trunk/drivers/acpi/battery.c
+++ b/trunk/drivers/acpi/battery.c
@@ -1,8 +1,6 @@
/*
- * battery.c - ACPI Battery Driver (Revision: 2.0)
+ * acpi_battery.c - ACPI Battery Driver ($Revision: 37 $)
*
- * Copyright (C) 2007 Alexey Starikovskiy
- * Copyright (C) 2004-2007 Vladimir Lebedev
* Copyright (C) 2001, 2002 Andy Grover
* Copyright (C) 2001, 2002 Paul Diefenbaugh
*
@@ -29,288 +27,244 @@
#include
#include
#include
-#include
-
-#ifdef CONFIG_ACPI_PROCFS
#include
#include
#include
-#endif
#include
#include
-#include
-
#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
+#define ACPI_BATTERY_FORMAT_BIF "NNNNNNNNNSSSS"
+#define ACPI_BATTERY_FORMAT_BST "NNNN"
+
#define ACPI_BATTERY_COMPONENT 0x00040000
#define ACPI_BATTERY_CLASS "battery"
#define ACPI_BATTERY_DEVICE_NAME "Battery"
#define ACPI_BATTERY_NOTIFY_STATUS 0x80
#define ACPI_BATTERY_NOTIFY_INFO 0x81
+#define ACPI_BATTERY_UNITS_WATTS "mW"
+#define ACPI_BATTERY_UNITS_AMPS "mA"
#define _COMPONENT ACPI_BATTERY_COMPONENT
+#define ACPI_BATTERY_UPDATE_TIME 0
+
+#define ACPI_BATTERY_NONE_UPDATE 0
+#define ACPI_BATTERY_EASY_UPDATE 1
+#define ACPI_BATTERY_INIT_UPDATE 2
+
ACPI_MODULE_NAME("battery");
MODULE_AUTHOR("Paul Diefenbaugh");
-MODULE_AUTHOR("Alexey Starikovskiy ");
MODULE_DESCRIPTION("ACPI Battery Driver");
MODULE_LICENSE("GPL");
-static unsigned int cache_time = 1000;
-module_param(cache_time, uint, 0644);
-MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
+static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME;
+
+/* 0 - every time, > 0 - by update_time */
+module_param(update_time, uint, 0644);
-#ifdef CONFIG_ACPI_PROCFS
extern struct proc_dir_entry *acpi_lock_battery_dir(void);
extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
-enum acpi_battery_files {
- info_tag = 0,
- state_tag,
- alarm_tag,
- ACPI_BATTERY_NUMFILES,
-};
-
-#endif
+static int acpi_battery_add(struct acpi_device *device);
+static int acpi_battery_remove(struct acpi_device *device, int type);
+static int acpi_battery_resume(struct acpi_device *device);
static const struct acpi_device_id battery_device_ids[] = {
{"PNP0C0A", 0},
{"", 0},
};
-
MODULE_DEVICE_TABLE(acpi, battery_device_ids);
+static struct acpi_driver acpi_battery_driver = {
+ .name = "battery",
+ .class = ACPI_BATTERY_CLASS,
+ .ids = battery_device_ids,
+ .ops = {
+ .add = acpi_battery_add,
+ .resume = acpi_battery_resume,
+ .remove = acpi_battery_remove,
+ },
+};
-struct acpi_battery {
- struct mutex lock;
- struct power_supply bat;
- struct acpi_device *device;
- unsigned long update_time;
- int current_now;
- int capacity_now;
- int voltage_now;
- int design_capacity;
- int full_charge_capacity;
- int technology;
- int design_voltage;
- int design_capacity_warning;
- int design_capacity_low;
- int capacity_granularity_1;
- int capacity_granularity_2;
- int alarm;
- char model_number[32];
- char serial_number[32];
- char type[32];
- char oem_info[32];
- int state;
- int power_unit;
+struct acpi_battery_state {
+ acpi_integer state;
+ acpi_integer present_rate;
+ acpi_integer remaining_capacity;
+ acpi_integer present_voltage;
+};
+
+struct acpi_battery_info {
+ acpi_integer power_unit;
+ acpi_integer design_capacity;
+ acpi_integer last_full_capacity;
+ acpi_integer battery_technology;
+ acpi_integer design_voltage;
+ acpi_integer design_capacity_warning;
+ acpi_integer design_capacity_low;
+ acpi_integer battery_capacity_granularity_1;
+ acpi_integer battery_capacity_granularity_2;
+ acpi_string model_number;
+ acpi_string serial_number;
+ acpi_string battery_type;
+ acpi_string oem_info;
+};
+
+enum acpi_battery_files{
+ ACPI_BATTERY_INFO = 0,
+ ACPI_BATTERY_STATE,
+ ACPI_BATTERY_ALARM,
+ ACPI_BATTERY_NUMFILES,
+};
+
+struct acpi_battery_flags {
+ u8 battery_present_prev;
u8 alarm_present;
+ u8 init_update;
+ u8 update[ACPI_BATTERY_NUMFILES];
+ u8 power_unit;
};
-#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
+struct acpi_battery {
+ struct mutex mutex;
+ struct acpi_device *device;
+ struct acpi_battery_flags flags;
+ struct acpi_buffer bif_data;
+ struct acpi_buffer bst_data;
+ unsigned long alarm;
+ unsigned long update_time[ACPI_BATTERY_NUMFILES];
+};
inline int acpi_battery_present(struct acpi_battery *battery)
{
return battery->device->status.battery_present;
}
-
-static int acpi_battery_technology(struct acpi_battery *battery)
+inline char *acpi_battery_power_units(struct acpi_battery *battery)
{
- if (!strcasecmp("NiCd", battery->type))
- return POWER_SUPPLY_TECHNOLOGY_NiCd;
- if (!strcasecmp("NiMH", battery->type))
- return POWER_SUPPLY_TECHNOLOGY_NiMH;
- if (!strcasecmp("LION", battery->type))
- return POWER_SUPPLY_TECHNOLOGY_LION;
- if (!strcasecmp("LiP", battery->type))
- return POWER_SUPPLY_TECHNOLOGY_LIPO;
- return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
-}
-
-static int acpi_battery_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct acpi_battery *battery = to_acpi_battery(psy);
-
- if ((!acpi_battery_present(battery)) &&
- psp != POWER_SUPPLY_PROP_PRESENT)
- return -ENODEV;
- switch (psp) {
- case POWER_SUPPLY_PROP_STATUS:
- if (battery->state & 0x01)
- val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
- else if (battery->state & 0x02)
- val->intval = POWER_SUPPLY_STATUS_CHARGING;
- else if (battery->state == 0)
- val->intval = POWER_SUPPLY_STATUS_FULL;
- break;
- case POWER_SUPPLY_PROP_PRESENT:
- val->intval = acpi_battery_present(battery);
- break;
- case POWER_SUPPLY_PROP_TECHNOLOGY:
- val->intval = acpi_battery_technology(battery);
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
- val->intval = battery->design_voltage * 1000;
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = battery->voltage_now * 1000;
- break;
- case POWER_SUPPLY_PROP_CURRENT_NOW:
- val->intval = battery->current_now * 1000;
- break;
- case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
- case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
- val->intval = battery->design_capacity * 1000;
- break;
- case POWER_SUPPLY_PROP_CHARGE_FULL:
- case POWER_SUPPLY_PROP_ENERGY_FULL:
- val->intval = battery->full_charge_capacity * 1000;
- break;
- case POWER_SUPPLY_PROP_CHARGE_NOW:
- case POWER_SUPPLY_PROP_ENERGY_NOW:
- val->intval = battery->capacity_now * 1000;
- break;
- case POWER_SUPPLY_PROP_MODEL_NAME:
- val->strval = battery->model_number;
- break;
- case POWER_SUPPLY_PROP_MANUFACTURER:
- val->strval = battery->oem_info;
- break;
- default:
- return -EINVAL;
- }
- return 0;
+ if (battery->flags.power_unit)
+ return ACPI_BATTERY_UNITS_AMPS;
+ else
+ return ACPI_BATTERY_UNITS_WATTS;
}
-static enum power_supply_property charge_battery_props[] = {
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_TECHNOLOGY,
- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_CURRENT_NOW,
- POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
- POWER_SUPPLY_PROP_CHARGE_FULL,
- POWER_SUPPLY_PROP_CHARGE_NOW,
- POWER_SUPPLY_PROP_MODEL_NAME,
- POWER_SUPPLY_PROP_MANUFACTURER,
-};
-
-static enum power_supply_property energy_battery_props[] = {
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_TECHNOLOGY,
- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_CURRENT_NOW,
- POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
- POWER_SUPPLY_PROP_ENERGY_FULL,
- POWER_SUPPLY_PROP_ENERGY_NOW,
- POWER_SUPPLY_PROP_MODEL_NAME,
- POWER_SUPPLY_PROP_MANUFACTURER,
-};
-
-#ifdef CONFIG_ACPI_PROCFS
-inline char *acpi_battery_units(struct acpi_battery *battery)
+inline acpi_handle acpi_battery_handle(struct acpi_battery *battery)
{
- return (battery->power_unit)?"mA":"mW";
+ return battery->device->handle;
}
-#endif
/* --------------------------------------------------------------------------
Battery Management
-------------------------------------------------------------------------- */
-struct acpi_offsets {
- size_t offset; /* offset inside struct acpi_sbs_battery */
- u8 mode; /* int or string? */
-};
-static struct acpi_offsets state_offsets[] = {
- {offsetof(struct acpi_battery, state), 0},
- {offsetof(struct acpi_battery, current_now), 0},
- {offsetof(struct acpi_battery, capacity_now), 0},
- {offsetof(struct acpi_battery, voltage_now), 0},
-};
+static void acpi_battery_check_result(struct acpi_battery *battery, int result)
+{
+ if (!battery)
+ return;
-static struct acpi_offsets info_offsets[] = {
- {offsetof(struct acpi_battery, power_unit), 0},
- {offsetof(struct acpi_battery, design_capacity), 0},
- {offsetof(struct acpi_battery, full_charge_capacity), 0},
- {offsetof(struct acpi_battery, technology), 0},
- {offsetof(struct acpi_battery, design_voltage), 0},
- {offsetof(struct acpi_battery, design_capacity_warning), 0},
- {offsetof(struct acpi_battery, design_capacity_low), 0},
- {offsetof(struct acpi_battery, capacity_granularity_1), 0},
- {offsetof(struct acpi_battery, capacity_granularity_2), 0},
- {offsetof(struct acpi_battery, model_number), 1},
- {offsetof(struct acpi_battery, serial_number), 1},
- {offsetof(struct acpi_battery, type), 1},
- {offsetof(struct acpi_battery, oem_info), 1},
-};
+ if (result) {
+ battery->flags.init_update = 1;
+ }
+}
-static int extract_package(struct acpi_battery *battery,
- union acpi_object *package,
- struct acpi_offsets *offsets, int num)
-{
- int i, *x;
- union acpi_object *element;
- if (package->type != ACPI_TYPE_PACKAGE)
- return -EFAULT;
- for (i = 0; i < num; ++i) {
- if (package->package.count <= i)
- return -EFAULT;
- element = &package->package.elements[i];
- if (offsets[i].mode) {
- if (element->type != ACPI_TYPE_STRING &&
- element->type != ACPI_TYPE_BUFFER)
- return -EFAULT;
- strncpy((u8 *)battery + offsets[i].offset,
- element->string.pointer, 32);
- } else {
- if (element->type != ACPI_TYPE_INTEGER)
- return -EFAULT;
- x = (int *)((u8 *)battery + offsets[i].offset);
- *x = element->integer.value;
+static int acpi_battery_extract_package(struct acpi_battery *battery,
+ union acpi_object *package,
+ struct acpi_buffer *format,
+ struct acpi_buffer *data,
+ char *package_name)
+{
+ acpi_status status = AE_OK;
+ struct acpi_buffer data_null = { 0, NULL };
+
+ status = acpi_extract_package(package, format, &data_null);
+ if (status != AE_BUFFER_OVERFLOW) {
+ ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s",
+ package_name));
+ return -ENODEV;
+ }
+
+ if (data_null.length != data->length) {
+ kfree(data->pointer);
+ data->pointer = kzalloc(data_null.length, GFP_KERNEL);
+ if (!data->pointer) {
+ ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()"));
+ return -ENOMEM;
}
+ data->length = data_null.length;
}
+
+ status = acpi_extract_package(package, format, data);
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status, "Extracting %s",
+ package_name));
+ return -ENODEV;
+ }
+
return 0;
}
static int acpi_battery_get_status(struct acpi_battery *battery)
{
- if (acpi_bus_get_status(battery->device)) {
+ int result = 0;
+
+ result = acpi_bus_get_status(battery->device);
+ if (result) {
ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
return -ENODEV;
}
- return 0;
+ return result;
}
static int acpi_battery_get_info(struct acpi_battery *battery)
{
- int result = -EFAULT;
+ int result = 0;
acpi_status status = 0;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF),
+ ACPI_BATTERY_FORMAT_BIF
+ };
+ union acpi_object *package = NULL;
+ struct acpi_buffer *data = NULL;
+ struct acpi_battery_info *bif = NULL;
+
+ battery->update_time[ACPI_BATTERY_INFO] = get_seconds();
if (!acpi_battery_present(battery))
return 0;
- mutex_lock(&battery->lock);
- status = acpi_evaluate_object(battery->device->handle, "_BIF",
- NULL, &buffer);
- mutex_unlock(&battery->lock);
+ /* Evaluate _BIF */
+
+ status =
+ acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
+ &buffer);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
return -ENODEV;
}
- result = extract_package(battery, buffer.pointer,
- info_offsets, ARRAY_SIZE(info_offsets));
+ package = buffer.pointer;
+
+ data = &battery->bif_data;
+
+ /* Extract Package Data */
+
+ result =
+ acpi_battery_extract_package(battery, package, &format, data,
+ "_BIF");
+ if (result)
+ goto end;
+
+ end:
+
kfree(buffer.pointer);
+
+ if (!result) {
+ bif = data->pointer;
+ battery->flags.power_unit = bif->power_unit;
+ }
+
return result;
}
@@ -319,203 +273,342 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
int result = 0;
acpi_status status = 0;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST),
+ ACPI_BATTERY_FORMAT_BST
+ };
+ union acpi_object *package = NULL;
+ struct acpi_buffer *data = NULL;
- if (!acpi_battery_present(battery))
- return 0;
+ battery->update_time[ACPI_BATTERY_STATE] = get_seconds();
- if (battery->update_time &&
- time_before(jiffies, battery->update_time +
- msecs_to_jiffies(cache_time)))
+ if (!acpi_battery_present(battery))
return 0;
- mutex_lock(&battery->lock);
- status = acpi_evaluate_object(battery->device->handle, "_BST",
- NULL, &buffer);
- mutex_unlock(&battery->lock);
+ /* Evaluate _BST */
+ status =
+ acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
+ &buffer);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
return -ENODEV;
}
- result = extract_package(battery, buffer.pointer,
- state_offsets, ARRAY_SIZE(state_offsets));
- battery->update_time = jiffies;
+ package = buffer.pointer;
+
+ data = &battery->bst_data;
+
+ /* Extract Package Data */
+
+ result =
+ acpi_battery_extract_package(battery, package, &format, data,
+ "_BST");
+ if (result)
+ goto end;
+
+ end:
kfree(buffer.pointer);
+
return result;
}
-static int acpi_battery_set_alarm(struct acpi_battery *battery)
+static int acpi_battery_get_alarm(struct acpi_battery *battery)
+{
+ battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
+
+ return 0;
+}
+
+static int acpi_battery_set_alarm(struct acpi_battery *battery,
+ unsigned long alarm)
{
acpi_status status = 0;
- union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
+ union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list arg_list = { 1, &arg0 };
- if (!acpi_battery_present(battery)|| !battery->alarm_present)
+ battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
+
+ if (!acpi_battery_present(battery))
return -ENODEV;
- arg0.integer.value = battery->alarm;
+ if (!battery->flags.alarm_present)
+ return -ENODEV;
- mutex_lock(&battery->lock);
- status = acpi_evaluate_object(battery->device->handle, "_BTP",
- &arg_list, NULL);
- mutex_unlock(&battery->lock);
+ arg0.integer.value = alarm;
+ status =
+ acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
+ &arg_list, NULL);
if (ACPI_FAILURE(status))
return -ENODEV;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm));
+
+ battery->alarm = alarm;
+
return 0;
}
static int acpi_battery_init_alarm(struct acpi_battery *battery)
{
+ int result = 0;
acpi_status status = AE_OK;
acpi_handle handle = NULL;
+ struct acpi_battery_info *bif = battery->bif_data.pointer;
+ unsigned long alarm = battery->alarm;
/* See if alarms are supported, and if so, set default */
- status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
- if (ACPI_FAILURE(status)) {
- battery->alarm_present = 0;
- return 0;
+
+ status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle);
+ if (ACPI_SUCCESS(status)) {
+ battery->flags.alarm_present = 1;
+ if (!alarm && bif) {
+ alarm = bif->design_capacity_warning;
+ }
+ result = acpi_battery_set_alarm(battery, alarm);
+ if (result)
+ goto end;
+ } else {
+ battery->flags.alarm_present = 0;
}
- battery->alarm_present = 1;
- if (!battery->alarm)
- battery->alarm = battery->design_capacity_warning;
- return acpi_battery_set_alarm(battery);
+
+ end:
+
+ return result;
}
-static int acpi_battery_update(struct acpi_battery *battery)
+static int acpi_battery_init_update(struct acpi_battery *battery)
{
- int saved_present = acpi_battery_present(battery);
- int result = acpi_battery_get_status(battery);
- if (result || !acpi_battery_present(battery))
+ int result = 0;
+
+ result = acpi_battery_get_status(battery);
+ if (result)
return result;
- if (saved_present != acpi_battery_present(battery) ||
- !battery->update_time) {
- battery->update_time = 0;
+
+ battery->flags.battery_present_prev = acpi_battery_present(battery);
+
+ if (acpi_battery_present(battery)) {
result = acpi_battery_get_info(battery);
if (result)
return result;
- if (battery->power_unit) {
- battery->bat.properties = charge_battery_props;
- battery->bat.num_properties =
- ARRAY_SIZE(charge_battery_props);
+ result = acpi_battery_get_state(battery);
+ if (result)
+ return result;
+
+ acpi_battery_init_alarm(battery);
+ }
+
+ return result;
+}
+
+static int acpi_battery_update(struct acpi_battery *battery,
+ int update, int *update_result_ptr)
+{
+ int result = 0;
+ int update_result = ACPI_BATTERY_NONE_UPDATE;
+
+ if (!acpi_battery_present(battery)) {
+ update = 1;
+ }
+
+ if (battery->flags.init_update) {
+ result = acpi_battery_init_update(battery);
+ if (result)
+ goto end;
+ update_result = ACPI_BATTERY_INIT_UPDATE;
+ } else if (update) {
+ result = acpi_battery_get_status(battery);
+ if (result)
+ goto end;
+ if ((!battery->flags.battery_present_prev & acpi_battery_present(battery))
+ || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) {
+ result = acpi_battery_init_update(battery);
+ if (result)
+ goto end;
+ update_result = ACPI_BATTERY_INIT_UPDATE;
} else {
- battery->bat.properties = energy_battery_props;
- battery->bat.num_properties =
- ARRAY_SIZE(energy_battery_props);
+ update_result = ACPI_BATTERY_EASY_UPDATE;
}
- acpi_battery_init_alarm(battery);
}
- return acpi_battery_get_state(battery);
+
+ end:
+
+ battery->flags.init_update = (result != 0);
+
+ *update_result_ptr = update_result;
+
+ return result;
+}
+
+static void acpi_battery_notify_update(struct acpi_battery *battery)
+{
+ acpi_battery_get_status(battery);
+
+ if (battery->flags.init_update) {
+ return;
+ }
+
+ if ((!battery->flags.battery_present_prev &
+ acpi_battery_present(battery)) ||
+ (battery->flags.battery_present_prev &
+ !acpi_battery_present(battery))) {
+ battery->flags.init_update = 1;
+ } else {
+ battery->flags.update[ACPI_BATTERY_INFO] = 1;
+ battery->flags.update[ACPI_BATTERY_STATE] = 1;
+ battery->flags.update[ACPI_BATTERY_ALARM] = 1;
+ }
}
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_PROCFS
static struct proc_dir_entry *acpi_battery_dir;
static int acpi_battery_print_info(struct seq_file *seq, int result)
{
struct acpi_battery *battery = seq->private;
+ struct acpi_battery_info *bif = NULL;
+ char *units = "?";
if (result)
goto end;
- seq_printf(seq, "present: %s\n",
- acpi_battery_present(battery)?"yes":"no");
- if (!acpi_battery_present(battery))
+ if (acpi_battery_present(battery))
+ seq_printf(seq, "present: yes\n");
+ else {
+ seq_printf(seq, "present: no\n");
goto end;
- if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+ }
+
+ bif = battery->bif_data.pointer;
+ if (!bif) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL"));
+ result = -ENODEV;
+ goto end;
+ }
+
+ /* Battery Units */
+
+ units = acpi_battery_power_units(battery);
+
+ if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "design capacity: unknown\n");
else
seq_printf(seq, "design capacity: %d %sh\n",
- battery->design_capacity,
- acpi_battery_units(battery));
+ (u32) bif->design_capacity, units);
- if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+ if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "last full capacity: unknown\n");
else
seq_printf(seq, "last full capacity: %d %sh\n",
- battery->full_charge_capacity,
- acpi_battery_units(battery));
+ (u32) bif->last_full_capacity, units);
- seq_printf(seq, "battery technology: %srechargeable\n",
- (!battery->technology)?"non-":"");
+ switch ((u32) bif->battery_technology) {
+ case 0:
+ seq_printf(seq, "battery technology: non-rechargeable\n");
+ break;
+ case 1:
+ seq_printf(seq, "battery technology: rechargeable\n");
+ break;
+ default:
+ seq_printf(seq, "battery technology: unknown\n");
+ break;
+ }
- if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
+ if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "design voltage: unknown\n");
else
seq_printf(seq, "design voltage: %d mV\n",
- battery->design_voltage);
+ (u32) bif->design_voltage);
seq_printf(seq, "design capacity warning: %d %sh\n",
- battery->design_capacity_warning,
- acpi_battery_units(battery));
+ (u32) bif->design_capacity_warning, units);
seq_printf(seq, "design capacity low: %d %sh\n",
- battery->design_capacity_low,
- acpi_battery_units(battery));
+ (u32) bif->design_capacity_low, units);
seq_printf(seq, "capacity granularity 1: %d %sh\n",
- battery->capacity_granularity_1,
- acpi_battery_units(battery));
+ (u32) bif->battery_capacity_granularity_1, units);
seq_printf(seq, "capacity granularity 2: %d %sh\n",
- battery->capacity_granularity_2,
- acpi_battery_units(battery));
- seq_printf(seq, "model number: %s\n", battery->model_number);
- seq_printf(seq, "serial number: %s\n", battery->serial_number);
- seq_printf(seq, "battery type: %s\n", battery->type);
- seq_printf(seq, "OEM info: %s\n", battery->oem_info);
+ (u32) bif->battery_capacity_granularity_2, units);
+ seq_printf(seq, "model number: %s\n", bif->model_number);
+ seq_printf(seq, "serial number: %s\n", bif->serial_number);
+ seq_printf(seq, "battery type: %s\n", bif->battery_type);
+ seq_printf(seq, "OEM info: %s\n", bif->oem_info);
+
end:
+
if (result)
seq_printf(seq, "ERROR: Unable to read battery info\n");
+
return result;
}
static int acpi_battery_print_state(struct seq_file *seq, int result)
{
struct acpi_battery *battery = seq->private;
+ struct acpi_battery_state *bst = NULL;
+ char *units = "?";
if (result)
goto end;
- seq_printf(seq, "present: %s\n",
- acpi_battery_present(battery)?"yes":"no");
- if (!acpi_battery_present(battery))
+ if (acpi_battery_present(battery))
+ seq_printf(seq, "present: yes\n");
+ else {
+ seq_printf(seq, "present: no\n");
+ goto end;
+ }
+
+ bst = battery->bst_data.pointer;
+ if (!bst) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL"));
+ result = -ENODEV;
goto end;
+ }
+
+ /* Battery Units */
+
+ units = acpi_battery_power_units(battery);
+
+ if (!(bst->state & 0x04))
+ seq_printf(seq, "capacity state: ok\n");
+ else
+ seq_printf(seq, "capacity state: critical\n");
- seq_printf(seq, "capacity state: %s\n",
- (battery->state & 0x04)?"critical":"ok");
- if ((battery->state & 0x01) && (battery->state & 0x02))
+ if ((bst->state & 0x01) && (bst->state & 0x02)) {
seq_printf(seq,
"charging state: charging/discharging\n");
- else if (battery->state & 0x01)
+ } else if (bst->state & 0x01)
seq_printf(seq, "charging state: discharging\n");
- else if (battery->state & 0x02)
+ else if (bst->state & 0x02)
seq_printf(seq, "charging state: charging\n");
- else
+ else {
seq_printf(seq, "charging state: charged\n");
+ }
- if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
+ if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "present rate: unknown\n");
else
seq_printf(seq, "present rate: %d %s\n",
- battery->current_now, acpi_battery_units(battery));
+ (u32) bst->present_rate, units);
- if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
+ if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "remaining capacity: unknown\n");
else
seq_printf(seq, "remaining capacity: %d %sh\n",
- battery->capacity_now, acpi_battery_units(battery));
- if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
+ (u32) bst->remaining_capacity, units);
+
+ if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "present voltage: unknown\n");
else
seq_printf(seq, "present voltage: %d mV\n",
- battery->voltage_now);
+ (u32) bst->present_voltage);
+
end:
- if (result)
+
+ if (result) {
seq_printf(seq, "ERROR: Unable to read battery state\n");
+ }
return result;
}
@@ -523,6 +616,7 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
static int acpi_battery_print_alarm(struct seq_file *seq, int result)
{
struct acpi_battery *battery = seq->private;
+ char *units = "?";
if (result)
goto end;
@@ -531,121 +625,189 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)
seq_printf(seq, "present: no\n");
goto end;
}
+
+ /* Battery Units */
+
+ units = acpi_battery_power_units(battery);
+
seq_printf(seq, "alarm: ");
if (!battery->alarm)
seq_printf(seq, "unsupported\n");
else
- seq_printf(seq, "%u %sh\n", battery->alarm,
- acpi_battery_units(battery));
+ seq_printf(seq, "%lu %sh\n", battery->alarm, units);
+
end:
+
if (result)
seq_printf(seq, "ERROR: Unable to read battery alarm\n");
+
return result;
}
-static ssize_t acpi_battery_write_alarm(struct file *file,
- const char __user * buffer,
- size_t count, loff_t * ppos)
+static ssize_t
+acpi_battery_write_alarm(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * ppos)
{
int result = 0;
char alarm_string[12] = { '\0' };
struct seq_file *m = file->private_data;
struct acpi_battery *battery = m->private;
+ int update_result = ACPI_BATTERY_NONE_UPDATE;
if (!battery || (count > sizeof(alarm_string) - 1))
return -EINVAL;
+
+ mutex_lock(&battery->mutex);
+
+ result = acpi_battery_update(battery, 1, &update_result);
if (result) {
result = -ENODEV;
goto end;
}
+
if (!acpi_battery_present(battery)) {
result = -ENODEV;
goto end;
}
+
if (copy_from_user(alarm_string, buffer, count)) {
result = -EFAULT;
goto end;
}
+
alarm_string[count] = '\0';
- battery->alarm = simple_strtol(alarm_string, NULL, 0);
- result = acpi_battery_set_alarm(battery);
+
+ result = acpi_battery_set_alarm(battery,
+ simple_strtoul(alarm_string, NULL, 0));
+ if (result)
+ goto end;
+
end:
+
+ acpi_battery_check_result(battery, result);
+
if (!result)
- return count;
+ result = count;
+
+ mutex_unlock(&battery->mutex);
+
return result;
}
typedef int(*print_func)(struct seq_file *seq, int result);
-
-static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
- acpi_battery_print_info,
- acpi_battery_print_state,
- acpi_battery_print_alarm,
+typedef int(*get_func)(struct acpi_battery *battery);
+
+static struct acpi_read_mux {
+ print_func print;
+ get_func get;
+} acpi_read_funcs[ACPI_BATTERY_NUMFILES] = {
+ {.get = acpi_battery_get_info, .print = acpi_battery_print_info},
+ {.get = acpi_battery_get_state, .print = acpi_battery_print_state},
+ {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm},
};
static int acpi_battery_read(int fid, struct seq_file *seq)
{
struct acpi_battery *battery = seq->private;
- int result = acpi_battery_update(battery);
- return acpi_print_funcs[fid](seq, result);
-}
-
-#define DECLARE_FILE_FUNCTIONS(_name) \
-static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
-{ \
- return acpi_battery_read(_name##_tag, seq); \
-} \
-static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \
-{ \
- return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \
-}
-
-DECLARE_FILE_FUNCTIONS(info);
-DECLARE_FILE_FUNCTIONS(state);
-DECLARE_FILE_FUNCTIONS(alarm);
-
-#undef DECLARE_FILE_FUNCTIONS
-
-#define FILE_DESCRIPTION_RO(_name) \
- { \
- .name = __stringify(_name), \
- .mode = S_IRUGO, \
- .ops = { \
- .open = acpi_battery_##_name##_open_fs, \
- .read = seq_read, \
- .llseek = seq_lseek, \
- .release = single_release, \
- .owner = THIS_MODULE, \
- }, \
- }
-
-#define FILE_DESCRIPTION_RW(_name) \
- { \
- .name = __stringify(_name), \
- .mode = S_IFREG | S_IRUGO | S_IWUSR, \
- .ops = { \
- .open = acpi_battery_##_name##_open_fs, \
- .read = seq_read, \
- .llseek = seq_lseek, \
- .write = acpi_battery_write_##_name, \
- .release = single_release, \
- .owner = THIS_MODULE, \
- }, \
+ int result = 0;
+ int update_result = ACPI_BATTERY_NONE_UPDATE;
+ int update = 0;
+
+ mutex_lock(&battery->mutex);
+
+ update = (get_seconds() - battery->update_time[fid] >= update_time);
+ update = (update | battery->flags.update[fid]);
+
+ result = acpi_battery_update(battery, update, &update_result);
+ if (result)
+ goto end;
+
+ if (update_result == ACPI_BATTERY_EASY_UPDATE) {
+ result = acpi_read_funcs[fid].get(battery);
+ if (result)
+ goto end;
}
+ end:
+ result = acpi_read_funcs[fid].print(seq, result);
+ acpi_battery_check_result(battery, result);
+ battery->flags.update[fid] = result;
+ mutex_unlock(&battery->mutex);
+ return result;
+}
+
+static int acpi_battery_read_info(struct seq_file *seq, void *offset)
+{
+ return acpi_battery_read(ACPI_BATTERY_INFO, seq);
+}
+
+static int acpi_battery_read_state(struct seq_file *seq, void *offset)
+{
+ return acpi_battery_read(ACPI_BATTERY_STATE, seq);
+}
+
+static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
+{
+ return acpi_battery_read(ACPI_BATTERY_ALARM, seq);
+}
+
+static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
+{
+ return single_open(file, acpi_battery_read_info, PDE(inode)->data);
+}
+
+static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
+{
+ return single_open(file, acpi_battery_read_state, PDE(inode)->data);
+}
+
+static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
+{
+ return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
+}
+
static struct battery_file {
struct file_operations ops;
mode_t mode;
char *name;
} acpi_battery_file[] = {
- FILE_DESCRIPTION_RO(info),
- FILE_DESCRIPTION_RO(state),
- FILE_DESCRIPTION_RW(alarm),
+ {
+ .name = "info",
+ .mode = S_IRUGO,
+ .ops = {
+ .open = acpi_battery_info_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+ },
+ },
+ {
+ .name = "state",
+ .mode = S_IRUGO,
+ .ops = {
+ .open = acpi_battery_state_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+ },
+ },
+ {
+ .name = "alarm",
+ .mode = S_IFREG | S_IRUGO | S_IWUSR,
+ .ops = {
+ .open = acpi_battery_alarm_open_fs,
+ .read = seq_read,
+ .write = acpi_battery_write_alarm,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+ },
+ },
};
-#undef FILE_DESCRIPTION_RO
-#undef FILE_DESCRIPTION_RW
-
static int acpi_battery_add_fs(struct acpi_device *device)
{
struct proc_dir_entry *entry = NULL;
@@ -670,51 +832,25 @@ static int acpi_battery_add_fs(struct acpi_device *device)
entry->owner = THIS_MODULE;
}
}
+
return 0;
}
-static void acpi_battery_remove_fs(struct acpi_device *device)
+static int acpi_battery_remove_fs(struct acpi_device *device)
{
int i;
- if (!acpi_device_dir(device))
- return;
- for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i)
- remove_proc_entry(acpi_battery_file[i].name,
+ if (acpi_device_dir(device)) {
+ for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
+ remove_proc_entry(acpi_battery_file[i].name,
acpi_device_dir(device));
+ }
+ remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
+ acpi_device_dir(device) = NULL;
+ }
- remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
- acpi_device_dir(device) = NULL;
-}
-
-#endif
-
-static ssize_t acpi_battery_alarm_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
- return sprintf(buf, "%d\n", battery->alarm * 1000);
-}
-
-static ssize_t acpi_battery_alarm_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- unsigned long x;
- struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
- if (sscanf(buf, "%ld\n", &x) == 1)
- battery->alarm = x/1000;
- if (acpi_battery_present(battery))
- acpi_battery_set_alarm(battery);
- return count;
+ return 0;
}
-static struct device_attribute alarm_attr = {
- .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
- .show = acpi_battery_alarm_show,
- .store = acpi_battery_alarm_store,
-};
-
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
@@ -722,17 +858,33 @@ static struct device_attribute alarm_attr = {
static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
{
struct acpi_battery *battery = data;
- struct acpi_device *device;
+ struct acpi_device *device = NULL;
+
if (!battery)
return;
+
device = battery->device;
- acpi_battery_update(battery);
- acpi_bus_generate_proc_event(device, event,
- acpi_battery_present(battery));
- acpi_bus_generate_netlink_event(device->pnp.device_class,
- device->dev.bus_id, event,
+
+ switch (event) {
+ case ACPI_BATTERY_NOTIFY_STATUS:
+ case ACPI_BATTERY_NOTIFY_INFO:
+ case ACPI_NOTIFY_BUS_CHECK:
+ case ACPI_NOTIFY_DEVICE_CHECK:
+ device = battery->device;
+ acpi_battery_notify_update(battery);
+ acpi_bus_generate_proc_event(device, event,
acpi_battery_present(battery));
- kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event,
+ acpi_battery_present(battery));
+ break;
+ default:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Unsupported event [0x%x]\n", event));
+ break;
+ }
+
+ return;
}
static int acpi_battery_add(struct acpi_device *device)
@@ -740,27 +892,33 @@ static int acpi_battery_add(struct acpi_device *device)
int result = 0;
acpi_status status = 0;
struct acpi_battery *battery = NULL;
+
if (!device)
return -EINVAL;
+
battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
if (!battery)
return -ENOMEM;
+
+ mutex_init(&battery->mutex);
+
+ mutex_lock(&battery->mutex);
+
battery->device = device;
strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
acpi_driver_data(device) = battery;
- mutex_init(&battery->lock);
- acpi_battery_update(battery);
-#ifdef CONFIG_ACPI_PROCFS
+
+ result = acpi_battery_get_status(battery);
+ if (result)
+ goto end;
+
+ battery->flags.init_update = 1;
+
result = acpi_battery_add_fs(device);
if (result)
goto end;
-#endif
- battery->bat.name = acpi_device_bid(device);
- battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
- battery->bat.get_property = acpi_battery_get_property;
- result = power_supply_register(&battery->device->dev, &battery->bat);
- result = device_create_file(battery->bat.dev, &alarm_attr);
+
status = acpi_install_notify_handler(device->handle,
ACPI_ALL_NOTIFY,
acpi_battery_notify, battery);
@@ -769,16 +927,20 @@ static int acpi_battery_add(struct acpi_device *device)
result = -ENODEV;
goto end;
}
+
printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
device->status.battery_present ? "present" : "absent");
+
end:
+
if (result) {
-#ifdef CONFIG_ACPI_PROCFS
acpi_battery_remove_fs(device);
-#endif
kfree(battery);
}
+
+ mutex_unlock(&battery->mutex);
+
return result;
}
@@ -789,19 +951,27 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
+
battery = acpi_driver_data(device);
+
+ mutex_lock(&battery->mutex);
+
status = acpi_remove_notify_handler(device->handle,
ACPI_ALL_NOTIFY,
acpi_battery_notify);
-#ifdef CONFIG_ACPI_PROCFS
+
acpi_battery_remove_fs(device);
-#endif
- if (battery->bat.dev) {
- device_remove_file(battery->bat.dev, &alarm_attr);
- power_supply_unregister(&battery->bat);
- }
- mutex_destroy(&battery->lock);
+
+ kfree(battery->bif_data.pointer);
+
+ kfree(battery->bst_data.pointer);
+
+ mutex_unlock(&battery->mutex);
+
+ mutex_destroy(&battery->mutex);
+
kfree(battery);
+
return 0;
}
@@ -809,48 +979,44 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
static int acpi_battery_resume(struct acpi_device *device)
{
struct acpi_battery *battery;
+
if (!device)
return -EINVAL;
- battery = acpi_driver_data(device);
- battery->update_time = 0;
+
+ battery = device->driver_data;
+
+ battery->flags.init_update = 1;
+
return 0;
}
-static struct acpi_driver acpi_battery_driver = {
- .name = "battery",
- .class = ACPI_BATTERY_CLASS,
- .ids = battery_device_ids,
- .ops = {
- .add = acpi_battery_add,
- .resume = acpi_battery_resume,
- .remove = acpi_battery_remove,
- },
-};
-
static int __init acpi_battery_init(void)
{
+ int result;
+
if (acpi_disabled)
return -ENODEV;
-#ifdef CONFIG_ACPI_PROCFS
+
acpi_battery_dir = acpi_lock_battery_dir();
if (!acpi_battery_dir)
return -ENODEV;
-#endif
- if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
-#ifdef CONFIG_ACPI_PROCFS
+
+ result = acpi_bus_register_driver(&acpi_battery_driver);
+ if (result < 0) {
acpi_unlock_battery_dir(acpi_battery_dir);
-#endif
return -ENODEV;
}
+
return 0;
}
static void __exit acpi_battery_exit(void)
{
acpi_bus_unregister_driver(&acpi_battery_driver);
-#ifdef CONFIG_ACPI_PROCFS
+
acpi_unlock_battery_dir(acpi_battery_dir);
-#endif
+
+ return;
}
module_init(acpi_battery_init);
diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c
index fb2cff9a2d24..cbfc81579c9a 100644
--- a/trunk/drivers/acpi/bus.c
+++ b/trunk/drivers/acpi/bus.c
@@ -286,11 +286,15 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
extern int event_is_open;
-int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
+int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
{
- struct acpi_bus_event *event;
+ struct acpi_bus_event *event = NULL;
unsigned long flags = 0;
+
+ if (!device)
+ return -EINVAL;
+
/* drop event on the floor if no one's listening */
if (!event_is_open)
return 0;
@@ -299,8 +303,8 @@ int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id,
if (!event)
return -ENOMEM;
- strcpy(event->device_class, device_class);
- strcpy(event->bus_id, bus_id);
+ strcpy(event->device_class, device->pnp.device_class);
+ strcpy(event->bus_id, device->pnp.bus_id);
event->type = type;
event->data = data;
@@ -311,17 +315,6 @@ int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id,
wake_up_interruptible(&acpi_bus_event_queue);
return 0;
-
-}
-
-EXPORT_SYMBOL_GPL(acpi_bus_generate_proc_event4);
-
-int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
-{
- if (!device)
- return -EINVAL;
- return acpi_bus_generate_proc_event4(device->pnp.device_class,
- device->pnp.bus_id, type, data);
}
EXPORT_SYMBOL(acpi_bus_generate_proc_event);
diff --git a/trunk/drivers/acpi/button.c b/trunk/drivers/acpi/button.c
index 301e832e6961..2e79a3395ecf 100644
--- a/trunk/drivers/acpi/button.c
+++ b/trunk/drivers/acpi/button.c
@@ -434,18 +434,18 @@ static int acpi_button_add(struct acpi_device *device)
switch (button->type) {
case ACPI_BUTTON_TYPE_POWER:
case ACPI_BUTTON_TYPE_POWERF:
- input->evbit[0] = BIT_MASK(EV_KEY);
+ input->evbit[0] = BIT(EV_KEY);
set_bit(KEY_POWER, input->keybit);
break;
case ACPI_BUTTON_TYPE_SLEEP:
case ACPI_BUTTON_TYPE_SLEEPF:
- input->evbit[0] = BIT_MASK(EV_KEY);
+ input->evbit[0] = BIT(EV_KEY);
set_bit(KEY_SLEEP, input->keybit);
break;
case ACPI_BUTTON_TYPE_LID:
- input->evbit[0] = BIT_MASK(EV_SW);
+ input->evbit[0] = BIT(EV_SW);
set_bit(SW_LID, input->swbit);
break;
}
diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c
index 7b4178393e34..3f7935ab0cf5 100644
--- a/trunk/drivers/acpi/ec.c
+++ b/trunk/drivers/acpi/ec.c
@@ -121,7 +121,6 @@ static struct acpi_ec {
atomic_t event_count;
wait_queue_head_t wait;
struct list_head list;
- u8 handlers_installed;
} *boot_ec, *first_ec;
/* --------------------------------------------------------------------------
@@ -426,7 +425,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
handler->func = func;
handler->data = data;
mutex_lock(&ec->lock);
- list_add(&handler->node, &ec->list);
+ list_add_tail(&handler->node, &ec->list);
mutex_unlock(&ec->lock);
return 0;
}
@@ -441,6 +440,7 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
if (query_bit == handler->query_bit) {
list_del(&handler->node);
kfree(handler);
+ break;
}
}
mutex_unlock(&ec->lock);
@@ -680,24 +680,20 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
if (ACPI_FAILURE(status))
return status;
+
/* Find and register all query methods */
acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
acpi_ec_register_query_methods, ec, NULL);
+
/* Use the global lock for all EC transactions? */
acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
+
ec->handle = handle;
- return AE_CTRL_TERMINATE;
-}
-static void ec_remove_handlers(struct acpi_ec *ec)
-{
- if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
- ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
- printk(KERN_ERR PREFIX "failed to remove space handler\n");
- if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
- &acpi_ec_gpe_handler)))
- printk(KERN_ERR PREFIX "failed to remove gpe handler\n");
- ec->handlers_installed = 0;
+ printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
+ ec->gpe, ec->command_addr, ec->data_addr);
+
+ return AE_CTRL_TERMINATE;
}
static int acpi_ec_add(struct acpi_device *device)
@@ -706,24 +702,10 @@ static int acpi_ec_add(struct acpi_device *device)
if (!device)
return -EINVAL;
+
strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_EC_CLASS);
- /* Check for boot EC */
- if (boot_ec) {
- if (boot_ec->handle == device->handle) {
- /* Pre-loaded EC from DSDT, just move pointer */
- ec = boot_ec;
- boot_ec = NULL;
- goto end;
- } else if (boot_ec->handle == ACPI_ROOT_OBJECT) {
- /* ECDT-based EC, time to shut it down */
- ec_remove_handlers(boot_ec);
- kfree(boot_ec);
- first_ec = boot_ec = NULL;
- }
- }
-
ec = make_acpi_ec();
if (!ec)
return -ENOMEM;
@@ -733,14 +715,25 @@ static int acpi_ec_add(struct acpi_device *device)
kfree(ec);
return -EINVAL;
}
- ec->handle = device->handle;
- end:
- if (!first_ec)
+
+ /* Check if we found the boot EC */
+ if (boot_ec) {
+ if (boot_ec->gpe == ec->gpe) {
+ /* We might have incorrect info for GL at boot time */
+ mutex_lock(&boot_ec->lock);
+ boot_ec->global_lock = ec->global_lock;
+ /* Copy handlers from new ec into boot ec */
+ list_splice(&ec->list, &boot_ec->list);
+ mutex_unlock(&boot_ec->lock);
+ kfree(ec);
+ ec = boot_ec;
+ }
+ } else
first_ec = ec;
+ ec->handle = device->handle;
acpi_driver_data(device) = ec;
+
acpi_ec_add_fs(device);
- printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
- ec->gpe, ec->command_addr, ec->data_addr);
return 0;
}
@@ -763,7 +756,10 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
acpi_driver_data(device) = NULL;
if (ec == first_ec)
first_ec = NULL;
- kfree(ec);
+
+ /* Don't touch boot EC */
+ if (boot_ec != ec)
+ kfree(ec);
return 0;
}
@@ -793,8 +789,6 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context)
static int ec_install_handlers(struct acpi_ec *ec)
{
acpi_status status;
- if (ec->handlers_installed)
- return 0;
status = acpi_install_gpe_handler(NULL, ec->gpe,
ACPI_GPE_EDGE_TRIGGERED,
&acpi_ec_gpe_handler, ec);
@@ -813,7 +807,6 @@ static int ec_install_handlers(struct acpi_ec *ec)
return -ENODEV;
}
- ec->handlers_installed = 1;
return 0;
}
@@ -830,22 +823,41 @@ static int acpi_ec_start(struct acpi_device *device)
if (!ec)
return -EINVAL;
- ret = ec_install_handlers(ec);
+ /* Boot EC is already working */
+ if (ec != boot_ec)
+ ret = ec_install_handlers(ec);
/* EC is fully operational, allow queries */
atomic_set(&ec->query_pending, 0);
+
return ret;
}
static int acpi_ec_stop(struct acpi_device *device, int type)
{
+ acpi_status status;
struct acpi_ec *ec;
+
if (!device)
return -EINVAL;
+
ec = acpi_driver_data(device);
if (!ec)
return -EINVAL;
- ec_remove_handlers(ec);
+
+ /* Don't touch boot EC */
+ if (ec == boot_ec)
+ return 0;
+
+ status = acpi_remove_address_space_handler(ec->handle,
+ ACPI_ADR_SPACE_EC,
+ &acpi_ec_space_handler);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
return 0;
}
@@ -865,7 +877,7 @@ int __init acpi_ec_ecdt_probe(void)
status = acpi_get_table(ACPI_SIG_ECDT, 1,
(struct acpi_table_header **)&ecdt_ptr);
if (ACPI_SUCCESS(status)) {
- printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
+ printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n");
boot_ec->command_addr = ecdt_ptr->control.address;
boot_ec->data_addr = ecdt_ptr->data.address;
boot_ec->gpe = ecdt_ptr->gpe;
@@ -887,6 +899,7 @@ int __init acpi_ec_ecdt_probe(void)
error:
kfree(boot_ec);
boot_ec = NULL;
+
return -ENODEV;
}
diff --git a/trunk/drivers/acpi/events/evevent.c b/trunk/drivers/acpi/events/evevent.c
index e41287815ea1..a1f87b5def2a 100644
--- a/trunk/drivers/acpi/events/evevent.c
+++ b/trunk/drivers/acpi/events/evevent.c
@@ -239,8 +239,10 @@ u32 acpi_ev_fixed_event_detect(void)
* Read the fixed feature status and enable registers, as all the cases
* depend on their values. Ignore errors here.
*/
- (void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);
- (void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
+ (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_STATUS, &fixed_status);
+ (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
"Fixed Event Block: Enable %08X Status %08X\n",
diff --git a/trunk/drivers/acpi/hardware/hwregs.c b/trunk/drivers/acpi/hardware/hwregs.c
index 73f9c5fb1ba7..1d371fa663f2 100644
--- a/trunk/drivers/acpi/hardware/hwregs.c
+++ b/trunk/drivers/acpi/hardware/hwregs.c
@@ -75,7 +75,8 @@ acpi_status acpi_hw_clear_acpi_status(void)
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
- status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_STATUS,
ACPI_BITMASK_ALL_FIXED_STATUS);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
@@ -258,7 +259,7 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
*
******************************************************************************/
-acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value)
+acpi_status acpi_get_register(u32 register_id, u32 * return_value)
{
u32 register_value = 0;
struct acpi_bit_register_info *bit_reg_info;
@@ -275,7 +276,8 @@ acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value)
/* Read from the register */
- status = acpi_hw_register_read(bit_reg_info->parent_register,
+ status = acpi_hw_register_read(ACPI_MTX_LOCK,
+ bit_reg_info->parent_register,
®ister_value);
if (ACPI_SUCCESS(status)) {
@@ -296,16 +298,6 @@ acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value)
return_ACPI_STATUS(status);
}
-acpi_status acpi_get_register(u32 register_id, u32 * return_value)
-{
- acpi_status status;
- acpi_cpu_flags flags;
- flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
- status = acpi_get_register_unlocked(register_id, return_value);
- acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
- return status;
-}
-
ACPI_EXPORT_SYMBOL(acpi_get_register)
/*******************************************************************************
@@ -343,7 +335,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
/* Always do a register read first so we can insert the new bits */
- status = acpi_hw_register_read(bit_reg_info->parent_register,
+ status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ bit_reg_info->parent_register,
®ister_value);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
@@ -370,7 +363,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
bit_reg_info->
access_bit_mask);
if (value) {
- status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_STATUS,
(u16) value);
register_value = 0;
}
@@ -383,7 +377,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
bit_reg_info->access_bit_mask,
value);
- status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_ENABLE,
(u16) register_value);
break;
@@ -402,13 +397,15 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
bit_reg_info->access_bit_mask,
value);
- status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_CONTROL,
(u16) register_value);
break;
case ACPI_REGISTER_PM2_CONTROL:
- status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
+ status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM2_CONTROL,
®ister_value);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
@@ -433,7 +430,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
xpm2_control_block.
address)));
- status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM2_CONTROL,
(u8) (register_value));
break;
@@ -463,7 +461,8 @@ ACPI_EXPORT_SYMBOL(acpi_set_register)
*
* FUNCTION: acpi_hw_register_read
*
- * PARAMETERS: register_id - ACPI Register ID
+ * PARAMETERS: use_lock - Lock hardware? True/False
+ * register_id - ACPI Register ID
* return_value - Where the register value is returned
*
* RETURN: Status and the value read.
@@ -472,14 +471,19 @@ ACPI_EXPORT_SYMBOL(acpi_set_register)
*
******************************************************************************/
acpi_status
-acpi_hw_register_read(u32 register_id, u32 * return_value)
+acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
{
u32 value1 = 0;
u32 value2 = 0;
acpi_status status;
+ acpi_cpu_flags lock_flags = 0;
ACPI_FUNCTION_TRACE(hw_register_read);
+ if (ACPI_MTX_LOCK == use_lock) {
+ lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
+ }
+
switch (register_id) {
case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
@@ -487,7 +491,7 @@ acpi_hw_register_read(u32 register_id, u32 * return_value)
acpi_hw_low_level_read(16, &value1,
&acpi_gbl_FADT.xpm1a_event_block);
if (ACPI_FAILURE(status)) {
- goto exit;
+ goto unlock_and_exit;
}
/* PM1B is optional */
@@ -503,7 +507,7 @@ acpi_hw_register_read(u32 register_id, u32 * return_value)
status =
acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable);
if (ACPI_FAILURE(status)) {
- goto exit;
+ goto unlock_and_exit;
}
/* PM1B is optional */
@@ -519,7 +523,7 @@ acpi_hw_register_read(u32 register_id, u32 * return_value)
acpi_hw_low_level_read(16, &value1,
&acpi_gbl_FADT.xpm1a_control_block);
if (ACPI_FAILURE(status)) {
- goto exit;
+ goto unlock_and_exit;
}
status =
@@ -554,7 +558,10 @@ acpi_hw_register_read(u32 register_id, u32 * return_value)
break;
}
- exit:
+ unlock_and_exit:
+ if (ACPI_MTX_LOCK == use_lock) {
+ acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
+ }
if (ACPI_SUCCESS(status)) {
*return_value = value1;
@@ -567,7 +574,8 @@ acpi_hw_register_read(u32 register_id, u32 * return_value)
*
* FUNCTION: acpi_hw_register_write
*
- * PARAMETERS: register_id - ACPI Register ID
+ * PARAMETERS: use_lock - Lock hardware? True/False
+ * register_id - ACPI Register ID
* Value - The value to write
*
* RETURN: Status
@@ -589,22 +597,28 @@ acpi_hw_register_read(u32 register_id, u32 * return_value)
*
******************************************************************************/
-acpi_status acpi_hw_register_write(u32 register_id, u32 value)
+acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
{
acpi_status status;
+ acpi_cpu_flags lock_flags = 0;
u32 read_value;
ACPI_FUNCTION_TRACE(hw_register_write);
+ if (ACPI_MTX_LOCK == use_lock) {
+ lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
+ }
+
switch (register_id) {
case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
/* Perform a read first to preserve certain bits (per ACPI spec) */
- status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
+ status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_STATUS,
&read_value);
if (ACPI_FAILURE(status)) {
- goto exit;
+ goto unlock_and_exit;
}
/* Insert the bits to be preserved */
@@ -618,7 +632,7 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
acpi_hw_low_level_write(16, value,
&acpi_gbl_FADT.xpm1a_event_block);
if (ACPI_FAILURE(status)) {
- goto exit;
+ goto unlock_and_exit;
}
/* PM1B is optional */
@@ -633,7 +647,7 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
status =
acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable);
if (ACPI_FAILURE(status)) {
- goto exit;
+ goto unlock_and_exit;
}
/* PM1B is optional */
@@ -647,10 +661,11 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
/*
* Perform a read first to preserve certain bits (per ACPI spec)
*/
- status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
+ status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_CONTROL,
&read_value);
if (ACPI_FAILURE(status)) {
- goto exit;
+ goto unlock_and_exit;
}
/* Insert the bits to be preserved */
@@ -664,7 +679,7 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
acpi_hw_low_level_write(16, value,
&acpi_gbl_FADT.xpm1a_control_block);
if (ACPI_FAILURE(status)) {
- goto exit;
+ goto unlock_and_exit;
}
status =
@@ -713,7 +728,11 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
break;
}
- exit:
+ unlock_and_exit:
+ if (ACPI_MTX_LOCK == use_lock) {
+ acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
+ }
+
return_ACPI_STATUS(status);
}
diff --git a/trunk/drivers/acpi/hardware/hwsleep.c b/trunk/drivers/acpi/hardware/hwsleep.c
index 81b248429703..cf69c0040a39 100644
--- a/trunk/drivers/acpi/hardware/hwsleep.c
+++ b/trunk/drivers/acpi/hardware/hwsleep.c
@@ -234,11 +234,15 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
"While executing method _SST"));
}
- /* Disable/Clear all GPEs */
-
+ /*
+ * 1) Disable/Clear all GPEs
+ */
status = acpi_hw_disable_all_gpes();
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
- return_ACPI_STATUS(status);
+ return_ACPI_STATUS(AE_OK);
}
ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
@@ -309,7 +313,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Get current value of PM1A control */
- status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+ status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -336,13 +341,15 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Write #1: fill in SLP_TYP data */
- status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1A_CONTROL,
PM1Acontrol);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1B_CONTROL,
PM1Bcontrol);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
@@ -357,13 +364,15 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
ACPI_FLUSH_CPU_CACHE();
- status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1A_CONTROL,
PM1Acontrol);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1B_CONTROL,
PM1Bcontrol);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
@@ -383,7 +392,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
*/
acpi_os_stall(10000000);
- status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
+ status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_CONTROL,
sleep_enable_reg_info->
access_bit_mask);
if (ACPI_FAILURE(status)) {
@@ -394,8 +404,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Wait until we enter sleep state */
do {
- status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
- &in_value);
+ status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -511,7 +520,8 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
/* Get current value of PM1A control */
- status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
+ status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1_CONTROL,
&PM1Acontrol);
if (ACPI_SUCCESS(status)) {
@@ -533,9 +543,11 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
/* Just ignore any errors */
- (void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
+ (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1A_CONTROL,
PM1Acontrol);
- (void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
+ (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
+ ACPI_REGISTER_PM1B_CONTROL,
PM1Bcontrol);
}
}
diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c
index aabc6ca4a81c..352cf81af581 100644
--- a/trunk/drivers/acpi/osl.c
+++ b/trunk/drivers/acpi/osl.c
@@ -1042,6 +1042,14 @@ static int __init acpi_wake_gpes_always_on_setup(char *str)
__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
+/*
+ * max_cstate is defined in the base kernel so modules can
+ * change it w/o depending on the state of the processor module.
+ */
+unsigned int max_cstate = ACPI_PROCESSOR_MAX_POWER;
+
+EXPORT_SYMBOL(max_cstate);
+
/*
* Acquire a spinlock.
*
diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c
index 235a51e328c3..9f11dc296cdd 100644
--- a/trunk/drivers/acpi/processor_core.c
+++ b/trunk/drivers/acpi/processor_core.c
@@ -44,7 +44,6 @@
#include
#include
#include
-#include
#include
#include
@@ -422,6 +421,12 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
return 0;
}
+#ifdef CONFIG_IA64
+#define arch_cpu_to_apicid ia64_cpu_to_sapicid
+#else
+#define arch_cpu_to_apicid x86_cpu_to_apicid
+#endif
+
static int map_madt_entry(u32 acpi_id)
{
unsigned long madt_end, entry;
@@ -495,7 +500,7 @@ static int get_cpu_id(acpi_handle handle, u32 acpi_id)
return apic_id;
for (i = 0; i < NR_CPUS; ++i) {
- if (cpu_physical_id(i) == apic_id)
+ if (arch_cpu_to_apicid[i] == apic_id)
return i;
}
return -1;
@@ -1044,13 +1049,11 @@ static int __init acpi_processor_init(void)
return -ENOMEM;
acpi_processor_dir->owner = THIS_MODULE;
- result = cpuidle_register_driver(&acpi_idle_driver);
- if (result < 0)
- goto out_proc;
-
result = acpi_bus_register_driver(&acpi_processor_driver);
- if (result < 0)
- goto out_cpuidle;
+ if (result < 0) {
+ remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+ return result;
+ }
acpi_processor_install_hotplug_notify();
@@ -1059,18 +1062,11 @@ static int __init acpi_processor_init(void)
acpi_processor_ppc_init();
return 0;
-
-out_cpuidle:
- cpuidle_unregister_driver(&acpi_idle_driver);
-
-out_proc:
- remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
-
- return result;
}
static void __exit acpi_processor_exit(void)
{
+
acpi_processor_ppc_exit();
acpi_thermal_cpufreq_exit();
@@ -1079,8 +1075,6 @@ static void __exit acpi_processor_exit(void)
acpi_bus_unregister_driver(&acpi_processor_driver);
- cpuidle_unregister_driver(&acpi_idle_driver);
-
remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
return;
diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c
index f996d0e37689..1f6fb38de017 100644
--- a/trunk/drivers/acpi/processor_idle.c
+++ b/trunk/drivers/acpi/processor_idle.c
@@ -40,7 +40,6 @@
#include /* need_resched() */
#include
#include
-#include
/*
* Include the apic definitions for x86 to have the APIC timer related defines
@@ -65,22 +64,14 @@ ACPI_MODULE_NAME("processor_idle");
#define ACPI_PROCESSOR_FILE_POWER "power"
#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
-#ifndef CONFIG_CPU_IDLE
#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */
#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */
static void (*pm_idle_save) (void) __read_mostly;
-#else
-#define C2_OVERHEAD 1 /* 1us */
-#define C3_OVERHEAD 1 /* 1us */
-#endif
-#define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000))
+module_param(max_cstate, uint, 0644);
-static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
-module_param(max_cstate, uint, 0000);
static unsigned int nocst __read_mostly;
module_param(nocst, uint, 0000);
-#ifndef CONFIG_CPU_IDLE
/*
* bm_history -- bit-mask with a bit per jiffy of bus-master activity
* 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms
@@ -91,10 +82,9 @@ module_param(nocst, uint, 0000);
static unsigned int bm_history __read_mostly =
(HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
module_param(bm_history, uint, 0644);
-
-static int acpi_processor_set_power_policy(struct acpi_processor *pr);
-
-#endif
+/* --------------------------------------------------------------------------
+ Power Management
+ -------------------------------------------------------------------------- */
/*
* IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
@@ -187,18 +177,6 @@ static inline u32 ticks_elapsed(u32 t1, u32 t2)
return ((0xFFFFFFFF - t1) + t2);
}
-static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
-{
- if (t2 >= t1)
- return PM_TIMER_TICKS_TO_US(t2 - t1);
- else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
- return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
- else
- return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
-}
-
-#ifndef CONFIG_CPU_IDLE
-
static void
acpi_processor_power_activate(struct acpi_processor *pr,
struct acpi_processor_cx *new)
@@ -270,7 +248,6 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
}
}
-#endif /* !CONFIG_CPU_IDLE */
#ifdef ARCH_APICTIMER_STOPS_ON_C3
@@ -353,7 +330,6 @@ int acpi_processor_resume(struct acpi_device * device)
return 0;
}
-#ifndef CONFIG_CPU_IDLE
static void acpi_processor_idle(void)
{
struct acpi_processor *pr = NULL;
@@ -451,7 +427,7 @@ static void acpi_processor_idle(void)
* an SMP system. We do it here instead of doing it at _CST/P_LVL
* detection phase, to work cleanly with logical CPU hotplug.
*/
- if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
+ if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
!pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
cx = &pr->power.states[ACPI_STATE_C1];
#endif
@@ -751,7 +727,6 @@ static int acpi_processor_set_power_policy(struct acpi_processor *pr)
return 0;
}
-#endif /* !CONFIG_CPU_IDLE */
static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
{
@@ -769,7 +744,7 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
#ifndef CONFIG_HOTPLUG_CPU
/*
* Check for P_LVL2_UP flag before entering C2 and above on
- * an SMP system.
+ * an SMP system.
*/
if ((num_online_cpus() > 1) &&
!(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
@@ -970,12 +945,7 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
* Normalize the C2 latency to expidite policy
*/
cx->valid = 1;
-
-#ifndef CONFIG_CPU_IDLE
cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
-#else
- cx->latency_ticks = cx->latency;
-#endif
return;
}
@@ -1055,12 +1025,7 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
* use this in our C3 policy
*/
cx->valid = 1;
-
-#ifndef CONFIG_CPU_IDLE
cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
-#else
- cx->latency_ticks = cx->latency;
-#endif
return;
}
@@ -1125,7 +1090,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
pr->power.count = acpi_processor_power_verify(pr);
-#ifndef CONFIG_CPU_IDLE
/*
* Set Default Policy
* ------------------
@@ -1137,7 +1101,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
result = acpi_processor_set_power_policy(pr);
if (result)
return result;
-#endif
/*
* if one state of type C2 or C3 is available, mark this
@@ -1154,6 +1117,35 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
return 0;
}
+int acpi_processor_cst_has_changed(struct acpi_processor *pr)
+{
+ int result = 0;
+
+
+ if (!pr)
+ return -EINVAL;
+
+ if (nocst) {
+ return -ENODEV;
+ }
+
+ if (!pr->flags.power_setup_done)
+ return -ENODEV;
+
+ /* Fall back to the default idle loop */
+ pm_idle = pm_idle_save;
+ synchronize_sched(); /* Relies on interrupts forcing exit from idle. */
+
+ pr->flags.power = 0;
+ result = acpi_processor_get_power_info(pr);
+ if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
+ pm_idle = acpi_processor_idle;
+
+ return result;
+}
+
+/* proc interface */
+
static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
{
struct acpi_processor *pr = seq->private;
@@ -1235,35 +1227,6 @@ static const struct file_operations acpi_processor_power_fops = {
.release = single_release,
};
-#ifndef CONFIG_CPU_IDLE
-
-int acpi_processor_cst_has_changed(struct acpi_processor *pr)
-{
- int result = 0;
-
-
- if (!pr)
- return -EINVAL;
-
- if (nocst) {
- return -ENODEV;
- }
-
- if (!pr->flags.power_setup_done)
- return -ENODEV;
-
- /* Fall back to the default idle loop */
- pm_idle = pm_idle_save;
- synchronize_sched(); /* Relies on interrupts forcing exit from idle. */
-
- pr->flags.power = 0;
- result = acpi_processor_get_power_info(pr);
- if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
- pm_idle = acpi_processor_idle;
-
- return result;
-}
-
#ifdef CONFIG_SMP
static void smp_callback(void *v)
{
@@ -1286,366 +1249,7 @@ static int acpi_processor_latency_notify(struct notifier_block *b,
static struct notifier_block acpi_processor_latency_notifier = {
.notifier_call = acpi_processor_latency_notify,
};
-
-#endif
-
-#else /* CONFIG_CPU_IDLE */
-
-/**
- * acpi_idle_bm_check - checks if bus master activity was detected
- */
-static int acpi_idle_bm_check(void)
-{
- u32 bm_status = 0;
-
- acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
- if (bm_status)
- acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
- /*
- * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
- * the true state of bus mastering activity; forcing us to
- * manually check the BMIDEA bit of each IDE channel.
- */
- else if (errata.piix4.bmisx) {
- if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
- || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
- bm_status = 1;
- }
- return bm_status;
-}
-
-/**
- * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state
- * @pr: the processor
- * @target: the new target state
- */
-static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr,
- struct acpi_processor_cx *target)
-{
- if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) {
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
- pr->flags.bm_rld_set = 0;
- }
-
- if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) {
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
- pr->flags.bm_rld_set = 1;
- }
-}
-
-/**
- * acpi_idle_do_entry - a helper function that does C2 and C3 type entry
- * @cx: cstate data
- */
-static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
-{
- if (cx->space_id == ACPI_CSTATE_FFH) {
- /* Call into architectural FFH based C-state */
- acpi_processor_ffh_cstate_enter(cx);
- } else {
- int unused;
- /* IO port based C-state */
- inb(cx->address);
- /* Dummy wait op - must do something useless after P_LVL2 read
- because chipsets cannot guarantee that STPCLK# signal
- gets asserted in time to freeze execution properly. */
- unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
- }
-}
-
-/**
- * acpi_idle_enter_c1 - enters an ACPI C1 state-type
- * @dev: the target CPU
- * @state: the state data
- *
- * This is equivalent to the HALT instruction.
- */
-static int acpi_idle_enter_c1(struct cpuidle_device *dev,
- struct cpuidle_state *state)
-{
- struct acpi_processor *pr;
- struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
- pr = processors[smp_processor_id()];
-
- if (unlikely(!pr))
- return 0;
-
- if (pr->flags.bm_check)
- acpi_idle_update_bm_rld(pr, cx);
-
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we test
- * NEED_RESCHED:
- */
- smp_mb();
- if (!need_resched())
- safe_halt();
- current_thread_info()->status |= TS_POLLING;
-
- cx->usage++;
-
- return 0;
-}
-
-/**
- * acpi_idle_enter_simple - enters an ACPI state without BM handling
- * @dev: the target CPU
- * @state: the state data
- */
-static int acpi_idle_enter_simple(struct cpuidle_device *dev,
- struct cpuidle_state *state)
-{
- struct acpi_processor *pr;
- struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
- u32 t1, t2;
- pr = processors[smp_processor_id()];
-
- if (unlikely(!pr))
- return 0;
-
- if (acpi_idle_suspend)
- return(acpi_idle_enter_c1(dev, state));
-
- if (pr->flags.bm_check)
- acpi_idle_update_bm_rld(pr, cx);
-
- local_irq_disable();
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we test
- * NEED_RESCHED:
- */
- smp_mb();
-
- if (unlikely(need_resched())) {
- current_thread_info()->status |= TS_POLLING;
- local_irq_enable();
- return 0;
- }
-
- if (cx->type == ACPI_STATE_C3)
- ACPI_FLUSH_CPU_CACHE();
-
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- acpi_state_timer_broadcast(pr, cx, 1);
- acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
- /* TSC could halt in idle, so notify users */
- mark_tsc_unstable("TSC halts in idle");;
-#endif
-
- local_irq_enable();
- current_thread_info()->status |= TS_POLLING;
-
- cx->usage++;
-
- acpi_state_timer_broadcast(pr, cx, 0);
- cx->time += ticks_elapsed(t1, t2);
- return ticks_elapsed_in_us(t1, t2);
-}
-
-static int c3_cpu_count;
-static DEFINE_SPINLOCK(c3_lock);
-
-/**
- * acpi_idle_enter_bm - enters C3 with proper BM handling
- * @dev: the target CPU
- * @state: the state data
- *
- * If BM is detected, the deepest non-C3 idle state is entered instead.
- */
-static int acpi_idle_enter_bm(struct cpuidle_device *dev,
- struct cpuidle_state *state)
-{
- struct acpi_processor *pr;
- struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
- u32 t1, t2;
- pr = processors[smp_processor_id()];
-
- if (unlikely(!pr))
- return 0;
-
- if (acpi_idle_suspend)
- return(acpi_idle_enter_c1(dev, state));
-
- local_irq_disable();
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we test
- * NEED_RESCHED:
- */
- smp_mb();
-
- if (unlikely(need_resched())) {
- current_thread_info()->status |= TS_POLLING;
- local_irq_enable();
- return 0;
- }
-
- /*
- * Must be done before busmaster disable as we might need to
- * access HPET !
- */
- acpi_state_timer_broadcast(pr, cx, 1);
-
- if (acpi_idle_bm_check()) {
- cx = pr->power.bm_state;
-
- acpi_idle_update_bm_rld(pr, cx);
-
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- } else {
- acpi_idle_update_bm_rld(pr, cx);
-
- spin_lock(&c3_lock);
- c3_cpu_count++;
- /* Disable bus master arbitration when all CPUs are in C3 */
- if (c3_cpu_count == num_online_cpus())
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
- spin_unlock(&c3_lock);
-
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
- acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-
- spin_lock(&c3_lock);
- /* Re-enable bus master arbitration */
- if (c3_cpu_count == num_online_cpus())
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
- c3_cpu_count--;
- spin_unlock(&c3_lock);
- }
-
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
- /* TSC could halt in idle, so notify users */
- mark_tsc_unstable("TSC halts in idle");
-#endif
-
- local_irq_enable();
- current_thread_info()->status |= TS_POLLING;
-
- cx->usage++;
-
- acpi_state_timer_broadcast(pr, cx, 0);
- cx->time += ticks_elapsed(t1, t2);
- return ticks_elapsed_in_us(t1, t2);
-}
-
-struct cpuidle_driver acpi_idle_driver = {
- .name = "acpi_idle",
- .owner = THIS_MODULE,
-};
-
-/**
- * acpi_processor_setup_cpuidle - prepares and configures CPUIDLE
- * @pr: the ACPI processor
- */
-static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
-{
- int i, count = 0;
- struct acpi_processor_cx *cx;
- struct cpuidle_state *state;
- struct cpuidle_device *dev = &pr->power.dev;
-
- if (!pr->flags.power_setup_done)
- return -EINVAL;
-
- if (pr->flags.power == 0) {
- return -EINVAL;
- }
-
- for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
- cx = &pr->power.states[i];
- state = &dev->states[count];
-
- if (!cx->valid)
- continue;
-
-#ifdef CONFIG_HOTPLUG_CPU
- if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
- !pr->flags.has_cst &&
- !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
- continue;
#endif
- cpuidle_set_statedata(state, cx);
-
- snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i);
- state->exit_latency = cx->latency;
- state->target_residency = cx->latency * 6;
- state->power_usage = cx->power;
-
- state->flags = 0;
- switch (cx->type) {
- case ACPI_STATE_C1:
- state->flags |= CPUIDLE_FLAG_SHALLOW;
- state->enter = acpi_idle_enter_c1;
- break;
-
- case ACPI_STATE_C2:
- state->flags |= CPUIDLE_FLAG_BALANCED;
- state->flags |= CPUIDLE_FLAG_TIME_VALID;
- state->enter = acpi_idle_enter_simple;
- break;
-
- case ACPI_STATE_C3:
- state->flags |= CPUIDLE_FLAG_DEEP;
- state->flags |= CPUIDLE_FLAG_TIME_VALID;
- state->flags |= CPUIDLE_FLAG_CHECK_BM;
- state->enter = pr->flags.bm_check ?
- acpi_idle_enter_bm :
- acpi_idle_enter_simple;
- break;
- }
-
- count++;
- }
-
- dev->state_count = count;
-
- if (!count)
- return -EINVAL;
-
- /* find the deepest state that can handle active BM */
- if (pr->flags.bm_check) {
- for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++)
- if (pr->power.states[i].type == ACPI_STATE_C3)
- break;
- pr->power.bm_state = &pr->power.states[i-1];
- }
-
- return 0;
-}
-
-int acpi_processor_cst_has_changed(struct acpi_processor *pr)
-{
- int ret;
-
- if (!pr)
- return -EINVAL;
-
- if (nocst) {
- return -ENODEV;
- }
-
- if (!pr->flags.power_setup_done)
- return -ENODEV;
-
- cpuidle_pause_and_lock();
- cpuidle_disable_device(&pr->power.dev);
- acpi_processor_get_power_info(pr);
- acpi_processor_setup_cpuidle(pr);
- ret = cpuidle_enable_device(&pr->power.dev);
- cpuidle_resume_and_unlock();
-
- return ret;
-}
-
-#endif /* CONFIG_CPU_IDLE */
int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
struct acpi_device *device)
@@ -1663,7 +1267,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
"ACPI: processor limited to max C-state %d\n",
max_cstate);
first_run++;
-#if !defined (CONFIG_CPU_IDLE) && defined (CONFIG_SMP)
+#ifdef CONFIG_SMP
register_latency_notifier(&acpi_processor_latency_notifier);
#endif
}
@@ -1681,7 +1285,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
}
acpi_processor_get_power_info(pr);
- pr->flags.power_setup_done = 1;
/*
* Install the idle handler if processor power management is supported.
@@ -1689,13 +1292,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
* platforms that only support C1.
*/
if ((pr->flags.power) && (!boot_option_idle_override)) {
-#ifdef CONFIG_CPU_IDLE
- acpi_processor_setup_cpuidle(pr);
- pr->power.dev.cpu = pr->id;
- if (cpuidle_register_device(&pr->power.dev))
- return -EIO;
-#endif
-
printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id);
for (i = 1; i <= pr->power.count; i++)
if (pr->power.states[i].valid)
@@ -1703,12 +1299,10 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
pr->power.states[i].type);
printk(")\n");
-#ifndef CONFIG_CPU_IDLE
if (pr->id == 0) {
pm_idle_save = pm_idle;
pm_idle = acpi_processor_idle;
}
-#endif
}
/* 'power' [R] */
@@ -1722,24 +1316,21 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
entry->owner = THIS_MODULE;
}
+ pr->flags.power_setup_done = 1;
+
return 0;
}
int acpi_processor_power_exit(struct acpi_processor *pr,
struct acpi_device *device)
{
-#ifdef CONFIG_CPU_IDLE
- if ((pr->flags.power) && (!boot_option_idle_override))
- cpuidle_unregister_device(&pr->power.dev);
-#endif
+
pr->flags.power_setup_done = 0;
if (acpi_device_dir(device))
remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,
acpi_device_dir(device));
-#ifndef CONFIG_CPU_IDLE
-
/* Unregister the idle handler when processor #0 is removed. */
if (pr->id == 0) {
pm_idle = pm_idle_save;
@@ -1754,7 +1345,6 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
unregister_latency_notifier(&acpi_processor_latency_notifier);
#endif
}
-#endif
return 0;
}
diff --git a/trunk/drivers/acpi/sbs.c b/trunk/drivers/acpi/sbs.c
index 90fd09c65f95..a578986e3214 100644
--- a/trunk/drivers/acpi/sbs.c
+++ b/trunk/drivers/acpi/sbs.c
@@ -1,8 +1,6 @@
/*
- * sbs.c - ACPI Smart Battery System Driver ($Revision: 2.0 $)
+ * acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $)
*
- * Copyright (c) 2007 Alexey Starikovskiy
- * Copyright (c) 2005-2007 Vladimir Lebedev
* Copyright (c) 2005 Rich Townsend
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -28,22 +26,15 @@
#include
#include
#include
-
-#ifdef CONFIG_ACPI_PROCFS
#include
#include
#include
-#endif
-
#include
#include
#include
#include
-#include
-
-#include "sbshc.h"
-
+#define ACPI_SBS_COMPONENT 0x00080000
#define ACPI_SBS_CLASS "sbs"
#define ACPI_AC_CLASS "ac_adapter"
#define ACPI_BATTERY_CLASS "battery"
@@ -53,436 +44,836 @@
#define ACPI_SBS_FILE_ALARM "alarm"
#define ACPI_BATTERY_DIR_NAME "BAT%i"
#define ACPI_AC_DIR_NAME "AC0"
+#define ACPI_SBC_SMBUS_ADDR 0x9
+#define ACPI_SBSM_SMBUS_ADDR 0xa
+#define ACPI_SB_SMBUS_ADDR 0xb
+#define ACPI_SBS_AC_NOTIFY_STATUS 0x80
+#define ACPI_SBS_BATTERY_NOTIFY_STATUS 0x80
+#define ACPI_SBS_BATTERY_NOTIFY_INFO 0x81
-enum acpi_sbs_device_addr {
- ACPI_SBS_CHARGER = 0x9,
- ACPI_SBS_MANAGER = 0xa,
- ACPI_SBS_BATTERY = 0xb,
-};
+#define _COMPONENT ACPI_SBS_COMPONENT
-#define ACPI_SBS_NOTIFY_STATUS 0x80
-#define ACPI_SBS_NOTIFY_INFO 0x81
+ACPI_MODULE_NAME("sbs");
-MODULE_AUTHOR("Alexey Starikovskiy ");
+MODULE_AUTHOR("Rich Townsend");
MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
MODULE_LICENSE("GPL");
-static unsigned int cache_time = 1000;
-module_param(cache_time, uint, 0644);
-MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
+#define xmsleep(t) msleep(t)
+
+#define ACPI_EC_SMB_PRTCL 0x00 /* protocol, PEC */
+
+#define ACPI_EC_SMB_STS 0x01 /* status */
+#define ACPI_EC_SMB_ADDR 0x02 /* address */
+#define ACPI_EC_SMB_CMD 0x03 /* command */
+#define ACPI_EC_SMB_DATA 0x04 /* 32 data registers */
+#define ACPI_EC_SMB_BCNT 0x24 /* number of data bytes */
+
+#define ACPI_EC_SMB_STS_DONE 0x80
+#define ACPI_EC_SMB_STS_STATUS 0x1f
+
+#define ACPI_EC_SMB_PRTCL_WRITE 0x00
+#define ACPI_EC_SMB_PRTCL_READ 0x01
+#define ACPI_EC_SMB_PRTCL_WORD_DATA 0x08
+#define ACPI_EC_SMB_PRTCL_BLOCK_DATA 0x0a
+
+#define ACPI_EC_SMB_TRANSACTION_SLEEP 1
+#define ACPI_EC_SMB_ACCESS_SLEEP1 1
+#define ACPI_EC_SMB_ACCESS_SLEEP2 10
+
+#define DEF_CAPACITY_UNIT 3
+#define MAH_CAPACITY_UNIT 1
+#define MWH_CAPACITY_UNIT 2
+#define CAPACITY_UNIT DEF_CAPACITY_UNIT
+
+#define REQUEST_UPDATE_MODE 1
+#define QUEUE_UPDATE_MODE 2
+
+#define DATA_TYPE_COMMON 0
+#define DATA_TYPE_INFO 1
+#define DATA_TYPE_STATE 2
+#define DATA_TYPE_ALARM 3
+#define DATA_TYPE_AC_STATE 4
extern struct proc_dir_entry *acpi_lock_ac_dir(void);
extern struct proc_dir_entry *acpi_lock_battery_dir(void);
extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
-#define MAX_SBS_BAT 4
+#define MAX_SBS_BAT 4
#define ACPI_SBS_BLOCK_MAX 32
+#define ACPI_SBS_SMBUS_READ 1
+#define ACPI_SBS_SMBUS_WRITE 2
+
+#define ACPI_SBS_WORD_DATA 1
+#define ACPI_SBS_BLOCK_DATA 2
+
+#define UPDATE_DELAY 10
+
+/* 0 - every time, > 0 - by update_time */
+static unsigned int update_time = 120;
+
+static unsigned int capacity_mode = CAPACITY_UNIT;
+
+module_param(update_time, uint, 0644);
+module_param(capacity_mode, uint, 0444);
+
+static int acpi_sbs_add(struct acpi_device *device);
+static int acpi_sbs_remove(struct acpi_device *device, int type);
+static int acpi_sbs_resume(struct acpi_device *device);
+
static const struct acpi_device_id sbs_device_ids[] = {
- {"ACPI0002", 0},
+ {"ACPI0001", 0},
+ {"ACPI0005", 0},
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
+static struct acpi_driver acpi_sbs_driver = {
+ .name = "sbs",
+ .class = ACPI_SBS_CLASS,
+ .ids = sbs_device_ids,
+ .ops = {
+ .add = acpi_sbs_add,
+ .remove = acpi_sbs_remove,
+ .resume = acpi_sbs_resume,
+ },
+};
+
+struct acpi_ac {
+ int ac_present;
+};
+
+struct acpi_battery_info {
+ int capacity_mode;
+ s16 full_charge_capacity;
+ s16 design_capacity;
+ s16 design_voltage;
+ int vscale;
+ int ipscale;
+ s16 serial_number;
+ char manufacturer_name[ACPI_SBS_BLOCK_MAX + 3];
+ char device_name[ACPI_SBS_BLOCK_MAX + 3];
+ char device_chemistry[ACPI_SBS_BLOCK_MAX + 3];
+};
+
+struct acpi_battery_state {
+ s16 voltage;
+ s16 amperage;
+ s16 remaining_capacity;
+ s16 battery_state;
+};
+
+struct acpi_battery_alarm {
+ s16 remaining_capacity;
+};
+
struct acpi_battery {
- struct power_supply bat;
+ int alive;
+ int id;
+ int init_state;
+ int battery_present;
struct acpi_sbs *sbs;
-#ifdef CONFIG_ACPI_PROCFS
- struct proc_dir_entry *proc_entry;
-#endif
- unsigned long update_time;
- char name[8];
- char manufacturer_name[ACPI_SBS_BLOCK_MAX];
- char device_name[ACPI_SBS_BLOCK_MAX];
- char device_chemistry[ACPI_SBS_BLOCK_MAX];
- u16 alarm_capacity;
- u16 full_charge_capacity;
- u16 design_capacity;
- u16 design_voltage;
- u16 serial_number;
- u16 cycle_count;
- u16 temp_now;
- u16 voltage_now;
- s16 current_now;
- s16 current_avg;
- u16 capacity_now;
- u16 state_of_charge;
- u16 state;
- u16 mode;
- u16 spec;
- u8 id;
- u8 present:1;
+ struct acpi_battery_info info;
+ struct acpi_battery_state state;
+ struct acpi_battery_alarm alarm;
+ struct proc_dir_entry *battery_entry;
};
-#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
-
struct acpi_sbs {
- struct power_supply charger;
+ int base;
struct acpi_device *device;
- struct acpi_smb_hc *hc;
- struct mutex lock;
-#ifdef CONFIG_ACPI_PROCFS
- struct proc_dir_entry *charger_entry;
-#endif
+ struct mutex mutex;
+ int sbsm_present;
+ int sbsm_batteries_supported;
+ struct proc_dir_entry *ac_entry;
+ struct acpi_ac ac;
struct acpi_battery battery[MAX_SBS_BAT];
- u8 batteries_supported:4;
- u8 manager_present:1;
- u8 charger_present:1;
+ int zombie;
+ struct timer_list update_timer;
+ int run_cnt;
+ int update_proc_flg;
};
-#define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger)
+static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type);
+static void acpi_sbs_update_time(void *data);
-static inline int battery_scale(int log)
+union sbs_rw_data {
+ u16 word;
+ u8 block[ACPI_SBS_BLOCK_MAX + 2];
+};
+
+static int acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
+ char read_write, u8 command, int size,
+ union sbs_rw_data *data);
+
+/* --------------------------------------------------------------------------
+ SMBus Communication
+ -------------------------------------------------------------------------- */
+
+static int acpi_ec_sbs_read(struct acpi_sbs *sbs, u8 address, u8 * data)
+{
+ u8 val;
+ int err;
+
+ err = ec_read(sbs->base + address, &val);
+ if (!err) {
+ *data = val;
+ }
+ xmsleep(ACPI_EC_SMB_TRANSACTION_SLEEP);
+ return (err);
+}
+
+static int acpi_ec_sbs_write(struct acpi_sbs *sbs, u8 address, u8 data)
{
- int scale = 1;
- while (log--)
- scale *= 10;
- return scale;
+ int err;
+
+ err = ec_write(sbs->base + address, data);
+ return (err);
+}
+
+static int
+acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
+ char read_write, u8 command, int size,
+ union sbs_rw_data *data)
+{
+ unsigned char protocol, len = 0, temp[2] = { 0, 0 };
+ int i;
+
+ if (read_write == ACPI_SBS_SMBUS_READ) {
+ protocol = ACPI_EC_SMB_PRTCL_READ;
+ } else {
+ protocol = ACPI_EC_SMB_PRTCL_WRITE;
+ }
+
+ switch (size) {
+
+ case ACPI_SBS_WORD_DATA:
+ acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command);
+ if (read_write == ACPI_SBS_SMBUS_WRITE) {
+ acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA, data->word);
+ acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + 1,
+ data->word >> 8);
+ }
+ protocol |= ACPI_EC_SMB_PRTCL_WORD_DATA;
+ break;
+ case ACPI_SBS_BLOCK_DATA:
+ acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command);
+ if (read_write == ACPI_SBS_SMBUS_WRITE) {
+ len = min_t(u8, data->block[0], 32);
+ acpi_ec_sbs_write(sbs, ACPI_EC_SMB_BCNT, len);
+ for (i = 0; i < len; i++)
+ acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + i,
+ data->block[i + 1]);
+ }
+ protocol |= ACPI_EC_SMB_PRTCL_BLOCK_DATA;
+ break;
+ default:
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "unsupported transaction %d", size));
+ return (-1);
+ }
+
+ acpi_ec_sbs_write(sbs, ACPI_EC_SMB_ADDR, addr << 1);
+ acpi_ec_sbs_write(sbs, ACPI_EC_SMB_PRTCL, protocol);
+
+ acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
+
+ if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
+ xmsleep(ACPI_EC_SMB_ACCESS_SLEEP1);
+ acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
+ }
+ if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
+ xmsleep(ACPI_EC_SMB_ACCESS_SLEEP2);
+ acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
+ }
+ if ((~temp[0] & ACPI_EC_SMB_STS_DONE)
+ || (temp[0] & ACPI_EC_SMB_STS_STATUS)) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "transaction %d error", size));
+ return (-1);
+ }
+
+ if (read_write == ACPI_SBS_SMBUS_WRITE) {
+ return (0);
+ }
+
+ switch (size) {
+
+ case ACPI_SBS_WORD_DATA:
+ acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA, temp);
+ acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + 1, temp + 1);
+ data->word = (temp[1] << 8) | temp[0];
+ break;
+
+ case ACPI_SBS_BLOCK_DATA:
+ len = 0;
+ acpi_ec_sbs_read(sbs, ACPI_EC_SMB_BCNT, &len);
+ len = min_t(u8, len, 32);
+ for (i = 0; i < len; i++)
+ acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + i,
+ data->block + i + 1);
+ data->block[0] = len;
+ break;
+ default:
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "unsupported transaction %d", size));
+ return (-1);
+ }
+
+ return (0);
}
-static inline int acpi_battery_vscale(struct acpi_battery *battery)
+static int
+acpi_sbs_read_word(struct acpi_sbs *sbs, int addr, int func, u16 * word)
{
- return battery_scale((battery->spec & 0x0f00) >> 8);
+ union sbs_rw_data data;
+ int result = 0;
+
+ result = acpi_ec_sbs_access(sbs, addr,
+ ACPI_SBS_SMBUS_READ, func,
+ ACPI_SBS_WORD_DATA, &data);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_ec_sbs_access() failed"));
+ } else {
+ *word = data.word;
+ }
+
+ return result;
}
-static inline int acpi_battery_ipscale(struct acpi_battery *battery)
+static int
+acpi_sbs_read_str(struct acpi_sbs *sbs, int addr, int func, char *str)
{
- return battery_scale((battery->spec & 0xf000) >> 12);
+ union sbs_rw_data data;
+ int result = 0;
+
+ result = acpi_ec_sbs_access(sbs, addr,
+ ACPI_SBS_SMBUS_READ, func,
+ ACPI_SBS_BLOCK_DATA, &data);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_ec_sbs_access() failed"));
+ } else {
+ strncpy(str, (const char *)data.block + 1, data.block[0]);
+ str[data.block[0]] = 0;
+ }
+
+ return result;
}
-static inline int acpi_battery_mode(struct acpi_battery *battery)
+static int
+acpi_sbs_write_word(struct acpi_sbs *sbs, int addr, int func, int word)
{
- return (battery->mode & 0x8000);
+ union sbs_rw_data data;
+ int result = 0;
+
+ data.word = word;
+
+ result = acpi_ec_sbs_access(sbs, addr,
+ ACPI_SBS_SMBUS_WRITE, func,
+ ACPI_SBS_WORD_DATA, &data);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_ec_sbs_access() failed"));
+ }
+
+ return result;
}
-static inline int acpi_battery_scale(struct acpi_battery *battery)
+static int sbs_zombie(struct acpi_sbs *sbs)
{
- return (acpi_battery_mode(battery) ? 10 : 1) *
- acpi_battery_ipscale(battery);
+ return (sbs->zombie);
}
-static int sbs_get_ac_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
+static int sbs_mutex_lock(struct acpi_sbs *sbs)
{
- struct acpi_sbs *sbs = to_acpi_sbs(psy);
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = sbs->charger_present;
- break;
- default:
- return -EINVAL;
+ if (sbs_zombie(sbs)) {
+ return -ENODEV;
}
+ mutex_lock(&sbs->mutex);
return 0;
}
-static int acpi_battery_technology(struct acpi_battery *battery)
+static void sbs_mutex_unlock(struct acpi_sbs *sbs)
{
- if (!strcasecmp("NiCd", battery->device_chemistry))
- return POWER_SUPPLY_TECHNOLOGY_NiCd;
- if (!strcasecmp("NiMH", battery->device_chemistry))
- return POWER_SUPPLY_TECHNOLOGY_NiMH;
- if (!strcasecmp("LION", battery->device_chemistry))
- return POWER_SUPPLY_TECHNOLOGY_LION;
- if (!strcasecmp("LiP", battery->device_chemistry))
- return POWER_SUPPLY_TECHNOLOGY_LIPO;
- return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
+ mutex_unlock(&sbs->mutex);
}
-static int acpi_sbs_battery_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
+/* --------------------------------------------------------------------------
+ Smart Battery System Management
+ -------------------------------------------------------------------------- */
+
+static int acpi_check_update_proc(struct acpi_sbs *sbs)
{
- struct acpi_battery *battery = to_acpi_battery(psy);
+ acpi_status status = AE_OK;
- if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT)
- return -ENODEV;
- switch (psp) {
- case POWER_SUPPLY_PROP_STATUS:
- if (battery->current_now < 0)
- val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
- else if (battery->current_now > 0)
- val->intval = POWER_SUPPLY_STATUS_CHARGING;
- else
- val->intval = POWER_SUPPLY_STATUS_FULL;
- break;
- case POWER_SUPPLY_PROP_PRESENT:
- val->intval = battery->present;
- break;
- case POWER_SUPPLY_PROP_TECHNOLOGY:
- val->intval = acpi_battery_technology(battery);
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
- val->intval = battery->design_voltage *
- acpi_battery_vscale(battery) * 1000;
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = battery->voltage_now *
- acpi_battery_vscale(battery) * 1000;
- break;
- case POWER_SUPPLY_PROP_CURRENT_NOW:
- val->intval = abs(battery->current_now) *
- acpi_battery_ipscale(battery) * 1000;
- break;
- case POWER_SUPPLY_PROP_CURRENT_AVG:
- val->intval = abs(battery->current_avg) *
- acpi_battery_ipscale(battery) * 1000;
- break;
- case POWER_SUPPLY_PROP_CAPACITY:
- val->intval = battery->state_of_charge;
- break;
- case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
- case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
- val->intval = battery->design_capacity *
- acpi_battery_scale(battery) * 1000;
- break;
- case POWER_SUPPLY_PROP_CHARGE_FULL:
- case POWER_SUPPLY_PROP_ENERGY_FULL:
- val->intval = battery->full_charge_capacity *
- acpi_battery_scale(battery) * 1000;
- break;
- case POWER_SUPPLY_PROP_CHARGE_NOW:
- case POWER_SUPPLY_PROP_ENERGY_NOW:
- val->intval = battery->capacity_now *
- acpi_battery_scale(battery) * 1000;
- break;
- case POWER_SUPPLY_PROP_TEMP:
- val->intval = battery->temp_now - 2730; // dK -> dC
- break;
- case POWER_SUPPLY_PROP_MODEL_NAME:
- val->strval = battery->device_name;
- break;
- case POWER_SUPPLY_PROP_MANUFACTURER:
- val->strval = battery->manufacturer_name;
- break;
- default:
- return -EINVAL;
+ if (update_time == 0) {
+ sbs->update_proc_flg = 0;
+ return 0;
+ }
+ if (sbs->update_proc_flg == 0) {
+ status = acpi_os_execute(OSL_GPE_HANDLER,
+ acpi_sbs_update_time, sbs);
+ if (status != AE_OK) {
+ ACPI_EXCEPTION((AE_INFO, status,
+ "acpi_os_execute() failed"));
+ return 1;
+ }
+ sbs->update_proc_flg = 1;
}
return 0;
}
-static enum power_supply_property sbs_ac_props[] = {
- POWER_SUPPLY_PROP_ONLINE,
-};
+static int acpi_sbs_generate_event(struct acpi_device *device,
+ int event, int state, char *bid, char *class)
+{
+ char bid_saved[5];
+ char class_saved[20];
+ int result = 0;
-static enum power_supply_property sbs_charge_battery_props[] = {
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_TECHNOLOGY,
- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_CURRENT_NOW,
- POWER_SUPPLY_PROP_CURRENT_AVG,
- POWER_SUPPLY_PROP_CAPACITY,
- POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
- POWER_SUPPLY_PROP_CHARGE_FULL,
- POWER_SUPPLY_PROP_CHARGE_NOW,
- POWER_SUPPLY_PROP_TEMP,
- POWER_SUPPLY_PROP_MODEL_NAME,
- POWER_SUPPLY_PROP_MANUFACTURER,
-};
+ strcpy(bid_saved, acpi_device_bid(device));
+ strcpy(class_saved, acpi_device_class(device));
-static enum power_supply_property sbs_energy_battery_props[] = {
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_PRESENT,
- POWER_SUPPLY_PROP_TECHNOLOGY,
- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_CURRENT_NOW,
- POWER_SUPPLY_PROP_CURRENT_AVG,
- POWER_SUPPLY_PROP_CAPACITY,
- POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
- POWER_SUPPLY_PROP_ENERGY_FULL,
- POWER_SUPPLY_PROP_ENERGY_NOW,
- POWER_SUPPLY_PROP_TEMP,
- POWER_SUPPLY_PROP_MODEL_NAME,
- POWER_SUPPLY_PROP_MANUFACTURER,
-};
+ strcpy(acpi_device_bid(device), bid);
+ strcpy(acpi_device_class(device), class);
-/* --------------------------------------------------------------------------
- Smart Battery System Management
- -------------------------------------------------------------------------- */
+ result = acpi_bus_generate_proc_event(device, event, state);
-struct acpi_battery_reader {
- u8 command; /* command for battery */
- u8 mode; /* word or block? */
- size_t offset; /* offset inside struct acpi_sbs_battery */
-};
+ strcpy(acpi_device_bid(device), bid_saved);
+ strcpy(acpi_device_class(device), class_saved);
-static struct acpi_battery_reader info_readers[] = {
- {0x01, SMBUS_READ_WORD, offsetof(struct acpi_battery, alarm_capacity)},
- {0x03, SMBUS_READ_WORD, offsetof(struct acpi_battery, mode)},
- {0x10, SMBUS_READ_WORD, offsetof(struct acpi_battery, full_charge_capacity)},
- {0x17, SMBUS_READ_WORD, offsetof(struct acpi_battery, cycle_count)},
- {0x18, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_capacity)},
- {0x19, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_voltage)},
- {0x1a, SMBUS_READ_WORD, offsetof(struct acpi_battery, spec)},
- {0x1c, SMBUS_READ_WORD, offsetof(struct acpi_battery, serial_number)},
- {0x20, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, manufacturer_name)},
- {0x21, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_name)},
- {0x22, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_chemistry)},
-};
+ acpi_bus_generate_netlink_event(class, bid, event, state);
+ return result;
+}
-static struct acpi_battery_reader state_readers[] = {
- {0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
- {0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
- {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
- {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
- {0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
- {0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
- {0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
-};
+static int acpi_battery_get_present(struct acpi_battery *battery)
+{
+ s16 state;
+ int result = 0;
+ int is_present = 0;
+
+ result = acpi_sbs_read_word(battery->sbs,
+ ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ }
+ if (!result) {
+ is_present = (state & 0x000f) & (1 << battery->id);
+ }
+ battery->battery_present = is_present;
+
+ return result;
+}
+
+static int acpi_battery_select(struct acpi_battery *battery)
+{
+ struct acpi_sbs *sbs = battery->sbs;
+ int result = 0;
+ s16 state;
+ int foo;
+
+ if (sbs->sbsm_present) {
+
+ /* Take special care not to knobble other nibbles of
+ * state (aka selector_state), since
+ * it causes charging to halt on SBSELs */
+
+ result =
+ acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+
+ foo = (state & 0x0fff) | (1 << (battery->id + 12));
+ result =
+ acpi_sbs_write_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, foo);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_write_word() failed"));
+ goto end;
+ }
+ }
+
+ end:
+ return result;
+}
-static int acpi_manager_get_info(struct acpi_sbs *sbs)
+static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
{
int result = 0;
- u16 battery_system_info;
+ s16 battery_system_info;
+
+ result = acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x04,
+ &battery_system_info);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+ sbs->sbsm_present = 1;
+ sbs->sbsm_batteries_supported = battery_system_info & 0x000f;
+
+ end:
- result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
- 0x04, (u8 *)&battery_system_info);
- if (!result)
- sbs->batteries_supported = battery_system_info & 0x000f;
return result;
}
static int acpi_battery_get_info(struct acpi_battery *battery)
{
- int i, result = 0;
-
- for (i = 0; i < ARRAY_SIZE(info_readers); ++i) {
- result = acpi_smbus_read(battery->sbs->hc,
- info_readers[i].mode,
- ACPI_SBS_BATTERY,
- info_readers[i].command,
- (u8 *) battery +
- info_readers[i].offset);
- if (result)
- break;
+ struct acpi_sbs *sbs = battery->sbs;
+ int result = 0;
+ s16 battery_mode;
+ s16 specification_info;
+
+ result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
+ &battery_mode);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+ battery->info.capacity_mode = (battery_mode & 0x8000) >> 15;
+
+ result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x10,
+ &battery->info.full_charge_capacity);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+
+ result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x18,
+ &battery->info.design_capacity);
+
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+
+ result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x19,
+ &battery->info.design_voltage);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+
+ result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1a,
+ &specification_info);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+
+ switch ((specification_info & 0x0f00) >> 8) {
+ case 1:
+ battery->info.vscale = 10;
+ break;
+ case 2:
+ battery->info.vscale = 100;
+ break;
+ case 3:
+ battery->info.vscale = 1000;
+ break;
+ default:
+ battery->info.vscale = 1;
+ }
+
+ switch ((specification_info & 0xf000) >> 12) {
+ case 1:
+ battery->info.ipscale = 10;
+ break;
+ case 2:
+ battery->info.ipscale = 100;
+ break;
+ case 3:
+ battery->info.ipscale = 1000;
+ break;
+ default:
+ battery->info.ipscale = 1;
+ }
+
+ result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1c,
+ &battery->info.serial_number);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+
+ result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x20,
+ battery->info.manufacturer_name);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_str() failed"));
+ goto end;
+ }
+
+ result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x21,
+ battery->info.device_name);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_str() failed"));
+ goto end;
}
+
+ result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x22,
+ battery->info.device_chemistry);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_str() failed"));
+ goto end;
+ }
+
+ end:
return result;
}
static int acpi_battery_get_state(struct acpi_battery *battery)
{
- int i, result = 0;
+ struct acpi_sbs *sbs = battery->sbs;
+ int result = 0;
- if (battery->update_time &&
- time_before(jiffies, battery->update_time +
- msecs_to_jiffies(cache_time)))
- return 0;
- for (i = 0; i < ARRAY_SIZE(state_readers); ++i) {
- result = acpi_smbus_read(battery->sbs->hc,
- state_readers[i].mode,
- ACPI_SBS_BATTERY,
- state_readers[i].command,
- (u8 *)battery +
- state_readers[i].offset);
- if (result)
- goto end;
+ result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09,
+ &battery->state.voltage);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+
+ result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a,
+ &battery->state.amperage);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+
+ result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f,
+ &battery->state.remaining_capacity);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
}
+
+ result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16,
+ &battery->state.battery_state);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+
end:
- battery->update_time = jiffies;
return result;
}
static int acpi_battery_get_alarm(struct acpi_battery *battery)
{
- return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
- ACPI_SBS_BATTERY, 0x01,
- (u8 *)&battery->alarm_capacity);
+ struct acpi_sbs *sbs = battery->sbs;
+ int result = 0;
+
+ result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
+ &battery->alarm.remaining_capacity);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+
+ end:
+
+ return result;
}
-static int acpi_battery_set_alarm(struct acpi_battery *battery)
+static int acpi_battery_set_alarm(struct acpi_battery *battery,
+ unsigned long alarm)
{
struct acpi_sbs *sbs = battery->sbs;
- u16 value, sel = 1 << (battery->id + 12);
+ int result = 0;
+ s16 battery_mode;
+ int foo;
- int ret;
+ result = acpi_battery_select(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_select() failed"));
+ goto end;
+ }
+ /* If necessary, enable the alarm */
- if (sbs->manager_present) {
- ret = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
- 0x01, (u8 *)&value);
- if (ret)
+ if (alarm > 0) {
+ result =
+ acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
+ &battery_mode);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
goto end;
- if ((value & 0xf000) != sel) {
- value &= 0x0fff;
- value |= sel;
- ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD,
- ACPI_SBS_MANAGER,
- 0x01, (u8 *)&value, 2);
- if (ret)
+ }
+
+ result =
+ acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
+ battery_mode & 0xbfff);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_write_word() failed"));
goto end;
}
}
- ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, ACPI_SBS_BATTERY,
- 0x01, (u8 *)&battery->alarm_capacity, 2);
+
+ foo = alarm / (battery->info.capacity_mode ? 10 : 1);
+ result = acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, foo);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_write_word() failed"));
+ goto end;
+ }
+
end:
- return ret;
+
+ return result;
}
-static int acpi_ac_get_present(struct acpi_sbs *sbs)
+static int acpi_battery_set_mode(struct acpi_battery *battery)
{
- int result;
- u16 status;
+ struct acpi_sbs *sbs = battery->sbs;
+ int result = 0;
+ s16 battery_mode;
+
+ if (capacity_mode == DEF_CAPACITY_UNIT) {
+ goto end;
+ }
+
+ result = acpi_sbs_read_word(sbs,
+ ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+
+ if (capacity_mode == MAH_CAPACITY_UNIT) {
+ battery_mode &= 0x7fff;
+ } else {
+ battery_mode |= 0x8000;
+ }
+ result = acpi_sbs_write_word(sbs,
+ ACPI_SB_SMBUS_ADDR, 0x03, battery_mode);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_write_word() failed"));
+ goto end;
+ }
+
+ result = acpi_sbs_read_word(sbs,
+ ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
- result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_CHARGER,
- 0x13, (u8 *) & status);
- if (!result)
- sbs->charger_present = (status >> 15) & 0x1;
+ end:
return result;
}
-static ssize_t acpi_battery_alarm_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static int acpi_battery_init(struct acpi_battery *battery)
{
- struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
- acpi_battery_get_alarm(battery);
- return sprintf(buf, "%d\n", battery->alarm_capacity *
- acpi_battery_scale(battery) * 1000);
+ int result = 0;
+
+ result = acpi_battery_select(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_select() failed"));
+ goto end;
+ }
+
+ result = acpi_battery_set_mode(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_set_mode() failed"));
+ goto end;
+ }
+
+ result = acpi_battery_get_info(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_get_info() failed"));
+ goto end;
+ }
+
+ result = acpi_battery_get_state(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_get_state() failed"));
+ goto end;
+ }
+
+ result = acpi_battery_get_alarm(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_get_alarm() failed"));
+ goto end;
+ }
+
+ end:
+ return result;
}
-static ssize_t acpi_battery_alarm_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static int acpi_ac_get_present(struct acpi_sbs *sbs)
{
- unsigned long x;
- struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
- if (sscanf(buf, "%ld\n", &x) == 1)
- battery->alarm_capacity = x /
- (1000 * acpi_battery_scale(battery));
- if (battery->present)
- acpi_battery_set_alarm(battery);
- return count;
-}
+ int result = 0;
+ s16 charger_status;
-static struct device_attribute alarm_attr = {
- .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
- .show = acpi_battery_alarm_show,
- .store = acpi_battery_alarm_store,
-};
+ result = acpi_sbs_read_word(sbs, ACPI_SBC_SMBUS_ADDR, 0x13,
+ &charger_status);
+
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_read_word() failed"));
+ goto end;
+ }
+
+ sbs->ac.ac_present = (charger_status & 0x8000) >> 15;
+
+ end:
+
+ return result;
+}
/* --------------------------------------------------------------------------
FS Interface (/proc/acpi)
-------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_PROCFS
/* Generic Routines */
+
static int
-acpi_sbs_add_fs(struct proc_dir_entry **dir,
- struct proc_dir_entry *parent_dir,
- char *dir_name,
- struct file_operations *info_fops,
- struct file_operations *state_fops,
- struct file_operations *alarm_fops, void *data)
+acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
+ struct proc_dir_entry *parent_dir,
+ char *dir_name,
+ struct file_operations *info_fops,
+ struct file_operations *state_fops,
+ struct file_operations *alarm_fops, void *data)
{
struct proc_dir_entry *entry = NULL;
if (!*dir) {
*dir = proc_mkdir(dir_name, parent_dir);
if (!*dir) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "proc_mkdir() failed"));
return -ENODEV;
}
(*dir)->owner = THIS_MODULE;
@@ -491,7 +882,10 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir,
/* 'info' [R] */
if (info_fops) {
entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir);
- if (entry) {
+ if (!entry) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "create_proc_entry() failed"));
+ } else {
entry->proc_fops = info_fops;
entry->data = data;
entry->owner = THIS_MODULE;
@@ -501,7 +895,10 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir,
/* 'state' [R] */
if (state_fops) {
entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir);
- if (entry) {
+ if (!entry) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "create_proc_entry() failed"));
+ } else {
entry->proc_fops = state_fops;
entry->data = data;
entry->owner = THIS_MODULE;
@@ -511,19 +908,24 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir,
/* 'alarm' [R/W] */
if (alarm_fops) {
entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir);
- if (entry) {
+ if (!entry) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "create_proc_entry() failed"));
+ } else {
entry->proc_fops = alarm_fops;
entry->data = data;
entry->owner = THIS_MODULE;
}
}
+
return 0;
}
static void
-acpi_sbs_remove_fs(struct proc_dir_entry **dir,
+acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,
struct proc_dir_entry *parent_dir)
{
+
if (*dir) {
remove_proc_entry(ACPI_SBS_FILE_INFO, *dir);
remove_proc_entry(ACPI_SBS_FILE_STATE, *dir);
@@ -531,52 +933,82 @@ acpi_sbs_remove_fs(struct proc_dir_entry **dir,
remove_proc_entry((*dir)->name, parent_dir);
*dir = NULL;
}
+
}
/* Smart Battery Interface */
-static struct proc_dir_entry *acpi_battery_dir = NULL;
-
-static inline char *acpi_battery_units(struct acpi_battery *battery)
-{
- return acpi_battery_mode(battery) ? " mWh" : " mAh";
-}
+static struct proc_dir_entry *acpi_battery_dir = NULL;
static int acpi_battery_read_info(struct seq_file *seq, void *offset)
{
struct acpi_battery *battery = seq->private;
struct acpi_sbs *sbs = battery->sbs;
+ int cscale;
int result = 0;
- mutex_lock(&sbs->lock);
+ if (sbs_mutex_lock(sbs)) {
+ return -ENODEV;
+ }
- seq_printf(seq, "present: %s\n",
- (battery->present) ? "yes" : "no");
- if (!battery->present)
+ result = acpi_check_update_proc(sbs);
+ if (result)
goto end;
+ if (update_time == 0) {
+ result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_INFO);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_update_run() failed"));
+ }
+ }
+
+ if (battery->battery_present) {
+ seq_printf(seq, "present: yes\n");
+ } else {
+ seq_printf(seq, "present: no\n");
+ goto end;
+ }
+
+ if (battery->info.capacity_mode) {
+ cscale = battery->info.vscale * battery->info.ipscale;
+ } else {
+ cscale = battery->info.ipscale;
+ }
seq_printf(seq, "design capacity: %i%s\n",
- battery->design_capacity * acpi_battery_scale(battery),
- acpi_battery_units(battery));
+ battery->info.design_capacity * cscale,
+ battery->info.capacity_mode ? "0 mWh" : " mAh");
+
seq_printf(seq, "last full capacity: %i%s\n",
- battery->full_charge_capacity * acpi_battery_scale(battery),
- acpi_battery_units(battery));
+ battery->info.full_charge_capacity * cscale,
+ battery->info.capacity_mode ? "0 mWh" : " mAh");
+
seq_printf(seq, "battery technology: rechargeable\n");
+
seq_printf(seq, "design voltage: %i mV\n",
- battery->design_voltage * acpi_battery_vscale(battery));
+ battery->info.design_voltage * battery->info.vscale);
+
seq_printf(seq, "design capacity warning: unknown\n");
seq_printf(seq, "design capacity low: unknown\n");
seq_printf(seq, "capacity granularity 1: unknown\n");
seq_printf(seq, "capacity granularity 2: unknown\n");
- seq_printf(seq, "model number: %s\n", battery->device_name);
+
+ seq_printf(seq, "model number: %s\n",
+ battery->info.device_name);
+
seq_printf(seq, "serial number: %i\n",
- battery->serial_number);
+ battery->info.serial_number);
+
seq_printf(seq, "battery type: %s\n",
- battery->device_chemistry);
+ battery->info.device_chemistry);
+
seq_printf(seq, "OEM info: %s\n",
- battery->manufacturer_name);
+ battery->info.manufacturer_name);
+
end:
- mutex_unlock(&sbs->lock);
+
+ sbs_mutex_unlock(sbs);
+
return result;
}
@@ -590,29 +1022,73 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
struct acpi_battery *battery = seq->private;
struct acpi_sbs *sbs = battery->sbs;
int result = 0;
+ int cscale;
+ int foo;
+
+ if (sbs_mutex_lock(sbs)) {
+ return -ENODEV;
+ }
+
+ result = acpi_check_update_proc(sbs);
+ if (result)
+ goto end;
+
+ if (update_time == 0) {
+ result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_STATE);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_update_run() failed"));
+ }
+ }
- mutex_lock(&sbs->lock);
- seq_printf(seq, "present: %s\n",
- (battery->present) ? "yes" : "no");
- if (!battery->present)
+ if (battery->battery_present) {
+ seq_printf(seq, "present: yes\n");
+ } else {
+ seq_printf(seq, "present: no\n");
goto end;
+ }
+
+ if (battery->info.capacity_mode) {
+ cscale = battery->info.vscale * battery->info.ipscale;
+ } else {
+ cscale = battery->info.ipscale;
+ }
+
+ if (battery->state.battery_state & 0x0010) {
+ seq_printf(seq, "capacity state: critical\n");
+ } else {
+ seq_printf(seq, "capacity state: ok\n");
+ }
+
+ foo = (s16) battery->state.amperage * battery->info.ipscale;
+ if (battery->info.capacity_mode) {
+ foo = foo * battery->info.design_voltage / 1000;
+ }
+ if (battery->state.amperage < 0) {
+ seq_printf(seq, "charging state: discharging\n");
+ seq_printf(seq, "present rate: %d %s\n",
+ -foo, battery->info.capacity_mode ? "mW" : "mA");
+ } else if (battery->state.amperage > 0) {
+ seq_printf(seq, "charging state: charging\n");
+ seq_printf(seq, "present rate: %d %s\n",
+ foo, battery->info.capacity_mode ? "mW" : "mA");
+ } else {
+ seq_printf(seq, "charging state: charged\n");
+ seq_printf(seq, "present rate: 0 %s\n",
+ battery->info.capacity_mode ? "mW" : "mA");
+ }
- acpi_battery_get_state(battery);
- seq_printf(seq, "capacity state: %s\n",
- (battery->state & 0x0010) ? "critical" : "ok");
- seq_printf(seq, "charging state: %s\n",
- (battery->current_now < 0) ? "discharging" :
- ((battery->current_now > 0) ? "charging" : "charged"));
- seq_printf(seq, "present rate: %d mA\n",
- abs(battery->current_now) * acpi_battery_ipscale(battery));
seq_printf(seq, "remaining capacity: %i%s\n",
- battery->capacity_now * acpi_battery_scale(battery),
- acpi_battery_units(battery));
+ battery->state.remaining_capacity * cscale,
+ battery->info.capacity_mode ? "0 mWh" : " mAh");
+
seq_printf(seq, "present voltage: %i mV\n",
- battery->voltage_now * acpi_battery_vscale(battery));
+ battery->state.voltage * battery->info.vscale);
end:
- mutex_unlock(&sbs->lock);
+
+ sbs_mutex_unlock(sbs);
+
return result;
}
@@ -626,25 +1102,48 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
struct acpi_battery *battery = seq->private;
struct acpi_sbs *sbs = battery->sbs;
int result = 0;
+ int cscale;
+
+ if (sbs_mutex_lock(sbs)) {
+ return -ENODEV;
+ }
- mutex_lock(&sbs->lock);
+ result = acpi_check_update_proc(sbs);
+ if (result)
+ goto end;
+
+ if (update_time == 0) {
+ result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_ALARM);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_update_run() failed"));
+ }
+ }
- if (!battery->present) {
+ if (!battery->battery_present) {
seq_printf(seq, "present: no\n");
goto end;
}
- acpi_battery_get_alarm(battery);
+ if (battery->info.capacity_mode) {
+ cscale = battery->info.vscale * battery->info.ipscale;
+ } else {
+ cscale = battery->info.ipscale;
+ }
+
seq_printf(seq, "alarm: ");
- if (battery->alarm_capacity)
+ if (battery->alarm.remaining_capacity) {
seq_printf(seq, "%i%s\n",
- battery->alarm_capacity *
- acpi_battery_scale(battery),
- acpi_battery_units(battery));
- else
+ battery->alarm.remaining_capacity * cscale,
+ battery->info.capacity_mode ? "0 mWh" : " mAh");
+ } else {
seq_printf(seq, "disabled\n");
+ }
+
end:
- mutex_unlock(&sbs->lock);
+
+ sbs_mutex_unlock(sbs);
+
return result;
}
@@ -656,29 +1155,59 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
struct acpi_battery *battery = seq->private;
struct acpi_sbs *sbs = battery->sbs;
char alarm_string[12] = { '\0' };
- int result = 0;
- mutex_lock(&sbs->lock);
- if (!battery->present) {
+ int result, old_alarm, new_alarm;
+
+ if (sbs_mutex_lock(sbs)) {
+ return -ENODEV;
+ }
+
+ result = acpi_check_update_proc(sbs);
+ if (result)
+ goto end;
+
+ if (!battery->battery_present) {
result = -ENODEV;
goto end;
}
+
if (count > sizeof(alarm_string) - 1) {
result = -EINVAL;
goto end;
}
+
if (copy_from_user(alarm_string, buffer, count)) {
result = -EFAULT;
goto end;
}
+
alarm_string[count] = 0;
- battery->alarm_capacity = simple_strtoul(alarm_string, NULL, 0) /
- acpi_battery_scale(battery);
- acpi_battery_set_alarm(battery);
+
+ old_alarm = battery->alarm.remaining_capacity;
+ new_alarm = simple_strtoul(alarm_string, NULL, 0);
+
+ result = acpi_battery_set_alarm(battery, new_alarm);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_set_alarm() failed"));
+ acpi_battery_set_alarm(battery, old_alarm);
+ goto end;
+ }
+ result = acpi_battery_get_alarm(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_get_alarm() failed"));
+ acpi_battery_set_alarm(battery, old_alarm);
+ goto end;
+ }
+
end:
- mutex_unlock(&sbs->lock);
- if (result)
+ sbs_mutex_unlock(sbs);
+
+ if (result) {
return result;
- return count;
+ } else {
+ return count;
+ }
}
static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
@@ -717,15 +1246,26 @@ static struct proc_dir_entry *acpi_ac_dir = NULL;
static int acpi_ac_read_state(struct seq_file *seq, void *offset)
{
-
struct acpi_sbs *sbs = seq->private;
+ int result;
+
+ if (sbs_mutex_lock(sbs)) {
+ return -ENODEV;
+ }
- mutex_lock(&sbs->lock);
+ if (update_time == 0) {
+ result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_AC_STATE);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_update_run() failed"));
+ }
+ }
seq_printf(seq, "state: %s\n",
- sbs->charger_present ? "on-line" : "off-line");
+ sbs->ac.ac_present ? "on-line" : "off-line");
+
+ sbs_mutex_unlock(sbs);
- mutex_unlock(&sbs->lock);
return 0;
}
@@ -742,203 +1282,429 @@ static struct file_operations acpi_ac_state_fops = {
.owner = THIS_MODULE,
};
-#endif
-
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
-static int acpi_battery_read(struct acpi_battery *battery)
-{
- int result = 0, saved_present = battery->present;
- u16 state;
-
- if (battery->sbs->manager_present) {
- result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
- ACPI_SBS_MANAGER, 0x01, (u8 *)&state);
- if (!result)
- battery->present = state & (1 << battery->id);
- state &= 0x0fff;
- state |= 1 << (battery->id + 12);
- acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD,
- ACPI_SBS_MANAGER, 0x01, (u8 *)&state, 2);
- } else if (battery->id == 0)
- battery->present = 1;
- if (result || !battery->present)
- return result;
-
- if (saved_present != battery->present) {
- battery->update_time = 0;
- result = acpi_battery_get_info(battery);
- if (result)
- return result;
- }
- result = acpi_battery_get_state(battery);
- return result;
-}
/* Smart Battery */
+
static int acpi_battery_add(struct acpi_sbs *sbs, int id)
{
- struct acpi_battery *battery = &sbs->battery[id];
+ int is_present;
int result;
+ char dir_name[32];
+ struct acpi_battery *battery;
+ battery = &sbs->battery[id];
+
+ battery->alive = 0;
+
+ battery->init_state = 0;
battery->id = id;
battery->sbs = sbs;
- result = acpi_battery_read(battery);
- if (result)
- return result;
- sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id);
-#ifdef CONFIG_ACPI_PROCFS
- acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir,
- battery->name, &acpi_battery_info_fops,
- &acpi_battery_state_fops, &acpi_battery_alarm_fops,
- battery);
-#endif
- battery->bat.name = battery->name;
- battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
- if (!acpi_battery_mode(battery)) {
- battery->bat.properties = sbs_charge_battery_props;
- battery->bat.num_properties =
- ARRAY_SIZE(sbs_charge_battery_props);
- } else {
- battery->bat.properties = sbs_energy_battery_props;
- battery->bat.num_properties =
- ARRAY_SIZE(sbs_energy_battery_props);
+ result = acpi_battery_select(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_select() failed"));
+ goto end;
+ }
+
+ result = acpi_battery_get_present(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_get_present() failed"));
+ goto end;
+ }
+
+ is_present = battery->battery_present;
+
+ if (is_present) {
+ result = acpi_battery_init(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_init() failed"));
+ goto end;
+ }
+ battery->init_state = 1;
+ }
+
+ sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
+
+ result = acpi_sbs_generic_add_fs(&battery->battery_entry,
+ acpi_battery_dir,
+ dir_name,
+ &acpi_battery_info_fops,
+ &acpi_battery_state_fops,
+ &acpi_battery_alarm_fops, battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_generic_add_fs() failed"));
+ goto end;
}
- battery->bat.get_property = acpi_sbs_battery_get_property;
- result = power_supply_register(&sbs->device->dev, &battery->bat);
- device_create_file(battery->bat.dev, &alarm_attr);
+ battery->alive = 1;
+
printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
- ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
- battery->name, sbs->battery->present ? "present" : "absent");
+ ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), dir_name,
+ sbs->battery->battery_present ? "present" : "absent");
+
+ end:
return result;
}
static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
{
- if (sbs->battery[id].bat.dev)
- device_remove_file(sbs->battery[id].bat.dev, &alarm_attr);
- power_supply_unregister(&sbs->battery[id].bat);
-#ifdef CONFIG_ACPI_PROCFS
- if (sbs->battery[id].proc_entry) {
- acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry),
- acpi_battery_dir);
- }
-#endif
+
+ if (sbs->battery[id].battery_entry) {
+ acpi_sbs_generic_remove_fs(&(sbs->battery[id].battery_entry),
+ acpi_battery_dir);
+ }
}
-static int acpi_charger_add(struct acpi_sbs *sbs)
+static int acpi_ac_add(struct acpi_sbs *sbs)
{
int result;
result = acpi_ac_get_present(sbs);
- if (result)
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_ac_get_present() failed"));
goto end;
-#ifdef CONFIG_ACPI_PROCFS
- result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir,
- ACPI_AC_DIR_NAME, NULL,
- &acpi_ac_state_fops, NULL, sbs);
- if (result)
+ }
+
+ result = acpi_sbs_generic_add_fs(&sbs->ac_entry,
+ acpi_ac_dir,
+ ACPI_AC_DIR_NAME,
+ NULL, &acpi_ac_state_fops, NULL, sbs);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_generic_add_fs() failed"));
goto end;
-#endif
- sbs->charger.name = "sbs-charger";
- sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
- sbs->charger.properties = sbs_ac_props;
- sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props);
- sbs->charger.get_property = sbs_get_ac_property;
- power_supply_register(&sbs->device->dev, &sbs->charger);
+ }
+
printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
- ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
+ ACPI_AC_DIR_NAME, sbs->ac.ac_present ? "on-line" : "off-line");
+
end:
+
return result;
}
-static void acpi_charger_remove(struct acpi_sbs *sbs)
+static void acpi_ac_remove(struct acpi_sbs *sbs)
{
- if (sbs->charger.dev)
- power_supply_unregister(&sbs->charger);
-#ifdef CONFIG_ACPI_PROCFS
- if (sbs->charger_entry)
- acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
-#endif
+
+ if (sbs->ac_entry) {
+ acpi_sbs_generic_remove_fs(&sbs->ac_entry, acpi_ac_dir);
+ }
}
-void acpi_sbs_callback(void *context)
+static void acpi_sbs_update_time_run(unsigned long data)
{
- int id;
- struct acpi_sbs *sbs = context;
- struct acpi_battery *bat;
- u8 saved_charger_state = sbs->charger_present;
- u8 saved_battery_state;
- acpi_ac_get_present(sbs);
- if (sbs->charger_present != saved_charger_state) {
-#ifdef CONFIG_ACPI_PROC_EVENT
- acpi_bus_generate_proc_event4(ACPI_AC_CLASS, ACPI_AC_DIR_NAME,
- ACPI_SBS_NOTIFY_STATUS,
- sbs->charger_present);
-#endif
- kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
- }
- if (sbs->manager_present) {
- for (id = 0; id < MAX_SBS_BAT; ++id) {
- if (!(sbs->batteries_supported & (1 << id)))
- continue;
- bat = &sbs->battery[id];
- saved_battery_state = bat->present;
- acpi_battery_read(bat);
- if (saved_battery_state == bat->present)
- continue;
-#ifdef CONFIG_ACPI_PROC_EVENT
- acpi_bus_generate_proc_event4(ACPI_BATTERY_CLASS,
- bat->name,
- ACPI_SBS_NOTIFY_STATUS,
- bat->present);
-#endif
- kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE);
+ acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_time, (void *)data);
+}
+
+static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
+{
+ struct acpi_battery *battery;
+ int result = 0, cnt;
+ int old_ac_present = -1;
+ int old_battery_present = -1;
+ int new_ac_present = -1;
+ int new_battery_present = -1;
+ int id_min = 0, id_max = MAX_SBS_BAT - 1;
+ char dir_name[32];
+ int do_battery_init = 0, do_ac_init = 0;
+ int old_remaining_capacity = 0;
+ int update_battery = 1;
+ int up_tm = update_time;
+
+ if (sbs_zombie(sbs)) {
+ goto end;
+ }
+
+ if (id >= 0) {
+ id_min = id_max = id;
+ }
+
+ if (data_type == DATA_TYPE_COMMON && up_tm > 0) {
+ cnt = up_tm / (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
+ if (sbs->run_cnt % cnt != 0) {
+ update_battery = 0;
+ }
+ }
+
+ sbs->run_cnt++;
+
+ old_ac_present = sbs->ac.ac_present;
+
+ result = acpi_ac_get_present(sbs);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_ac_get_present() failed"));
+ }
+
+ new_ac_present = sbs->ac.ac_present;
+
+ do_ac_init = (old_ac_present != new_ac_present);
+ if (sbs->run_cnt == 1 && data_type == DATA_TYPE_COMMON) {
+ do_ac_init = 1;
+ }
+
+ if (do_ac_init) {
+ result = acpi_sbs_generate_event(sbs->device,
+ ACPI_SBS_AC_NOTIFY_STATUS,
+ new_ac_present,
+ ACPI_AC_DIR_NAME,
+ ACPI_AC_CLASS);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_generate_event() failed"));
+ }
+ }
+
+ if (data_type == DATA_TYPE_COMMON) {
+ if (!do_ac_init && !update_battery) {
+ goto end;
+ }
+ }
+
+ if (data_type == DATA_TYPE_AC_STATE && !do_ac_init) {
+ goto end;
+ }
+
+ for (id = id_min; id <= id_max; id++) {
+ battery = &sbs->battery[id];
+ if (battery->alive == 0) {
+ continue;
+ }
+
+ old_remaining_capacity = battery->state.remaining_capacity;
+
+ old_battery_present = battery->battery_present;
+
+ result = acpi_battery_select(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_select() failed"));
+ }
+
+ result = acpi_battery_get_present(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_get_present() failed"));
+ }
+
+ new_battery_present = battery->battery_present;
+
+ do_battery_init = ((old_battery_present != new_battery_present)
+ && new_battery_present);
+ if (!new_battery_present)
+ goto event;
+ if (do_ac_init || do_battery_init) {
+ result = acpi_battery_init(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_init() "
+ "failed"));
+ }
+ }
+ if (sbs_zombie(sbs)) {
+ goto end;
+ }
+
+ if ((data_type == DATA_TYPE_COMMON
+ || data_type == DATA_TYPE_INFO)
+ && new_battery_present) {
+ result = acpi_battery_get_info(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_get_info() failed"));
+ }
+ }
+ if (data_type == DATA_TYPE_INFO) {
+ continue;
+ }
+ if (sbs_zombie(sbs)) {
+ goto end;
+ }
+
+ if ((data_type == DATA_TYPE_COMMON
+ || data_type == DATA_TYPE_STATE)
+ && new_battery_present) {
+ result = acpi_battery_get_state(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_get_state() failed"));
+ }
+ }
+ if (data_type == DATA_TYPE_STATE) {
+ goto event;
+ }
+ if (sbs_zombie(sbs)) {
+ goto end;
+ }
+
+ if ((data_type == DATA_TYPE_COMMON
+ || data_type == DATA_TYPE_ALARM)
+ && new_battery_present) {
+ result = acpi_battery_get_alarm(battery);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_get_alarm() "
+ "failed"));
+ }
+ }
+ if (data_type == DATA_TYPE_ALARM) {
+ continue;
+ }
+ if (sbs_zombie(sbs)) {
+ goto end;
+ }
+
+ event:
+
+ if (old_battery_present != new_battery_present || do_ac_init ||
+ old_remaining_capacity !=
+ battery->state.remaining_capacity) {
+ sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
+ result = acpi_sbs_generate_event(sbs->device,
+ ACPI_SBS_BATTERY_NOTIFY_STATUS,
+ new_battery_present,
+ dir_name,
+ ACPI_BATTERY_CLASS);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_generate_event() "
+ "failed"));
+ }
}
}
+
+ end:
+
+ return result;
}
-static int acpi_sbs_remove(struct acpi_device *device, int type);
+static void acpi_sbs_update_time(void *data)
+{
+ struct acpi_sbs *sbs = data;
+ unsigned long delay = -1;
+ int result;
+ unsigned int up_tm = update_time;
+
+ if (sbs_mutex_lock(sbs))
+ return;
+
+ result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_COMMON);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_update_run() failed"));
+ }
+
+ if (sbs_zombie(sbs)) {
+ goto end;
+ }
+
+ if (!up_tm) {
+ if (timer_pending(&sbs->update_timer))
+ del_timer(&sbs->update_timer);
+ } else {
+ delay = (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
+ delay = jiffies + HZ * delay;
+ if (timer_pending(&sbs->update_timer)) {
+ mod_timer(&sbs->update_timer, delay);
+ } else {
+ sbs->update_timer.data = (unsigned long)data;
+ sbs->update_timer.function = acpi_sbs_update_time_run;
+ sbs->update_timer.expires = delay;
+ add_timer(&sbs->update_timer);
+ }
+ }
+
+ end:
+
+ sbs_mutex_unlock(sbs);
+}
static int acpi_sbs_add(struct acpi_device *device)
{
- struct acpi_sbs *sbs;
- int result = 0;
+ struct acpi_sbs *sbs = NULL;
+ int result = 0, remove_result = 0;
int id;
+ acpi_status status = AE_OK;
+ unsigned long val;
+
+ status =
+ acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC"));
+ return -EIO;
+ }
sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
if (!sbs) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kzalloc() failed"));
result = -ENOMEM;
goto end;
}
- mutex_init(&sbs->lock);
+ mutex_init(&sbs->mutex);
- sbs->hc = acpi_driver_data(device->parent);
+ sbs_mutex_lock(sbs);
+
+ sbs->base = 0xff & (val >> 8);
sbs->device = device;
+
strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
acpi_driver_data(device) = sbs;
- result = acpi_charger_add(sbs);
+ result = acpi_ac_add(sbs);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
+ goto end;
+ }
+
+ acpi_sbsm_get_info(sbs);
+
+ if (!sbs->sbsm_present) {
+ result = acpi_battery_add(sbs, 0);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_add() failed"));
+ goto end;
+ }
+ } else {
+ for (id = 0; id < MAX_SBS_BAT; id++) {
+ if ((sbs->sbsm_batteries_supported & (1 << id))) {
+ result = acpi_battery_add(sbs, id);
+ if (result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_battery_add() failed"));
+ goto end;
+ }
+ }
+ }
+ }
+
+ init_timer(&sbs->update_timer);
+ result = acpi_check_update_proc(sbs);
if (result)
goto end;
- result = acpi_manager_get_info(sbs);
- if (!result) {
- sbs->manager_present = 1;
- for (id = 0; id < MAX_SBS_BAT; ++id)
- if ((sbs->batteries_supported & (1 << id)))
- acpi_battery_add(sbs, id);
- } else
- acpi_battery_add(sbs, 0);
- acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs);
end:
- if (result)
- acpi_sbs_remove(device, 0);
+
+ sbs_mutex_unlock(sbs);
+
+ if (result) {
+ remove_result = acpi_sbs_remove(device, 0);
+ if (remove_result) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_sbs_remove() failed"));
+ }
+ }
+
return result;
}
@@ -947,25 +1713,39 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)
struct acpi_sbs *sbs;
int id;
- if (!device)
+ if (!device) {
return -EINVAL;
+ }
+
sbs = acpi_driver_data(device);
- if (!sbs)
+ if (!sbs) {
return -EINVAL;
- mutex_lock(&sbs->lock);
- acpi_smbus_unregister_callback(sbs->hc);
- for (id = 0; id < MAX_SBS_BAT; ++id)
+ }
+
+ sbs_mutex_lock(sbs);
+
+ sbs->zombie = 1;
+ del_timer_sync(&sbs->update_timer);
+ acpi_os_wait_events_complete(NULL);
+ del_timer_sync(&sbs->update_timer);
+
+ for (id = 0; id < MAX_SBS_BAT; id++) {
acpi_battery_remove(sbs, id);
- acpi_charger_remove(sbs);
- mutex_unlock(&sbs->lock);
- mutex_destroy(&sbs->lock);
+ }
+
+ acpi_ac_remove(sbs);
+
+ sbs_mutex_unlock(sbs);
+
+ mutex_destroy(&sbs->mutex);
+
kfree(sbs);
+
return 0;
}
static void acpi_sbs_rmdirs(void)
{
-#ifdef CONFIG_ACPI_PROCFS
if (acpi_ac_dir) {
acpi_unlock_ac_dir(acpi_ac_dir);
acpi_ac_dir = NULL;
@@ -974,58 +1754,69 @@ static void acpi_sbs_rmdirs(void)
acpi_unlock_battery_dir(acpi_battery_dir);
acpi_battery_dir = NULL;
}
-#endif
}
static int acpi_sbs_resume(struct acpi_device *device)
{
struct acpi_sbs *sbs;
+
if (!device)
return -EINVAL;
+
sbs = device->driver_data;
- acpi_sbs_callback(sbs);
+
+ sbs->run_cnt = 0;
+
return 0;
}
-static struct acpi_driver acpi_sbs_driver = {
- .name = "sbs",
- .class = ACPI_SBS_CLASS,
- .ids = sbs_device_ids,
- .ops = {
- .add = acpi_sbs_add,
- .remove = acpi_sbs_remove,
- .resume = acpi_sbs_resume,
- },
-};
-
static int __init acpi_sbs_init(void)
{
int result = 0;
if (acpi_disabled)
return -ENODEV;
-#ifdef CONFIG_ACPI_PROCFS
+
+ if (capacity_mode != DEF_CAPACITY_UNIT
+ && capacity_mode != MAH_CAPACITY_UNIT
+ && capacity_mode != MWH_CAPACITY_UNIT) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "invalid capacity_mode = %d", capacity_mode));
+ return -EINVAL;
+ }
+
acpi_ac_dir = acpi_lock_ac_dir();
- if (!acpi_ac_dir)
+ if (!acpi_ac_dir) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_lock_ac_dir() failed"));
return -ENODEV;
+ }
+
acpi_battery_dir = acpi_lock_battery_dir();
if (!acpi_battery_dir) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_lock_battery_dir() failed"));
acpi_sbs_rmdirs();
return -ENODEV;
}
-#endif
+
result = acpi_bus_register_driver(&acpi_sbs_driver);
if (result < 0) {
+ ACPI_EXCEPTION((AE_INFO, AE_ERROR,
+ "acpi_bus_register_driver() failed"));
acpi_sbs_rmdirs();
return -ENODEV;
}
+
return 0;
}
static void __exit acpi_sbs_exit(void)
{
acpi_bus_unregister_driver(&acpi_sbs_driver);
+
acpi_sbs_rmdirs();
+
return;
}
diff --git a/trunk/drivers/acpi/sbshc.c b/trunk/drivers/acpi/sbshc.c
deleted file mode 100644
index 046d7c3ed356..000000000000
--- a/trunk/drivers/acpi/sbshc.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * SMBus driver for ACPI Embedded Controller (v0.1)
- *
- * Copyright (c) 2007 Alexey Starikovskiy
- *
- * 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 version 2.
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include "sbshc.h"
-
-#define ACPI_SMB_HC_CLASS "smbus_host_controller"
-#define ACPI_SMB_HC_DEVICE_NAME "ACPI SMBus HC"
-
-struct acpi_smb_hc {
- struct acpi_ec *ec;
- struct mutex lock;
- wait_queue_head_t wait;
- u8 offset;
- u8 query_bit;
- smbus_alarm_callback callback;
- void *context;
-};
-
-static int acpi_smbus_hc_add(struct acpi_device *device);
-static int acpi_smbus_hc_remove(struct acpi_device *device, int type);
-
-static const struct acpi_device_id sbs_device_ids[] = {
- {"ACPI0001", 0},
- {"ACPI0005", 0},
- {"", 0},
-};
-
-MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
-
-static struct acpi_driver acpi_smb_hc_driver = {
- .name = "smbus_hc",
- .class = ACPI_SMB_HC_CLASS,
- .ids = sbs_device_ids,
- .ops = {
- .add = acpi_smbus_hc_add,
- .remove = acpi_smbus_hc_remove,
- },
-};
-
-union acpi_smb_status {
- u8 raw;
- struct {
- u8 status:5;
- u8 reserved:1;
- u8 alarm:1;
- u8 done:1;
- } fields;
-};
-
-enum acpi_smb_status_codes {
- SMBUS_OK = 0,
- SMBUS_UNKNOWN_FAILURE = 0x07,
- SMBUS_DEVICE_ADDRESS_NACK = 0x10,
- SMBUS_DEVICE_ERROR = 0x11,
- SMBUS_DEVICE_COMMAND_ACCESS_DENIED = 0x12,
- SMBUS_UNKNOWN_ERROR = 0x13,
- SMBUS_DEVICE_ACCESS_DENIED = 0x17,
- SMBUS_TIMEOUT = 0x18,
- SMBUS_HOST_UNSUPPORTED_PROTOCOL = 0x19,
- SMBUS_BUSY = 0x1a,
- SMBUS_PEC_ERROR = 0x1f,
-};
-
-enum acpi_smb_offset {
- ACPI_SMB_PROTOCOL = 0, /* protocol, PEC */
- ACPI_SMB_STATUS = 1, /* status */
- ACPI_SMB_ADDRESS = 2, /* address */
- ACPI_SMB_COMMAND = 3, /* command */
- ACPI_SMB_DATA = 4, /* 32 data registers */
- ACPI_SMB_BLOCK_COUNT = 0x24, /* number of data bytes */
- ACPI_SMB_ALARM_ADDRESS = 0x25, /* alarm address */
- ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */
-};
-
-static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data)
-{
- return ec_read(hc->offset + address, data);
-}
-
-static inline int smb_hc_write(struct acpi_smb_hc *hc, u8 address, u8 data)
-{
- return ec_write(hc->offset + address, data);
-}
-
-static inline int smb_check_done(struct acpi_smb_hc *hc)
-{
- union acpi_smb_status status = {.raw = 0};
- smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw);
- return status.fields.done && (status.fields.status == SMBUS_OK);
-}
-
-static int wait_transaction_complete(struct acpi_smb_hc *hc, int timeout)
-{
- if (wait_event_timeout(hc->wait, smb_check_done(hc),
- msecs_to_jiffies(timeout)))
- return 0;
- else
- return -ETIME;
-}
-
-int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol, u8 address,
- u8 command, u8 *data, u8 length)
-{
- int ret = -EFAULT, i;
- u8 temp, sz = 0;
-
- mutex_lock(&hc->lock);
- if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp))
- goto end;
- if (temp) {
- ret = -EBUSY;
- goto end;
- }
- smb_hc_write(hc, ACPI_SMB_COMMAND, command);
- smb_hc_write(hc, ACPI_SMB_COMMAND, command);
- if (!(protocol & 0x01)) {
- smb_hc_write(hc, ACPI_SMB_BLOCK_COUNT, length);
- for (i = 0; i < length; ++i)
- smb_hc_write(hc, ACPI_SMB_DATA + i, data[i]);
- }
- smb_hc_write(hc, ACPI_SMB_ADDRESS, address << 1);
- smb_hc_write(hc, ACPI_SMB_PROTOCOL, protocol);
- /*
- * Wait for completion. Save the status code, data size,
- * and data into the return package (if required by the protocol).
- */
- ret = wait_transaction_complete(hc, 1000);
- if (ret || !(protocol & 0x01))
- goto end;
- switch (protocol) {
- case SMBUS_RECEIVE_BYTE:
- case SMBUS_READ_BYTE:
- sz = 1;
- break;
- case SMBUS_READ_WORD:
- sz = 2;
- break;
- case SMBUS_READ_BLOCK:
- if (smb_hc_read(hc, ACPI_SMB_BLOCK_COUNT, &sz)) {
- ret = -EFAULT;
- goto end;
- }
- sz &= 0x1f;
- break;
- }
- for (i = 0; i < sz; ++i)
- smb_hc_read(hc, ACPI_SMB_DATA + i, &data[i]);
- end:
- mutex_unlock(&hc->lock);
- return ret;
-}
-
-int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
- u8 command, u8 *data)
-{
- return acpi_smbus_transaction(hc, protocol, address, command, data, 0);
-}
-
-EXPORT_SYMBOL_GPL(acpi_smbus_read);
-
-int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 address,
- u8 command, u8 *data, u8 length)
-{
- return acpi_smbus_transaction(hc, protocol, address, command, data, length);
-}
-
-EXPORT_SYMBOL_GPL(acpi_smbus_write);
-
-int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
- smbus_alarm_callback callback, void *context)
-{
- mutex_lock(&hc->lock);
- hc->callback = callback;
- hc->context = context;
- mutex_unlock(&hc->lock);
- return 0;
-}
-
-EXPORT_SYMBOL_GPL(acpi_smbus_register_callback);
-
-int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc)
-{
- mutex_lock(&hc->lock);
- hc->callback = NULL;
- hc->context = NULL;
- mutex_unlock(&hc->lock);
- return 0;
-}
-
-EXPORT_SYMBOL_GPL(acpi_smbus_unregister_callback);
-
-static void acpi_smbus_callback(void *context)
-{
- struct acpi_smb_hc *hc = context;
-
- if (hc->callback)
- hc->callback(hc->context);
-}
-
-static int smbus_alarm(void *context)
-{
- struct acpi_smb_hc *hc = context;
- union acpi_smb_status status;
- if (smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw))
- return 0;
- /* Check if it is only a completion notify */
- if (status.fields.done)
- wake_up(&hc->wait);
- if (!status.fields.alarm)
- return 0;
- mutex_lock(&hc->lock);
- smb_hc_write(hc, ACPI_SMB_STATUS, status.raw);
- if (hc->callback)
- acpi_os_execute(OSL_GPE_HANDLER, acpi_smbus_callback, hc);
- mutex_unlock(&hc->lock);
- return 0;
-}
-
-typedef int (*acpi_ec_query_func) (void *data);
-
-extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
- acpi_handle handle, acpi_ec_query_func func,
- void *data);
-
-static int acpi_smbus_hc_add(struct acpi_device *device)
-{
- int status;
- unsigned long val;
- struct acpi_smb_hc *hc;
-
- if (!device)
- return -EINVAL;
-
- status = acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
- if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX "error obtaining _EC.\n");
- return -EIO;
- }
-
- strcpy(acpi_device_name(device), ACPI_SMB_HC_DEVICE_NAME);
- strcpy(acpi_device_class(device), ACPI_SMB_HC_CLASS);
-
- hc = kzalloc(sizeof(struct acpi_smb_hc), GFP_KERNEL);
- if (!hc)
- return -ENOMEM;
- mutex_init(&hc->lock);
- init_waitqueue_head(&hc->wait);
-
- hc->ec = acpi_driver_data(device->parent);
- hc->offset = (val >> 8) & 0xff;
- hc->query_bit = val & 0xff;
- acpi_driver_data(device) = hc;
-
- acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
- printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n",
- hc->ec, hc->offset, hc->query_bit);
-
- return 0;
-}
-
-extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
-
-static int acpi_smbus_hc_remove(struct acpi_device *device, int type)
-{
- struct acpi_smb_hc *hc;
-
- if (!device)
- return -EINVAL;
-
- hc = acpi_driver_data(device);
- acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
- kfree(hc);
- return 0;
-}
-
-static int __init acpi_smb_hc_init(void)
-{
- int result;
-
- result = acpi_bus_register_driver(&acpi_smb_hc_driver);
- if (result < 0)
- return -ENODEV;
- return 0;
-}
-
-static void __exit acpi_smb_hc_exit(void)
-{
- acpi_bus_unregister_driver(&acpi_smb_hc_driver);
-}
-
-module_init(acpi_smb_hc_init);
-module_exit(acpi_smb_hc_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Alexey Starikovskiy");
-MODULE_DESCRIPTION("ACPI SMBus HC driver");
diff --git a/trunk/drivers/acpi/sbshc.h b/trunk/drivers/acpi/sbshc.h
deleted file mode 100644
index 3bda3491a97b..000000000000
--- a/trunk/drivers/acpi/sbshc.h
+++ /dev/null
@@ -1,27 +0,0 @@
-struct acpi_smb_hc;
-enum acpi_smb_protocol {
- SMBUS_WRITE_QUICK = 2,
- SMBUS_READ_QUICK = 3,
- SMBUS_SEND_BYTE = 4,
- SMBUS_RECEIVE_BYTE = 5,
- SMBUS_WRITE_BYTE = 6,
- SMBUS_READ_BYTE = 7,
- SMBUS_WRITE_WORD = 8,
- SMBUS_READ_WORD = 9,
- SMBUS_WRITE_BLOCK = 0xa,
- SMBUS_READ_BLOCK = 0xb,
- SMBUS_PROCESS_CALL = 0xc,
- SMBUS_BLOCK_PROCESS_CALL = 0xd,
-};
-
-static const u8 SMBUS_PEC = 0x80;
-
-typedef void (*smbus_alarm_callback)(void *context);
-
-extern int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
- u8 command, u8 * data);
-extern int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 slave_address,
- u8 command, u8 * data, u8 length);
-extern int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
- smbus_alarm_callback callback, void *context);
-extern int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc);
diff --git a/trunk/drivers/acpi/sleep/main.c b/trunk/drivers/acpi/sleep/main.c
index f3d3867303ec..048295ec3707 100644
--- a/trunk/drivers/acpi/sleep/main.c
+++ b/trunk/drivers/acpi/sleep/main.c
@@ -44,6 +44,7 @@ int acpi_sleep_prepare(u32 acpi_state)
ACPI_FLUSH_CPU_CACHE();
acpi_enable_wakeup_device_prep(acpi_state);
#endif
+ acpi_gpe_sleep_prepare(acpi_state);
acpi_enter_sleep_state_prep(acpi_state);
return 0;
}
@@ -267,11 +268,6 @@ static void acpi_hibernation_leave(void)
static void acpi_hibernation_finish(void)
{
- /*
- * If ACPI is not enabled by the BIOS and the boot kernel, we need to
- * enable it here.
- */
- acpi_enable();
acpi_leave_sleep_state(ACPI_STATE_S4);
acpi_disable_wakeup_device(ACPI_STATE_S4);
diff --git a/trunk/drivers/acpi/sleep/sleep.h b/trunk/drivers/acpi/sleep/sleep.h
index a2ea125ae2d0..ff1f8504f497 100644
--- a/trunk/drivers/acpi/sleep/sleep.h
+++ b/trunk/drivers/acpi/sleep/sleep.h
@@ -5,5 +5,6 @@ extern int acpi_suspend (u32 state);
extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
extern void acpi_enable_wakeup_device(u8 sleep_state);
extern void acpi_disable_wakeup_device(u8 sleep_state);
+extern void acpi_gpe_sleep_prepare(u32 sleep_state);
extern int acpi_sleep_prepare(u32 acpi_state);
diff --git a/trunk/drivers/acpi/sleep/wakeup.c b/trunk/drivers/acpi/sleep/wakeup.c
index ed8e41becf0c..97c27ddb144d 100644
--- a/trunk/drivers/acpi/sleep/wakeup.c
+++ b/trunk/drivers/acpi/sleep/wakeup.c
@@ -64,29 +64,36 @@ void acpi_enable_wakeup_device(u8 sleep_state)
ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device");
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device *dev =
- container_of(node, struct acpi_device, wakeup_list);
- if (!dev->wakeup.flags.valid)
- continue;
+ struct acpi_device *dev = container_of(node,
+ struct acpi_device,
+ wakeup_list);
+
/* If users want to disable run-wake GPE,
* we only disable it for wake and leave it for runtime
*/
- if (!dev->wakeup.state.enabled ||
- sleep_state > (u32) dev->wakeup.sleep_state) {
- if (dev->wakeup.flags.run_wake) {
- spin_unlock(&acpi_device_lock);
- /* set_gpe_type will disable GPE, leave it like that */
- acpi_set_gpe_type(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number,
- ACPI_GPE_TYPE_RUNTIME);
- spin_lock(&acpi_device_lock);
- }
+ if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
+ spin_unlock(&acpi_device_lock);
+ acpi_set_gpe_type(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number,
+ ACPI_GPE_TYPE_RUNTIME);
+ /* Re-enable it, since set_gpe_type will disable it */
+ acpi_enable_gpe(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number, ACPI_ISR);
+ spin_lock(&acpi_device_lock);
continue;
}
+
+ if (!dev->wakeup.flags.valid ||
+ !dev->wakeup.state.enabled ||
+ (sleep_state > (u32) dev->wakeup.sleep_state))
+ continue;
+
spin_unlock(&acpi_device_lock);
+ /* run-wake GPE has been enabled */
if (!dev->wakeup.flags.run_wake)
acpi_enable_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number, ACPI_ISR);
+ dev->wakeup.state.active = 1;
spin_lock(&acpi_device_lock);
}
spin_unlock(&acpi_device_lock);
@@ -105,26 +112,27 @@ void acpi_disable_wakeup_device(u8 sleep_state)
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device *dev =
- container_of(node, struct acpi_device, wakeup_list);
+ struct acpi_device *dev = container_of(node,
+ struct acpi_device,
+ wakeup_list);
- if (!dev->wakeup.flags.valid)
- continue;
- if (!dev->wakeup.state.enabled ||
- sleep_state > (u32) dev->wakeup.sleep_state) {
- if (dev->wakeup.flags.run_wake) {
- spin_unlock(&acpi_device_lock);
- acpi_set_gpe_type(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number,
- ACPI_GPE_TYPE_WAKE_RUN);
- /* Re-enable it, since set_gpe_type will disable it */
- acpi_enable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_NOT_ISR);
- spin_lock(&acpi_device_lock);
- }
+ if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
+ spin_unlock(&acpi_device_lock);
+ acpi_set_gpe_type(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number,
+ ACPI_GPE_TYPE_WAKE_RUN);
+ /* Re-enable it, since set_gpe_type will disable it */
+ acpi_enable_gpe(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number, ACPI_NOT_ISR);
+ spin_lock(&acpi_device_lock);
continue;
}
+ if (!dev->wakeup.flags.valid ||
+ !dev->wakeup.state.active ||
+ (sleep_state > (u32) dev->wakeup.sleep_state))
+ continue;
+
spin_unlock(&acpi_device_lock);
acpi_disable_wakeup_device_power(dev);
/* Never disable run-wake GPE */
@@ -134,6 +142,7 @@ void acpi_disable_wakeup_device(u8 sleep_state)
acpi_clear_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number, ACPI_NOT_ISR);
}
+ dev->wakeup.state.active = 0;
spin_lock(&acpi_device_lock);
}
spin_unlock(&acpi_device_lock);
@@ -151,20 +160,48 @@ static int __init acpi_wakeup_device_init(void)
struct acpi_device *dev = container_of(node,
struct acpi_device,
wakeup_list);
+
/* In case user doesn't load button driver */
- if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
- continue;
- spin_unlock(&acpi_device_lock);
- acpi_set_gpe_type(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number,
- ACPI_GPE_TYPE_WAKE_RUN);
- acpi_enable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_NOT_ISR);
- dev->wakeup.state.enabled = 1;
- spin_lock(&acpi_device_lock);
+ if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
+ spin_unlock(&acpi_device_lock);
+ acpi_set_gpe_type(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number,
+ ACPI_GPE_TYPE_WAKE_RUN);
+ acpi_enable_gpe(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number, ACPI_NOT_ISR);
+ dev->wakeup.state.enabled = 1;
+ spin_lock(&acpi_device_lock);
+ }
}
spin_unlock(&acpi_device_lock);
+
return 0;
}
late_initcall(acpi_wakeup_device_init);
+
+/*
+ * Disable all wakeup GPEs before entering requested sleep state.
+ * @sleep_state: ACPI state
+ * Since acpi_enter_sleep_state() will disable all
+ * RUNTIME GPEs, we simply mark all GPES that
+ * are not enabled for wakeup from requested state as RUNTIME.
+ */
+void acpi_gpe_sleep_prepare(u32 sleep_state)
+{
+ struct list_head *node, *next;
+
+ list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+ struct acpi_device *dev = container_of(node,
+ struct acpi_device,
+ wakeup_list);
+
+ /* The GPE can wakeup system from this state, don't touch it */
+ if ((u32) dev->wakeup.sleep_state >= sleep_state)
+ continue;
+ /* acpi_set_gpe_type will automatically disable GPE */
+ acpi_set_gpe_type(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number,
+ ACPI_GPE_TYPE_RUNTIME);
+ }
+}
diff --git a/trunk/drivers/acpi/tables/tbutils.c b/trunk/drivers/acpi/tables/tbutils.c
index 5f1d85f2ffe4..8cc9492ffbf2 100644
--- a/trunk/drivers/acpi/tables/tbutils.c
+++ b/trunk/drivers/acpi/tables/tbutils.c
@@ -400,7 +400,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
u32 table_count;
struct acpi_table_header *table;
acpi_physical_address address;
- acpi_physical_address uninitialized_var(rsdt_address);
+ acpi_physical_address rsdt_address;
u32 length;
u8 *table_entry;
acpi_status status;
diff --git a/trunk/drivers/acpi/thermal.c b/trunk/drivers/acpi/thermal.c
index 5f79b4451212..ad898e10c1a9 100644
--- a/trunk/drivers/acpi/thermal.c
+++ b/trunk/drivers/acpi/thermal.c
@@ -195,7 +195,6 @@ struct acpi_thermal {
struct acpi_thermal_trips trips;
struct acpi_handle_list devices;
struct timer_list timer;
- struct mutex lock;
};
static const struct file_operations acpi_thermal_state_fops = {
@@ -712,7 +711,6 @@ static void acpi_thermal_check(void *data)
int result = 0;
struct acpi_thermal *tz = data;
unsigned long sleep_time = 0;
- unsigned long timeout_jiffies = 0;
int i = 0;
struct acpi_thermal_state state;
@@ -722,15 +720,11 @@ static void acpi_thermal_check(void *data)
return;
}
- /* Check if someone else is already running */
- if (!mutex_trylock(&tz->lock))
- return;
-
state = tz->state;
result = acpi_thermal_get_temperature(tz);
if (result)
- goto unlock;
+ return;
memset(&tz->state, 0, sizeof(tz->state));
@@ -793,13 +787,10 @@ static void acpi_thermal_check(void *data)
* a thermal event occurs). Note that _TSP and _TZD values are
* given in 1/10th seconds (we must covert to milliseconds).
*/
- if (tz->state.passive) {
+ if (tz->state.passive)
sleep_time = tz->trips.passive.tsp * 100;
- timeout_jiffies = jiffies + (HZ * sleep_time) / 1000;
- } else if (tz->polling_frequency > 0) {
+ else if (tz->polling_frequency > 0)
sleep_time = tz->polling_frequency * 100;
- timeout_jiffies = round_jiffies(jiffies + (HZ * sleep_time) / 1000);
- }
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
tz->name, tz->temperature, sleep_time));
@@ -813,16 +804,17 @@ static void acpi_thermal_check(void *data)
del_timer(&(tz->timer));
} else {
if (timer_pending(&(tz->timer)))
- mod_timer(&(tz->timer), timeout_jiffies);
+ mod_timer(&(tz->timer),
+ jiffies + (HZ * sleep_time) / 1000);
else {
tz->timer.data = (unsigned long)tz;
tz->timer.function = acpi_thermal_run;
- tz->timer.expires = timeout_jiffies;
+ tz->timer.expires = jiffies + (HZ * sleep_time) / 1000;
add_timer(&(tz->timer));
}
}
- unlock:
- mutex_unlock(&tz->lock);
+
+ return;
}
/* --------------------------------------------------------------------------
@@ -1259,7 +1251,7 @@ static int acpi_thermal_add(struct acpi_device *device)
strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
acpi_driver_data(device) = tz;
- mutex_init(&tz->lock);
+
result = acpi_thermal_get_info(tz);
if (result)
goto end;
@@ -1329,7 +1321,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
}
acpi_thermal_remove_fs(device);
- mutex_destroy(&tz->lock);
+
kfree(tz);
return 0;
}
diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c
index bac956b30c57..b8a2095cb5ee 100644
--- a/trunk/drivers/acpi/video.c
+++ b/trunk/drivers/acpi/video.c
@@ -409,17 +409,14 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
static int
acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
{
- int status = AE_OK;
+ int status;
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list args = { 1, &arg0 };
arg0.integer.value = level;
+ status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL);
- if (device->cap._BCM)
- status = acpi_evaluate_object(device->dev->handle, "_BCM",
- &args, NULL);
- device->brightness->curr = level;
return status;
}
@@ -427,11 +424,11 @@ static int
acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
unsigned long *level)
{
- if (device->cap._BQC)
- return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
- level);
- *level = device->brightness->curr;
- return AE_OK;
+ int status;
+
+ status = acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, level);
+
+ return status;
}
static int
@@ -1636,20 +1633,9 @@ static int
acpi_video_get_next_level(struct acpi_video_device *device,
u32 level_current, u32 event)
{
- int min, max, min_above, max_below, i, l, delta = 255;
+ int min, max, min_above, max_below, i, l;
max = max_below = 0;
min = min_above = 255;
- /* Find closest level to level_current */
- for (i = 0; i < device->brightness->count; i++) {
- l = device->brightness->levels[i];
- if (abs(l - level_current) < abs(delta)) {
- delta = l - level_current;
- if (!delta)
- break;
- }
- }
- /* Ajust level_current to closest available level */
- level_current += delta;
for (i = 0; i < device->brightness->count; i++) {
l = device->brightness->levels[i];
if (l < min)
diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c
index bbaa545ea999..629eadbd0ec0 100644
--- a/trunk/drivers/ata/libata-core.c
+++ b/trunk/drivers/ata/libata-core.c
@@ -1392,7 +1392,7 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
* @tf: Taskfile registers for the command and the result
* @cdb: CDB for packet command
* @dma_dir: Data tranfer direction of the command
- * @sg: sg list for the data buffer of the command
+ * @sgl: sg list for the data buffer of the command
* @n_elem: Number of sg entries
* @timeout: Timeout in msecs (0 for default)
*
diff --git a/trunk/drivers/block/nbd.c b/trunk/drivers/block/nbd.c
index ac4a0cb217ab..cb136a919f2a 100644
--- a/trunk/drivers/block/nbd.c
+++ b/trunk/drivers/block/nbd.c
@@ -188,7 +188,7 @@ static int sock_xmit(struct nbd_device *lo, int send, void *buf, int size,
if (signal_pending(current)) {
siginfo_t info;
printk(KERN_WARNING "nbd (pid %d: %s) got signal %d\n",
- task_pid_nr(current), current->comm,
+ current->pid, current->comm,
dequeue_signal_lock(current, ¤t->blocked, &info));
result = -EINTR;
sock_shutdown(lo, !send);
diff --git a/trunk/drivers/cdrom/cdrom.c b/trunk/drivers/cdrom/cdrom.c
index af0561053167..d70745c84250 100644
--- a/trunk/drivers/cdrom/cdrom.c
+++ b/trunk/drivers/cdrom/cdrom.c
@@ -1107,7 +1107,7 @@ int open_for_data(struct cdrom_device_info * cdi)
is the default case! */
cdinfo(CD_OPEN, "bummer. wrong media type.\n");
cdinfo(CD_WARNING, "pid %d must open device O_NONBLOCK!\n",
- (unsigned int)task_pid_nr(current));
+ (unsigned int)current->pid);
ret=-EMEDIUMTYPE;
goto clean_up_and_return;
}
diff --git a/trunk/drivers/char/drm/drm_bufs.c b/trunk/drivers/char/drm/drm_bufs.c
index d24a6c2c2c24..856774fbe025 100644
--- a/trunk/drivers/char/drm/drm_bufs.c
+++ b/trunk/drivers/char/drm/drm_bufs.c
@@ -1456,7 +1456,7 @@ int drm_freebufs(struct drm_device *dev, void *data,
buf = dma->buflist[idx];
if (buf->file_priv != file_priv) {
DRM_ERROR("Process %d freeing buffer not owned\n",
- task_pid_nr(current));
+ current->pid);
return -EINVAL;
}
drm_free_buffer(dev, buf);
diff --git a/trunk/drivers/char/drm/drm_drv.c b/trunk/drivers/char/drm/drm_drv.c
index 44a46268b02b..72668b15e5ce 100644
--- a/trunk/drivers/char/drm/drm_drv.c
+++ b/trunk/drivers/char/drm/drm_drv.c
@@ -463,7 +463,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
++file_priv->ioctl_count;
DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
- task_pid_nr(current), cmd, nr,
+ current->pid, cmd, nr,
(long)old_encode_dev(file_priv->head->device),
file_priv->authenticated);
diff --git a/trunk/drivers/char/drm/drm_fops.c b/trunk/drivers/char/drm/drm_fops.c
index 3992f73299cc..f383fc37190c 100644
--- a/trunk/drivers/char/drm/drm_fops.c
+++ b/trunk/drivers/char/drm/drm_fops.c
@@ -234,7 +234,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
if (!drm_cpu_valid())
return -EINVAL;
- DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor);
+ DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
if (!priv)
@@ -244,7 +244,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
filp->private_data = priv;
priv->filp = filp;
priv->uid = current->euid;
- priv->pid = task_pid_nr(current);
+ priv->pid = current->pid;
priv->minor = minor;
priv->head = drm_heads[minor];
priv->ioctl_count = 0;
@@ -339,8 +339,7 @@ int drm_release(struct inode *inode, struct file *filp)
*/
DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
- task_pid_nr(current),
- (long)old_encode_dev(file_priv->head->device),
+ current->pid, (long)old_encode_dev(file_priv->head->device),
dev->open_count);
if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) {
diff --git a/trunk/drivers/char/drm/drm_lock.c b/trunk/drivers/char/drm/drm_lock.c
index bea2a7d5b2b2..c6b73e744d67 100644
--- a/trunk/drivers/char/drm/drm_lock.c
+++ b/trunk/drivers/char/drm/drm_lock.c
@@ -58,12 +58,12 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
if (lock->context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
- task_pid_nr(current), lock->context);
+ current->pid, lock->context);
return -EINVAL;
}
DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
- lock->context, task_pid_nr(current),
+ lock->context, current->pid,
dev->lock.hw_lock->lock, lock->flags);
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
@@ -153,7 +153,7 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
if (lock->context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
- task_pid_nr(current), lock->context);
+ current->pid, lock->context);
return -EINVAL;
}
diff --git a/trunk/drivers/char/drm/drm_os_linux.h b/trunk/drivers/char/drm/drm_os_linux.h
index 76e44ac94fb5..114e54e0f61b 100644
--- a/trunk/drivers/char/drm/drm_os_linux.h
+++ b/trunk/drivers/char/drm/drm_os_linux.h
@@ -7,7 +7,7 @@
#include
/** Current process ID */
-#define DRM_CURRENTPID task_pid_nr(current)
+#define DRM_CURRENTPID current->pid
#define DRM_SUSER(p) capable(CAP_SYS_ADMIN)
#define DRM_UDELAY(d) udelay(d)
/** Read a byte from a MMIO region */
diff --git a/trunk/drivers/char/drm/i810_dma.c b/trunk/drivers/char/drm/i810_dma.c
index eb381a7c5bee..8e841bdee6dc 100644
--- a/trunk/drivers/char/drm/i810_dma.c
+++ b/trunk/drivers/char/drm/i810_dma.c
@@ -1024,7 +1024,7 @@ static int i810_getbuf(struct drm_device *dev, void *data,
retcode = i810_dma_get_buffer(dev, d, file_priv);
DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
- task_pid_nr(current), retcode, d->granted);
+ current->pid, retcode, d->granted);
sarea_priv->last_dispatch = (int)hw_status[5];
diff --git a/trunk/drivers/char/drm/i830_dma.c b/trunk/drivers/char/drm/i830_dma.c
index 69a363edb0d2..43a1f78712d6 100644
--- a/trunk/drivers/char/drm/i830_dma.c
+++ b/trunk/drivers/char/drm/i830_dma.c
@@ -1409,7 +1409,7 @@ static int i830_getbuf(struct drm_device *dev, void *data,
retcode = i830_dma_get_buffer(dev, d, file_priv);
DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n",
- task_pid_nr(current), retcode, d->granted);
+ current->pid, retcode, d->granted);
sarea_priv->last_dispatch = (int)hw_status[5];
diff --git a/trunk/drivers/char/esp.c b/trunk/drivers/char/esp.c
index 0f8fb135da53..2e7ae42a5503 100644
--- a/trunk/drivers/char/esp.c
+++ b/trunk/drivers/char/esp.c
@@ -58,10 +58,10 @@
#include
#include
#include
-#include
#include
#include
+#include
#include
#include
diff --git a/trunk/drivers/char/keyboard.c b/trunk/drivers/char/keyboard.c
index fc54d234507a..212276affa1f 100644
--- a/trunk/drivers/char/keyboard.c
+++ b/trunk/drivers/char/keyboard.c
@@ -42,7 +42,6 @@
#include
#include
#include
-#include
extern void ctrl_alt_del(void);
@@ -82,8 +81,7 @@ void compute_shiftstate(void);
typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
char up_flag);
static k_handler_fn K_HANDLERS;
-k_handler_fn *k_handler[16] = { K_HANDLERS };
-EXPORT_SYMBOL_GPL(k_handler);
+static k_handler_fn *k_handler[16] = { K_HANDLERS };
#define FN_HANDLERS\
fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
@@ -129,7 +127,7 @@ int shift_state = 0;
*/
static struct input_handler kbd_handler;
-static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
+static unsigned long key_down[NBITS(KEY_MAX)]; /* keyboard key bitmap */
static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
static int dead_key_next;
static int npadch = -1; /* -1 or number assembled on pad */
@@ -161,23 +159,6 @@ static int sysrq_alt_use;
#endif
static int sysrq_alt;
-/*
- * Notifier list for console keyboard events
- */
-static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list);
-
-int register_keyboard_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_register(&keyboard_notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(register_keyboard_notifier);
-
-int unregister_keyboard_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb);
-}
-EXPORT_SYMBOL_GPL(unregister_keyboard_notifier);
-
/*
* Translation of scancodes to keycodes. We set them on only the first
* keyboard in the list that accepts the scancode and keycode.
@@ -1149,7 +1130,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
unsigned char type, raw_mode;
struct tty_struct *tty;
int shift_final;
- struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down };
tty = vc->vc_tty;
@@ -1237,11 +1217,10 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
return;
}
- param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
+ shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
key_map = key_maps[shift_final];
- if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYCODE, ¶m) == NOTIFY_STOP || !key_map) {
- atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNBOUND_KEYCODE, ¶m);
+ if (!key_map) {
compute_shiftstate();
kbd->slockstate = 0;
return;
@@ -1258,9 +1237,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
type = KTYP(keysym);
if (type < 0xf0) {
- param.value = keysym;
- if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNICODE, ¶m) == NOTIFY_STOP)
- return;
if (down && !raw_mode)
to_utf8(vc, keysym);
return;
@@ -1268,6 +1244,9 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
type -= 0xf0;
+ if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
+ return;
+
if (type == KT_LETTER) {
type = KT_LATIN;
if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
@@ -1276,18 +1255,9 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
keysym = key_map[keycode];
}
}
- param.value = keysym;
-
- if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYSYM, ¶m) == NOTIFY_STOP)
- return;
-
- if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
- return;
(*k_handler[type])(vc, keysym & 0xff, !down);
- atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, ¶m);
-
if (type != KT_SLOCK)
kbd->slockstate = 0;
}
@@ -1377,12 +1347,12 @@ static void kbd_start(struct input_handle *handle)
static const struct input_device_id kbd_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
- .evbit = { BIT_MASK(EV_KEY) },
+ .evbit = { BIT(EV_KEY) },
},
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
- .evbit = { BIT_MASK(EV_SND) },
+ .evbit = { BIT(EV_SND) },
},
{ }, /* Terminating entry */
diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c
index fd0abef7ee08..661aca0e155d 100644
--- a/trunk/drivers/char/mxser.c
+++ b/trunk/drivers/char/mxser.c
@@ -56,11 +56,11 @@
#include
#include
#include